diff options
author | ariff <ariff@FreeBSD.org> | 2007-06-14 11:13:38 +0000 |
---|---|---|
committer | ariff <ariff@FreeBSD.org> | 2007-06-14 11:13:38 +0000 |
commit | 3567d731719f9ab23a0e67093d33937a5917ba30 (patch) | |
tree | ba2e184b19750b6d83ceb2bd571bca30efa72f16 /sys | |
parent | 034f58f66350dc0b5d62b6d590c60842bed6935a (diff) | |
download | FreeBSD-src-3567d731719f9ab23a0e67093d33937a5917ba30.zip FreeBSD-src-3567d731719f9ab23a0e67093d33937a5917ba30.tar.gz |
Drain all callout handlers during driver detach appropriately.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/sound/pci/atiixp.c | 15 | ||||
-rw-r--r-- | sys/dev/sound/pci/es137x.c | 9 | ||||
-rw-r--r-- | sys/dev/sound/pci/hda/hdac.c | 9 | ||||
-rw-r--r-- | sys/dev/sound/pci/via8233.c | 16 |
4 files changed, 32 insertions, 17 deletions
diff --git a/sys/dev/sound/pci/atiixp.c b/sys/dev/sound/pci/atiixp.c index 58d99ae..6842c29 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 0daaad8..e332db3 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 69cff37..4c048a4 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 c351293..68de81b 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); |