Simplify aha resource management, and fix a few bugs in unwinding

error cases.
This commit is contained in:
Warner Losh 2005-01-19 06:54:10 +00:00
parent 234111d6d0
commit 0ca891272b
3 changed files with 51 additions and 74 deletions

View File

@ -193,7 +193,8 @@ aha_isa_attach(device_t dev)
void *filter_arg;
bus_addr_t lowaddr;
void *ih;
int error;
int error = ENOMEM;
int aha_free_needed = 0;
aha->dev = dev;
aha->portrid = 0;
@ -201,7 +202,7 @@ aha_isa_attach(device_t dev)
0, ~0, AHA_NREGS, RF_ACTIVE);
if (!aha->port) {
device_printf(dev, "Unable to allocate I/O ports\n");
return ENOMEM;
goto fail;
}
aha->irqrid = 0;
@ -209,9 +210,7 @@ aha_isa_attach(device_t dev)
RF_ACTIVE);
if (!aha->irq) {
device_printf(dev, "Unable to allocate excluse use of irq\n");
bus_release_resource(dev, SYS_RES_IOPORT, aha->portrid,
aha->port);
return ENOMEM;
goto fail;
}
aha->drqrid = 0;
@ -219,10 +218,7 @@ aha_isa_attach(device_t dev)
RF_ACTIVE);
if (!aha->drq) {
device_printf(dev, "Unable to allocate drq\n");
bus_release_resource(dev, SYS_RES_IOPORT, aha->portrid,
aha->port);
bus_release_resource(dev, SYS_RES_IRQ, aha->irqrid, aha->irq);
return ENOMEM;
goto fail;
}
#if 0 /* is the drq ever unset? */
@ -250,23 +246,14 @@ aha_isa_attach(device_t dev)
/* lockfunc */ busdma_lock_mutex,
/* lockarg */ &Giant,
&aha->parent_dmat) != 0) {
bus_release_resource(dev, SYS_RES_IOPORT, aha->portrid,
aha->port);
bus_release_resource(dev, SYS_RES_IRQ, aha->irqrid, aha->irq);
bus_release_resource(dev, SYS_RES_DRQ, aha->drqrid, aha->drq);
aha_free(aha);
return (ENOMEM);
}
device_printf(dev, "dma tag create failed.\n");
goto fail;
}
if (aha_init(aha)) {
device_printf(dev, "init failed\n");
bus_release_resource(dev, SYS_RES_IOPORT, aha->portrid,
aha->port);
bus_release_resource(dev, SYS_RES_IRQ, aha->irqrid, aha->irq);
bus_release_resource(dev, SYS_RES_DRQ, aha->drqrid, aha->drq);
aha_free(aha);
return (ENOMEM);
}
goto fail;
}
/*
* The 1542A and B look the same. So we guess based on
* the firmware revision. It appears that only rev 0 is on
@ -277,31 +264,29 @@ aha_isa_attach(device_t dev)
aha->ccb_sg_opcode = INITIATOR_SG_CCB;
aha->ccb_ccb_opcode = INITIATOR_CCB;
}
aha_free_needed++;
error = aha_attach(aha);
if (error) {
device_printf(dev, "attach failed\n");
bus_release_resource(dev, SYS_RES_IOPORT, aha->portrid,
aha->port);
bus_release_resource(dev, SYS_RES_IRQ, aha->irqrid, aha->irq);
bus_release_resource(dev, SYS_RES_DRQ, aha->drqrid, aha->drq);
aha_free(aha);
return (error);
goto fail;
}
error = bus_setup_intr(dev, aha->irq, INTR_TYPE_CAM|INTR_ENTROPY,
aha_intr, aha, &ih);
if (error) {
device_printf(dev, "Unable to register interrupt handler\n");
bus_release_resource(dev, SYS_RES_IOPORT, aha->portrid,
aha->port);
bus_release_resource(dev, SYS_RES_IRQ, aha->irqrid, aha->irq);
bus_release_resource(dev, SYS_RES_DRQ, aha->drqrid, aha->drq);
aha_free(aha);
return (error);
goto fail;
}
return (0);
fail: ;
bus_free_resource(dev, SYS_RES_IOPORT, aha->port);
bus_free_resource(dev, SYS_RES_IRQ, aha->irq);
bus_free_resource(dev, SYS_RES_DRQ, aha->drq);
if (aha_free_needed)
aha_free(aha);
return (error);
}
static int
@ -311,13 +296,12 @@ aha_isa_detach(device_t dev)
int error;
error = bus_teardown_intr(dev, aha->irq, aha->ih);
if (error) {
if (error)
device_printf(dev, "failed to unregister interrupt handler\n");
}
bus_release_resource(dev, SYS_RES_IOPORT, aha->portrid, aha->port);
bus_release_resource(dev, SYS_RES_IRQ, aha->irqrid, aha->irq);
bus_release_resource(dev, SYS_RES_DRQ, aha->drqrid, aha->drq);
bus_free_resource(dev, SYS_RES_IOPORT, aha->port);
bus_free_resource(dev, SYS_RES_IRQ, aha->irq);
bus_free_resource(dev, SYS_RES_DRQ, aha->drq);
error = aha_detach(aha);
if (error) {

View File

@ -87,9 +87,9 @@ aha_mca_probe (device_t dev)
mca_id_t id = mca_get_id(dev);
uint32_t iobase = 0;
uint32_t iosize = 0;
uint8_t drq = 0;
uint8_t irq = 0;
uint8_t pos;
uint8_t drq = 0;
uint8_t irq = 0;
uint8_t pos;
desc = mca_match_id(id, aha_mca_devs);
if (!desc)
@ -117,39 +117,36 @@ static int
aha_mca_attach (device_t dev)
{
struct aha_softc * sc = device_get_softc(dev);
struct resource * io = NULL;
struct resource * irq = NULL;
struct resource * drq = NULL;
int error = 0;
int error = ENOMEM;
int unit = device_get_unit(dev);
int rid;
void * ih;
rid = 0;
io = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE);
if (!io) {
sc->portrid = 0;
sc->port = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &sc->portrid,
RF_ACTIVE);
if (sc->port == NULL) {
device_printf(dev, "No I/O space?!\n");
error = ENOMEM;
goto bad;
}
rid = 0;
irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE);
if (irq == NULL) {
sc->irqrid = 0;
sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irqrid,
RF_ACTIVE);
if (sc->irq == NULL) {
device_printf(dev, "No IRQ?!\n");
error = ENOMEM;
goto bad;
}
rid = 0;
drq = bus_alloc_resource_any(dev, SYS_RES_DRQ, &rid, RF_ACTIVE);
if (drq == NULL) {
sc->drqrid = 0;
sc->drq = bus_alloc_resource_any(dev, SYS_RES_DRQ, &sc->drqrid,
RF_ACTIVE);
if (sc->drq == NULL) {
device_printf(dev, "No DRQ?!\n");
error = ENOMEM;
goto bad;
}
aha_alloc(sc, unit, rman_get_bustag(io), rman_get_bushandle(io));
aha_alloc(sc, unit, rman_get_bustag(sc->port),
rman_get_bushandle(sc->port));
error = aha_probe(sc);
if (error) {
device_printf(dev, "aha_probe() failed!\n");
@ -162,7 +159,7 @@ aha_mca_attach (device_t dev)
goto bad;
}
isa_dmacascade(rman_get_start(drq));
isa_dmacascade(rman_get_start(sc->drq));
error = bus_dma_tag_create(
/* parent */ NULL,
@ -196,7 +193,8 @@ aha_mca_attach (device_t dev)
goto bad;
}
error = bus_setup_intr(dev, irq, INTR_TYPE_CAM|INTR_ENTROPY, aha_intr, sc, &ih);
error = bus_setup_intr(dev, sc->irq, INTR_TYPE_CAM | INTR_ENTROPY,
aha_intr, sc, &ih);
if (error) {
device_printf(dev, "Unable to register interrupt handler\n");
goto bad;
@ -206,14 +204,9 @@ aha_mca_attach (device_t dev)
bad:
aha_free(sc);
if (io)
bus_release_resource(dev, SYS_RES_IOPORT, 0, io);
if (irq)
bus_release_resource(dev, SYS_RES_IRQ, 0, irq);
if (drq)
bus_release_resource(dev, SYS_RES_DRQ, 0, drq);
bus_free_resource(dev, SYS_RES_IOPORT, sc->port);
bus_free_resource(dev, SYS_RES_IRQ, sc->irq);
bus_free_resource(dev, SYS_RES_DRQ, sc->drq);
return (error);
}

View File

@ -390,11 +390,11 @@ struct aha_softc {
char model[32];
uint8_t boardid;
struct resource *irq;
int irqrid;
struct resource *port;
int portrid;
struct resource *drq;
int drqrid;
int irqrid;
int portrid;
int drqrid;
void **ih;
device_t dev;
};