diff options
author | cg <cg@FreeBSD.org> | 2001-03-24 23:10:29 +0000 |
---|---|---|
committer | cg <cg@FreeBSD.org> | 2001-03-24 23:10:29 +0000 |
commit | 11442775804b9679c2c761846072b171d2507840 (patch) | |
tree | 2c8e61a99c9323312c5656a92269f975ac6b0c12 /sys/dev/sound/isa/sbc.c | |
parent | fb291ae7e5515cf63d4544d3eeff0a4c791e3cad (diff) | |
download | FreeBSD-src-11442775804b9679c2c761846072b171d2507840.zip FreeBSD-src-11442775804b9679c2c761846072b171d2507840.tar.gz |
mega-commit.
this introduces a new buffering mechanism which results in dramatic
simplification of the channel manager.
as several structures have changed, we take the opportunity to move their
definitions into the source files where they are used, make them private and
de-typedef them.
the sound drivers are updated to use snd_setup_intr instead of
bus_setup_intr, and to comply with the de-typedefed structures.
the ac97, mixer and channel layers have been updated with finegrained
locking, as have some drivers- not all though. the rest will follow soon.
Diffstat (limited to 'sys/dev/sound/isa/sbc.c')
-rw-r--r-- | sys/dev/sound/isa/sbc.c | 61 |
1 files changed, 51 insertions, 10 deletions
diff --git a/sys/dev/sound/isa/sbc.c b/sys/dev/sound/isa/sbc.c index 8629554..2129161 100644 --- a/sys/dev/sound/isa/sbc.c +++ b/sys/dev/sound/isa/sbc.c @@ -35,9 +35,12 @@ #define DRQ_MAX 2 #define INTR_MAX 2 +struct sbc_softc; + struct sbc_ihl { driver_intr_t *intr[INTR_MAX]; void *intr_arg[INTR_MAX]; + struct sbc_softc *parent; }; /* Here is the parameter structure per a device. */ @@ -61,6 +64,8 @@ struct sbc_softc { void *ih[IRQ_MAX]; + void *lock; + u_int32_t bd_ver; }; @@ -106,6 +111,30 @@ static int sb_cmd(struct resource *io, u_char val); static u_int sb_get_byte(struct resource *io); static void sb_setmixer(struct resource *io, u_int port, u_int value); +static void +sbc_lockinit(struct sbc_softc *scp) +{ + scp->lock = snd_mtxcreate(device_get_nameunit(scp->dev)); +} + +static void +sbc_lockdestroy(struct sbc_softc *scp) +{ + snd_mtxfree(scp->lock); +} + +void +sbc_lock(struct sbc_softc *scp) +{ + snd_mtxlock(scp->lock); +} + +void +sbc_unlock(struct sbc_softc *scp) +{ + snd_mtxunlock(scp->lock); +} + static int sb_rd(struct resource *io, int reg) { @@ -311,6 +340,7 @@ sbc_attach(device_t dev) scp = device_get_softc(dev); bzero(scp, sizeof(*scp)); scp->dev = dev; + sbc_lockinit(scp); err = "alloc_resource"; if (alloc_resource(scp)) goto bad; @@ -396,7 +426,8 @@ sbc_attach(device_t dev) err = "setup_intr"; for (i = 0; i < IRQ_MAX; i++) { - if (bus_setup_intr(dev, scp->irq[i], INTR_TYPE_TTY, sbc_intr, &scp->ihl[i], &scp->ih[i])) + scp->ihl[i].parent = scp; + if (snd_setup_intr(dev, scp->irq[i], INTR_MPSAFE, sbc_intr, &scp->ihl[i], &scp->ih[i])) goto bad; } @@ -439,10 +470,12 @@ sbc_detach(device_t dev) { struct sbc_softc *scp = device_get_softc(dev); + sbc_lock(scp); device_delete_child(dev, scp->child_midi2); device_delete_child(dev, scp->child_midi1); device_delete_child(dev, scp->child_pcm); release_resource(scp); + sbc_lockdestroy(scp); return bus_generic_detach(dev); } @@ -452,11 +485,13 @@ sbc_intr(void *p) struct sbc_ihl *ihl = p; int i; + /* sbc_lock(ihl->parent); */ i = 0; while (i < INTR_MAX) { if (ihl->intr[i] != NULL) ihl->intr[i](ihl->intr_arg[i]); i++; } + /* sbc_unlock(ihl->parent); */ } static int @@ -466,24 +501,27 @@ sbc_setup_intr(device_t dev, device_t child, struct resource *irq, { struct sbc_softc *scp = device_get_softc(dev); struct sbc_ihl *ihl = NULL; - int i; + int i, ret; + sbc_lock(scp); i = 0; while (i < IRQ_MAX) { if (irq == scp->irq[i]) ihl = &scp->ihl[i]; i++; } - if (ihl == NULL) return (EINVAL); + ret = 0; + if (ihl == NULL) ret = EINVAL; i = 0; - while (i < INTR_MAX) { + while ((ret == 0) && (i < INTR_MAX)) { if (ihl->intr[i] == NULL) { ihl->intr[i] = intr; ihl->intr_arg[i] = arg; *cookiep = &ihl->intr[i]; - return 0; + ret = -1; } else i++; } - return (EINVAL); + sbc_unlock(scp); + return (ret > 0)? EINVAL : 0; } static int @@ -492,23 +530,26 @@ sbc_teardown_intr(device_t dev, device_t child, struct resource *irq, { struct sbc_softc *scp = device_get_softc(dev); struct sbc_ihl *ihl = NULL; - int i; + int i, ret; + sbc_lock(scp); i = 0; while (i < IRQ_MAX) { if (irq == scp->irq[i]) ihl = &scp->ihl[i]; i++; } - if (ihl == NULL) return (EINVAL); + ret = 0; + if (ihl == NULL) ret = EINVAL; i = 0; - while (i < INTR_MAX) { + while ((ret == 0) && (i < INTR_MAX)) { if (cookie == &ihl->intr[i]) { ihl->intr[i] = NULL; ihl->intr_arg[i] = NULL; return 0; } else i++; } - return (EINVAL); + sbc_unlock(scp); + return (ret > 0)? EINVAL : 0; } static struct resource * |