allow the hardware buffer size to be controlled with hints

release isa dma channels on unload (ad1816, ess, sb8)
This commit is contained in:
Cameron Grant 2001-09-29 07:57:07 +00:00
parent b53adbbf93
commit 374e1c5baa
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=84111
5 changed files with 122 additions and 95 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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),

View File

@ -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;