summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
authortmm <tmm@FreeBSD.org>2001-06-18 18:36:34 +0000
committertmm <tmm@FreeBSD.org>2001-06-18 18:36:34 +0000
commitaa003601da3ca6a93264cdc83ea3e655a3a366b2 (patch)
tree2ca7c5adf70976a7255e97a6d359429d21ee632e /sys/dev
parent3f41cb9d845f29f7cc5902a58e6b42b85886a16a (diff)
downloadFreeBSD-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/dev')
-rw-r--r--sys/dev/sound/pci/csa.c60
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
OpenPOWER on IntegriCloud