Module Name:    src
Committed By:   riz
Date:           Mon Apr  9 17:46:58 UTC 2012

Modified Files:
        src/sys/dev [netbsd-6]: audio.c

Log Message:
Pull up following revision(s) (requested by mrg in ticket #164):
        sys/dev/audio.c: revision 1.259
deal with PR#46232:  ensure locking around audio_clear() is handled
consistently and avoid locking against self.


To generate a diff of this commit:
cvs rdiff -u -r1.257.2.1 -r1.257.2.2 src/sys/dev/audio.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/audio.c
diff -u src/sys/dev/audio.c:1.257.2.1 src/sys/dev/audio.c:1.257.2.2
--- src/sys/dev/audio.c:1.257.2.1	Thu Feb 23 18:23:03 2012
+++ src/sys/dev/audio.c	Mon Apr  9 17:46:58 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: audio.c,v 1.257.2.1 2012/02/23 18:23:03 riz Exp $	*/
+/*	$NetBSD: audio.c,v 1.257.2.2 2012/04/09 17:46:58 riz Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -155,7 +155,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.257.2.1 2012/02/23 18:23:03 riz Exp $");
+__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.257.2.2 2012/04/09 17:46:58 riz Exp $");
 
 #include "audio.h"
 #if NAUDIO > 0
@@ -241,6 +241,7 @@ int	audio_initbufs(struct audio_softc *)
 void	audio_calcwater(struct audio_softc *);
 int	audio_drain(struct audio_softc *);
 void	audio_clear(struct audio_softc *);
+void	audio_clear_intr_unlocked(struct audio_softc *sc);
 static inline void audio_pint_silence
 	(struct audio_softc *, struct audio_ringbuffer *, uint8_t *, int);
 
@@ -1992,7 +1993,6 @@ audio_clear(struct audio_softc *sc)
 
 	KASSERT(mutex_owned(sc->sc_lock));
 
-	mutex_enter(sc->sc_intr_lock);
 	if (sc->sc_rbus) {
 		cv_broadcast(&sc->sc_rchan);
 		sc->hw_if->halt_input(sc->hw_hdl);
@@ -2005,6 +2005,14 @@ audio_clear(struct audio_softc *sc)
 		sc->sc_pbus = false;
 		sc->sc_pr.pause = false;
 	}
+}
+
+void
+audio_clear_intr_unlocked(struct audio_softc *sc)
+{
+
+	mutex_enter(sc->sc_intr_lock);
+	audio_clear(sc);
 	mutex_exit(sc->sc_intr_lock);
 }
 
@@ -3643,7 +3651,7 @@ audiosetinfo(struct audio_softc *sc, str
 	setmode = 0;
 	if (nr > 0) {
 		if (!cleared) {
-			audio_clear(sc);
+			audio_clear_intr_unlocked(sc);
 			cleared = true;
 		}
 		modechange = true;
@@ -3651,7 +3659,7 @@ audiosetinfo(struct audio_softc *sc, str
 	}
 	if (np > 0) {
 		if (!cleared) {
-			audio_clear(sc);
+			audio_clear_intr_unlocked(sc);
 			cleared = true;
 		}
 		modechange = true;
@@ -3660,7 +3668,7 @@ audiosetinfo(struct audio_softc *sc, str
 
 	if (SPECIFIED(ai->mode)) {
 		if (!cleared) {
-			audio_clear(sc);
+			audio_clear_intr_unlocked(sc);
 			cleared = true;
 		}
 		modechange = true;
@@ -3754,7 +3762,7 @@ audiosetinfo(struct audio_softc *sc, str
 
 	if (SPECIFIED(p->port)) {
 		if (!cleared) {
-			audio_clear(sc);
+			audio_clear_intr_unlocked(sc);
 			cleared = true;
 		}
 		error = au_set_port(sc, &sc->sc_outports, p->port);
@@ -3763,7 +3771,7 @@ audiosetinfo(struct audio_softc *sc, str
 	}
 	if (SPECIFIED(r->port)) {
 		if (!cleared) {
-			audio_clear(sc);
+			audio_clear_intr_unlocked(sc);
 			cleared = true;
 		}
 		error = au_set_port(sc, &sc->sc_inports, r->port);
@@ -3825,7 +3833,7 @@ audiosetinfo(struct audio_softc *sc, str
 		/* Block size specified explicitly. */
 		if (ai->blocksize == 0) {
 			if (!cleared) {
-				audio_clear(sc);
+				audio_clear_intr_unlocked(sc);
 				cleared = true;
 			}
 			sc->sc_blkset = false;
@@ -3836,7 +3844,7 @@ audiosetinfo(struct audio_softc *sc, str
 			/* check whether new blocksize changes actually */
 			if (hw->round_blocksize == NULL) {
 				if (!cleared) {
-					audio_clear(sc);
+					audio_clear_intr_unlocked(sc);
 					cleared = true;
 				}
 				sc->sc_pr.blksize = ai->blocksize;
@@ -3849,7 +3857,7 @@ audiosetinfo(struct audio_softc *sc, str
 				if (pblksize != sc->sc_pr.blksize ||
 				    rblksize != sc->sc_rr.blksize) {
 					if (!cleared) {
-						audio_clear(sc);
+						audio_clear_intr_unlocked(sc);
 						cleared = true;
 					}
 					sc->sc_pr.blksize = ai->blocksize;

Reply via email to