summaryrefslogtreecommitdiffstats
path: root/sys/dev/aha
diff options
context:
space:
mode:
authorimp <imp@FreeBSD.org>2005-01-19 06:54:10 +0000
committerimp <imp@FreeBSD.org>2005-01-19 06:54:10 +0000
commit387b96fb2c80766278f4bc7046cd1be28d7db180 (patch)
treebaa76a9aef1391bbdc18671711168f6dec3809c7 /sys/dev/aha
parent4a464d3b435ff2839d13677f2d2b9e73a3f2cc92 (diff)
downloadFreeBSD-src-387b96fb2c80766278f4bc7046cd1be28d7db180.zip
FreeBSD-src-387b96fb2c80766278f4bc7046cd1be28d7db180.tar.gz
Simplify aha resource management, and fix a few bugs in unwinding
error cases.
Diffstat (limited to 'sys/dev/aha')
-rw-r--r--sys/dev/aha/aha_isa.c64
-rw-r--r--sys/dev/aha/aha_mca.c55
-rw-r--r--sys/dev/aha/ahareg.h6
3 files changed, 51 insertions, 74 deletions
diff --git a/sys/dev/aha/aha_isa.c b/sys/dev/aha/aha_isa.c
index 4ff3450..177b5cd 100644
--- a/sys/dev/aha/aha_isa.c
+++ b/sys/dev/aha/aha_isa.c
@@ -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) {
diff --git a/sys/dev/aha/aha_mca.c b/sys/dev/aha/aha_mca.c
index 69fcf14..81f1064 100644
--- a/sys/dev/aha/aha_mca.c
+++ b/sys/dev/aha/aha_mca.c
@@ -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);
}
diff --git a/sys/dev/aha/ahareg.h b/sys/dev/aha/ahareg.h
index c5b61f8..a248caa 100644
--- a/sys/dev/aha/ahareg.h
+++ b/sys/dev/aha/ahareg.h
@@ -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;
};
OpenPOWER on IntegriCloud