diff options
author | cg <cg@FreeBSD.org> | 2000-09-09 19:21:04 +0000 |
---|---|---|
committer | cg <cg@FreeBSD.org> | 2000-09-09 19:21:04 +0000 |
commit | a081b436a34dc6b7c3f1418e1429edbd7a31c3ff (patch) | |
tree | 916a90fe682463a47c2285b9f4bc874b6720fce7 /sys/dev/sound/isa | |
parent | f80149566df17edb15598b2d33d559f831c5edb5 (diff) | |
download | FreeBSD-src-a081b436a34dc6b7c3f1418e1429edbd7a31c3ff.zip FreeBSD-src-a081b436a34dc6b7c3f1418e1429edbd7a31c3ff.tar.gz |
detach support
remove un-needed setdir functions
add bus_teardown_intr calls where necessary
destroy our dma tags where necessary
destroy ac97 before releasing resources
Diffstat (limited to 'sys/dev/sound/isa')
-rw-r--r-- | sys/dev/sound/isa/ad1816.c | 28 | ||||
-rw-r--r-- | sys/dev/sound/isa/ess.c | 49 | ||||
-rw-r--r-- | sys/dev/sound/isa/mss.c | 35 | ||||
-rw-r--r-- | sys/dev/sound/isa/sb.c | 31 | ||||
-rw-r--r-- | sys/dev/sound/isa/sb16.c | 31 | ||||
-rw-r--r-- | sys/dev/sound/isa/sb8.c | 31 | ||||
-rw-r--r-- | sys/dev/sound/isa/sbc.c | 28 |
7 files changed, 188 insertions, 45 deletions
diff --git a/sys/dev/sound/isa/ad1816.c b/sys/dev/sound/isa/ad1816.c index 3cebbe3..d25931e 100644 --- a/sys/dev/sound/isa/ad1816.c +++ b/sys/dev/sound/isa/ad1816.c @@ -49,6 +49,7 @@ struct ad1816_info { int drq1_rid; struct resource *drq2; /* rec */ int drq2_rid; + void *ih; bus_dma_tag_t parent_dmat; struct ad1816_chinfo pch, rch; @@ -480,6 +481,8 @@ static void 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); ad1816->irq = 0; @@ -499,7 +502,11 @@ ad1816_release_resources(struct ad1816_info *ad1816, device_t dev) ad1816->io_base); ad1816->io_base = 0; } - free(ad1816, M_DEVBUF); + if (ad1816->parent_dmat) { + bus_dma_tag_destroy(ad1816->parent_dmat); + ad1816->parent_dmat = 0; + } + free(ad1816, M_DEVBUF); } static int @@ -575,7 +582,6 @@ static int ad1816_attach(device_t dev) { struct ad1816_info *ad1816; - void *ih; char status[SND_STATUSLEN]; ad1816 = (struct ad1816_info *)malloc(sizeof *ad1816, M_DEVBUF, M_NOWAIT); @@ -590,7 +596,7 @@ ad1816_attach(device_t dev) if (!ad1816_alloc_resources(ad1816, dev)) goto no; ad1816_init(ad1816, dev); mixer_init(dev, &ad1816_mixer, ad1816); - bus_setup_intr(dev, ad1816->irq, INTR_TYPE_TTY, ad1816_intr, ad1816, &ih); + bus_setup_intr(dev, ad1816->irq, INTR_TYPE_TTY, ad1816_intr, ad1816, &ad1816->ih); if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0, /*lowaddr*/BUS_SPACE_MAXADDR_24BIT, /*highaddr*/BUS_SPACE_MAXADDR, @@ -621,10 +627,26 @@ no: } +static int +ad1816_detach(device_t dev) +{ + int r; + struct ad1816_info *ad1816; + + r = pcm_unregister(dev); + if (r) + return r; + + ad1816 = pcm_getdevinfo(dev); + ad1816_release_resources(ad1816, dev); + return 0; +} + static device_method_t ad1816_methods[] = { /* Device interface */ DEVMETHOD(device_probe, ad1816_probe), DEVMETHOD(device_attach, ad1816_attach), + DEVMETHOD(device_detach, ad1816_detach), { 0, 0 } }; diff --git a/sys/dev/sound/isa/ess.c b/sys/dev/sound/isa/ess.c index abef688..7b1bddf 100644 --- a/sys/dev/sound/isa/ess.c +++ b/sys/dev/sound/isa/ess.c @@ -47,7 +47,6 @@ /* channel interface for ESS */ static void *esschan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir); -static int esschan_setdir(void *data, int dir); static int esschan_setformat(void *data, u_int32_t format); static int esschan_setspeed(void *data, u_int32_t speed); static int esschan_setblocksize(void *data, u_int32_t blocksize); @@ -85,7 +84,7 @@ static pcmchan_caps ess_reccaps = {5000, 49000, ess_rfmt, 0}; static pcm_channel ess_chantemplate = { esschan_init, - esschan_setdir, + NULL, /* setdir */ esschan_setformat, esschan_setspeed, esschan_setblocksize, @@ -117,6 +116,7 @@ struct ess_info { struct resource *irq; struct resource *drq1; struct resource *drq2; + void *ih; bus_dma_tag_t parent_dmat; int type, duplex:1, newspeed:1; @@ -312,8 +312,9 @@ ess_reset_dsp(struct ess_info *sc) static void 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; } @@ -329,7 +330,11 @@ ess_release_resources(struct ess_info *sc, device_t dev) bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->io_base); sc->io_base = 0; } - free(sc, M_DEVBUF); + if (sc->parent_dmat) { + bus_dma_tag_destroy(sc->parent_dmat); + sc->parent_dmat = 0; + } + free(sc, M_DEVBUF); } static int @@ -374,7 +379,6 @@ ess_alloc_resources(struct ess_info *sc, device_t dev) static int ess_doattach(device_t dev, struct ess_info *sc) { - void *ih; char status[SND_STATUSLEN], buf[64]; int ver; @@ -410,7 +414,7 @@ ess_doattach(device_t dev, struct ess_info *sc) if (sc->newspeed) ess_setmixer(sc, 0x71, 0x22); - 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); @@ -445,6 +449,21 @@ no: return ENXIO; } +static int +ess_detach(device_t dev) +{ + int r; + struct ess_info *sc; + + r = pcm_unregister(dev); + if (r) + return r; + + sc = pcm_getdevinfo(dev); + ess_release_resources(sc, dev); + return 0; +} + static void ess_intr(void *arg) { @@ -650,6 +669,7 @@ esschan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir) ch->buffer->bufsize = ESS_BUFFSIZE; if (chn_allocbuf(ch->buffer, sc->parent_dmat) == -1) return NULL; + ch->dir = dir; ch->hwch = 1; if ((dir == PCMDIR_PLAY) && (sc->duplex)) ch->hwch = 2; @@ -658,15 +678,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; @@ -881,6 +892,7 @@ 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 } }; @@ -935,10 +947,17 @@ esscontrol_attach(device_t dev) return 0; } +static int +esscontrol_detach(device_t dev) +{ + return 0; +} + static device_method_t esscontrol_methods[] = { /* Device interface */ DEVMETHOD(device_probe, esscontrol_probe), DEVMETHOD(device_attach, esscontrol_attach), + DEVMETHOD(device_detach, esscontrol_detach), { 0, 0 } }; diff --git a/sys/dev/sound/isa/mss.c b/sys/dev/sound/isa/mss.c index 93347c5..a59d9b9 100644 --- a/sys/dev/sound/isa/mss.c +++ b/sys/dev/sound/isa/mss.c @@ -60,6 +60,7 @@ struct mss_info { int drq1_rid; struct resource *drq2; /* rec */ int drq2_rid; + void *ih; bus_dma_tag_t parent_dmat; char mss_indexed_regs[MSS_INDEXED_REGS]; @@ -284,7 +285,9 @@ static void mss_release_resources(struct mss_info *mss, device_t dev) { if (mss->irq) { - bus_release_resource(dev, SYS_RES_IRQ, mss->irq_rid, + if (mss->ih) + bus_teardown_intr(dev, mss->irq, mss->ih); + bus_release_resource(dev, SYS_RES_IRQ, mss->irq_rid, mss->irq); mss->irq = 0; } @@ -310,7 +313,11 @@ mss_release_resources(struct mss_info *mss, device_t dev) mss->conf_base); mss->conf_base = 0; } - free(mss, M_DEVBUF); + if (mss->parent_dmat) { + bus_dma_tag_destroy(mss->parent_dmat); + mss->parent_dmat = 0; + } + free(mss, M_DEVBUF); } static int @@ -872,7 +879,6 @@ ymf_test(device_t dev, struct mss_info *mss) static int mss_doattach(device_t dev, struct mss_info *mss) { - void *ih; int flags = device_get_flags(dev); char status[SND_STATUSLEN]; @@ -914,10 +920,10 @@ mss_doattach(device_t dev, struct mss_info *mss) mixer_init(dev, (mss->bd_id == MD_YM0020)? &yamaha_mixer : &mss_mixer, mss); switch (mss->bd_id) { case MD_OPTI931: - bus_setup_intr(dev, mss->irq, INTR_TYPE_TTY, opti931_intr, mss, &ih); + bus_setup_intr(dev, mss->irq, INTR_TYPE_TTY, opti931_intr, mss, &mss->ih); break; default: - bus_setup_intr(dev, mss->irq, INTR_TYPE_TTY, mss_intr, mss, &ih); + bus_setup_intr(dev, mss->irq, INTR_TYPE_TTY, mss_intr, mss, &mss->ih); } if (mss->pdma == mss->rdma) pcm_setflags(dev, pcm_getflags(dev) | SD_F_SIMPLEX); @@ -948,6 +954,22 @@ no: } static int +mss_detach(device_t dev) +{ + int r; + struct mss_info *mss; + + r = pcm_unregister(dev); + if (r) + return r; + + mss = pcm_getdevinfo(dev); + mss_release_resources(mss, dev); + + return 0; +} + +static int mss_attach(device_t dev) { struct mss_info *mss; @@ -1043,6 +1065,7 @@ static device_method_t mss_methods[] = { /* Device interface */ DEVMETHOD(device_probe, mss_probe), DEVMETHOD(device_attach, mss_attach), + DEVMETHOD(device_detach, mss_detach), DEVMETHOD(device_suspend, mss_suspend), DEVMETHOD(device_resume, mss_resume), @@ -1540,6 +1563,7 @@ static device_method_t pnpmss_methods[] = { /* Device interface */ DEVMETHOD(device_probe, pnpmss_probe), DEVMETHOD(device_attach, pnpmss_attach), + DEVMETHOD(device_detach, mss_detach), DEVMETHOD(device_suspend, mss_suspend), DEVMETHOD(device_resume, mss_resume), @@ -1684,6 +1708,7 @@ skip_setup: static device_method_t guspcm_methods[] = { DEVMETHOD(device_probe, guspcm_probe), DEVMETHOD(device_attach, guspcm_attach), + DEVMETHOD(device_detach, mss_detach), { 0, 0 } }; diff --git a/sys/dev/sound/isa/sb.c b/sys/dev/sound/isa/sb.c index 21c3e6f..6d9154a 100644 --- a/sys/dev/sound/isa/sb.c +++ b/sys/dev/sound/isa/sb.c @@ -132,6 +132,7 @@ struct sb_info { struct resource *irq; struct resource *drq1; struct resource *drq2; + void *ih; bus_dma_tag_t parent_dmat; int bd_id; @@ -329,9 +330,10 @@ sb_reset_dsp(struct sb_info *sb) static void sb_release_resources(struct sb_info *sb, device_t dev) { - /* should we bus_teardown_intr here? */ if (sb->irq) { - bus_release_resource(dev, SYS_RES_IRQ, 0, sb->irq); + if (sb->ih) + bus_teardown_intr(dev, sb->irq, sb->ih); + bus_release_resource(dev, SYS_RES_IRQ, 0, sb->irq); sb->irq = 0; } if (sb->drq1) { @@ -346,7 +348,11 @@ sb_release_resources(struct sb_info *sb, device_t dev) bus_release_resource(dev, SYS_RES_IOPORT, 0, sb->io_base); sb->io_base = 0; } - free(sb, M_DEVBUF); + if (sb->parent_dmat) { + bus_dma_tag_destroy(sb->parent_dmat); + sb->parent_dmat = 0; + } + free(sb, M_DEVBUF); } static int @@ -421,7 +427,6 @@ sb16_swap(void *v, int dir) static int sb_doattach(device_t dev, struct sb_info *sb) { - void *ih; char status[SND_STATUSLEN]; int bs = DSP_BUFFSIZE; @@ -431,7 +436,7 @@ sb_doattach(device_t dev, struct sb_info *sb) goto no; mixer_init(dev, &sb_mixer, sb); - bus_setup_intr(dev, sb->irq, INTR_TYPE_TTY, sb_intr, sb, &ih); + bus_setup_intr(dev, sb->irq, INTR_TYPE_TTY, sb_intr, sb, &sb->ih); if ((sb->bd_flags & BD_F_SB16) && !(sb->bd_flags & BD_F_SB16X)) pcm_setswap(dev, sb16_swap); if (!sb->drq2) @@ -468,6 +473,21 @@ no: return ENXIO; } +static int +sb_detach(device_t dev) +{ + int r; + struct sb_info *sb; + + r = pcm_unregister(dev); + if (r) + return r; + + sb = pcm_getdevinfo(dev); + sb_release_resources(sb, dev); + return 0; +} + static void sb_intr(void *arg) { @@ -897,6 +917,7 @@ static device_method_t sbsbc_methods[] = { /* Device interface */ DEVMETHOD(device_probe, sbsbc_probe), DEVMETHOD(device_attach, sbsbc_attach), + DEVMETHOD(device_detach, sb_detach), { 0, 0 } }; diff --git a/sys/dev/sound/isa/sb16.c b/sys/dev/sound/isa/sb16.c index 21c3e6f..6d9154a 100644 --- a/sys/dev/sound/isa/sb16.c +++ b/sys/dev/sound/isa/sb16.c @@ -132,6 +132,7 @@ struct sb_info { struct resource *irq; struct resource *drq1; struct resource *drq2; + void *ih; bus_dma_tag_t parent_dmat; int bd_id; @@ -329,9 +330,10 @@ sb_reset_dsp(struct sb_info *sb) static void sb_release_resources(struct sb_info *sb, device_t dev) { - /* should we bus_teardown_intr here? */ if (sb->irq) { - bus_release_resource(dev, SYS_RES_IRQ, 0, sb->irq); + if (sb->ih) + bus_teardown_intr(dev, sb->irq, sb->ih); + bus_release_resource(dev, SYS_RES_IRQ, 0, sb->irq); sb->irq = 0; } if (sb->drq1) { @@ -346,7 +348,11 @@ sb_release_resources(struct sb_info *sb, device_t dev) bus_release_resource(dev, SYS_RES_IOPORT, 0, sb->io_base); sb->io_base = 0; } - free(sb, M_DEVBUF); + if (sb->parent_dmat) { + bus_dma_tag_destroy(sb->parent_dmat); + sb->parent_dmat = 0; + } + free(sb, M_DEVBUF); } static int @@ -421,7 +427,6 @@ sb16_swap(void *v, int dir) static int sb_doattach(device_t dev, struct sb_info *sb) { - void *ih; char status[SND_STATUSLEN]; int bs = DSP_BUFFSIZE; @@ -431,7 +436,7 @@ sb_doattach(device_t dev, struct sb_info *sb) goto no; mixer_init(dev, &sb_mixer, sb); - bus_setup_intr(dev, sb->irq, INTR_TYPE_TTY, sb_intr, sb, &ih); + bus_setup_intr(dev, sb->irq, INTR_TYPE_TTY, sb_intr, sb, &sb->ih); if ((sb->bd_flags & BD_F_SB16) && !(sb->bd_flags & BD_F_SB16X)) pcm_setswap(dev, sb16_swap); if (!sb->drq2) @@ -468,6 +473,21 @@ no: return ENXIO; } +static int +sb_detach(device_t dev) +{ + int r; + struct sb_info *sb; + + r = pcm_unregister(dev); + if (r) + return r; + + sb = pcm_getdevinfo(dev); + sb_release_resources(sb, dev); + return 0; +} + static void sb_intr(void *arg) { @@ -897,6 +917,7 @@ static device_method_t sbsbc_methods[] = { /* Device interface */ DEVMETHOD(device_probe, sbsbc_probe), DEVMETHOD(device_attach, sbsbc_attach), + DEVMETHOD(device_detach, sb_detach), { 0, 0 } }; diff --git a/sys/dev/sound/isa/sb8.c b/sys/dev/sound/isa/sb8.c index 21c3e6f..6d9154a 100644 --- a/sys/dev/sound/isa/sb8.c +++ b/sys/dev/sound/isa/sb8.c @@ -132,6 +132,7 @@ struct sb_info { struct resource *irq; struct resource *drq1; struct resource *drq2; + void *ih; bus_dma_tag_t parent_dmat; int bd_id; @@ -329,9 +330,10 @@ sb_reset_dsp(struct sb_info *sb) static void sb_release_resources(struct sb_info *sb, device_t dev) { - /* should we bus_teardown_intr here? */ if (sb->irq) { - bus_release_resource(dev, SYS_RES_IRQ, 0, sb->irq); + if (sb->ih) + bus_teardown_intr(dev, sb->irq, sb->ih); + bus_release_resource(dev, SYS_RES_IRQ, 0, sb->irq); sb->irq = 0; } if (sb->drq1) { @@ -346,7 +348,11 @@ sb_release_resources(struct sb_info *sb, device_t dev) bus_release_resource(dev, SYS_RES_IOPORT, 0, sb->io_base); sb->io_base = 0; } - free(sb, M_DEVBUF); + if (sb->parent_dmat) { + bus_dma_tag_destroy(sb->parent_dmat); + sb->parent_dmat = 0; + } + free(sb, M_DEVBUF); } static int @@ -421,7 +427,6 @@ sb16_swap(void *v, int dir) static int sb_doattach(device_t dev, struct sb_info *sb) { - void *ih; char status[SND_STATUSLEN]; int bs = DSP_BUFFSIZE; @@ -431,7 +436,7 @@ sb_doattach(device_t dev, struct sb_info *sb) goto no; mixer_init(dev, &sb_mixer, sb); - bus_setup_intr(dev, sb->irq, INTR_TYPE_TTY, sb_intr, sb, &ih); + bus_setup_intr(dev, sb->irq, INTR_TYPE_TTY, sb_intr, sb, &sb->ih); if ((sb->bd_flags & BD_F_SB16) && !(sb->bd_flags & BD_F_SB16X)) pcm_setswap(dev, sb16_swap); if (!sb->drq2) @@ -468,6 +473,21 @@ no: return ENXIO; } +static int +sb_detach(device_t dev) +{ + int r; + struct sb_info *sb; + + r = pcm_unregister(dev); + if (r) + return r; + + sb = pcm_getdevinfo(dev); + sb_release_resources(sb, dev); + return 0; +} + static void sb_intr(void *arg) { @@ -897,6 +917,7 @@ static device_method_t sbsbc_methods[] = { /* Device interface */ DEVMETHOD(device_probe, sbsbc_probe), DEVMETHOD(device_attach, sbsbc_attach), + DEVMETHOD(device_detach, sb_detach), { 0, 0 } }; diff --git a/sys/dev/sound/isa/sbc.c b/sys/dev/sound/isa/sbc.c index dcb85ee..6bce41a 100644 --- a/sys/dev/sound/isa/sbc.c +++ b/sys/dev/sound/isa/sbc.c @@ -58,7 +58,7 @@ struct sbc_softc { struct sbc_ihl ihl[IRQ_MAX]; - void *ih; + void *ih[IRQ_MAX]; u_int32_t bd_ver; }; @@ -372,9 +372,11 @@ sbc_attach(device_t dev) else sb_setmixer(scp->io[0], IRQ_NR, x); sb_setmixer(scp->io[0], DMA_NR, (1 << dh) | (1 << dl)); #endif - device_printf(dev, "setting card to irq %d, drq %d", irq, dl); - if (dl != dh) printf(", %d", dh); - printf("\n"); + if (bootverbose) { + device_printf(dev, "setting card to irq %d, drq %d", irq, dl); + if (dl != dh) printf(", %d", dh); + printf("\n"); + } break; } @@ -389,7 +391,7 @@ sbc_attach(device_t dev) err = "setup_intr"; for (i = 0; i < IRQ_MAX; i++) { - if (bus_setup_intr(dev, scp->irq[i], INTR_TYPE_TTY, sbc_intr, &scp->ihl[i], &scp->ih)) + if (bus_setup_intr(dev, scp->irq[i], INTR_TYPE_TTY, sbc_intr, &scp->ihl[i], &scp->ih[i])) goto bad; } @@ -427,6 +429,15 @@ bad: if (err) device_printf(dev, "%s\n", err); return (ENXIO); } +static int +sbc_detach(device_t dev) +{ + struct sbc_softc *scp = device_get_softc(dev); + + release_resource(scp); + return bus_generic_detach(dev); +} + static void sbc_intr(void *p) { @@ -648,7 +659,7 @@ alloc_resource(struct sbc_softc *scp) } } for (i = 0 ; i < IRQ_MAX ; i++) { - if (scp->irq[i] == NULL) { + if (scp->irq[i] == NULL) { scp->irq_rid[i] = i; scp->irq[i] = bus_alloc_resource(scp->dev, SYS_RES_IRQ, &scp->irq_rid[i], 0, ~0, 1, RF_ACTIVE); @@ -679,6 +690,9 @@ release_resource(struct sbc_softc *scp) } for (i = 0 ; i < IRQ_MAX ; i++) { if (scp->irq[i] != NULL) { + if (scp->ih[i] != NULL) + bus_teardown_intr(scp->dev, scp->irq[i], scp->ih[i]); + scp->ih[i] = NULL; bus_release_resource(scp->dev, SYS_RES_IRQ, scp->irq_rid[i], scp->irq[i]); scp->irq[i] = NULL; } @@ -690,7 +704,7 @@ static device_method_t sbc_methods[] = { /* Device interface */ DEVMETHOD(device_probe, sbc_probe), DEVMETHOD(device_attach, sbc_attach), - DEVMETHOD(device_detach, bus_generic_detach), + DEVMETHOD(device_detach, sbc_detach), DEVMETHOD(device_shutdown, bus_generic_shutdown), DEVMETHOD(device_suspend, bus_generic_suspend), DEVMETHOD(device_resume, bus_generic_resume), |