From 374e1c5baac6ef3f79b3ed525a821852f152a8d7 Mon Sep 17 00:00:00 2001 From: Cameron Grant Date: Sat, 29 Sep 2001 07:57:07 +0000 Subject: [PATCH] allow the hardware buffer size to be controlled with hints release isa dma channels on unload (ad1816, ess, sb8) --- sys/dev/sound/isa/ad1816.c | 82 +++++++++++++++++++------------------- sys/dev/sound/isa/ess.c | 26 +++++++----- sys/dev/sound/isa/mss.c | 14 ++++--- sys/dev/sound/isa/sb16.c | 77 +++++++++++++++++++++-------------- sys/dev/sound/isa/sb8.c | 18 ++++----- 5 files changed, 122 insertions(+), 95 deletions(-) diff --git a/sys/dev/sound/isa/ad1816.c b/sys/dev/sound/isa/ad1816.c index c15992d9ed18..18bbf8760abd 100644 --- a/sys/dev/sound/isa/ad1816.c +++ b/sys/dev/sound/isa/ad1816.c @@ -43,30 +43,22 @@ struct ad1816_chinfo { }; struct ad1816_info { - struct resource *io_base; /* primary I/O address for the board */ - int io_rid; - struct resource *irq; - int irq_rid; - struct resource *drq1; /* play */ - int drq1_rid; - struct resource *drq2; /* rec */ - int drq2_rid; - void *ih; - bus_dma_tag_t parent_dmat; - void *lock; + struct resource *io_base; /* primary I/O address for the board */ + int io_rid; + struct resource *irq; + int irq_rid; + struct resource *drq1; /* play */ + int drq1_rid; + struct resource *drq2; /* rec */ + int drq2_rid; + void *ih; + bus_dma_tag_t parent_dmat; + void *lock; - struct ad1816_chinfo pch, rch; + unsigned int bufsize; + struct ad1816_chinfo pch, rch; }; -static driver_intr_t ad1816_intr; -static int ad1816_probe(device_t dev); -static int ad1816_attach(device_t dev); - -/* IO primitives */ -static int ad1816_wait_init(struct ad1816_info *ad1816, int x); -static u_short ad1816_read(struct ad1816_info *ad1816, u_int reg); -static void ad1816_write(struct ad1816_info *ad1816, u_int reg, u_short data); - static u_int32_t ad1816_fmt[] = { AFMT_U8, AFMT_STEREO | AFMT_U8, @@ -320,7 +312,7 @@ ad1816chan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channe ch->parent = ad1816; ch->channel = c; ch->buffer = b; - if (sndbuf_alloc(ch->buffer, ad1816->parent_dmat, DSP_BUFFSIZE) == -1) return NULL; + if (sndbuf_alloc(ch->buffer, ad1816->parent_dmat, ad1816->bufsize) == -1) return NULL; return ch; } @@ -487,30 +479,30 @@ ad1816_release_resources(struct ad1816_info *ad1816, device_t dev) if (ad1816->irq) { if (ad1816->ih) bus_teardown_intr(dev, ad1816->irq, ad1816->ih); - bus_release_resource(dev, SYS_RES_IRQ, ad1816->irq_rid, - ad1816->irq); + bus_release_resource(dev, SYS_RES_IRQ, ad1816->irq_rid, ad1816->irq); ad1816->irq = 0; } if (ad1816->drq1) { - bus_release_resource(dev, SYS_RES_DRQ, ad1816->drq1_rid, - ad1816->drq1); + isa_dma_release(rman_get_start(ad1816->drq1)); + bus_release_resource(dev, SYS_RES_DRQ, ad1816->drq1_rid, ad1816->drq1); ad1816->drq1 = 0; } if (ad1816->drq2) { - bus_release_resource(dev, SYS_RES_DRQ, ad1816->drq2_rid, - ad1816->drq2); + isa_dma_release(rman_get_start(ad1816->drq2)); + bus_release_resource(dev, SYS_RES_DRQ, ad1816->drq2_rid, ad1816->drq2); ad1816->drq2 = 0; } if (ad1816->io_base) { - bus_release_resource(dev, SYS_RES_IOPORT, ad1816->io_rid, - ad1816->io_base); + bus_release_resource(dev, SYS_RES_IOPORT, ad1816->io_rid, ad1816->io_base); ad1816->io_base = 0; } if (ad1816->parent_dmat) { bus_dma_tag_destroy(ad1816->parent_dmat); ad1816->parent_dmat = 0; } - if (ad1816->lock) snd_mtxfree(ad1816->lock); + if (ad1816->lock) + snd_mtxfree(ad1816->lock); + free(ad1816, M_DEVBUF); } @@ -518,6 +510,7 @@ static int ad1816_alloc_resources(struct ad1816_info *ad1816, device_t dev) { int ok = 1, pdma, rdma; + if (!ad1816->io_base) ad1816->io_base = bus_alloc_resource(dev, SYS_RES_IOPORT, &ad1816->io_rid, 0, ~0, 1, RF_ACTIVE); @@ -536,15 +529,17 @@ ad1816_alloc_resources(struct ad1816_info *ad1816, device_t dev) if (ok) { pdma = rman_get_start(ad1816->drq1); isa_dma_acquire(pdma); - isa_dmainit(pdma, DSP_BUFFSIZE); + isa_dmainit(pdma, ad1816->bufsize); if (ad1816->drq2) { rdma = rman_get_start(ad1816->drq2); isa_dma_acquire(rdma); - isa_dmainit(rdma, DSP_BUFFSIZE); - } else rdma = pdma; + isa_dmainit(rdma, ad1816->bufsize); + } else + rdma = pdma; if (pdma == rdma) pcm_setflags(dev, pcm_getflags(dev) | SD_F_SIMPLEX); } + return ok; } @@ -587,7 +582,7 @@ static int ad1816_attach(device_t dev) { struct ad1816_info *ad1816; - char status[SND_STATUSLEN]; + char status[SND_STATUSLEN], status2[SND_STATUSLEN]; ad1816 = (struct ad1816_info *)malloc(sizeof *ad1816, M_DEVBUF, M_NOWAIT | M_ZERO); if (!ad1816) return ENXIO; @@ -597,6 +592,7 @@ ad1816_attach(device_t dev) ad1816->irq_rid = 0; ad1816->drq1_rid = 0; ad1816->drq2_rid = 1; + ad1816->bufsize = pcm_getbuffersize(dev, 4096, DSP_BUFFSIZE, 65536); if (!ad1816_alloc_resources(ad1816, dev)) goto no; ad1816_init(ad1816, dev); @@ -607,19 +603,23 @@ ad1816_attach(device_t dev) /*lowaddr*/BUS_SPACE_MAXADDR_24BIT, /*highaddr*/BUS_SPACE_MAXADDR, /*filter*/NULL, /*filterarg*/NULL, - /*maxsize*/DSP_BUFFSIZE, /*nsegments*/1, + /*maxsize*/ad1816->bufsize, /*nsegments*/1, /*maxsegz*/0x3ffff, /*flags*/0, &ad1816->parent_dmat) != 0) { device_printf(dev, "unable to create dma tag\n"); goto no; } - snprintf(status, SND_STATUSLEN, "at io 0x%lx irq %ld drq %ld", + if (ad1816->drq2) + snprintf(status2, SND_STATUSLEN, ":%ld", rman_get_start(ad1816->drq2)); + else + status2[0] = '\0'; + + snprintf(status, SND_STATUSLEN, "at io 0x%lx irq %ld drq %ld%s bufsz %u", rman_get_start(ad1816->io_base), rman_get_start(ad1816->irq), - rman_get_start(ad1816->drq1)); - if (ad1816->drq2) snprintf(status + strlen(status), - SND_STATUSLEN - strlen(status), ":%ld", - rman_get_start(ad1816->drq2)); + rman_get_start(ad1816->drq1), + status2, + ad1816->bufsize); if (pcm_register(dev, ad1816, 1, 1)) goto no; pcm_addchan(dev, PCMDIR_REC, &ad1816chan_class, ad1816); diff --git a/sys/dev/sound/isa/ess.c b/sys/dev/sound/isa/ess.c index 6f8919756096..624f81caf200 100644 --- a/sys/dev/sound/isa/ess.c +++ b/sys/dev/sound/isa/ess.c @@ -94,11 +94,13 @@ struct ess_info { void *ih; bus_dma_tag_t parent_dmat; + unsigned int bufsize; int type, duplex:1, newspeed:1; u_long bd_flags; /* board-specific flags */ struct ess_chinfo pch, rch; }; +#if 0 static int ess_rd(struct ess_info *sc, int reg); static void ess_wr(struct ess_info *sc, int reg, u_int8_t val); static int ess_dspready(struct ess_info *sc); @@ -116,6 +118,7 @@ static void ess_intr(void *arg); static int ess_setupch(struct ess_info *sc, int ch, int dir, int spd, u_int32_t fmt, int len); static int ess_start(struct ess_chinfo *ch); static int ess_stop(struct ess_chinfo *ch); +#endif /* * Common code for the midi and pcm functions @@ -284,10 +287,12 @@ ess_release_resources(struct ess_info *sc, device_t dev) sc->irq = 0; } if (sc->drq1) { + isa_dma_release(rman_get_start(sc->drq1)); bus_release_resource(dev, SYS_RES_DRQ, 0, sc->drq1); sc->drq1 = 0; } if (sc->drq2) { + isa_dma_release(rman_get_start(sc->drq2)); bus_release_resource(dev, SYS_RES_DRQ, 1, sc->drq2); sc->drq2 = 0; } @@ -330,11 +335,11 @@ ess_alloc_resources(struct ess_info *sc, device_t dev) if (sc->io_base && sc->drq1 && sc->irq) { isa_dma_acquire(rman_get_start(sc->drq1)); - isa_dmainit(rman_get_start(sc->drq1), ESS_BUFFSIZE); + isa_dmainit(rman_get_start(sc->drq1), sc->bufsize); if (sc->drq2) { isa_dma_acquire(rman_get_start(sc->drq2)); - isa_dmainit(rman_get_start(sc->drq2), ESS_BUFFSIZE); + isa_dmainit(rman_get_start(sc->drq2), sc->bufsize); } return 0; @@ -554,7 +559,7 @@ esschan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel * ch->parent = sc; ch->channel = c; ch->buffer = b; - if (sndbuf_alloc(ch->buffer, sc->parent_dmat, ESS_BUFFSIZE) == -1) + if (sndbuf_alloc(ch->buffer, sc->parent_dmat, sc->bufsize) == -1) return NULL; ch->dir = dir; ch->hwch = 1; @@ -804,6 +809,7 @@ ess_attach(device_t dev) return ENXIO; sc->parent_dev = device_get_parent(dev); + sc->bufsize = pcm_getbuffersize(dev, 4096, ESS_BUFFSIZE, 65536); if (ess_alloc_resources(sc, dev)) goto no; if (ess_reset_dsp(sc)) @@ -845,19 +851,21 @@ ess_attach(device_t dev) /*lowaddr*/BUS_SPACE_MAXADDR_24BIT, /*highaddr*/BUS_SPACE_MAXADDR, /*filter*/NULL, /*filterarg*/NULL, - /*maxsize*/ESS_BUFFSIZE, /*nsegments*/1, + /*maxsize*/sc->bufsize, /*nsegments*/1, /*maxsegz*/0x3ffff, /*flags*/0, &sc->parent_dmat) != 0) { device_printf(dev, "unable to create dma tag\n"); goto no; } - snprintf(status, SND_STATUSLEN, "at io 0x%lx irq %ld drq %ld", - rman_get_start(sc->io_base), rman_get_start(sc->irq), - rman_get_start(sc->drq1)); if (sc->drq2) - snprintf(status + strlen(status), SND_STATUSLEN - strlen(status), - ":%ld", rman_get_start(sc->drq2)); + snprintf(buf, SND_STATUSLEN, ":%ld", rman_get_start(sc->drq2)); + else + buf[0] = '\0'; + + snprintf(status, SND_STATUSLEN, "at io 0x%lx irq %ld drq %ld%s bufsz %u", + rman_get_start(sc->io_base), rman_get_start(sc->irq), + rman_get_start(sc->drq1), buf, sc->bufsize); if (pcm_register(dev, sc, 1, 1)) goto no; diff --git a/sys/dev/sound/isa/mss.c b/sys/dev/sound/isa/mss.c index 917a0edbc4d3..5c2596a8d6bb 100644 --- a/sys/dev/sound/isa/mss.c +++ b/sys/dev/sound/isa/mss.c @@ -1658,7 +1658,7 @@ static int mss_doattach(device_t dev, struct mss_info *mss) { int pdma, rdma, flags = device_get_flags(dev); - char status[SND_STATUSLEN]; + char status[SND_STATUSLEN], status2[SND_STATUSLEN]; mss->lock = snd_mtxcreate(device_get_nameunit(dev)); mss->bufsize = pcm_getbuffersize(dev, 4096, MSS_DEFAULT_BUFSZ, 65536); @@ -1718,10 +1718,14 @@ mss_doattach(device_t dev, struct mss_info *mss) device_printf(dev, "unable to create dma tag\n"); goto no; } - snprintf(status, SND_STATUSLEN, "at io 0x%lx irq %ld drq %d", - rman_get_start(mss->io_base), rman_get_start(mss->irq), pdma); - if (pdma != rdma) snprintf(status + strlen(status), - SND_STATUSLEN - strlen(status), ":%d", rdma); + + if (pdma != rdma) + snprintf(status2, SND_STATUSLEN, ":%d", rdma); + else + status2[0] = '\0'; + + snprintf(status, SND_STATUSLEN, "at io 0x%lx irq %ld drq %d%s bufsz %u", + rman_get_start(mss->io_base), rman_get_start(mss->irq), pdma, status2, mss->bufsize); if (pcm_register(dev, mss, 1, 1)) goto no; pcm_addchan(dev, PCMDIR_REC, &msschan_class, mss); diff --git a/sys/dev/sound/isa/sb16.c b/sys/dev/sound/isa/sb16.c index 53c4242c210e..7aef4e3d9218 100644 --- a/sys/dev/sound/isa/sb16.c +++ b/sys/dev/sound/isa/sb16.c @@ -82,6 +82,7 @@ struct sb_info { void *ih; bus_dma_tag_t parent_dmat; + unsigned int bufsize; int bd_id; u_long bd_flags; /* board-specific flags */ int prio, prio16; @@ -89,6 +90,7 @@ struct sb_info { device_t parent_dev; }; +#if 0 static void sb_lock(struct sb_info *sb); static void sb_unlock(struct sb_info *sb); static int sb_rd(struct sb_info *sb, int reg); @@ -102,6 +104,7 @@ static int sb_getmixer(struct sb_info *sb, u_int port); static int sb_reset_dsp(struct sb_info *sb); static void sb_intr(void *arg); +#endif /* * Common code for the midi and pcm functions @@ -112,6 +115,18 @@ static void sb_intr(void *arg); * sb_get_byte returns a single byte from the DSP data port */ +static void +sb_lock(struct sb_info *sb) { + + sbc_lock(device_get_softc(sb->parent_dev)); +} + +static void +sb_unlock(struct sb_info *sb) { + + sbc_unlock(device_get_softc(sb->parent_dev)); +} + static int port_rd(struct resource *port, int off) { @@ -181,13 +196,23 @@ sb_cmd1(struct sb_info *sb, u_char cmd, int val) static int sb_cmd2(struct sb_info *sb, u_char cmd, int val) { + int r; + #if 0 printf("sb_cmd2: %x, %x\n", cmd, val); #endif + sb_lock(sb); + r = 0; if (sb_dspwr(sb, cmd)) { - return sb_dspwr(sb, val & 0xff) && - sb_dspwr(sb, (val >> 8) & 0xff); - } else return 0; + if (sb_dspwr(sb, val & 0xff)) { + if (sb_dspwr(sb, (val >> 8) & 0xff)) { + r = 1; + } + } + } + sb_unlock(sb); + + return r; } /* @@ -376,9 +401,11 @@ sb16_release_resources(struct sb_info *sb, device_t dev) bus_release_resource(dev, SYS_RES_IRQ, 0, sb->irq); sb->irq = 0; } - if (sb->drq2 && (sb->drq2 != sb->drq1)) { - isa_dma_release(rman_get_start(sb->drq2)); - bus_release_resource(dev, SYS_RES_DRQ, 1, sb->drq2); + if (sb->drq2) { + if (sb->drq2 != sb->drq1) { + isa_dma_release(rman_get_start(sb->drq2)); + bus_release_resource(dev, SYS_RES_DRQ, 1, sb->drq2); + } sb->drq2 = 0; } if (sb->drq1) { @@ -419,14 +446,12 @@ sb16_alloc_resources(struct sb_info *sb, device_t dev) sb->drq2 = bus_alloc_resource(dev, SYS_RES_DRQ, &rid, 0, ~0, 1, RF_ACTIVE); if (sb->io_base && sb->drq1 && sb->irq) { - int bs = SB16_BUFFSIZE; - isa_dma_acquire(rman_get_start(sb->drq1)); - isa_dmainit(rman_get_start(sb->drq1), bs); + isa_dmainit(rman_get_start(sb->drq1), sb->bufsize); if (sb->drq2) { isa_dma_acquire(rman_get_start(sb->drq2)); - isa_dmainit(rman_get_start(sb->drq2), bs); + isa_dmainit(rman_get_start(sb->drq2), sb->bufsize); } else { sb->drq2 = sb->drq1; pcm_setflags(dev, pcm_getflags(dev) | SD_F_SIMPLEX); @@ -617,7 +642,7 @@ sb16chan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel ch->buffer = b; ch->dir = dir; - if (sndbuf_alloc(ch->buffer, sb->parent_dmat, SB16_BUFFSIZE) == -1) + if (sndbuf_alloc(ch->buffer, sb->parent_dmat, sb->bufsize) == -1) return NULL; return ch; @@ -747,8 +772,7 @@ sb16_attach(device_t dev) { struct sb_info *sb; uintptr_t ver; - char status[SND_STATUSLEN]; - int bs = SB16_BUFFSIZE; + char status[SND_STATUSLEN], status2[SND_STATUSLEN]; sb = (struct sb_info *)malloc(sizeof *sb, M_DEVBUF, M_NOWAIT | M_ZERO); if (!sb) @@ -758,6 +782,7 @@ sb16_attach(device_t dev) BUS_READ_IVAR(sb->parent_dev, dev, 1, &ver); sb->bd_id = ver & 0x0000ffff; sb->bd_flags = (ver & 0xffff0000) >> 16; + sb->bufsize = pcm_getbuffersize(dev, 4096, SB16_BUFFSIZE, 65536); if (sb16_alloc_resources(sb, dev)) goto no; @@ -777,19 +802,21 @@ sb16_attach(device_t dev) /*lowaddr*/BUS_SPACE_MAXADDR_24BIT, /*highaddr*/BUS_SPACE_MAXADDR, /*filter*/NULL, /*filterarg*/NULL, - /*maxsize*/bs, /*nsegments*/1, + /*maxsize*/sb->bufsize, /*nsegments*/1, /*maxsegz*/0x3ffff, /*flags*/0, &sb->parent_dmat) != 0) { device_printf(dev, "unable to create dma tag\n"); goto no; } - snprintf(status, SND_STATUSLEN, "at io 0x%lx irq %ld drq %ld", - rman_get_start(sb->io_base), rman_get_start(sb->irq), - rman_get_start(sb->drq1)); if (!(pcm_getflags(dev) & SD_F_SIMPLEX)) - snprintf(status + strlen(status), SND_STATUSLEN - strlen(status), - ":%ld", rman_get_start(sb->drq2)); + snprintf(status2, SND_STATUSLEN, ":%ld", rman_get_start(sb->drq2)); + else + status2[0] = '\0'; + + snprintf(status, SND_STATUSLEN, "at io 0x%lx irq %ld drq %ld%s bufsz %ud", + rman_get_start(sb->io_base), rman_get_start(sb->irq), + rman_get_start(sb->drq1), status2, sb->bufsize); if (pcm_register(dev, sb, 1, 1)) goto no; @@ -820,18 +847,6 @@ sb16_detach(device_t dev) return 0; } -static void -sb_lock(struct sb_info *sb) { - - sbc_lock(device_get_softc(sb->parent_dev)); -} - -static void -sb_unlock(struct sb_info *sb) { - - sbc_unlock(device_get_softc(sb->parent_dev)); -} - static device_method_t sb16_methods[] = { /* Device interface */ DEVMETHOD(device_probe, sb16_probe), diff --git a/sys/dev/sound/isa/sb8.c b/sys/dev/sound/isa/sb8.c index b02e5e4f18bc..41c64cead324 100644 --- a/sys/dev/sound/isa/sb8.c +++ b/sys/dev/sound/isa/sb8.c @@ -38,7 +38,7 @@ SND_DECLARE_FILE("$FreeBSD$"); -#define SB_BUFFSIZE 4096 +#define SB_DEFAULT_BUFSZ 4096 static u_int32_t sb_fmt[] = { AFMT_U8, @@ -75,6 +75,7 @@ struct sb_info { void *ih; bus_dma_tag_t parent_dmat; + unsigned int bufsize; int bd_id; u_long bd_flags; /* board-specific flags */ struct sb_chinfo pch, rch; @@ -261,6 +262,7 @@ sb_release_resources(struct sb_info *sb, device_t dev) sb->irq = 0; } if (sb->drq) { + isa_dma_release(rman_get_start(sb->drq)); bus_release_resource(dev, SYS_RES_DRQ, 0, sb->drq); sb->drq = 0; } @@ -291,10 +293,8 @@ sb_alloc_resources(struct sb_info *sb, device_t dev) sb->drq = bus_alloc_resource(dev, SYS_RES_DRQ, &rid, 0, ~0, 1, RF_ACTIVE); if (sb->io_base && sb->drq && sb->irq) { - int bs = SB_BUFFSIZE; - isa_dma_acquire(rman_get_start(sb->drq)); - isa_dmainit(rman_get_start(sb->drq), bs); + isa_dmainit(rman_get_start(sb->drq), sb->bufsize); return 0; } else return ENXIO; @@ -580,7 +580,7 @@ sbchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c ch->channel = c; ch->dir = dir; ch->buffer = b; - if (sndbuf_alloc(ch->buffer, sb->parent_dmat, SB_BUFFSIZE) == -1) + if (sndbuf_alloc(ch->buffer, sb->parent_dmat, sb->bufsize) == -1) return NULL; sndbuf_isadmasetup(ch->buffer, sb->drq); return ch; @@ -693,7 +693,6 @@ sb_attach(device_t dev) { struct sb_info *sb; char status[SND_STATUSLEN]; - int bs = SB_BUFFSIZE; uintptr_t ver; sb = (struct sb_info *)malloc(sizeof *sb, M_DEVBUF, M_NOWAIT | M_ZERO); @@ -704,6 +703,7 @@ sb_attach(device_t dev) BUS_READ_IVAR(device_get_parent(dev), dev, 1, &ver); sb->bd_id = ver & 0x0000ffff; sb->bd_flags = (ver & 0xffff0000) >> 16; + sb->bufsize = pcm_getbuffersize(dev, 4096, SB_DEFAULT_BUFSZ, 65536); if (sb_alloc_resources(sb, dev)) goto no; @@ -720,15 +720,15 @@ sb_attach(device_t dev) /*lowaddr*/BUS_SPACE_MAXADDR_24BIT, /*highaddr*/BUS_SPACE_MAXADDR, /*filter*/NULL, /*filterarg*/NULL, - /*maxsize*/bs, /*nsegments*/1, + /*maxsize*/sb->bufsize, /*nsegments*/1, /*maxsegz*/0x3ffff, /*flags*/0, &sb->parent_dmat) != 0) { device_printf(dev, "unable to create dma tag\n"); goto no; } - snprintf(status, SND_STATUSLEN, "at io 0x%lx irq %ld drq %ld", - rman_get_start(sb->io_base), rman_get_start(sb->irq), rman_get_start(sb->drq)); + snprintf(status, SND_STATUSLEN, "at io 0x%lx irq %ld drq %ld bufsz %u", + rman_get_start(sb->io_base), rman_get_start(sb->irq), rman_get_start(sb->drq), sb->bufsize); if (pcm_register(dev, sb, 1, 1)) goto no;