diff options
Diffstat (limited to 'sys/dev/sound/pci/es137x.c')
-rw-r--r-- | sys/dev/sound/pci/es137x.c | 77 |
1 files changed, 49 insertions, 28 deletions
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, ®id, + 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, ®id, + 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 } }; |