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
This commit is contained in:
Thomas Moestl 2001-06-18 18:36:34 +00:00
parent 75328eca8d
commit 916076fefc
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=78421

View File

@ -241,6 +241,7 @@ csa_attach(device_t dev)
sc_p scp; sc_p scp;
csa_res *resp; csa_res *resp;
struct sndcard_func *func; struct sndcard_func *func;
int error = ENXIO;
scp = device_get_softc(dev); scp = device_get_softc(dev);
@ -266,55 +267,40 @@ csa_attach(device_t dev)
return (ENXIO); return (ENXIO);
resp->mem_rid = PCIR_MAPS + 4; resp->mem_rid = PCIR_MAPS + 4;
resp->mem = bus_alloc_resource(dev, SYS_RES_MEMORY, &resp->mem_rid, 0, ~0, 1, RF_ACTIVE); resp->mem = bus_alloc_resource(dev, SYS_RES_MEMORY, &resp->mem_rid, 0, ~0, 1, RF_ACTIVE);
if (resp->mem == NULL) { if (resp->mem == NULL)
bus_release_resource(dev, SYS_RES_MEMORY, resp->io_rid, resp->io); goto err_io;
return (ENXIO);
}
resp->irq_rid = 0; resp->irq_rid = 0;
resp->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &resp->irq_rid, 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE); resp->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &resp->irq_rid, 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE);
if (resp->irq == NULL) { if (resp->irq == NULL)
bus_release_resource(dev, SYS_RES_MEMORY, resp->io_rid, resp->io); goto err_mem;
bus_release_resource(dev, SYS_RES_MEMORY, resp->mem_rid, resp->mem);
return (ENXIO);
}
/* Enable interrupt. */ /* Enable interrupt. */
if (snd_setup_intr(dev, resp->irq, INTR_MPSAFE, csa_intr, scp, &scp->ih)) { 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); goto err_intr;
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 0 #if 0
if ((csa_readio(resp, BA0_HISR) & HISR_INTENA) == 0) if ((csa_readio(resp, BA0_HISR) & HISR_INTENA) == 0)
csa_writeio(resp, BA0_HICR, HICR_IEV | HICR_CHGM); csa_writeio(resp, BA0_HICR, HICR_IEV | HICR_CHGM);
#endif #endif
/* Initialize the chip. */ /* Initialize the chip. */
if (csa_initialize(scp)) { if (csa_initialize(scp))
bus_release_resource(dev, SYS_RES_MEMORY, resp->io_rid, resp->io); goto err_teardown;
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);
}
/* Reset the Processor. */ /* Reset the Processor. */
csa_resetdsp(resp); csa_resetdsp(resp);
/* Download the Processor Image to the processor. */ /* Download the Processor Image to the processor. */
if (csa_downloadimage(resp)) { if (csa_downloadimage(resp))
bus_release_resource(dev, SYS_RES_MEMORY, resp->io_rid, resp->io); goto err_teardown;
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);
}
/* Attach the children. */ /* Attach the children. */
/* PCM Audio */ /* PCM Audio */
func = malloc(sizeof(struct sndcard_func), M_DEVBUF, M_NOWAIT); func = malloc(sizeof(struct sndcard_func), M_DEVBUF, M_NOWAIT);
if (func == NULL) if (func == NULL) {
return (ENOMEM); error = ENOMEM;
goto err_teardown;
}
bzero(func, sizeof(*func)); bzero(func, sizeof(*func));
func->varinfo = &scp->binfo; func->varinfo = &scp->binfo;
func->func = SCF_PCM; func->func = SCF_PCM;
@ -323,8 +309,10 @@ csa_attach(device_t dev)
/* Midi Interface */ /* Midi Interface */
func = malloc(sizeof(struct sndcard_func), M_DEVBUF, M_NOWAIT); func = malloc(sizeof(struct sndcard_func), M_DEVBUF, M_NOWAIT);
if (func == NULL) if (func == NULL) {
return (ENOMEM); error = ENOMEM;
goto err_teardown;
}
bzero(func, sizeof(*func)); bzero(func, sizeof(*func));
func->varinfo = &scp->binfo; func->varinfo = &scp->binfo;
func->func = SCF_MIDI; func->func = SCF_MIDI;
@ -334,6 +322,16 @@ csa_attach(device_t dev)
bus_generic_attach(dev); bus_generic_attach(dev);
return (0); 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 static int