Simplify aha resource management, and fix a few bugs in unwinding
error cases.
This commit is contained in:
parent
3e996cd639
commit
f911a9b324
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user