summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorariff <ariff@FreeBSD.org>2007-06-14 11:13:38 +0000
committerariff <ariff@FreeBSD.org>2007-06-14 11:13:38 +0000
commit3567d731719f9ab23a0e67093d33937a5917ba30 (patch)
treeba2e184b19750b6d83ceb2bd571bca30efa72f16 /sys
parent034f58f66350dc0b5d62b6d590c60842bed6935a (diff)
downloadFreeBSD-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.c15
-rw-r--r--sys/dev/sound/pci/es137x.c9
-rw-r--r--sys/dev/sound/pci/hda/hdac.c9
-rw-r--r--sys/dev/sound/pci/via8233.c16
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);
OpenPOWER on IntegriCloud