diff options
author | tmm <tmm@FreeBSD.org> | 2001-06-18 18:36:34 +0000 |
---|---|---|
committer | tmm <tmm@FreeBSD.org> | 2001-06-18 18:36:34 +0000 |
commit | aa003601da3ca6a93264cdc83ea3e655a3a366b2 (patch) | |
tree | 2ca7c5adf70976a7255e97a6d359429d21ee632e /sys | |
parent | 3f41cb9d845f29f7cc5902a58e6b42b85886a16a (diff) | |
download | FreeBSD-src-aa003601da3ca6a93264cdc83ea3e655a3a366b2.zip FreeBSD-src-aa003601da3ca6a93264cdc83ea3e655a3a366b2.tar.gz |
Call bus_teardown_intr when csa_attach fails after the interrupt has
been set up.
PR: kern/28178
Reviewed by: cg
MFC after: 2 weeks
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/sound/pci/csa.c | 60 |
1 files changed, 29 insertions, 31 deletions
diff --git a/sys/dev/sound/pci/csa.c b/sys/dev/sound/pci/csa.c index b916cdc..30957c3 100644 --- a/sys/dev/sound/pci/csa.c +++ b/sys/dev/sound/pci/csa.c @@ -241,6 +241,7 @@ csa_attach(device_t dev) sc_p scp; csa_res *resp; struct sndcard_func *func; + int error = ENXIO; scp = device_get_softc(dev); @@ -266,55 +267,40 @@ csa_attach(device_t dev) return (ENXIO); resp->mem_rid = PCIR_MAPS + 4; resp->mem = bus_alloc_resource(dev, SYS_RES_MEMORY, &resp->mem_rid, 0, ~0, 1, RF_ACTIVE); - if (resp->mem == NULL) { - bus_release_resource(dev, SYS_RES_MEMORY, resp->io_rid, resp->io); - return (ENXIO); - } + if (resp->mem == NULL) + goto err_io; resp->irq_rid = 0; resp->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &resp->irq_rid, 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE); - if (resp->irq == NULL) { - bus_release_resource(dev, SYS_RES_MEMORY, resp->io_rid, resp->io); - bus_release_resource(dev, SYS_RES_MEMORY, resp->mem_rid, resp->mem); - return (ENXIO); - } + if (resp->irq == NULL) + goto err_mem; /* Enable interrupt. */ - if (snd_setup_intr(dev, resp->irq, INTR_MPSAFE, csa_intr, scp, &scp->ih)) { - bus_release_resource(dev, SYS_RES_MEMORY, resp->io_rid, resp->io); - bus_release_resource(dev, SYS_RES_MEMORY, resp->mem_rid, resp->mem); - bus_release_resource(dev, SYS_RES_IRQ, resp->irq_rid, resp->irq); - return (ENXIO); - } + if (snd_setup_intr(dev, resp->irq, INTR_MPSAFE, csa_intr, scp, &scp->ih)) + goto err_intr; #if 0 if ((csa_readio(resp, BA0_HISR) & HISR_INTENA) == 0) csa_writeio(resp, BA0_HICR, HICR_IEV | HICR_CHGM); #endif /* Initialize the chip. */ - if (csa_initialize(scp)) { - bus_release_resource(dev, SYS_RES_MEMORY, resp->io_rid, resp->io); - bus_release_resource(dev, SYS_RES_MEMORY, resp->mem_rid, resp->mem); - bus_release_resource(dev, SYS_RES_IRQ, resp->irq_rid, resp->irq); - return (ENXIO); - } + if (csa_initialize(scp)) + goto err_teardown; /* Reset the Processor. */ csa_resetdsp(resp); /* Download the Processor Image to the processor. */ - if (csa_downloadimage(resp)) { - bus_release_resource(dev, SYS_RES_MEMORY, resp->io_rid, resp->io); - bus_release_resource(dev, SYS_RES_MEMORY, resp->mem_rid, resp->mem); - bus_release_resource(dev, SYS_RES_IRQ, resp->irq_rid, resp->irq); - return (ENXIO); - } + if (csa_downloadimage(resp)) + goto err_teardown; /* Attach the children. */ /* PCM Audio */ func = malloc(sizeof(struct sndcard_func), M_DEVBUF, M_NOWAIT); - if (func == NULL) - return (ENOMEM); + if (func == NULL) { + error = ENOMEM; + goto err_teardown; + } bzero(func, sizeof(*func)); func->varinfo = &scp->binfo; func->func = SCF_PCM; @@ -323,8 +309,10 @@ csa_attach(device_t dev) /* Midi Interface */ func = malloc(sizeof(struct sndcard_func), M_DEVBUF, M_NOWAIT); - if (func == NULL) - return (ENOMEM); + if (func == NULL) { + error = ENOMEM; + goto err_teardown; + } bzero(func, sizeof(*func)); func->varinfo = &scp->binfo; func->func = SCF_MIDI; @@ -334,6 +322,16 @@ csa_attach(device_t dev) bus_generic_attach(dev); return (0); + +err_teardown: + bus_teardown_intr(dev, resp->irq, scp->ih); +err_intr: + bus_release_resource(dev, SYS_RES_IRQ, resp->irq_rid, resp->irq); +err_mem: + bus_release_resource(dev, SYS_RES_MEMORY, resp->mem_rid, resp->mem); +err_io: + bus_release_resource(dev, SYS_RES_MEMORY, resp->io_rid, resp->io); + return (error); } static int |