NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

re: kern/46232: netbsd-6 pad(4) panic: locking against myself



could you please try this patch?  thanks.


.mrg.


Index: audio.c
===================================================================
RCS file: /cvsroot/src/sys/dev/audio.c,v
retrieving revision 1.258
diff -p -r1.258 audio.c
*** audio.c     21 Feb 2012 20:53:34 -0000      1.258
--- audio.c     26 Mar 2012 06:45:55 -0000
*************** int     audio_initbufs(struct audio_softc *)
*** 241,246 ****
--- 241,247 ----
  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);
  
*************** audio_clear(struct audio_softc *sc)
*** 1992,1998 ****
  
        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);
--- 1993,1998 ----
*************** audio_clear(struct audio_softc *sc)
*** 2005,2010 ****
--- 2005,2018 ----
                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);
  }
  
*************** audiosetinfo(struct audio_softc *sc, str
*** 3643,3649 ****
        setmode = 0;
        if (nr > 0) {
                if (!cleared) {
!                       audio_clear(sc);
                        cleared = true;
                }
                modechange = true;
--- 3651,3657 ----
        setmode = 0;
        if (nr > 0) {
                if (!cleared) {
!                       audio_clear_intr_unlocked(sc);
                        cleared = true;
                }
                modechange = true;
*************** audiosetinfo(struct audio_softc *sc, str
*** 3651,3657 ****
        }
        if (np > 0) {
                if (!cleared) {
!                       audio_clear(sc);
                        cleared = true;
                }
                modechange = true;
--- 3659,3665 ----
        }
        if (np > 0) {
                if (!cleared) {
!                       audio_clear_intr_unlocked(sc);
                        cleared = true;
                }
                modechange = true;
*************** audiosetinfo(struct audio_softc *sc, str
*** 3660,3666 ****
  
        if (SPECIFIED(ai->mode)) {
                if (!cleared) {
!                       audio_clear(sc);
                        cleared = true;
                }
                modechange = true;
--- 3668,3674 ----
  
        if (SPECIFIED(ai->mode)) {
                if (!cleared) {
!                       audio_clear_intr_unlocked(sc);
                        cleared = true;
                }
                modechange = true;
*************** audiosetinfo(struct audio_softc *sc, str
*** 3754,3760 ****
  
        if (SPECIFIED(p->port)) {
                if (!cleared) {
!                       audio_clear(sc);
                        cleared = true;
                }
                error = au_set_port(sc, &sc->sc_outports, p->port);
--- 3762,3768 ----
  
        if (SPECIFIED(p->port)) {
                if (!cleared) {
!                       audio_clear_intr_unlocked(sc);
                        cleared = true;
                }
                error = au_set_port(sc, &sc->sc_outports, p->port);
*************** audiosetinfo(struct audio_softc *sc, str
*** 3763,3769 ****
        }
        if (SPECIFIED(r->port)) {
                if (!cleared) {
!                       audio_clear(sc);
                        cleared = true;
                }
                error = au_set_port(sc, &sc->sc_inports, r->port);
--- 3771,3777 ----
        }
        if (SPECIFIED(r->port)) {
                if (!cleared) {
!                       audio_clear_intr_unlocked(sc);
                        cleared = true;
                }
                error = au_set_port(sc, &sc->sc_inports, r->port);
*************** audiosetinfo(struct audio_softc *sc, str
*** 3825,3831 ****
                /* Block size specified explicitly. */
                if (ai->blocksize == 0) {
                        if (!cleared) {
!                               audio_clear(sc);
                                cleared = true;
                        }
                        sc->sc_blkset = false;
--- 3833,3839 ----
                /* Block size specified explicitly. */
                if (ai->blocksize == 0) {
                        if (!cleared) {
!                               audio_clear_intr_unlocked(sc);
                                cleared = true;
                        }
                        sc->sc_blkset = false;
*************** audiosetinfo(struct audio_softc *sc, str
*** 3836,3842 ****
                        /* check whether new blocksize changes actually */
                        if (hw->round_blocksize == NULL) {
                                if (!cleared) {
!                                       audio_clear(sc);
                                        cleared = true;
                                }
                                sc->sc_pr.blksize = ai->blocksize;
--- 3844,3850 ----
                        /* check whether new blocksize changes actually */
                        if (hw->round_blocksize == NULL) {
                                if (!cleared) {
!                                       audio_clear_intr_unlocked(sc);
                                        cleared = true;
                                }
                                sc->sc_pr.blksize = ai->blocksize;
*************** audiosetinfo(struct audio_softc *sc, str
*** 3849,3855 ****
                                if (pblksize != sc->sc_pr.blksize ||
                                    rblksize != sc->sc_rr.blksize) {
                                        if (!cleared) {
!                                               audio_clear(sc);
                                                cleared = true;
                                        }
                                        sc->sc_pr.blksize = ai->blocksize;
--- 3857,3863 ----
                                if (pblksize != sc->sc_pr.blksize ||
                                    rblksize != sc->sc_rr.blksize) {
                                        if (!cleared) {
!                                               audio_clear_intr_unlocked(sc);
                                                cleared = true;
                                        }
                                        sc->sc_pr.blksize = ai->blocksize;


Home | Main Index | Thread Index | Old Index