summaryrefslogtreecommitdiffstats
path: root/sys/dev/sound/pci
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/sound/pci')
-rw-r--r--sys/dev/sound/pci/csapcm.c38
-rw-r--r--sys/dev/sound/pci/ds1.c32
-rw-r--r--sys/dev/sound/pci/emu10k1.c5
-rw-r--r--sys/dev/sound/pci/es137x.c77
-rw-r--r--sys/dev/sound/pci/fm801.c75
-rw-r--r--sys/dev/sound/pci/maestro.c4
-rw-r--r--sys/dev/sound/pci/neomagic.c31
-rw-r--r--sys/dev/sound/pci/solo.c39
-rw-r--r--sys/dev/sound/pci/t4dwave.c23
-rw-r--r--sys/dev/sound/pci/via82c686.c65
10 files changed, 246 insertions, 143 deletions
diff --git a/sys/dev/sound/pci/csapcm.c b/sys/dev/sound/pci/csapcm.c
index 2c9e5ca..1a5f807 100644
--- a/sys/dev/sound/pci/csapcm.c
+++ b/sys/dev/sound/pci/csapcm.c
@@ -751,6 +751,8 @@ csa_releaseres(struct csa_info *csa, device_t dev)
resp = &csa->res;
if (resp->irq != NULL) {
+ if (csa->ih)
+ bus_teardown_intr(dev, resp->irq, csa->ih);
bus_release_resource(dev, SYS_RES_IRQ, resp->irq_rid, resp->irq);
resp->irq = NULL;
}
@@ -762,6 +764,14 @@ csa_releaseres(struct csa_info *csa, device_t dev)
bus_release_resource(dev, SYS_RES_MEMORY, resp->mem_rid, resp->mem);
resp->mem = NULL;
}
+ if (csa->parent_dmat != NULL) {
+ bus_dma_tag_destroy(csa->parent_dmat);
+ csa->parent_dmat = NULL;
+ }
+ if (csa != NULL) {
+ free(csa, M_DEVBUF);
+ csa = NULL;
+ }
}
static int pcmcsa_probe(device_t dev);
@@ -824,15 +834,21 @@ pcmcsa_attach(device_t dev)
return (ENXIO);
}
codec = ac97_create(dev, csa, NULL, csa_rdcd, csa_wrcd);
- if (codec == NULL)
+ if (codec == NULL) {
+ csa_releaseres(csa, dev);
return (ENXIO);
- if (mixer_init(dev, &ac97_mixer, codec) == -1)
+ }
+ if (mixer_init(dev, &ac97_mixer, codec) == -1) {
+ ac97_destroy(codec);
+ csa_releaseres(csa, dev);
return (ENXIO);
+ }
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)) {
+ ac97_destroy(codec);
csa_releaseres(csa, dev);
return (ENXIO);
}
@@ -840,6 +856,7 @@ pcmcsa_attach(device_t dev)
csa_writemem(resp, BA1_CIE, (csa_readmem(resp, BA1_CIE) & ~0x0000003f) | 0x00000001);
if (pcm_register(dev, csa, 1, 1)) {
+ ac97_destroy(codec);
csa_releaseres(csa, dev);
return (ENXIO);
}
@@ -850,6 +867,22 @@ pcmcsa_attach(device_t dev)
return (0);
}
+static int
+pcmcsa_detach(device_t dev)
+{
+ int r;
+ struct csa_info *csa;
+
+ r = pcm_unregister(dev);
+ if (r)
+ return r;
+
+ csa = pcm_getdevinfo(dev);
+ csa_releaseres(csa, dev);
+
+ return 0;
+}
+
/* ac97 codec */
static u_int32_t
@@ -876,6 +909,7 @@ static device_method_t pcmcsa_methods[] = {
/* Device interface */
DEVMETHOD(device_probe , pcmcsa_probe ),
DEVMETHOD(device_attach, pcmcsa_attach),
+ DEVMETHOD(device_detach, pcmcsa_detach),
{ 0, 0 },
};
diff --git a/sys/dev/sound/pci/ds1.c b/sys/dev/sound/pci/ds1.c
index 143b5b4..3195c8b 100644
--- a/sys/dev/sound/pci/ds1.c
+++ b/sys/dev/sound/pci/ds1.c
@@ -210,7 +210,7 @@ static pcmchan_caps ds_playcaps = {4000, 96000, ds_playfmt, 0};
static pcm_channel ds_pchantemplate = {
ds1pchan_init,
- ds1pchan_setdir,
+ NULL, /* setdir */
ds1pchan_setformat,
ds1pchan_setspeed,
ds1pchan_setblocksize,
@@ -229,7 +229,7 @@ static pcm_channel ds_pchantemplate = {
static pcm_channel ds_rchantemplate = {
ds1rchan_init,
- ds1rchan_setdir,
+ NULL, /* setdir */
ds1rchan_setformat,
ds1rchan_setspeed,
ds1rchan_setblocksize,
@@ -550,12 +550,6 @@ ds1pchan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir)
}
static int
-ds1pchan_setdir(void *data, int dir)
-{
- return 0;
-}
-
-static int
ds1pchan_setformat(void *data, u_int32_t format)
{
struct sc_pchinfo *ch = data;
@@ -661,12 +655,6 @@ ds1rchan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir)
}
static int
-ds1rchan_setdir(void *data, int dir)
-{
- return 0;
-}
-
-static int
ds1rchan_setformat(void *data, u_int32_t format)
{
struct sc_rchinfo *ch = data;
@@ -938,7 +926,7 @@ ds_pci_attach(device_t dev)
u_int32_t data;
u_int32_t subdev, i;
struct sc_info *sc;
- struct ac97_info *codec;
+ struct ac97_info *codec = NULL;
char status[SND_STATUSLEN];
if ((sc = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT)) == NULL) {
@@ -1012,12 +1000,16 @@ ds_pci_attach(device_t dev)
return 0;
bad:
+ if (codec)
+ ac97_destroy(codec);
if (sc->reg)
bus_release_resource(dev, SYS_RES_MEMORY, sc->regid, sc->reg);
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);
free(sc, M_DEVBUF);
return ENXIO;
}
@@ -1052,12 +1044,10 @@ ds_pci_detach(device_t dev)
sc = pcm_getdevinfo(dev);
ds_uninit(sc);
- if (sc->reg)
- bus_release_resource(dev, SYS_RES_MEMORY, sc->regid, sc->reg);
- 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);
+ bus_release_resource(dev, SYS_RES_MEMORY, sc->regid, sc->reg);
+ 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);
free(sc, M_DEVBUF);
return 0;
}
diff --git a/sys/dev/sound/pci/emu10k1.c b/sys/dev/sound/pci/emu10k1.c
index d0f73d2..98d55c7 100644
--- a/sys/dev/sound/pci/emu10k1.c
+++ b/sys/dev/sound/pci/emu10k1.c
@@ -1410,7 +1410,7 @@ emu_pci_attach(device_t dev)
{
u_int32_t data;
struct sc_info *sc;
- struct ac97_info *codec;
+ struct ac97_info *codec = NULL;
int i, mapped;
char status[SND_STATUSLEN];
@@ -1496,9 +1496,11 @@ emu_pci_attach(device_t dev)
return 0;
bad:
+ if (codec) ac97_destroy(codec);
if (sc->reg) bus_release_resource(dev, sc->regtype, sc->regid, sc->reg);
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);
free(sc, M_DEVBUF);
return ENXIO;
}
@@ -1520,6 +1522,7 @@ emu_pci_detach(device_t dev)
bus_release_resource(dev, sc->regtype, sc->regid, sc->reg);
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);
free(sc, M_DEVBUF);
return 0;
diff --git a/sys/dev/sound/pci/es137x.c b/sys/dev/sound/pci/es137x.c
index 544ad83..3764e15 100644
--- a/sys/dev/sound/pci/es137x.c
+++ b/sys/dev/sound/pci/es137x.c
@@ -88,6 +88,10 @@ struct es_info {
bus_space_handle_t sh;
bus_dma_tag_t parent_dmat;
+ struct resource *reg, *irq;
+ int regtype, regid, irqid;
+ void *ih;
+
device_t dev;
int num;
/* Contents of board's registers */
@@ -761,15 +765,9 @@ es_pci_attach(device_t dev)
{
u_int32_t data;
struct es_info *es = 0;
- int type = 0;
- int regid;
- struct resource *reg = 0;
int mapped;
- int irqid;
- struct resource *irq = 0;
- void *ih = 0;
char status[SND_STATUSLEN];
- struct ac97_info *codec;
+ struct ac97_info *codec = 0;
pcm_channel *ct = NULL;
if ((es = malloc(sizeof *es, M_DEVBUF, M_NOWAIT)) == NULL) {
@@ -785,24 +783,24 @@ es_pci_attach(device_t dev)
pci_write_config(dev, PCIR_COMMAND, data, 2);
data = pci_read_config(dev, PCIR_COMMAND, 2);
if (mapped == 0 && (data & PCIM_CMD_MEMEN)) {
- regid = MEM_MAP_REG;
- type = SYS_RES_MEMORY;
- reg = bus_alloc_resource(dev, type, &regid,
+ es->regid = MEM_MAP_REG;
+ es->regtype = SYS_RES_MEMORY;
+ es->reg = bus_alloc_resource(dev, es->regtype, &es->regid,
0, ~0, 1, RF_ACTIVE);
- if (reg) {
- es->st = rman_get_bustag(reg);
- es->sh = rman_get_bushandle(reg);
+ if (es->reg) {
+ es->st = rman_get_bustag(es->reg);
+ es->sh = rman_get_bushandle(es->reg);
mapped++;
}
}
if (mapped == 0 && (data & PCIM_CMD_PORTEN)) {
- regid = PCIR_MAPS;
- type = SYS_RES_IOPORT;
- reg = bus_alloc_resource(dev, type, &regid,
+ es->regid = PCIR_MAPS;
+ es->regtype = SYS_RES_IOPORT;
+ es->reg = bus_alloc_resource(dev, es->regtype, &es->regid,
0, ~0, 1, RF_ACTIVE);
- if (reg) {
- es->st = rman_get_bustag(reg);
- es->sh = rman_get_bushandle(reg);
+ if (es->reg) {
+ es->st = rman_get_bustag(es->reg);
+ es->sh = rman_get_bushandle(es->reg);
mapped++;
}
}
@@ -834,11 +832,11 @@ es_pci_attach(device_t dev)
ct = &es1370_chantemplate;
} else goto bad;
- irqid = 0;
- irq = bus_alloc_resource(dev, SYS_RES_IRQ, &irqid,
+ es->irqid = 0;
+ es->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &es->irqid,
0, ~0, 1, RF_ACTIVE | RF_SHAREABLE);
- if (!irq
- || bus_setup_intr(dev, irq, INTR_TYPE_TTY, es_intr, es, &ih)) {
+ if (!es->irq
+ || bus_setup_intr(dev, es->irq, INTR_TYPE_TTY, es_intr, es, &es->ih)) {
device_printf(dev, "unable to map interrupt\n");
goto bad;
}
@@ -854,8 +852,8 @@ es_pci_attach(device_t dev)
}
snprintf(status, SND_STATUSLEN, "at %s 0x%lx irq %ld",
- (type == SYS_RES_IOPORT)? "io" : "memory",
- rman_get_start(reg), rman_get_start(irq));
+ (es->regtype == SYS_RES_IOPORT)? "io" : "memory",
+ rman_get_start(es->reg), rman_get_start(es->irq));
if (pcm_register(dev, es, 1, 1)) goto bad;
pcm_addchan(dev, PCMDIR_REC, ct, es);
@@ -865,17 +863,40 @@ es_pci_attach(device_t dev)
return 0;
bad:
+ if (codec) ac97_destroy(codec);
+ if (es->reg) bus_release_resource(dev, es->regtype, es->regid, es->reg);
+ if (es->ih) bus_teardown_intr(dev, es->irq, es->ih);
+ if (es->irq) bus_release_resource(dev, SYS_RES_IRQ, es->irqid, es->irq);
+ if (es->parent_dmat) bus_dma_tag_destroy(es->parent_dmat);
if (es) free(es, M_DEVBUF);
- if (reg) bus_release_resource(dev, type, regid, reg);
- if (ih) bus_teardown_intr(dev, irq, ih);
- if (irq) bus_release_resource(dev, SYS_RES_IRQ, irqid, irq);
return ENXIO;
}
+static int
+es_pci_detach(device_t dev)
+{
+ int r;
+ struct es_info *es;
+
+ r = pcm_unregister(dev);
+ if (r)
+ return r;
+
+ es = pcm_getdevinfo(dev);
+ bus_release_resource(dev, es->regtype, es->regid, es->reg);
+ bus_teardown_intr(dev, es->irq, es->ih);
+ bus_release_resource(dev, SYS_RES_IRQ, es->irqid, es->irq);
+ bus_dma_tag_destroy(es->parent_dmat);
+ free(es, M_DEVBUF);
+
+ return 0;
+}
+
static device_method_t es_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, es_pci_probe),
DEVMETHOD(device_attach, es_pci_attach),
+ DEVMETHOD(device_detach, es_pci_detach),
{ 0, 0 }
};
diff --git a/sys/dev/sound/pci/fm801.c b/sys/dev/sound/pci/fm801.c
index 8188a1d..2173c0a 100644
--- a/sys/dev/sound/pci/fm801.c
+++ b/sys/dev/sound/pci/fm801.c
@@ -104,7 +104,6 @@
/* channel interface */
static void *fm801ch_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir);
-static int fm801ch_setdir(void *data, int dir);
static int fm801ch_setformat(void *data, u_int32_t format);
static int fm801ch_setspeed(void *data, u_int32_t speed);
static int fm801ch_setblocksize(void *data, u_int32_t blocksize);
@@ -119,9 +118,7 @@ static u_int32_t fmts[] = {
AFMT_U8,
AFMT_STEREO | AFMT_U8,
AFMT_S16_LE,
- AFMT_STEREO | AFMT_S16_LE, /*
- AFMT_STEREO | (AFMT_S16_LE | AFMT_S16_BE | AFMT_U16_LE | AFMT_U16_BE),
- (AFMT_S16_LE | AFMT_S16_BE | AFMT_U16_LE | AFMT_U16_BE), */
+ AFMT_STEREO | AFMT_S16_LE,
0
};
@@ -132,7 +129,7 @@ static pcmchan_caps fm801ch_caps = {
static pcm_channel fm801_chantemplate = {
fm801ch_init,
- fm801ch_setdir,
+ NULL, /* setdir */
fm801ch_setformat,
fm801ch_setspeed,
fm801ch_setblocksize,
@@ -192,23 +189,6 @@ struct fm801_info {
struct fm801_chinfo pch, rch;
};
-
-/* several procedures to release the thing properly if compiled as module */
-static struct fm801_info *save801;
-struct fm801_info *fm801_get __P((void ));
-
-static void
-fm801_save(struct fm801_info *fm801)
-{
- save801 = fm801;
-}
-
-struct fm801_info *
-fm801_get(void )
-{
- return save801;
-}
-
/* Bus Read / Write routines */
static u_int32_t
fm801_rd(struct fm801_info *fm801, int regno, int size)
@@ -395,7 +375,7 @@ static int
fm801_pci_attach(device_t dev)
{
u_int32_t data;
- struct ac97_info *codec;
+ struct ac97_info *codec = 0;
struct fm801_info *fm801;
int i;
int mapped = 0;
@@ -475,19 +455,40 @@ fm801_pci_attach(device_t dev)
pcm_addchan(dev, PCMDIR_REC, &fm801_chantemplate, fm801);
pcm_setstatus(dev, status);
- fm801_save(fm801);
return 0;
oops:
- printf("Forte Media FM801 initialization failed\n");
+ if (codec) ac97_destroy(codec);
if (fm801->reg) bus_release_resource(dev, fm801->regtype, fm801->regid, fm801->reg);
if (fm801->ih) bus_teardown_intr(dev, fm801->irq, fm801->ih);
if (fm801->irq) bus_release_resource(dev, SYS_RES_IRQ, fm801->irqid, fm801->irq);
+ if (fm801->parent_dmat) bus_dma_tag_destroy(fm801->parent_dmat);
free(fm801, M_DEVBUF);
return ENXIO;
}
static int
+fm801_pci_detach(device_t dev)
+{
+ int r;
+ struct fm801_info *fm801;
+
+ DPRINT("Forte Media FM801 detach\n");
+
+ r = pcm_unregister(dev);
+ if (r)
+ return r;
+
+ fm801 = pcm_getdevinfo(dev);
+ bus_release_resource(dev, fm801->regtype, fm801->regid, fm801->reg);
+ bus_teardown_intr(dev, fm801->irq, fm801->ih);
+ bus_release_resource(dev, SYS_RES_IRQ, fm801->irqid, fm801->irq);
+ bus_dma_tag_destroy(fm801->parent_dmat);
+ free(fm801, M_DEVBUF);
+ return 0;
+}
+
+static int
fm801_pci_probe( device_t dev )
{
int id;
@@ -524,14 +525,6 @@ fm801ch_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir)
}
static int
-fm801ch_setdir(void *data, int dir)
-{
- struct fm801_chinfo *ch = data;
- ch->dir = dir;
- return 0;
-}
-
-static int
fm801ch_setformat(void *data, u_int32_t format)
{
struct fm801_chinfo *ch = data;
@@ -716,20 +709,6 @@ fm801ch_getcaps(void *data)
return &fm801ch_caps;
}
-static int
-fm801_pci_detach(device_t dev)
-{
- struct fm801_info *fm801 = fm801_get();
-
- DPRINT("Forte Media FM801 detach\n");
-
- if (fm801->reg) bus_release_resource(dev, fm801->regtype, fm801->regid, fm801->reg);
- if (fm801->ih) bus_teardown_intr(dev, fm801->irq, fm801->ih);
- if (fm801->irq) bus_release_resource(dev, SYS_RES_IRQ, fm801->irqid, fm801->irq);
- free(fm801, M_DEVBUF);
- return 0;
-}
-
static device_method_t fm801_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, fm801_pci_probe),
@@ -746,4 +725,4 @@ static driver_t fm801_driver = {
static devclass_t pcm_devclass;
-DRIVER_MODULE(fm801, pci, fm801_driver, pcm_devclass,0, 0);
+DRIVER_MODULE(fm801, pci, fm801_driver, pcm_devclass, 0, 0);
diff --git a/sys/dev/sound/pci/maestro.c b/sys/dev/sound/pci/maestro.c
index c9926c4..a465d5c 100644
--- a/sys/dev/sound/pci/maestro.c
+++ b/sys/dev/sound/pci/maestro.c
@@ -1041,12 +1041,12 @@ agg_attach(device_t dev)
return 0;
bad:
+ if (codec != NULL)
+ ac97_destroy(codec);
if (ih != NULL)
bus_teardown_intr(dev, irq, ih);
if (irq != NULL)
bus_release_resource(dev, SYS_RES_IRQ, irqid, irq);
- if (codec != NULL)
- free(codec, M_DEVBUF);
if (reg != NULL)
bus_release_resource(dev, SYS_RES_IOPORT, regid, reg);
if (ess != NULL) {
diff --git a/sys/dev/sound/pci/neomagic.c b/sys/dev/sound/pci/neomagic.c
index 72ae8b8..7cfe838 100644
--- a/sys/dev/sound/pci/neomagic.c
+++ b/sys/dev/sound/pci/neomagic.c
@@ -137,7 +137,7 @@ static pcmchan_caps nm_caps = {4000, 48000, nm_fmt, 0};
static pcm_channel nm_chantemplate = {
nmchan_init,
- nmchan_setdir,
+ NULL, /* setdir */
nmchan_setformat,
nmchan_setspeed,
nmchan_setblocksize,
@@ -379,12 +379,6 @@ nmchan_free(void *data)
}
static int
-nmchan_setdir(void *data, int dir)
-{
- return 0;
-}
-
-static int
nmchan_setformat(void *data, u_int32_t format)
{
struct sc_chinfo *ch = data;
@@ -599,7 +593,7 @@ nm_pci_attach(device_t dev)
{
u_int32_t data;
struct sc_info *sc;
- struct ac97_info *codec;
+ struct ac97_info *codec = 0;
char status[SND_STATUSLEN];
if ((sc = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT)) == NULL) {
@@ -658,6 +652,7 @@ nm_pci_attach(device_t dev)
return 0;
bad:
+ if (codec) ac97_destroy(codec);
if (sc->buf) bus_release_resource(dev, SYS_RES_MEMORY, sc->bufid, sc->buf);
if (sc->reg) bus_release_resource(dev, SYS_RES_MEMORY, sc->regid, sc->reg);
if (sc->ih) bus_teardown_intr(dev, sc->irq, sc->ih);
@@ -667,6 +662,26 @@ bad:
}
static int
+nm_pci_detach(device_t dev)
+{
+ int r;
+ struct sc_info *sc;
+
+ r = pcm_unregister(dev);
+ if (r)
+ return r;
+
+ sc = pcm_getdevinfo(dev);
+ bus_release_resource(dev, SYS_RES_MEMORY, sc->bufid, sc->buf);
+ bus_release_resource(dev, SYS_RES_MEMORY, sc->regid, sc->reg);
+ bus_teardown_intr(dev, sc->irq, sc->ih);
+ bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq);
+ free(sc, M_DEVBUF);
+
+ return 0;
+}
+
+static int
nm_pci_resume(device_t dev)
{
struct sc_info *sc;
diff --git a/sys/dev/sound/pci/solo.c b/sys/dev/sound/pci/solo.c
index 58161db..315262d 100644
--- a/sys/dev/sound/pci/solo.c
+++ b/sys/dev/sound/pci/solo.c
@@ -83,7 +83,7 @@ static pcmchan_caps ess_reccaps = {5000, 49000, ess_recfmt, 0};
static pcm_channel ess_chantemplate = {
esschan_init,
- esschan_setdir,
+ NULL, /* setdir */
esschan_setformat,
esschan_setspeed,
esschan_setblocksize,
@@ -113,6 +113,7 @@ struct ess_chinfo {
struct ess_info {
struct resource *io, *sb, *vc, *mpu, *gp; /* I/O address for the board */
struct resource *irq;
+ void *ih;
bus_dma_tag_t parent_dmat;
int simplex_dir, type, duplex:1, newspeed:1, dmasz[2];
@@ -557,6 +558,7 @@ esschan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir)
ch->channel = c;
ch->buffer = b;
ch->buffer->bufsize = ESS_BUFFSIZE;
+ ch->dir = dir;
if (chn_allocbuf(ch->buffer, sc->parent_dmat) == -1)
return NULL;
ch->hwch = 1;
@@ -566,15 +568,6 @@ esschan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir)
}
static int
-esschan_setdir(void *data, int dir)
-{
- struct ess_chinfo *ch = data;
-
- ch->dir = dir;
- return 0;
-}
-
-static int
esschan_setformat(void *data, u_int32_t format)
{
struct ess_chinfo *ch = data;
@@ -830,6 +823,8 @@ ess_release_resources(struct ess_info *sc, device_t dev)
{
/* should we bus_teardown_intr here? */
if (sc->irq) {
+ if (sc->ih)
+ bus_teardown_intr(dev, sc->irq, sc->ih);
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq);
sc->irq = 0;
}
@@ -858,6 +853,11 @@ ess_release_resources(struct ess_info *sc, device_t dev)
sc->gp = 0;
}
+ if (sc->parent_dmat) {
+ bus_dma_tag_destroy(sc->parent_dmat);
+ sc->parent_dmat = 0;
+ }
+
free(sc, M_DEVBUF);
}
@@ -918,7 +918,6 @@ static int
ess_attach(device_t dev)
{
struct ess_info *sc;
- void *ih;
char status[SND_STATUSLEN];
u_int16_t ddma;
u_int32_t data;
@@ -960,7 +959,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, &ih);
+ bus_setup_intr(dev, sc->irq, INTR_TYPE_TTY, ess_intr, sc, &sc->ih);
if (!sc->duplex)
pcm_setflags(dev, pcm_getflags(dev) | SD_F_SIMPLEX);
@@ -992,10 +991,26 @@ no:
return ENXIO;
}
+static int
+ess_detach(device_t dev)
+{
+ int r;
+ struct sc_info *sc;
+
+ r = pcm_unregister(dev);
+ if (r)
+ return r;
+
+ sc = pcm_getdevinfo(dev);
+ ess_release_resources(sc, dev);
+ return 0;
+}
+
static device_method_t ess_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, ess_probe),
DEVMETHOD(device_attach, ess_attach),
+ DEVMETHOD(device_detach, ess_detach),
{ 0, 0 }
};
diff --git a/sys/dev/sound/pci/t4dwave.c b/sys/dev/sound/pci/t4dwave.c
index f65bdb4..f411338 100644
--- a/sys/dev/sound/pci/t4dwave.c
+++ b/sys/dev/sound/pci/t4dwave.c
@@ -695,17 +695,40 @@ tr_pci_attach(device_t dev)
return 0;
bad:
+ if (codec) ac97_destroy(codec);
if (tr->reg) bus_release_resource(dev, tr->regtype, tr->regid, tr->reg);
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);
free(tr, M_DEVBUF);
return ENXIO;
}
+static int
+tr_pci_detach(device_t dev)
+{
+ int r;
+ struct tr_info *tr;
+
+ r = pcm_unregister(dev);
+ if (r)
+ return r;
+
+ tr = pcm_getdevinfo(dev);
+ bus_release_resource(dev, tr->regtype, tr->regid, tr->reg);
+ 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);
+ free(tr, M_DEVBUF);
+
+ return 0;
+}
+
static device_method_t tr_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, tr_pci_probe),
DEVMETHOD(device_attach, tr_pci_attach),
+ DEVMETHOD(device_detach, tr_pci_detach),
{ 0, 0 }
};
diff --git a/sys/dev/sound/pci/via82c686.c b/sys/dev/sound/pci/via82c686.c
index 14fe9bf..df72136 100644
--- a/sys/dev/sound/pci/via82c686.c
+++ b/sys/dev/sound/pci/via82c686.c
@@ -58,6 +58,10 @@ struct via_info {
bus_dma_tag_t parent_dmat;
bus_dma_tag_t sgd_dmat;
+ struct resource *reg, *irq;
+ int regid, irqid;
+ void *ih;
+
struct via_chinfo pch, rch;
struct via_dma_op *sgd_table;
u_int16_t codec_caps;
@@ -146,15 +150,10 @@ static int
via_attach(device_t dev)
{
struct via_info *via = 0;
- struct ac97_info *codec;
+ struct ac97_info *codec = 0;
char status[SND_STATUSLEN];
u_int32_t data;
- struct resource *reg = 0;
- int regid;
- struct resource *irq = 0;
- void *ih = 0;
- int irqid;
u_int16_t v;
bus_dmamap_t sgd_dma_map;
@@ -175,21 +174,21 @@ via_attach(device_t dev)
VIA_PCICONF_ACLINKENAB | VIA_PCICONF_ACSGD |
VIA_PCICONF_ACNOTRST | VIA_PCICONF_ACVSR, 1);
- regid = PCIR_MAPS;
- reg = bus_alloc_resource(dev, SYS_RES_IOPORT, &regid,
+ via->regid = PCIR_MAPS;
+ via->reg = bus_alloc_resource(dev, SYS_RES_IOPORT, &via->regid,
0, ~0, 1, RF_ACTIVE);
- if (!reg) {
+ if (!via->reg) {
device_printf(dev, "via: Cannot allocate bus resource.");
goto bad;
}
- via->st = rman_get_bustag(reg);
- via->sh = rman_get_bushandle(reg);
+ via->st = rman_get_bustag(via->reg);
+ via->sh = rman_get_bushandle(via->reg);
- irqid = 0;
- irq = bus_alloc_resource(dev, SYS_RES_IRQ, &irqid,
+ via->irqid = 0;
+ via->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &via->irqid,
0, ~0, 1, RF_ACTIVE | RF_SHAREABLE);
- if (!irq
- || bus_setup_intr(dev, irq, INTR_TYPE_TTY, via_intr, via, &ih)){
+ if (!via->irq
+ || bus_setup_intr(dev, via->irq, INTR_TYPE_TTY, via_intr, via, &via->ih)){
device_printf(dev, "unable to map interrupt\n");
goto bad;
}
@@ -216,8 +215,8 @@ via_attach(device_t dev)
via_write_codec(via, AC97_REG_EXT_AUDIO_STAT, v);
via->codec_caps = v;
{
- v = via_read_codec(via, AC97_REG_EXT_AUDIO_STAT);
- DEB(printf("init: codec stat: %d\n", v));
+ v = via_read_codec(via, AC97_REG_EXT_AUDIO_STAT);
+ DEB(printf("init: codec stat: %d\n", v));
}
if (!(v & AC97_CODEC_DOES_VRA)) {
@@ -259,7 +258,7 @@ via_attach(device_t dev)
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(reg), rman_get_start(irq));
+ rman_get_start(via->reg), rman_get_start(via->irq));
/* Register */
if (pcm_register(dev, via, 1, 1)) goto bad;
@@ -268,17 +267,41 @@ via_attach(device_t dev)
pcm_setstatus(dev, status);
return 0;
bad:
+ if (codec) ac97_destroy(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_dmat) bus_dma_tag_destroy(via->sgd_dmat);
if (via) free(via, M_DEVBUF);
- bus_release_resource(dev, SYS_RES_IOPORT, regid, reg);
- if (ih) bus_teardown_intr(dev, irq, ih);
- if (irq) bus_release_resource(dev, SYS_RES_IRQ, irqid, irq);
return ENXIO;
}
+static int
+via_detach(device_t dev)
+{
+ int r;
+ struct via_info *via = 0;
+
+ r = pcm_unregister(dev);
+ if (r)
+ return r;
+
+ via = pcm_getdevinfo(dev);
+ bus_release_resource(dev, SYS_RES_IOPORT, via->regid, via->reg);
+ bus_teardown_intr(dev, via->irq, via->ih);
+ bus_release_resource(dev, SYS_RES_IRQ, via->irqid, via->irq);
+ bus_dma_tag_destroy(via->parent_dmat);
+ bus_dma_tag_destroy(via->sgd_dmat);
+ free(via, M_DEVBUF);
+ return 0;
+}
+
static device_method_t via_methods[] = {
DEVMETHOD(device_probe, via_probe),
DEVMETHOD(device_attach, via_attach),
+ DEVMETHOD(device_detach, via_detach),
{ 0, 0}
};
OpenPOWER on IntegriCloud