Hello, > I ran into a problem with uaudio, but I'll have a look at uaudio_detach().
With a hint from skrll@, I looked at uaudio_detach(). We already have code in uaudio_halt_out_dma() and uaudio_halt_in_dma() to stop any playback or recording, so it looks like we can reuse these when detaching. With the attached patch, I no longer see the panics when removing a uaudio device when playback is in progress. Regards, Julian
Index: uaudio.c =================================================================== RCS file: /cvsroot/src/sys/dev/usb/uaudio.c,v retrieving revision 1.165 diff -u -r1.165 uaudio.c --- uaudio.c 14 Mar 2020 02:35:33 -0000 1.165 +++ uaudio.c 26 Dec 2020 08:17:35 -0000 @@ -343,6 +343,8 @@ const audio_params_t *); Static int uaudio_halt_in_dma(void *); Static int uaudio_halt_out_dma(void *); +Static void uaudio_halt_in_dma_unlocked(struct uaudio_softc *); +Static void uaudio_halt_out_dma_unlocked(struct uaudio_softc *); Static int uaudio_getdev(void *, struct audio_device *); Static int uaudio_mixer_set_port(void *, mixer_ctrl_t *); Static int uaudio_mixer_get_port(void *, mixer_ctrl_t *); @@ -519,10 +521,13 @@ struct uaudio_softc *sc = device_private(self); int rv = 0; + sc->sc_dying = 1; + pmf_device_deregister(self); /* Wait for outstanding requests to complete. */ - usbd_delay_ms(sc->sc_udev, UAUDIO_NCHANBUFS * UAUDIO_NFRAMES); + uaudio_halt_out_dma_unlocked(sc); + uaudio_halt_in_dma_unlocked(sc); if (sc->sc_audiodev != NULL) rv = config_detach(sc->sc_audiodev, flags); @@ -2167,15 +2172,21 @@ DPRINTF("%s", "enter\n"); mutex_exit(&sc->sc_intr_lock); + uaudio_halt_out_dma_unlocked(sc); + mutex_enter(&sc->sc_intr_lock); + + return 0; +} + +Static void +uaudio_halt_out_dma_unlocked(struct uaudio_softc *sc) +{ if (sc->sc_playchan.pipe != NULL) { uaudio_chan_abort(sc, &sc->sc_playchan); uaudio_chan_free_buffers(sc, &sc->sc_playchan); uaudio_chan_close(sc, &sc->sc_playchan); sc->sc_playchan.intr = NULL; } - mutex_enter(&sc->sc_intr_lock); - - return 0; } Static int @@ -2186,15 +2197,21 @@ DPRINTF("%s", "enter\n"); mutex_exit(&sc->sc_intr_lock); + uaudio_halt_in_dma_unlocked(sc); + mutex_enter(&sc->sc_intr_lock); + + return 0; +} + +Static void +uaudio_halt_in_dma_unlocked(struct uaudio_softc *sc) +{ if (sc->sc_recchan.pipe != NULL) { uaudio_chan_abort(sc, &sc->sc_recchan); uaudio_chan_free_buffers(sc, &sc->sc_recchan); uaudio_chan_close(sc, &sc->sc_recchan); sc->sc_recchan.intr = NULL; } - mutex_enter(&sc->sc_intr_lock); - - return 0; } Static int