diff options
Diffstat (limited to 'sys/dev/sound/pci')
-rw-r--r-- | sys/dev/sound/pci/aureal.c | 18 | ||||
-rw-r--r-- | sys/dev/sound/pci/cmi.c | 22 | ||||
-rw-r--r-- | sys/dev/sound/pci/cs4281.c | 14 | ||||
-rw-r--r-- | sys/dev/sound/pci/csa.c | 2 | ||||
-rw-r--r-- | sys/dev/sound/pci/csapcm.c | 16 | ||||
-rw-r--r-- | sys/dev/sound/pci/ds1.c | 41 | ||||
-rw-r--r-- | sys/dev/sound/pci/emu10k1.c | 116 | ||||
-rw-r--r-- | sys/dev/sound/pci/es137x.c | 23 | ||||
-rw-r--r-- | sys/dev/sound/pci/fm801.c | 18 | ||||
-rw-r--r-- | sys/dev/sound/pci/maestro.c | 21 | ||||
-rw-r--r-- | sys/dev/sound/pci/maestro3.c | 37 | ||||
-rw-r--r-- | sys/dev/sound/pci/neomagic.c | 17 | ||||
-rw-r--r-- | sys/dev/sound/pci/solo.c | 22 | ||||
-rw-r--r-- | sys/dev/sound/pci/t4dwave.c | 44 | ||||
-rw-r--r-- | sys/dev/sound/pci/via82c686.c | 343 | ||||
-rw-r--r-- | sys/dev/sound/pci/vibes.c | 20 |
16 files changed, 345 insertions, 429 deletions
diff --git a/sys/dev/sound/pci/aureal.c b/sys/dev/sound/pci/aureal.c index 09ead9f..419eb98 100644 --- a/sys/dev/sound/pci/aureal.c +++ b/sys/dev/sound/pci/aureal.c @@ -44,7 +44,7 @@ static u_int32_t au_playfmt[] = { AFMT_STEREO | AFMT_S16_LE, 0 }; -static pcmchan_caps au_playcaps = {4000, 48000, au_playfmt, 0}; +static struct pcmchan_caps au_playcaps = {4000, 48000, au_playfmt, 0}; static u_int32_t au_recfmt[] = { AFMT_U8, @@ -53,7 +53,7 @@ static u_int32_t au_recfmt[] = { AFMT_STEREO | AFMT_S16_LE, 0 }; -static pcmchan_caps au_reccaps = {4000, 48000, au_recfmt, 0}; +static struct pcmchan_caps au_reccaps = {4000, 48000, au_recfmt, 0}; /* -------------------------------------------------------------------- */ @@ -61,8 +61,8 @@ struct au_info; struct au_chinfo { struct au_info *parent; - pcm_channel *channel; - snd_dbuf *buffer; + struct pcm_channel *channel; + struct snd_dbuf *buffer; int dir; }; @@ -73,6 +73,7 @@ struct au_info { bus_space_handle_t sh[3]; bus_dma_tag_t parent_dmat; + void *lock; u_int32_t x[32], y[128]; char z[128]; @@ -293,7 +294,7 @@ au_prepareoutput(struct au_chinfo *ch, u_int32_t format) /* -------------------------------------------------------------------- */ /* channel interface */ static void * -auchan_init(kobj_t obj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir) +auchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir) { struct au_info *au = devinfo; struct au_chinfo *ch = (dir == PCMDIR_PLAY)? &au->pch : NULL; @@ -365,7 +366,7 @@ auchan_getptr(kobj_t obj, void *data) } } -static pcmchan_caps * +static struct pcmchan_caps * auchan_getcaps(kobj_t obj, void *data) { struct au_chinfo *ch = data; @@ -620,8 +621,7 @@ au_pci_attach(device_t dev) irqid = 0; irq = bus_alloc_resource(dev, SYS_RES_IRQ, &irqid, 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE); - if (!irq - || bus_setup_intr(dev, irq, INTR_TYPE_TTY, au_intr, au, &ih)) { + if (!irq || snd_setup_intr(dev, irq, 0, au_intr, au, &ih)) { device_printf(dev, "unable to map interrupt\n"); goto bad; } @@ -678,7 +678,7 @@ static device_method_t au_methods[] = { static driver_t au_driver = { "pcm", au_methods, - sizeof(snddev_info), + sizeof(struct snddev_info), }; static devclass_t pcm_devclass; diff --git a/sys/dev/sound/pci/cmi.c b/sys/dev/sound/pci/cmi.c index 27489a2..bb48b70 100644 --- a/sys/dev/sound/pci/cmi.c +++ b/sys/dev/sound/pci/cmi.c @@ -83,8 +83,8 @@ struct cmi_info; struct cmi_chinfo { struct cmi_info *parent; - pcm_channel *channel; - snd_dbuf *buffer; + struct pcm_channel *channel; + struct snd_dbuf *buffer; int dir; int bps; /* bytes per sample */ u_int32_t fmt, spd, phys_buf; @@ -115,7 +115,7 @@ static u_int32_t cmi_fmt[] = { 0 }; -static pcmchan_caps cmi_caps = {5512, 48000, cmi_fmt, 0}; +static struct pcmchan_caps cmi_caps = {5512, 48000, cmi_fmt, 0}; /* ------------------------------------------------------------------------- */ /* Register Utilities */ @@ -328,7 +328,7 @@ cmi_spdif_speed(struct cmi_info *cmi, int speed) { /* Channel Interface implementation */ static void * -cmichan_init(kobj_t obj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir) +cmichan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir) { struct cmi_info *cmi = devinfo; struct cmi_chinfo *ch = (dir == PCMDIR_PLAY) ? &cmi->pch : &cmi->rch; @@ -541,7 +541,7 @@ cmi_intr(void *data) return; } -static pcmchan_caps * +static struct pcmchan_caps * cmichan_getcaps(kobj_t obj, void *data) { return &cmi_caps; @@ -610,7 +610,7 @@ struct sb16props { #define MIXER_GAIN_REG_RTOL(r) (r - 1) static int -cmimix_init(snd_mixer *m) +cmimix_init(struct snd_mixer *m) { struct cmi_info *cmi = mix_getdevinfo(m); u_int32_t i,v; @@ -635,7 +635,7 @@ cmimix_init(snd_mixer *m) } static int -cmimix_set(snd_mixer *m, unsigned dev, unsigned left, unsigned right) +cmimix_set(struct snd_mixer *m, unsigned dev, unsigned left, unsigned right) { struct cmi_info *cmi = mix_getdevinfo(m); u_int32_t r, l, max; @@ -683,7 +683,7 @@ cmimix_set(snd_mixer *m, unsigned dev, unsigned left, unsigned right) } static int -cmimix_setrecsrc(snd_mixer *m, u_int32_t src) +cmimix_setrecsrc(struct snd_mixer *m, u_int32_t src) { struct cmi_info *cmi = mix_getdevinfo(m); u_int32_t i, ml, sl; @@ -760,7 +760,7 @@ cmi_probe(device_t dev) static int cmi_attach(device_t dev) { - snddev_info *d; + struct snddev_info *d; struct cmi_info *cmi; u_int32_t data; char status[SND_STATUSLEN]; @@ -793,7 +793,7 @@ cmi_attach(device_t dev) cmi->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &cmi->irqid, 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE); if (!cmi->irq || - bus_setup_intr(dev, cmi->irq, INTR_TYPE_TTY, cmi_intr, cmi, &cmi->ih)){ + snd_setup_intr(dev, cmi->irq, 0, cmi_intr, cmi, &cmi->ih)) { device_printf(dev, "cmi_attach: Unable to map interrupt\n"); goto bad; } @@ -877,7 +877,7 @@ static device_method_t cmi_methods[] = { static driver_t cmi_driver = { "pcm", cmi_methods, - sizeof(snddev_info) + sizeof(struct snddev_info) }; static devclass_t pcm_devclass; diff --git a/sys/dev/sound/pci/cs4281.c b/sys/dev/sound/pci/cs4281.c index 2f5f633..506a58a 100644 --- a/sys/dev/sound/pci/cs4281.c +++ b/sys/dev/sound/pci/cs4281.c @@ -68,8 +68,8 @@ struct sc_info; struct sc_chinfo { struct sc_info *parent; - snd_dbuf *buffer; - pcm_channel *channel; + struct snd_dbuf *buffer; + struct pcm_channel *channel; u_int32_t spd, fmt, bps, blksz; @@ -134,7 +134,7 @@ static u_int32_t cs4281_fmts[] = { 0 }; -static pcmchan_caps cs4281_caps = {6024, 48000, cs4281_fmts, 0}; +static struct pcmchan_caps cs4281_caps = {6024, 48000, cs4281_fmts, 0}; /* -------------------------------------------------------------------- */ /* Hardware */ @@ -310,7 +310,7 @@ AC97_DECLARE(cs4281_ac97); /* shared rec/play channel interface */ static void * -cs4281chan_init(kobj_t obj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir) +cs4281chan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir) { struct sc_info *sc = devinfo; struct sc_chinfo *ch = (dir == PCMDIR_PLAY) ? &sc->pch : &sc->rch; @@ -437,7 +437,7 @@ cs4281chan_trigger(kobj_t obj, void *data, int go) return 0; } -static pcmchan_caps * +static struct pcmchan_caps * cs4281chan_getcaps(kobj_t obj, void *data) { return &cs4281_caps; @@ -810,7 +810,7 @@ cs4281_pci_attach(device_t dev) goto bad; } - if (bus_setup_intr(dev, sc->irq, INTR_TYPE_TTY, cs4281_intr, sc, &sc->ih)) { + if (snd_setup_intr(dev, sc->irq, 0, cs4281_intr, sc, &sc->ih)) { device_printf(dev, "unable to setup interrupt\n"); goto bad; } @@ -962,7 +962,7 @@ static device_method_t cs4281_methods[] = { static driver_t cs4281_driver = { "pcm", cs4281_methods, - sizeof(snddev_info), + sizeof(struct snddev_info), }; static devclass_t pcm_devclass; diff --git a/sys/dev/sound/pci/csa.c b/sys/dev/sound/pci/csa.c index 8cfc179..9dad2f2 100644 --- a/sys/dev/sound/pci/csa.c +++ b/sys/dev/sound/pci/csa.c @@ -155,7 +155,7 @@ csa_attach(device_t dev) } /* Enable interrupt. */ - if (bus_setup_intr(dev, resp->irq, INTR_TYPE_TTY, csa_intr, scp, &scp->ih)) { + if (snd_setup_intr(dev, resp->irq, 0, csa_intr, scp, &scp->ih)) { bus_release_resource(dev, SYS_RES_MEMORY, resp->io_rid, resp->io); bus_release_resource(dev, SYS_RES_MEMORY, resp->mem_rid, resp->mem); bus_release_resource(dev, SYS_RES_IRQ, resp->irq_rid, resp->irq); diff --git a/sys/dev/sound/pci/csapcm.c b/sys/dev/sound/pci/csapcm.c index 8bad7b5..399ac15 100644 --- a/sys/dev/sound/pci/csapcm.c +++ b/sys/dev/sound/pci/csapcm.c @@ -45,8 +45,8 @@ struct csa_info; struct csa_chinfo { struct csa_info *parent; - pcm_channel *channel; - snd_dbuf *buffer; + struct pcm_channel *channel; + struct snd_dbuf *buffer; int dir; u_int32_t fmt; int dma; @@ -93,14 +93,14 @@ static u_int32_t csa_playfmt[] = { AFMT_STEREO | AFMT_S16_BE, 0 }; -static pcmchan_caps csa_playcaps = {8000, 48000, csa_playfmt, 0}; +static struct pcmchan_caps csa_playcaps = {8000, 48000, csa_playfmt, 0}; static u_int32_t csa_recfmt[] = { AFMT_S16_LE, AFMT_STEREO | AFMT_S16_LE, 0 }; -static pcmchan_caps csa_reccaps = {11025, 48000, csa_recfmt, 0}; +static struct pcmchan_caps csa_reccaps = {11025, 48000, csa_recfmt, 0}; /* -------------------------------------------------------------------- */ /* ac97 codec */ @@ -515,7 +515,7 @@ csa_startdsp(csa_res *resp) /* channel interface */ static void * -csachan_init(kobj_t obj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir) +csachan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir) { struct csa_info *csa = devinfo; struct csa_chinfo *ch = (dir == PCMDIR_PLAY)? &csa->pch : &csa->rch; @@ -654,7 +654,7 @@ csachan_getptr(kobj_t obj, void *data) return (ptr); } -static pcmchan_caps * +static struct pcmchan_caps * csachan_getcaps(kobj_t obj, void *data) { struct csa_chinfo *ch = data; @@ -854,7 +854,7 @@ pcmcsa_attach(device_t dev) snprintf(status, SND_STATUSLEN, "at irq %ld", rman_get_start(resp->irq)); /* Enable interrupt. */ - if (bus_setup_intr(dev, resp->irq, INTR_TYPE_TTY, csa_intr, csa, &csa->ih)) { + if (snd_setup_intr(dev, resp->irq, 0, csa_intr, csa, &csa->ih)) { ac97_destroy(codec); csa_releaseres(csa, dev); return (ENXIO); @@ -902,7 +902,7 @@ static device_method_t pcmcsa_methods[] = { static driver_t pcmcsa_driver = { "pcm", pcmcsa_methods, - sizeof(snddev_info), + sizeof(struct snddev_info), }; static devclass_t pcm_devclass; diff --git a/sys/dev/sound/pci/ds1.c b/sys/dev/sound/pci/ds1.c index 64db2b7..1870917 100644 --- a/sys/dev/sound/pci/ds1.c +++ b/sys/dev/sound/pci/ds1.c @@ -87,8 +87,8 @@ struct sc_info; /* channel registers */ struct sc_pchinfo { int run, spd, dir, fmt; - snd_dbuf *buffer; - pcm_channel *channel; + struct snd_dbuf *buffer; + struct pcm_channel *channel; volatile struct pbank *lslot, *rslot; int lsnum, rsnum; struct sc_info *parent; @@ -96,8 +96,8 @@ struct sc_pchinfo { struct sc_rchinfo { int run, spd, dir, fmt, num; - snd_dbuf *buffer; - pcm_channel *channel; + struct snd_dbuf *buffer; + struct pcm_channel *channel; volatile struct rbank *slot; struct sc_info *parent; }; @@ -116,6 +116,7 @@ struct sc_info { struct resource *reg, *irq; int regid, irqid; void *ih; + void *lock; void *regbase; u_int32_t *pbase, pbankbase, pbanksize; @@ -175,7 +176,7 @@ static u_int32_t ds_recfmt[] = { AFMT_STEREO | AFMT_U16_LE, 0 }; -static pcmchan_caps ds_reccaps = {4000, 48000, ds_recfmt, 0}; +static struct pcmchan_caps ds_reccaps = {4000, 48000, ds_recfmt, 0}; static u_int32_t ds_playfmt[] = { AFMT_U8, @@ -184,7 +185,7 @@ static u_int32_t ds_playfmt[] = { AFMT_STEREO | AFMT_S16_LE, 0 }; -static pcmchan_caps ds_playcaps = {4000, 96000, ds_playfmt, 0}; +static struct pcmchan_caps ds_playcaps = {4000, 96000, ds_playfmt, 0}; /* -------------------------------------------------------------------- */ /* Hardware */ @@ -473,7 +474,7 @@ ds_setuprch(struct sc_rchinfo *ch) /* -------------------------------------------------------------------- */ /* play channel interface */ static void * -ds1pchan_init(kobj_t obj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir) +ds1pchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir) { struct sc_info *sc = devinfo; struct sc_pchinfo *ch; @@ -550,7 +551,9 @@ ds1pchan_trigger(kobj_t obj, void *data, int go) ds_setuppch(ch); ds_enapslot(sc, ch->lsnum, 1); ds_enapslot(sc, ch->rsnum, stereo); + snd_mtxlock(sc->lock); ds_wr(sc, YDSXGR_MODE, 0x00000003, 4); + snd_mtxunlock(sc->lock); } else { ch->run = 0; /* ds_setuppch(ch); */ @@ -580,7 +583,7 @@ ds1pchan_getptr(kobj_t obj, void *data) return ptr; } -static pcmchan_caps * +static struct pcmchan_caps * ds1pchan_getcaps(kobj_t obj, void *data) { return &ds_playcaps; @@ -601,7 +604,7 @@ CHANNEL_DECLARE(ds1pchan); /* -------------------------------------------------------------------- */ /* record channel interface */ static void * -ds1rchan_init(kobj_t obj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir) +ds1rchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir) { struct sc_info *sc = devinfo; struct sc_rchinfo *ch; @@ -672,15 +675,19 @@ ds1rchan_trigger(kobj_t obj, void *data, int go) if (go == PCMTRIG_START) { ch->run = 1; ds_setuprch(ch); + snd_mtxlock(sc->lock); x = ds_rd(sc, YDSXGR_MAPOFREC, 4); x |= (ch->num == DS1_RECPRIMARY)? 0x02 : 0x01; ds_wr(sc, YDSXGR_MAPOFREC, x, 4); ds_wr(sc, YDSXGR_MODE, 0x00000003, 4); + snd_mtxunlock(sc->lock); } else { ch->run = 0; + snd_mtxlock(sc->lock); x = ds_rd(sc, YDSXGR_MAPOFREC, 4); x &= ~((ch->num == DS1_RECPRIMARY)? 0x02 : 0x01); ds_wr(sc, YDSXGR_MAPOFREC, x, 4); + snd_mtxunlock(sc->lock); } return 0; @@ -695,7 +702,7 @@ ds1rchan_getptr(kobj_t obj, void *data) return ch->slot[sc->currbank].PgStart; } -static pcmchan_caps * +static struct pcmchan_caps * ds1rchan_getcaps(kobj_t obj, void *data) { return &ds_reccaps; @@ -721,6 +728,7 @@ ds_intr(void *p) struct sc_info *sc = (struct sc_info *)p; u_int32_t i, x; + snd_mtxlock(sc->lock); i = ds_rd(sc, YDSXGR_STATUS, 4); if (i & 0x00008000) device_printf(sc->dev, "timeout irq\n"); @@ -746,6 +754,7 @@ ds_intr(void *p) ds_wr(sc, YDSXGR_MODE, i | 0x00000002, 4); } + snd_mtxunlock(sc->lock); } /* -------------------------------------------------------------------- */ @@ -922,12 +931,12 @@ ds_pci_attach(device_t dev) struct ac97_info *codec = NULL; char status[SND_STATUSLEN]; - if ((sc = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT)) == NULL) { + if ((sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO)) == NULL) { device_printf(dev, "cannot allocate softc\n"); return ENXIO; } - bzero(sc, sizeof(*sc)); + sc->lock = snd_mtxcreate(device_get_nameunit(dev)); sc->dev = dev; subdev = (pci_get_subdevice(dev) << 16) | pci_get_subvendor(dev); sc->type = ds_finddev(pci_get_devid(dev), subdev); @@ -973,8 +982,7 @@ ds_pci_attach(device_t dev) sc->irqid = 0; sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irqid, 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE); - if (!sc->irq || - bus_setup_intr(dev, sc->irq, INTR_TYPE_TTY, ds_intr, sc, &sc->ih)) { + if (!sc->irq || snd_setup_intr(dev, sc->irq, INTR_MPSAFE, ds_intr, sc, &sc->ih)) { device_printf(dev, "unable to map interrupt\n"); goto bad; } @@ -1003,6 +1011,8 @@ bad: bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq); if (sc->parent_dmat) bus_dma_tag_destroy(sc->parent_dmat); + if (sc->lock) + snd_mtxfree(sc->lock); free(sc, M_DEVBUF); return ENXIO; } @@ -1041,6 +1051,7 @@ ds_pci_detach(device_t dev) bus_teardown_intr(dev, sc->irq, sc->ih); bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq); bus_dma_tag_destroy(sc->parent_dmat); + snd_mtxfree(sc->lock); free(sc, M_DEVBUF); return 0; } @@ -1057,7 +1068,7 @@ static device_method_t ds1_methods[] = { static driver_t ds1_driver = { "pcm", ds1_methods, - sizeof(snddev_info), + sizeof(struct snddev_info), }; static devclass_t pcm_devclass; diff --git a/sys/dev/sound/pci/emu10k1.c b/sys/dev/sound/pci/emu10k1.c index e816572..388a8e7 100644 --- a/sys/dev/sound/pci/emu10k1.c +++ b/sys/dev/sound/pci/emu10k1.c @@ -61,7 +61,7 @@ struct emu_voice { int start, end, vol; u_int32_t buf; struct emu_voice *slave; - pcm_channel *channel; + struct pcm_channel *channel; }; struct sc_info; @@ -70,16 +70,16 @@ struct sc_info; struct sc_pchinfo { int spd, fmt, blksz, run; struct emu_voice *master, *slave; - snd_dbuf *buffer; - pcm_channel *channel; + struct snd_dbuf *buffer; + struct pcm_channel *channel; struct sc_info *parent; }; struct sc_rchinfo { int spd, fmt, run, blksz, num; u_int32_t idxreg, basereg, sizereg, setupreg, irqmask; - snd_dbuf *buffer; - pcm_channel *channel; + struct snd_dbuf *buffer; + struct pcm_channel *channel; struct sc_info *parent; }; @@ -96,6 +96,7 @@ struct sc_info { struct resource *reg, *irq; int regtype, regid, irqid; void *ih; + void *lock; int timer, timerinterval; int pnum, rnum; @@ -144,7 +145,7 @@ static u_int32_t emu_rfmt_efx[] = { 0 }; -static pcmchan_caps emu_reccaps[3] = { +static struct pcmchan_caps emu_reccaps[3] = { {8000, 48000, emu_rfmt_ac97, 0}, {8000, 8000, emu_rfmt_mic, 0}, {48000, 48000, emu_rfmt_efx, 0}, @@ -158,7 +159,7 @@ static u_int32_t emu_pfmt[] = { 0 }; -static pcmchan_caps emu_playcaps = {4000, 48000, emu_pfmt, 0}; +static struct pcmchan_caps emu_playcaps = {4000, 48000, emu_pfmt, 0}; static int adcspeed[8] = {48000, 44100, 32000, 24000, 22050, 16000, 11025, 8000}; @@ -239,6 +240,7 @@ emu_wrefx(struct sc_info *sc, unsigned int pc, unsigned int data) /* -------------------------------------------------------------------- */ /* ac97 codec */ +/* no locking needed */ static int emu_rdcd(kobj_t obj, void *devinfo, int regno) @@ -267,40 +269,6 @@ static kobj_method_t emu_ac97_methods[] = { AC97_DECLARE(emu_ac97); /* -------------------------------------------------------------------- */ - -#if 0 -/* playback channel interrupts */ -static u_int32_t -emu_testint(struct sc_info *sc, char channel) -{ - int reg = (channel & 0x20)? CLIPH : CLIPL; - channel &= 0x1f; - reg |= 1 << 24; - reg |= channel << 16; - return emu_rdptr(sc, 0, reg); -} - -static void -emu_clrint(struct sc_info *sc, char channel) -{ - int reg = (channel & 0x20)? CLIPH : CLIPL; - channel &= 0x1f; - reg |= 1 << 24; - reg |= channel << 16; - emu_wrptr(sc, 0, reg, 1); -} - -static void -emu_enaint(struct sc_info *sc, char channel, int enable) -{ - int reg = (channel & 0x20)? CLIEH : CLIEL; - channel &= 0x1f; - reg |= 1 << 24; - reg |= channel << 16; - emu_wrptr(sc, 0, reg, enable); -} -#endif - /* stuff */ static int emu_settimer(struct sc_info *sc) @@ -450,15 +418,15 @@ emu_valloc(struct sc_info *sc) static int emu_vinit(struct sc_info *sc, struct emu_voice *m, struct emu_voice *s, - u_int32_t sz, pcm_channel *c) + u_int32_t sz, struct snd_dbuf *b) { void *buf; buf = emu_memalloc(sc, sz); if (buf == NULL) return -1; - if (c != NULL) - sndbuf_setup(&c->buffer, buf, sz); + if (b != NULL) + sndbuf_setup(b, buf, sz); m->start = emu_memstart(sc, buf) * EMUPAGESIZE; m->end = m->start + sz; m->channel = NULL; @@ -646,10 +614,11 @@ emu_vdump(struct sc_info *sc, struct emu_voice *v) /* channel interface */ static void * -emupchan_init(kobj_t obj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir) +emupchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir) { struct sc_info *sc = devinfo; struct sc_pchinfo *ch; + void *r; KASSERT(dir == PCMDIR_PLAY, ("emupchan_init: bad direction")); ch = &sc->pch[sc->pnum++]; @@ -659,12 +628,13 @@ emupchan_init(kobj_t obj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir) ch->blksz = EMU_BUFFSIZE / 2; ch->fmt = AFMT_U8; ch->spd = 8000; + snd_mtxlock(sc->lock); ch->master = emu_valloc(sc); ch->slave = emu_valloc(sc); - if (emu_vinit(sc, ch->master, ch->slave, EMU_BUFFSIZE, ch->channel)) - return NULL; - else - return ch; + r = (emu_vinit(sc, ch->master, ch->slave, EMU_BUFFSIZE, ch->buffer))? NULL : ch; + snd_mtxunlock(sc->lock); + + return r; } static int @@ -672,8 +642,13 @@ emupchan_free(kobj_t obj, void *data) { struct sc_pchinfo *ch = data; struct sc_info *sc = ch->parent; + int r; + + snd_mtxlock(sc->lock); + r = emu_memfree(sc, sndbuf_getbuf(ch->buffer)); + snd_mtxunlock(sc->lock); - return emu_memfree(sc, sndbuf_getbuf(ch->buffer)); + return r; } static int @@ -702,8 +677,10 @@ emupchan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize) int irqrate, blksz; ch->blksz = blocksize; + snd_mtxlock(sc->lock); emu_settimer(sc); irqrate = 48000 / sc->timerinterval; + snd_mtxunlock(sc->lock); blksz = (ch->spd * sndbuf_getbps(ch->buffer)) / irqrate; return blocksize; } @@ -717,6 +694,7 @@ emupchan_trigger(kobj_t obj, void *data, int go) if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD) return 0; + snd_mtxlock(sc->lock); if (go == PCMTRIG_START) { emu_vsetup(ch); emu_vwrite(sc, ch->master); @@ -733,6 +711,7 @@ emupchan_trigger(kobj_t obj, void *data, int go) } ch->run = (go == PCMTRIG_START)? 1 : 0; emu_vtrigger(sc, ch->master, ch->run); + snd_mtxunlock(sc->lock); return 0; } @@ -741,11 +720,16 @@ emupchan_getptr(kobj_t obj, void *data) { struct sc_pchinfo *ch = data; struct sc_info *sc = ch->parent; + int r; + + snd_mtxlock(sc->lock); + r = emu_vpos(sc, ch->master); + snd_mtxunlock(sc->lock); - return emu_vpos(sc, ch->master); + return r; } -static pcmchan_caps * +static struct pcmchan_caps * emupchan_getcaps(kobj_t obj, void *data) { return &emu_playcaps; @@ -766,7 +750,7 @@ CHANNEL_DECLARE(emupchan); /* channel interface */ static void * -emurchan_init(kobj_t obj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir) +emurchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir) { struct sc_info *sc = devinfo; struct sc_rchinfo *ch; @@ -809,8 +793,10 @@ emurchan_init(kobj_t obj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir) if (sndbuf_alloc(ch->buffer, sc->parent_dmat, EMU_BUFFSIZE) == -1) return NULL; else { + snd_mtxlock(sc->lock); emu_wrptr(sc, 0, ch->basereg, vtophys(sndbuf_getbuf(ch->buffer))); emu_wrptr(sc, 0, ch->sizereg, 0); /* off */ + snd_mtxunlock(sc->lock); return ch; } } @@ -847,8 +833,10 @@ emurchan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize) int irqrate, blksz; ch->blksz = blocksize; + snd_mtxlock(sc->lock); emu_settimer(sc); irqrate = 48000 / sc->timerinterval; + snd_mtxunlock(sc->lock); blksz = (ch->spd * sndbuf_getbps(ch->buffer)) / irqrate; return blocksize; } @@ -861,6 +849,7 @@ emurchan_trigger(kobj_t obj, void *data, int go) struct sc_info *sc = ch->parent; u_int32_t val; + snd_mtxlock(sc->lock); switch(go) { case PCMTRIG_START: ch->run = 1; @@ -893,6 +882,7 @@ emurchan_trigger(kobj_t obj, void *data, int go) default: break; } + snd_mtxunlock(sc->lock); return 0; } @@ -902,11 +892,16 @@ emurchan_getptr(kobj_t obj, void *data) { struct sc_rchinfo *ch = data; struct sc_info *sc = ch->parent; + int r; + + snd_mtxlock(sc->lock); + r = emu_rdptr(sc, 0, ch->idxreg) & 0x0000ffff; + snd_mtxunlock(sc->lock); - return emu_rdptr(sc, 0, ch->idxreg) & 0x0000ffff; + return r; } -static pcmchan_caps * +static struct pcmchan_caps * emurchan_getcaps(kobj_t obj, void *data) { struct sc_rchinfo *ch = data; @@ -1421,12 +1416,12 @@ emu_pci_attach(device_t dev) int i, mapped; char status[SND_STATUSLEN]; - if ((sc = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT)) == NULL) { + if ((sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO)) == NULL) { device_printf(dev, "cannot allocate softc\n"); return ENXIO; } - bzero(sc, sizeof(*sc)); + sc->lock = snd_mtxcreate(device_get_nameunit(dev)); sc->dev = dev; sc->type = pci_get_devid(dev); sc->rev = pci_get_revid(dev); @@ -1482,8 +1477,7 @@ emu_pci_attach(device_t dev) sc->irqid = 0; sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irqid, 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE); - if (!sc->irq || - bus_setup_intr(dev, sc->irq, INTR_TYPE_TTY, emu_intr, sc, &sc->ih)) { + if (!sc->irq || snd_setup_intr(dev, sc->irq, INTR_MPSAFE, emu_intr, sc, &sc->ih)) { device_printf(dev, "unable to map interrupt\n"); goto bad; } @@ -1508,6 +1502,7 @@ bad: if (sc->ih) bus_teardown_intr(dev, sc->irq, sc->ih); if (sc->irq) bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq); if (sc->parent_dmat) bus_dma_tag_destroy(sc->parent_dmat); + if (sc->lock) snd_mtxfree(sc->lock); free(sc, M_DEVBUF); return ENXIO; } @@ -1530,6 +1525,7 @@ emu_pci_detach(device_t dev) bus_teardown_intr(dev, sc->irq, sc->ih); bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq); bus_dma_tag_destroy(sc->parent_dmat); + snd_mtxfree(sc->lock); free(sc, M_DEVBUF); return 0; @@ -1548,7 +1544,7 @@ static device_method_t emu_methods[] = { static driver_t emu_driver = { "pcm", emu_methods, - sizeof(snddev_info), + sizeof(struct snddev_info), }; static devclass_t pcm_devclass; diff --git a/sys/dev/sound/pci/es137x.c b/sys/dev/sound/pci/es137x.c index 6ea6507..116a0ff 100644 --- a/sys/dev/sound/pci/es137x.c +++ b/sys/dev/sound/pci/es137x.c @@ -79,8 +79,8 @@ struct es_info; struct es_chinfo { struct es_info *parent; - pcm_channel *channel; - snd_dbuf *buffer; + struct pcm_channel *channel; + struct snd_dbuf *buffer; int dir, num; u_int32_t fmt, blksz, bufsz; }; @@ -122,7 +122,7 @@ static u_int32_t es_playfmt[] = { AFMT_STEREO | AFMT_S16_LE, 0 }; -static pcmchan_caps es_playcaps = {4000, 48000, es_playfmt, 0}; +static struct pcmchan_caps es_playcaps = {4000, 48000, es_playfmt, 0}; static u_int32_t es_recfmt[] = { AFMT_U8, @@ -131,7 +131,7 @@ static u_int32_t es_recfmt[] = { AFMT_STEREO | AFMT_S16_LE, 0 }; -static pcmchan_caps es_reccaps = {4000, 48000, es_recfmt, 0}; +static struct pcmchan_caps es_reccaps = {4000, 48000, es_recfmt, 0}; static const struct { unsigned volidx:4; @@ -157,7 +157,7 @@ static const struct { /* The es1370 mixer interface */ static int -es1370_mixinit(snd_mixer *m) +es1370_mixinit(struct snd_mixer *m) { int i; u_int32_t v; @@ -174,7 +174,7 @@ es1370_mixinit(snd_mixer *m) } static int -es1370_mixset(snd_mixer *m, unsigned dev, unsigned left, unsigned right) +es1370_mixset(struct snd_mixer *m, unsigned dev, unsigned left, unsigned right) { int l, r, rl, rr; @@ -195,7 +195,7 @@ es1370_mixset(snd_mixer *m, unsigned dev, unsigned left, unsigned right) } static int -es1370_mixsetrecsrc(snd_mixer *m, u_int32_t src) +es1370_mixsetrecsrc(struct snd_mixer *m, u_int32_t src) { int i, j = 0; @@ -245,7 +245,7 @@ es1370_wrcodec(struct es_info *es, u_char i, u_char data) /* channel interface */ static void * -eschan_init(kobj_t obj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir) +eschan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir) { struct es_info *es = devinfo; struct es_chinfo *ch = (dir == PCMDIR_PLAY)? &es->pch : &es->rch; @@ -394,7 +394,7 @@ eschan_getptr(kobj_t obj, void *data) return cnt << 2; } -static pcmchan_caps * +static struct pcmchan_caps * eschan_getcaps(kobj_t obj, void *data) { struct es_chinfo *ch = data; @@ -818,8 +818,7 @@ es_pci_attach(device_t dev) es->irqid = 0; es->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &es->irqid, 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE); - if (!es->irq - || bus_setup_intr(dev, es->irq, INTR_TYPE_TTY, es_intr, es, &es->ih)) { + if (!es->irq || snd_setup_intr(dev, es->irq, 0, es_intr, es, &es->ih)) { device_printf(dev, "unable to map interrupt\n"); goto bad; } @@ -887,7 +886,7 @@ static device_method_t es_methods[] = { static driver_t es_driver = { "pcm", es_methods, - sizeof(snddev_info), + sizeof(struct snddev_info), }; static devclass_t pcm_devclass; diff --git a/sys/dev/sound/pci/fm801.c b/sys/dev/sound/pci/fm801.c index 48b9940..0584c01 100644 --- a/sys/dev/sound/pci/fm801.c +++ b/sys/dev/sound/pci/fm801.c @@ -102,7 +102,7 @@ #define DPRINT if(0) printf /* -static int fm801ch_setup(pcm_channel *c); +static int fm801ch_setup(struct pcm_channel *c); */ static u_int32_t fmts[] = { @@ -113,7 +113,7 @@ static u_int32_t fmts[] = { 0 }; -static pcmchan_caps fm801ch_caps = { +static struct pcmchan_caps fm801ch_caps = { 4000, 48000, fmts, 0 }; @@ -122,8 +122,8 @@ struct fm801_info; struct fm801_chinfo { struct fm801_info *parent; - pcm_channel *channel; - snd_dbuf *buffer; + struct pcm_channel *channel; + struct snd_dbuf *buffer; u_int32_t spd, dir, fmt; /* speed, direction, format */ u_int32_t shift; }; @@ -318,7 +318,7 @@ fm801_intr(void *p) /* -------------------------------------------------------------------- */ /* channel interface */ static void * -fm801ch_init(kobj_t obj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir) +fm801ch_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir) { struct fm801_info *fm801 = (struct fm801_info *)devinfo; struct fm801_chinfo *ch = (dir == PCMDIR_PLAY)? &fm801->pch : &fm801->rch; @@ -504,7 +504,7 @@ fm801ch_getptr(kobj_t obj, void *data) return result; } -static pcmchan_caps * +static struct pcmchan_caps * fm801ch_getcaps(kobj_t obj, void *data) { return &fm801ch_caps; @@ -615,9 +615,7 @@ fm801_pci_attach(device_t dev) fm801->irqid = 0; fm801->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &fm801->irqid, 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE); - if (!fm801->irq || - bus_setup_intr(dev, fm801->irq, INTR_TYPE_TTY, - fm801_intr, fm801, &fm801->ih)) { + if (!fm801->irq || snd_setup_intr(dev, fm801->irq, 0, fm801_intr, fm801, &fm801->ih)) { device_printf(dev, "unable to map interrupt\n"); goto oops; } @@ -703,7 +701,7 @@ static device_method_t fm801_methods[] = { static driver_t fm801_driver = { "pcm", fm801_methods, - sizeof(snddev_info), + sizeof(struct snddev_info), }; static devclass_t pcm_devclass; diff --git a/sys/dev/sound/pci/maestro.c b/sys/dev/sound/pci/maestro.c index e35e547..2042eaf 100644 --- a/sys/dev/sound/pci/maestro.c +++ b/sys/dev/sound/pci/maestro.c @@ -81,8 +81,8 @@ */ struct agg_chinfo { struct agg_info *parent; - pcm_channel *channel; - snd_dbuf *buffer; + struct pcm_channel *channel; + struct snd_dbuf *buffer; bus_addr_t offset; u_int32_t blocksize; u_int32_t speed; @@ -109,6 +109,7 @@ struct agg_info { bus_addr_t baseaddr; struct ac97_info *codec; + void *lock; u_int playchns, active; struct agg_chinfo pch[AGG_MAXPLAYCH]; @@ -637,7 +638,7 @@ set_timer(struct agg_info *ess) */ static void * -aggch_init(kobj_t obj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir) +aggch_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir) { struct agg_info *ess = devinfo; struct agg_chinfo *ch; @@ -661,8 +662,7 @@ aggch_init(kobj_t obj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir) if (physaddr < ess->baseaddr || ch->offset > WPWA_MAXADDR) { device_printf(ess->dev, "offset %#x exceeds limit. ", ch->offset); - dma_free(ess, b->buf); - b->buf = NULL; + dma_free(ess, sndbuf_getbuf(b)); return NULL; } @@ -786,7 +786,7 @@ aggch_getplayptr(kobj_t obj, void *data) return cp; } -static pcmchan_caps * +static struct pcmchan_caps * aggch_getcaps(kobj_t obj, void *data) { static u_int32_t playfmt[] = { @@ -798,7 +798,7 @@ aggch_getcaps(kobj_t obj, void *data) AFMT_STEREO | AFMT_S16_LE, 0 }; - static pcmchan_caps playcaps = {2000, 96000, playfmt, 0}; + static struct pcmchan_caps playcaps = {2000, 96000, playfmt, 0}; static u_int32_t recfmt[] = { AFMT_S8, @@ -807,7 +807,7 @@ aggch_getcaps(kobj_t obj, void *data) AFMT_STEREO | AFMT_S16_LE, 0 }; - static pcmchan_caps reccaps = {4000, 48000, recfmt, 0}; + static struct pcmchan_caps reccaps = {4000, 48000, recfmt, 0}; return (((struct agg_chinfo*)data)->dir == PCMDIR_PLAY)? &playcaps : &reccaps; @@ -1020,8 +1020,7 @@ agg_attach(device_t dev) irq = bus_alloc_resource(dev, SYS_RES_IRQ, &irqid, 0, BUS_SPACE_UNRESTRICTED, 1, RF_ACTIVE | RF_SHAREABLE); - if (irq == NULL - || bus_setup_intr(dev, irq, INTR_TYPE_TTY, agg_intr, ess, &ih)) { + if (irq == NULL || snd_setup_intr(dev, irq, 0, agg_intr, ess, &ih)) { device_printf(dev, "unable to map interrupt\n"); goto bad; } @@ -1183,7 +1182,7 @@ static device_method_t agg_methods[] = { static driver_t agg_driver = { "pcm", agg_methods, - sizeof(snddev_info), + sizeof(struct snddev_info), }; static devclass_t pcm_devclass; diff --git a/sys/dev/sound/pci/maestro3.c b/sys/dev/sound/pci/maestro3.c index 9551dee..375fa31 100644 --- a/sys/dev/sound/pci/maestro3.c +++ b/sys/dev/sound/pci/maestro3.c @@ -95,8 +95,8 @@ struct sc_info; struct sc_pchinfo { u_int32_t spd; u_int32_t fmt; - snd_dbuf *buffer; - pcm_channel *channel; + struct snd_dbuf *buffer; + struct pcm_channel *channel; struct sc_info *parent; u_int32_t bufsize; u_int32_t dac_data; @@ -107,8 +107,8 @@ struct sc_pchinfo { struct sc_rchinfo { u_int32_t spd; u_int32_t fmt; - snd_dbuf *buffer; - pcm_channel *channel; + struct snd_dbuf *buffer; + struct pcm_channel *channel; struct sc_info *parent; u_int32_t bufsize; u_int32_t adc_data; @@ -145,24 +145,24 @@ struct sc_info { /* -------------------------------------------------------------------- */ /* play channel interface */ -static void *m3_pchan_init(kobj_t, void *, snd_dbuf *, pcm_channel *, int); +static void *m3_pchan_init(kobj_t, void *, struct snd_dbuf *, struct pcm_channel *, int); static int m3_pchan_free(kobj_t, void *); static int m3_pchan_setformat(kobj_t, void *, u_int32_t); static int m3_pchan_setspeed(kobj_t, void *, u_int32_t); static int m3_pchan_setblocksize(kobj_t, void *, u_int32_t); static int m3_pchan_trigger(kobj_t, void *, int); static int m3_pchan_getptr(kobj_t, void *); -static pcmchan_caps *m3_pchan_getcaps(kobj_t, void *); +static struct pcmchan_caps *m3_pchan_getcaps(kobj_t, void *); /* record channel interface */ -static void *m3_rchan_init(kobj_t, void *, snd_dbuf *, pcm_channel *, int); +static void *m3_rchan_init(kobj_t, void *, struct snd_dbuf *, struct pcm_channel *, int); static int m3_rchan_free(kobj_t, void *); static int m3_rchan_setformat(kobj_t, void *, u_int32_t); static int m3_rchan_setspeed(kobj_t, void *, u_int32_t); static int m3_rchan_setblocksize(kobj_t, void *, u_int32_t); static int m3_rchan_trigger(kobj_t, void *, int); static int m3_rchan_getptr(kobj_t, void *); -static pcmchan_caps *m3_rchan_getcaps(kobj_t, void *); +static struct pcmchan_caps *m3_rchan_getcaps(kobj_t, void *); /* talk to the codec - called from ac97.c */ static int m3_initcd(kobj_t, void *); @@ -200,7 +200,7 @@ static u_int32_t m3_playfmt[] = { AFMT_STEREO | AFMT_S16_LE, 0 }; -static pcmchan_caps m3_playcaps = {8000, 48000, m3_playfmt, 0}; +static struct pcmchan_caps m3_playcaps = {8000, 48000, m3_playfmt, 0}; static kobj_method_t m3_pch_methods[] = { KOBJMETHOD(channel_init, m3_pchan_init), @@ -222,7 +222,7 @@ static u_int32_t m3_recfmt[] = { AFMT_STEREO | AFMT_S16_LE, 0 }; -static pcmchan_caps m3_reccaps = {8000, 48000, m3_recfmt, 0}; +static struct pcmchan_caps m3_reccaps = {8000, 48000, m3_recfmt, 0}; static kobj_method_t m3_rch_methods[] = { KOBJMETHOD(channel_init, m3_rchan_init), @@ -314,7 +314,7 @@ m3_rdcd(kobj_t kobj, void *devinfo, int regno) return -1; } m3_wr_1(sc, CODEC_COMMAND, (regno & 0x7f) | 0x80); - DELAY(21); /* ac97 cycle = 20.8 usec */ + DELAY(50); /* ac97 cycle = 20.8 usec */ if (m3_wait(sc)) { device_printf(sc->dev, "m3_rdcd timed out.\n"); return -1; @@ -333,6 +333,7 @@ m3_wrcd(kobj_t kobj, void *devinfo, int regno, u_int32_t data) } m3_wr_2(sc, CODEC_DATA, data); m3_wr_1(sc, CODEC_COMMAND, regno & 0x7f); + DELAY(50); /* ac97 cycle = 20.8 usec */ return 0; } @@ -343,7 +344,7 @@ m3_wrcd(kobj_t kobj, void *devinfo, int regno, u_int32_t data) #define HI(x) (((x) & 0xffff0000) >> 16) static void * -m3_pchan_init(kobj_t kobj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir) +m3_pchan_init(kobj_t kobj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir) { struct sc_info *sc = devinfo; struct sc_pchinfo *ch; @@ -609,7 +610,7 @@ m3_pchan_getptr(kobj_t kobj, void *chdata) return (bus_crnt - bus_base); /* current byte offset of channel */ } -static pcmchan_caps * +static struct pcmchan_caps * m3_pchan_getcaps(kobj_t kobj, void *chdata) { struct sc_pchinfo *ch = chdata; @@ -623,7 +624,7 @@ m3_pchan_getcaps(kobj_t kobj, void *chdata) /* rec channel interface */ static void * -m3_rchan_init(kobj_t kobj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir) +m3_rchan_init(kobj_t kobj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir) { struct sc_info *sc = devinfo; struct sc_rchinfo *ch; @@ -879,7 +880,7 @@ m3_rchan_getptr(kobj_t kobj, void *chdata) return (bus_crnt - bus_base); /* current byte offset of channel */ } -static pcmchan_caps * +static struct pcmchan_caps * m3_rchan_getcaps(kobj_t kobj, void *chdata) { struct sc_rchinfo *ch = chdata; @@ -1133,8 +1134,7 @@ m3_pci_attach(device_t dev) goto bad; } - if (bus_setup_intr(dev, sc->irq, INTR_TYPE_TTY, m3_intr, sc, - &sc->ih)) { + if (snd_setup_intr(dev, sc->irq, 0, m3_intr, sc, &sc->ih)) { device_printf(dev, "unable to setup interrupt\n"); goto bad; } @@ -1192,6 +1192,7 @@ m3_pci_attach(device_t dev) device_printf(dev, "attach: pcm_setstatus error\n"); goto bad; } + mixer_hwvol_init(dev); /* Create the buffer for saving the card state during suspend */ len = sizeof(u_int16_t) * (REV_B_CODE_MEMORY_LENGTH + @@ -1491,7 +1492,7 @@ static device_method_t m3_methods[] = { static driver_t m3_driver = { "pcm", m3_methods, - sizeof(snddev_info), + sizeof(struct snddev_info), }; static devclass_t pcm_devclass; diff --git a/sys/dev/sound/pci/neomagic.c b/sys/dev/sound/pci/neomagic.c index 5a6ca8c..8771136 100644 --- a/sys/dev/sound/pci/neomagic.c +++ b/sys/dev/sound/pci/neomagic.c @@ -48,8 +48,8 @@ struct sc_info; /* channel registers */ struct sc_chinfo { int spd, dir, fmt; - snd_dbuf *buffer; - pcm_channel *channel; + struct snd_dbuf *buffer; + struct pcm_channel *channel; struct sc_info *parent; }; @@ -117,7 +117,7 @@ static u_int32_t nm_fmt[] = { AFMT_STEREO | AFMT_S16_LE, 0 }; -static pcmchan_caps nm_caps = {4000, 48000, nm_fmt, 0}; +static struct pcmchan_caps nm_caps = {4000, 48000, nm_fmt, 0}; /* -------------------------------------------------------------------- */ @@ -329,7 +329,7 @@ nm_setch(struct sc_chinfo *ch) /* channel interface */ static void * -nmchan_init(kobj_t obj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir) +nmchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir) { struct sc_info *sc = devinfo; struct sc_chinfo *ch; @@ -341,7 +341,7 @@ nmchan_init(kobj_t obj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir) sndbuf_setup(ch->buffer, (u_int8_t *)rman_get_virtual(sc->buf) + chnbuf, NM_BUFFSIZE); if (bootverbose) device_printf(sc->dev, "%s buf %p\n", (dir == PCMDIR_PLAY)? - "play" : "rec", ch->buffer->buf); + "play" : "rec", sndbuf_getbuf(ch->buffer)); ch->parent = sc; ch->channel = c; ch->dir = dir; @@ -432,7 +432,7 @@ nmchan_getptr(kobj_t obj, void *data) return nm_rd(sc, NM_RBUFFER_CURRP, 4) - sc->rbuf; } -static pcmchan_caps * +static struct pcmchan_caps * nmchan_getcaps(kobj_t obj, void *data) { return &nm_caps; @@ -623,8 +623,7 @@ nm_pci_attach(device_t dev) sc->irqid = 0; sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irqid, 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE); - if (!sc->irq || - bus_setup_intr(dev, sc->irq, INTR_TYPE_TTY, nm_intr, sc, &sc->ih)) { + if (!sc->irq || snd_setup_intr(dev, sc->irq, 0, nm_intr, sc, &sc->ih)) { device_printf(dev, "unable to map interrupt\n"); goto bad; } @@ -702,7 +701,7 @@ static device_method_t nm_methods[] = { static driver_t nm_driver = { "pcm", nm_methods, - sizeof(snddev_info), + sizeof(struct snddev_info), }; static devclass_t pcm_devclass; diff --git a/sys/dev/sound/pci/solo.c b/sys/dev/sound/pci/solo.c index 71a00f1..d6d7c71 100644 --- a/sys/dev/sound/pci/solo.c +++ b/sys/dev/sound/pci/solo.c @@ -55,7 +55,7 @@ static u_int32_t ess_playfmt[] = { AFMT_STEREO | AFMT_U16_LE, 0 }; -static pcmchan_caps ess_playcaps = {5000, 49000, ess_playfmt, 0}; +static struct pcmchan_caps ess_playcaps = {5000, 49000, ess_playfmt, 0}; /* * Recording output is byte-swapped @@ -71,14 +71,14 @@ static u_int32_t ess_recfmt[] = { AFMT_STEREO | AFMT_U16_BE, 0 }; -static pcmchan_caps ess_reccaps = {5000, 49000, ess_recfmt, 0}; +static struct pcmchan_caps ess_reccaps = {5000, 49000, ess_recfmt, 0}; struct ess_info; struct ess_chinfo { struct ess_info *parent; - pcm_channel *channel; - snd_dbuf *buffer; + struct pcm_channel *channel; + struct snd_dbuf *buffer; int dir, hwch, stopping; u_int32_t fmt, spd, blksz; }; @@ -510,7 +510,7 @@ ess_stop(struct ess_chinfo *ch) /* -------------------------------------------------------------------- */ /* channel interface for ESS18xx */ static void * -esschan_init(kobj_t obj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir) +esschan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir) { struct ess_info *sc = devinfo; struct ess_chinfo *ch = (dir == PCMDIR_PLAY)? &sc->pch : &sc->rch; @@ -595,7 +595,7 @@ esschan_getptr(kobj_t obj, void *data) return ess_dmapos(sc, ch->hwch); } -static pcmchan_caps * +static struct pcmchan_caps * esschan_getcaps(kobj_t obj, void *data) { struct ess_chinfo *ch = data; @@ -618,7 +618,7 @@ CHANNEL_DECLARE(esschan); /************************************************************/ static int -essmix_init(snd_mixer *m) +essmix_init(struct snd_mixer *m) { struct ess_info *sc = mix_getdevinfo(m); @@ -635,7 +635,7 @@ essmix_init(snd_mixer *m) } static int -essmix_set(snd_mixer *m, unsigned dev, unsigned left, unsigned right) +essmix_set(struct snd_mixer *m, unsigned dev, unsigned left, unsigned right) { struct ess_info *sc = mix_getdevinfo(m); int preg = 0, rreg = 0, l, r; @@ -695,7 +695,7 @@ essmix_set(snd_mixer *m, unsigned dev, unsigned left, unsigned right) } static int -essmix_setrecsrc(snd_mixer *m, u_int32_t src) +essmix_setrecsrc(struct snd_mixer *m, u_int32_t src) { struct ess_info *sc = mix_getdevinfo(m); u_char recdev; @@ -944,7 +944,7 @@ ess_attach(device_t dev) if (sc->newspeed) ess_setmixer(sc, 0x71, 0x2a); - bus_setup_intr(dev, sc->irq, INTR_TYPE_TTY, ess_intr, sc, &sc->ih); + snd_setup_intr(dev, sc->irq, 0, ess_intr, sc, &sc->ih); if (!sc->duplex) pcm_setflags(dev, pcm_getflags(dev) | SD_F_SIMPLEX); @@ -1005,7 +1005,7 @@ static device_method_t ess_methods[] = { static driver_t ess_driver = { "pcm", ess_methods, - sizeof(snddev_info), + sizeof(struct snddev_info), }; DRIVER_MODULE(snd_solo, pci, ess_driver, pcm_devclass, 0, 0); diff --git a/sys/dev/sound/pci/t4dwave.c b/sys/dev/sound/pci/t4dwave.c index b1a3c44..76254cc 100644 --- a/sys/dev/sound/pci/t4dwave.c +++ b/sys/dev/sound/pci/t4dwave.c @@ -52,15 +52,15 @@ struct tr_chinfo { u_int32_t rvol, cvol; u_int32_t gvsel, pan, vol, ctrl; int index, bufhalf; - snd_dbuf *buffer; - pcm_channel *channel; + struct snd_dbuf *buffer; + struct pcm_channel *channel; struct tr_info *parent; }; struct tr_rchinfo { u_int32_t delta; - snd_dbuf *buffer; - pcm_channel *channel; + struct snd_dbuf *buffer; + struct pcm_channel *channel; struct tr_info *parent; }; @@ -76,6 +76,8 @@ struct tr_info { int regtype, regid, irqid; void *ih; + void *lock; + u_int32_t playchns; struct tr_chinfo chinfo[TR_MAXPLAYCH]; struct tr_rchinfo recchinfo; @@ -94,7 +96,7 @@ static u_int32_t tr_recfmt[] = { AFMT_STEREO | AFMT_U16_LE, 0 }; -static pcmchan_caps tr_reccaps = {4000, 48000, tr_recfmt, 0}; +static struct pcmchan_caps tr_reccaps = {4000, 48000, tr_recfmt, 0}; static u_int32_t tr_playfmt[] = { AFMT_U8, @@ -107,7 +109,7 @@ static u_int32_t tr_playfmt[] = { AFMT_STEREO | AFMT_U16_LE, 0 }; -static pcmchan_caps tr_playcaps = {4000, 48000, tr_playfmt, 0}; +static struct pcmchan_caps tr_playcaps = {4000, 48000, tr_playfmt, 0}; /* -------------------------------------------------------------------- */ @@ -168,9 +170,11 @@ tr_rdcd(kobj_t obj, void *devinfo, int regno) } regno &= 0x7f; + snd_mtxlock(tr->lock); tr_wr(tr, treg, regno | trw, 4); j=trw; for (i=TR_TIMEOUT_CDC; (i > 0) && (j & trw); i--) j=tr_rd(tr, treg, 4); + snd_mtxunlock(tr->lock); if (i == 0) printf("codec timeout during read of register %x\n", regno); return (j >> TR_CDC_DATA) & 0xffff; } @@ -200,11 +204,13 @@ tr_wrcd(kobj_t obj, void *devinfo, int regno, u_int32_t data) printf("tr_wrcd: reg %x was %x", regno, tr_rdcd(devinfo, regno)); #endif j=trw; + snd_mtxlock(tr->lock); for (i=TR_TIMEOUT_CDC; (i>0) && (j & trw); i--) j=tr_rd(tr, treg, 4); tr_wr(tr, treg, (data << TR_CDC_DATA) | regno | trw, 4); #if 0 printf(" - wrote %x, now %x\n", data, tr_rdcd(devinfo, regno)); #endif + snd_mtxunlock(tr->lock); if (i==0) printf("codec timeout writing %x, data %x\n", regno, data); return (i > 0)? 0 : -1; } @@ -250,6 +256,7 @@ tr_enaint(struct tr_chinfo *ch, int enable) u_int32_t i, reg; int bank, chan; + snd_mtxlock(tr->lock); bank = (ch->index & 0x20) ? 1 : 0; chan = ch->index & 0x1f; reg = bank? TR_REG_INTENB : TR_REG_INTENA; @@ -260,6 +267,7 @@ tr_enaint(struct tr_chinfo *ch, int enable) tr_clrint(ch); tr_wr(tr, reg, i, 4); + snd_mtxunlock(tr->lock); } /* playback channels */ @@ -336,9 +344,11 @@ tr_wrch(struct tr_chinfo *ch) cr[3]|=(ch->alpha<<20) | (ch->fms<<16) | (ch->fmc<<14); break; } + snd_mtxlock(tr->lock); tr_selch(ch); for (i=0; i<TR_CHN_REGS; i++) tr_wr(tr, TR_REG_CHNBASE+(i<<2), cr[i], 4); + snd_mtxunlock(tr->lock); } static void @@ -347,9 +357,11 @@ tr_rdch(struct tr_chinfo *ch) struct tr_info *tr = ch->parent; u_int32_t cr[5], i; + snd_mtxlock(tr->lock); tr_selch(ch); for (i=0; i<5; i++) cr[i]=tr_rd(tr, TR_REG_CHNBASE+(i<<2), 4); + snd_mtxunlock(tr->lock); ch->lba= (cr[1] & 0x3fffffff); @@ -396,7 +408,7 @@ tr_fmttobits(u_int32_t fmt) /* channel interface */ static void * -trpchan_init(kobj_t obj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir) +trpchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir) { struct tr_info *tr = devinfo; struct tr_chinfo *ch; @@ -480,7 +492,7 @@ trpchan_getptr(kobj_t obj, void *data) return ch->cso * sndbuf_getbps(ch->buffer); } -static pcmchan_caps * +static struct pcmchan_caps * trpchan_getcaps(kobj_t obj, void *data) { return &tr_playcaps; @@ -502,7 +514,7 @@ CHANNEL_DECLARE(trpchan); /* rec channel interface */ static void * -trrchan_init(kobj_t obj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir) +trrchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir) { struct tr_info *tr = devinfo; struct tr_rchinfo *ch; @@ -600,7 +612,7 @@ trrchan_getptr(kobj_t obj, void *data) return tr_rd(tr, TR_REG_DMAR0, 4) - vtophys(sndbuf_getbuf(ch->buffer)); } -static pcmchan_caps * +static struct pcmchan_caps * trrchan_getcaps(kobj_t obj, void *data) { return &tr_reccaps; @@ -646,9 +658,7 @@ tr_intr(void *p) if (ch->bufhalf != tmp) { chn_intr(ch->channel); ch->bufhalf = tmp; - } else - printf("same bufhalf\n"); - + } } } chnum++; @@ -716,6 +726,7 @@ tr_pci_attach(device_t dev) bzero(tr, sizeof(*tr)); tr->type = pci_get_devid(dev); + tr->lock = snd_mtxcreate(device_get_nameunit(dev)); data = pci_read_config(dev, PCIR_COMMAND, 2); data |= (PCIM_CMD_PORTEN|PCIM_CMD_MEMEN|PCIM_CMD_BUSMASTEREN); @@ -745,8 +756,7 @@ tr_pci_attach(device_t dev) tr->irqid = 0; tr->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &tr->irqid, 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE); - if (!tr->irq || - bus_setup_intr(dev, tr->irq, INTR_TYPE_TTY, tr_intr, tr, &tr->ih)) { + if (!tr->irq || snd_setup_intr(dev, tr->irq, INTR_MPSAFE, tr_intr, tr, &tr->ih)) { device_printf(dev, "unable to map interrupt\n"); goto bad; } @@ -778,6 +788,7 @@ bad: if (tr->ih) bus_teardown_intr(dev, tr->irq, tr->ih); if (tr->irq) bus_release_resource(dev, SYS_RES_IRQ, tr->irqid, tr->irq); if (tr->parent_dmat) bus_dma_tag_destroy(tr->parent_dmat); + if (tr->lock) snd_mtxfree(tr->lock); free(tr, M_DEVBUF); return ENXIO; } @@ -797,6 +808,7 @@ tr_pci_detach(device_t dev) bus_teardown_intr(dev, tr->irq, tr->ih); bus_release_resource(dev, SYS_RES_IRQ, tr->irqid, tr->irq); bus_dma_tag_destroy(tr->parent_dmat); + snd_mtxfree(tr->lock); free(tr, M_DEVBUF); return 0; @@ -814,7 +826,7 @@ static device_method_t tr_methods[] = { static driver_t tr_driver = { "pcm", tr_methods, - sizeof(snddev_info), + sizeof(struct snddev_info), }; static devclass_t pcm_devclass; diff --git a/sys/dev/sound/pci/via82c686.c b/sys/dev/sound/pci/via82c686.c index 5f5a2b1..7450e2a 100644 --- a/sys/dev/sound/pci/via82c686.c +++ b/sys/dev/sound/pci/via82c686.c @@ -36,12 +36,12 @@ #include <dev/sound/pci/via82c686.h> #define VIA_PCI_ID 0x30581106 -#define NSEGS 16 /* Number of segments in SGD table */ +#define NSEGS 4 /* Number of segments in SGD table */ #define SEGS_PER_CHAN (NSEGS/2) #define TIMEOUT 50 -#define VIA_BUFFSIZE 0x4000 +#define VIA_BUFFSIZE 0x1000 #undef DEB #define DEB(x) @@ -60,9 +60,11 @@ struct via_info; struct via_chinfo { struct via_info *parent; - pcm_channel *channel; - snd_dbuf *buffer; - int dir; + struct pcm_channel *channel; + struct snd_dbuf *buffer; + struct via_dma_op *sgd_table; + int dir, blksz; + int base, count, mode, ctrl; }; struct via_info { @@ -70,39 +72,27 @@ struct via_info { bus_space_handle_t sh; bus_dma_tag_t parent_dmat; bus_dma_tag_t sgd_dmat; + bus_dmamap_t sgd_dmamap; struct resource *reg, *irq; int regid, irqid; void *ih; + struct ac97_info *codec; struct via_chinfo pch, rch; struct via_dma_op *sgd_table; u_int16_t codec_caps; }; -static u_int32_t via_rd(struct via_info *via, int regno, int size); -static void via_wr(struct via_info *, int regno, u_int32_t data, int size); - -static void via_intr(void *); -bus_dmamap_callback_t dma_cb; - -static u_int32_t via_playfmt[] = { - AFMT_U8, - AFMT_STEREO | AFMT_U8, - AFMT_S16_LE, - AFMT_STEREO | AFMT_S16_LE, - 0 -}; -static pcmchan_caps via_playcaps = {4000, 48000, via_playfmt, 0}; - -static u_int32_t via_recfmt[] = { +static u_int32_t via_fmt[] = { AFMT_U8, AFMT_STEREO | AFMT_U8, AFMT_S16_LE, AFMT_STEREO | AFMT_S16_LE, 0 }; -static pcmchan_caps via_reccaps = {4000, 48000, via_recfmt, 0}; +static struct pcmchan_caps via_vracaps = {4000, 48000, via_fmt, 0}; +static struct pcmchan_caps via_caps = {48000, 48000, via_fmt, 0}; static u_int32_t via_rd(struct via_info *via, int regno, int size) @@ -184,8 +174,7 @@ via_write_codec(kobj_t obj, void *addr, int reg, u_int32_t val) if (via_waitready_codec(via)) return -1; - via_wr(via, VIA_CODEC_CTL, - VIA_CODEC_PRIVALID | VIA_CODEC_INDEX(reg) | val, 4); + via_wr(via, VIA_CODEC_CTL, VIA_CODEC_PRIVALID | VIA_CODEC_INDEX(reg) | val, 4); return 0; } @@ -197,16 +186,15 @@ via_read_codec(kobj_t obj, void *addr, int reg) struct via_info *via = addr; if (via_waitready_codec(via)) - return 1; + return -1; - via_wr(via, VIA_CODEC_CTL, - VIA_CODEC_PRIVALID | VIA_CODEC_READ | VIA_CODEC_INDEX(reg),4); + via_wr(via, VIA_CODEC_CTL, VIA_CODEC_PRIVALID | VIA_CODEC_READ | VIA_CODEC_INDEX(reg),4); if (via_waitready_codec(via)) - return 1; + return -1; if (via_waitvalid_codec(via)) - return 1; + return -1; return via_rd(via, VIA_CODEC_CTL, 2); } @@ -220,58 +208,60 @@ AC97_DECLARE(via_ac97); /* -------------------------------------------------------------------- */ -/* channel interface */ -static void * -viachan_init(kobj_t obj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir) -{ - struct via_info *via = devinfo; - struct via_chinfo *ch = (dir == PCMDIR_PLAY) ? &via->pch : &via->rch; - - ch->parent = via; - ch->channel = c; - ch->buffer = b; - - if (sndbuf_alloc(ch->buffer, via->parent_dmat, VIA_BUFFSIZE) == -1) return NULL; - return ch; -} - static int -viachan_setdir(kobj_t obj, void *data, int dir) +via_buildsgdt(struct via_chinfo *ch) { - struct via_chinfo *ch = data; - struct via_info *via = ch->parent; - struct via_dma_op *ado; - int i, chunk_size; - int phys_addr, flag; + u_int32_t phys_addr, flag; + int i, segs, seg_size; - ch->dir = dir; /* * Build the scatter/gather DMA (SGD) table. * There are four slots in the table: two for play, two for record. * This creates two half-buffers, one of which is playing; the other * is feeding. */ - ado = via->sgd_table; - chunk_size = sndbuf_getsize(ch->buffer) / SEGS_PER_CHAN; + seg_size = ch->blksz; + segs = sndbuf_getsize(ch->buffer) / seg_size; + phys_addr = vtophys(sndbuf_getbuf(ch->buffer)); - if (dir == PCMDIR_REC) { - ado += SEGS_PER_CHAN; + for (i = 0; i < segs; i++) { + flag = (i == segs - 1)? VIA_DMAOP_EOL : VIA_DMAOP_FLAG; + ch->sgd_table[i].ptr = phys_addr + (i * seg_size); + ch->sgd_table[i].flags = flag | seg_size; } - DEB(printf("SGD table located at va %p\n", ado)); - phys_addr = vtophys(sndbuf_getbuf(ch->buffer)); - for (i = 0; i < SEGS_PER_CHAN; i++) { - ado->ptr = phys_addr; - flag = (i == SEGS_PER_CHAN-1) ? - VIA_DMAOP_EOL : VIA_DMAOP_FLAG; - ado->flags = flag | chunk_size; - DEB(printf("ado->ptr/flags = %x/%x\n", phys_addr, flag)); - phys_addr += chunk_size; - ado++; - } return 0; } +/* channel interface */ +static void * +viachan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir) +{ + struct via_info *via = devinfo; + struct via_chinfo *ch = (dir == PCMDIR_PLAY)? &via->pch : &via->rch; + + ch->parent = via; + ch->channel = c; + ch->buffer = b; + ch->dir = dir; + ch->sgd_table = &via->sgd_table[(dir == PCMDIR_PLAY)? 0 : SEGS_PER_CHAN]; + if (ch->dir == PCMDIR_PLAY) { + ch->base = VIA_PLAY_DMAOPS_BASE; + ch->count = VIA_PLAY_DMAOPS_COUNT; + ch->ctrl = VIA_RECORD_CONTROL; + ch->mode = VIA_PLAY_MODE; + } else { + ch->base = VIA_RECORD_DMAOPS_BASE; + ch->count = VIA_RECORD_DMAOPS_COUNT; + ch->ctrl = VIA_PLAY_CONTROL; + ch->mode = VIA_RECORD_MODE; + } + + if (sndbuf_alloc(ch->buffer, via->parent_dmat, VIA_BUFFSIZE) == -1) + return NULL; + return ch; +} + static int viachan_setformat(kobj_t obj, void *data, u_int32_t format) { @@ -285,21 +275,11 @@ viachan_setformat(kobj_t obj, void *data, u_int32_t format) if (format & AFMT_S16_LE) mode_set |= VIA_RPMODE_16BIT; - /* Set up for output format */ - if (ch->dir == PCMDIR_PLAY) { - DEB(printf("set play format: %x\n", format)); - mode = via_rd(via, VIA_PLAY_MODE, 1); - mode &= ~(VIA_RPMODE_16BIT | VIA_RPMODE_STEREO); - mode |= mode_set; - via_wr(via, VIA_PLAY_MODE, mode, 1); - } - else { - DEB(printf("set record format: %x\n", format)); - mode = via_rd(via, VIA_RECORD_MODE, 1); + DEB(printf("set format: dir = %d, format=%x\n", ch->dir, format)); + mode = via_rd(via, ch->mode, 1); mode &= ~(VIA_RPMODE_16BIT | VIA_RPMODE_STEREO); mode |= mode_set; - via_wr(via, VIA_RECORD_MODE, mode, 1); - } + via_wr(via, ch->mode, mode, 1); return 0; } @@ -309,6 +289,7 @@ viachan_setspeed(kobj_t obj, void *data, u_int32_t speed) { struct via_chinfo *ch = data; struct via_info *via = ch->parent; + int reg; /* * Basic AC'97 defines a 48 kHz sample rate only. For other rates, @@ -319,31 +300,11 @@ viachan_setspeed(kobj_t obj, void *data, u_int32_t speed) * itself), then negotiate the rate with the codec. Otherwise, * return 48 kHz cuz that's all you got. */ - if (ch->dir == PCMDIR_PLAY) { - DEB(printf("requested play speed: %d\n", speed)); - if (via->codec_caps & AC97_CODEC_DOES_VRA) { - via_write_codec(NULL, via, AC97_REG_EXT_DAC_RATE, speed); - speed = via_read_codec(NULL, via, AC97_REG_EXT_DAC_RATE); - } - else { - DEB(printf("VRA not supported!\n")); - speed = 48000; - } - DEB(printf("obtained play speed: %d\n", speed)); - } - else { - DEB(printf("requested record speed: %d\n", speed)); - if (via->codec_caps & AC97_CODEC_DOES_VRA) { - via_write_codec(NULL, via, AC97_REG_EXT_ADC_RATE, speed); - speed = via_read_codec(NULL, via, AC97_REG_EXT_ADC_RATE); - } - else { - DEB(printf("VRA not supported!\n")); - speed = 48000; - } - DEB(printf("obtained record speed: %d\n", speed)); - } - return speed; + if (via->codec_caps & AC97_EXTCAP_VRA) { + reg = (ch->dir == PCMDIR_PLAY)? AC97_REGEXT_FDACRATE : AC97_REGEXT_LADCRATE; + return ac97_setrate(via->codec, reg, speed); + } else + return 48000; } static int @@ -351,7 +312,10 @@ viachan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize) { struct via_chinfo *ch = data; - return sndbuf_getsize(ch->buffer) / 2; + ch->blksz = blocksize; + sndbuf_resize(ch->buffer, SEGS_PER_CHAN, ch->blksz); + + return ch->blksz; } static int @@ -361,37 +325,20 @@ viachan_trigger(kobj_t obj, void *data, int go) struct via_info *via = ch->parent; struct via_dma_op *ado; - if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD) return 0; - if (ch->dir == PCMDIR_PLAY) { - if (go == PCMTRIG_START) { - ado = &via->sgd_table[0]; + if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD) + return 0; + + ado = ch->sgd_table; DEB(printf("ado located at va=%p pa=%x\n", ado, vtophys(ado))); - via_wr(via, VIA_PLAY_DMAOPS_BASE, vtophys(ado),4); - via_wr(via, VIA_PLAY_CONTROL, - VIA_RPCTRL_START, 1); - } - else { - /* Stop DMA */ - via_wr(via, VIA_PLAY_CONTROL, - VIA_RPCTRL_TERMINATE, 1); - } - } else { + if (go == PCMTRIG_START) { - ado = &via->sgd_table[SEGS_PER_CHAN]; - DEB(printf("ado located at va=%p pa=%x\n", ado, vtophys(ado))); - via_wr(via, VIA_RECORD_DMAOPS_BASE, - vtophys(ado),4); - via_wr(via, VIA_RECORD_CONTROL, - VIA_RPCTRL_START, 1); - } - else { - /* Stop DMA */ - via_wr(via, VIA_RECORD_CONTROL, - VIA_RPCTRL_TERMINATE, 1); - } - } + via_buildsgdt(ch); + via_wr(via, ch->base, vtophys(ado), 4); + via_wr(via, ch->ctrl, VIA_RPCTRL_START, 1); + } else + via_wr(via, ch->ctrl, VIA_RPCTRL_TERMINATE, 1); -DEB(printf("viachan_trigger: go=%d\n", go)); + DEB(printf("viachan_trigger: go=%d\n", go)); return 0; } @@ -401,68 +348,47 @@ viachan_getptr(kobj_t obj, void *data) struct via_chinfo *ch = data; struct via_info *via = ch->parent; struct via_dma_op *ado; - int ptr, base, len, seg; - int base1; + int ptr, base, base1, len, seg; - if (ch->dir == PCMDIR_PLAY) { - ado = &via->sgd_table[0]; - base1 = via_rd(via, VIA_PLAY_DMAOPS_BASE, 4); - len = via_rd(via, VIA_PLAY_DMAOPS_COUNT, 4); - base = via_rd(via, VIA_PLAY_DMAOPS_BASE, 4); - if (base != base1) { /* Avoid race hazzard */ - len = via_rd(via, VIA_PLAY_DMAOPS_COUNT, 4); - } - DEB(printf("viachan_getptr: len / base = %x / %x\n", len, base)); - - /* Base points to SGD segment to do, one past current */ - - /* Determine how many segments have been done */ - seg = (base - vtophys(ado)) / sizeof(struct via_dma_op); - if (seg == 0) seg = SEGS_PER_CHAN; + ado = ch->sgd_table; + base1 = via_rd(via, ch->base, 4); + len = via_rd(via, ch->count, 4); + base = via_rd(via, ch->base, 4); + if (base != base1) /* Avoid race hazard */ + len = via_rd(via, ch->count, 4); - /* Now work out offset: seg less count */ - ptr = seg * sndbuf_getsize(ch->buffer) / SEGS_PER_CHAN - len; - DEB(printf("return ptr=%d\n", ptr)); - return ptr; - } - else { - base1 = via_rd(via, VIA_RECORD_DMAOPS_BASE, 4); - ado = &via->sgd_table[SEGS_PER_CHAN]; - len = via_rd(via, VIA_RECORD_DMAOPS_COUNT, 4); - base = via_rd(via, VIA_RECORD_DMAOPS_BASE, 4); - if (base != base1) { /* Avoid race hazzard */ - len = via_rd(via, VIA_RECORD_DMAOPS_COUNT, 4); - } DEB(printf("viachan_getptr: len / base = %x / %x\n", len, base)); - /* Base points to next block to do, one past current */ + /* Base points to SGD segment to do, one past current */ /* Determine how many segments have been done */ seg = (base - vtophys(ado)) / sizeof(struct via_dma_op); - if (seg == 0) seg = SEGS_PER_CHAN; + if (seg == 0) + seg = SEGS_PER_CHAN; /* Now work out offset: seg less count */ - ptr = seg * sndbuf_getsize(ch->buffer) / SEGS_PER_CHAN - len; - + ptr = (seg * sndbuf_getsize(ch->buffer) / SEGS_PER_CHAN) - len; + if (ch->dir == PCMDIR_REC) { /* DMA appears to operate on memory 'lines' of 32 bytes */ /* so don't return any part line - it isn't in RAM yet */ ptr = ptr & ~0x1f; + } + DEB(printf("return ptr=%d\n", ptr)); return ptr; - } - return 0; } -static pcmchan_caps * +static struct pcmchan_caps * viachan_getcaps(kobj_t obj, void *data) { struct via_chinfo *ch = data; - return (ch->dir == PCMDIR_PLAY) ? &via_playcaps : &via_reccaps; + struct via_info *via = ch->parent; + + return (via->codec_caps & AC97_EXTCAP_VRA)? &via_vracaps : &via_caps; } static kobj_method_t viachan_methods[] = { KOBJMETHOD(channel_init, viachan_init), - KOBJMETHOD(channel_setdir, viachan_setdir), KOBJMETHOD(channel_setformat, viachan_setformat), KOBJMETHOD(channel_setspeed, viachan_setspeed), KOBJMETHOD(channel_setblocksize, viachan_setblocksize), @@ -511,7 +437,8 @@ via_probe(device_t dev) } -void dma_cb(void *p, bus_dma_segment_t *bds, int a, int b) +static void +dma_cb(void *p, bus_dma_segment_t *bds, int a, int b) { } @@ -520,14 +447,9 @@ static int via_attach(device_t dev) { struct via_info *via = 0; - struct ac97_info *codec = 0; char status[SND_STATUSLEN]; - u_int32_t data; - u_int16_t v; - bus_dmamap_t sgd_dma_map; - if ((via = malloc(sizeof *via, M_DEVBUF, M_NOWAIT)) == NULL) { device_printf(dev, "cannot allocate softc\n"); return ENXIO; @@ -541,12 +463,10 @@ via_attach(device_t dev) data = pci_read_config(dev, PCIR_COMMAND, 2); pci_write_config(dev, VIA_PCICONF_MISC, - VIA_PCICONF_ACLINKENAB | VIA_PCICONF_ACSGD | - VIA_PCICONF_ACNOTRST | VIA_PCICONF_ACVSR, 1); + VIA_PCICONF_ACLINKENAB | VIA_PCICONF_ACSGD | VIA_PCICONF_ACNOTRST | VIA_PCICONF_ACVSR, 1); via->regid = PCIR_MAPS; - via->reg = bus_alloc_resource(dev, SYS_RES_IOPORT, &via->regid, - 0, ~0, 1, RF_ACTIVE); + via->reg = bus_alloc_resource(dev, SYS_RES_IOPORT, &via->regid, 0, ~0, 1, RF_ACTIVE); if (!via->reg) { device_printf(dev, "cannot allocate bus resource."); goto bad; @@ -555,44 +475,24 @@ via_attach(device_t dev) via->sh = rman_get_bushandle(via->reg); via->irqid = 0; - via->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &via->irqid, - 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE); - if (!via->irq - || bus_setup_intr(dev, via->irq, INTR_TYPE_TTY, via_intr, via, &via->ih)){ + via->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &via->irqid, 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE); + if (!via->irq || snd_setup_intr(dev, via->irq, 0, via_intr, via, &via->ih)) { device_printf(dev, "unable to map interrupt\n"); goto bad; } - via_wr(via, VIA_PLAY_MODE, - VIA_RPMODE_AUTOSTART | - VIA_RPMODE_INTR_FLAG | VIA_RPMODE_INTR_EOL, 1); - via_wr(via, VIA_RECORD_MODE, - VIA_RPMODE_AUTOSTART | - VIA_RPMODE_INTR_FLAG | VIA_RPMODE_INTR_EOL, 1); + via_wr(via, VIA_PLAY_MODE, VIA_RPMODE_AUTOSTART | VIA_RPMODE_INTR_FLAG | VIA_RPMODE_INTR_EOL, 1); + via_wr(via, VIA_RECORD_MODE, VIA_RPMODE_AUTOSTART | VIA_RPMODE_INTR_FLAG | VIA_RPMODE_INTR_EOL, 1); - codec = AC97_CREATE(dev, via, via_ac97); - if (!codec) goto bad; + via->codec = AC97_CREATE(dev, via, via_ac97); + if (!via->codec) + goto bad; - mixer_init(dev, ac97_getmixerclass(), codec); + mixer_init(dev, ac97_getmixerclass(), via->codec); - /* - * The mixer init resets the codec. So enabling VRA must be done - * afterwards. - */ - v = via_read_codec(NULL, via, AC97_REG_EXT_AUDIO_ID); - v &= (AC97_ENAB_VRA | AC97_ENAB_MICVRA); - via_write_codec(NULL, via, AC97_REG_EXT_AUDIO_STAT, v); - via->codec_caps = v; - { - v = via_read_codec(NULL, via, AC97_REG_EXT_AUDIO_STAT); - DEB(printf("init: codec stat: %d\n", v)); - } - - if (!(v & AC97_CODEC_DOES_VRA)) { - /* no VRA => can do only 48 kbps */ - via_playcaps.minspeed = 48000; - via_reccaps.minspeed = 48000; - } + via->codec_caps = ac97_getextcaps(via->codec); + if (via->codec_caps & AC97_EXTCAP_VRA) + ac97_setextmode(via->codec, AC97_EXTCAP_VRA | AC97_EXTCAP_VRM); /* DMA tag for buffers */ if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0, @@ -621,13 +521,12 @@ via_attach(device_t dev) goto bad; } - if (bus_dmamem_alloc(via->sgd_dmat, (void **)&via->sgd_table, - BUS_DMA_NOWAIT, &sgd_dma_map) == -1) goto bad; - if (bus_dmamap_load(via->sgd_dmat, sgd_dma_map, via->sgd_table, - NSEGS * sizeof(struct via_dma_op), dma_cb, 0, 0)) goto bad; + if (bus_dmamem_alloc(via->sgd_dmat, (void **)&via->sgd_table, BUS_DMA_NOWAIT, &via->sgd_dmamap) == -1) + goto bad; + if (bus_dmamap_load(via->sgd_dmat, via->sgd_dmamap, via->sgd_table, NSEGS * sizeof(struct via_dma_op), dma_cb, 0, 0)) + goto bad; - snprintf(status, SND_STATUSLEN, "at io 0x%lx irq %ld", - rman_get_start(via->reg), rman_get_start(via->irq)); + snprintf(status, SND_STATUSLEN, "at io 0x%lx irq %ld", rman_get_start(via->reg), rman_get_start(via->irq)); /* Register */ if (pcm_register(dev, via, 1, 1)) goto bad; @@ -636,11 +535,12 @@ via_attach(device_t dev) pcm_setstatus(dev, status); return 0; bad: - if (codec) ac97_destroy(codec); + if (via->codec) ac97_destroy(via->codec); if (via->reg) bus_release_resource(dev, SYS_RES_IOPORT, via->regid, via->reg); if (via->ih) bus_teardown_intr(dev, via->irq, via->ih); if (via->irq) bus_release_resource(dev, SYS_RES_IRQ, via->irqid, via->irq); if (via->parent_dmat) bus_dma_tag_destroy(via->parent_dmat); + if (via->sgd_dmamap) bus_dmamap_unload(via->sgd_dmat, via->sgd_dmamap); if (via->sgd_dmat) bus_dma_tag_destroy(via->sgd_dmat); if (via) free(via, M_DEVBUF); return ENXIO; @@ -661,6 +561,7 @@ via_detach(device_t dev) bus_teardown_intr(dev, via->irq, via->ih); bus_release_resource(dev, SYS_RES_IRQ, via->irqid, via->irq); bus_dma_tag_destroy(via->parent_dmat); + bus_dmamap_unload(via->sgd_dmat, via->sgd_dmamap); bus_dma_tag_destroy(via->sgd_dmat); free(via, M_DEVBUF); return 0; @@ -677,7 +578,7 @@ static device_method_t via_methods[] = { static driver_t via_driver = { "pcm", via_methods, - sizeof(snddev_info), + sizeof(struct snddev_info), }; static devclass_t pcm_devclass; diff --git a/sys/dev/sound/pci/vibes.c b/sys/dev/sound/pci/vibes.c index 28ce36f..228b281 100644 --- a/sys/dev/sound/pci/vibes.c +++ b/sys/dev/sound/pci/vibes.c @@ -56,8 +56,8 @@ struct sc_info; struct sc_chinfo { struct sc_info *parent; - pcm_channel *channel; - snd_dbuf *buffer; + struct pcm_channel *channel; + struct snd_dbuf *buffer; u_int32_t fmt, spd; int dir; int dma_active, dma_was_active; @@ -100,7 +100,7 @@ static u_int32_t sc_fmt[] = { 0 }; -static pcmchan_caps sc_caps = {8000, 48000, sc_fmt, 0}; +static struct pcmchan_caps sc_caps = {8000, 48000, sc_fmt, 0}; /* ------------------------------------------------------------------------- */ /* Register Manipulations */ @@ -178,7 +178,7 @@ sv_dma_get_count(bus_space_tag_t st, bus_space_handle_t sh) /* Play / Record Common Interface */ static void * -svchan_init(kobj_t obj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir) +svchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir) { struct sc_info *sc = devinfo; struct sc_chinfo *ch; @@ -200,7 +200,7 @@ svchan_init(kobj_t obj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir) return ch; } -static pcmchan_caps * +static struct pcmchan_caps * svchan_getcaps(kobj_t obj, void *data) { return &sc_caps; @@ -505,7 +505,7 @@ sv_mix_mute_all(struct sc_info *sc) } static int -sv_mix_init(snd_mixer *m) +sv_mix_init(struct snd_mixer *m) { u_int32_t i, v; @@ -523,14 +523,14 @@ sv_mix_init(snd_mixer *m) } static int -sv_mix_set(snd_mixer *m, u_int32_t dev, u_int32_t left, u_int32_t right) +sv_mix_set(struct snd_mixer *m, u_int32_t dev, u_int32_t left, u_int32_t right) { struct sc_info *sc = mix_getdevinfo(m); return sv_gain(sc, dev, left, right); } static int -sv_mix_setrecsrc(snd_mixer *m, u_int32_t mask) +sv_mix_setrecsrc(struct snd_mixer *m, u_int32_t mask) { struct sc_info *sc = mix_getdevinfo(m); u_int32_t i, v; @@ -706,7 +706,7 @@ sv_probe(device_t dev) static int sv_attach(device_t dev) { - snddev_info *d; + struct snddev_info *d; struct sc_info *sc; u_int32_t data; char status[SND_STATUSLEN]; @@ -920,7 +920,7 @@ static device_method_t sc_methods[] = { static driver_t sonicvibes_driver = { "pcm", sc_methods, - sizeof(snddev_info) + sizeof(struct snddev_info) }; static devclass_t pcm_devclass; |