diff options
Diffstat (limited to 'sys/dev/sound/pci/solo.c')
-rw-r--r-- | sys/dev/sound/pci/solo.c | 39 |
1 files changed, 27 insertions, 12 deletions
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 } }; |