diff --git a/sys/dev/sound/pci/atiixp.c b/sys/dev/sound/pci/atiixp.c index 58d99ae4d5f..6842c294b48 100644 --- a/sys/dev/sound/pci/atiixp.c +++ b/sys/dev/sound/pci/atiixp.c @@ -1111,6 +1111,13 @@ atiixp_release_resource(struct atiixp_info *sc) { if (sc == NULL) return; + if (sc->registered_channels != 0) { + atiixp_lock(sc); + sc->polling = 0; + callout_stop(&sc->poll_timer); + atiixp_unlock(sc); + callout_drain(&sc->poll_timer); + } if (sc->codec) { ac97_destroy(sc->codec); sc->codec = NULL; @@ -1146,6 +1153,7 @@ atiixp_release_resource(struct atiixp_info *sc) snd_mtxfree(sc->lock); sc->lock = NULL; } + free(sc, M_DEVBUF); } static int @@ -1173,11 +1181,7 @@ atiixp_pci_attach(device_t dev) struct atiixp_info *sc; int i; - if ((sc = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT | M_ZERO)) == NULL) { - device_printf(dev, "cannot allocate softc\n"); - return (ENXIO); - } - + sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO); sc->lock = snd_mtxcreate(device_get_nameunit(dev), "snd_atiixp softc"); sc->dev = dev; @@ -1312,7 +1316,6 @@ atiixp_pci_detach(device_t dev) if (sc->st != 0 && sc->sh != 0) atiixp_disable_interrupts(sc); atiixp_release_resource(sc); - free(sc, M_DEVBUF); } return (0); } diff --git a/sys/dev/sound/pci/es137x.c b/sys/dev/sound/pci/es137x.c index 0daaad8ff00..e332db3a7f5 100644 --- a/sys/dev/sound/pci/es137x.c +++ b/sys/dev/sound/pci/es137x.c @@ -1885,6 +1885,15 @@ es_pci_detach(device_t dev) return (r); es = pcm_getdevinfo(dev); + + if (es != NULL && es->num != 0) { + ES_LOCK(es); + es->polling = 0; + callout_stop(&es->poll_timer); + ES_UNLOCK(es); + callout_drain(&es->poll_timer); + } + bus_teardown_intr(dev, es->irq, es->ih); bus_release_resource(dev, SYS_RES_IRQ, es->irqid, es->irq); bus_release_resource(dev, es->regtype, es->regid, es->reg); diff --git a/sys/dev/sound/pci/hda/hdac.c b/sys/dev/sound/pci/hda/hdac.c index 69cff378ef4..4c048a45160 100644 --- a/sys/dev/sound/pci/hda/hdac.c +++ b/sys/dev/sound/pci/hda/hdac.c @@ -3576,12 +3576,7 @@ hdac_attach(device_t dev) uint16_t vendor; uint8_t v; - sc = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT | M_ZERO); - if (sc == NULL) { - device_printf(dev, "cannot allocate softc\n"); - return (ENOMEM); - } - + sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO); sc->lock = snd_mtxcreate(device_get_nameunit(dev), HDAC_MTX_NAME); sc->dev = dev; sc->pci_subvendor = (uint32_t)pci_get_subdevice(sc->dev) << 16; @@ -5608,10 +5603,12 @@ hdac_release_resources(struct hdac_softc *sc) hdac_lock(sc); sc->polling = 0; sc->poll_ival = 0; + callout_stop(&sc->poll_hda); callout_stop(&sc->poll_hdac); callout_stop(&sc->poll_jack); hdac_reset(sc); hdac_unlock(sc); + callout_drain(&sc->poll_hda); callout_drain(&sc->poll_hdac); callout_drain(&sc->poll_jack); diff --git a/sys/dev/sound/pci/via8233.c b/sys/dev/sound/pci/via8233.c index c35129363f7..68de81b7e5f 100644 --- a/sys/dev/sound/pci/via8233.c +++ b/sys/dev/sound/pci/via8233.c @@ -1171,10 +1171,7 @@ via_attach(device_t dev) int nsegs; uint32_t revid; - if ((via = malloc(sizeof *via, M_DEVBUF, M_NOWAIT | M_ZERO)) == NULL) { - device_printf(dev, "cannot allocate softc\n"); - return (ENXIO); - } + via = malloc(sizeof *via, M_DEVBUF, M_WAITOK | M_ZERO); via->lock = snd_mtxcreate(device_get_nameunit(dev), "snd_via8233 softc"); via->dev = dev; @@ -1402,13 +1399,22 @@ static int via_detach(device_t dev) { int r; - struct via_info *via = 0; + struct via_info *via; r = pcm_unregister(dev); if (r) return (r); via = pcm_getdevinfo(dev); + + if (via != NULL && (via->play_num != 0 || via->rec_num != 0)) { + snd_mtxlock(via->lock); + via->polling = 0; + callout_stop(&via->poll_timer); + snd_mtxunlock(via->lock); + callout_drain(&via->poll_timer); + } + bus_release_resource(dev, SYS_RES_IOPORT, via->regid, via->reg); bus_teardown_intr(dev, via->irq, via->ih); bus_release_resource(dev, SYS_RES_IRQ, via->irqid, via->irq);