diff options
author | imp <imp@FreeBSD.org> | 2005-01-19 06:54:10 +0000 |
---|---|---|
committer | imp <imp@FreeBSD.org> | 2005-01-19 06:54:10 +0000 |
commit | 387b96fb2c80766278f4bc7046cd1be28d7db180 (patch) | |
tree | baa76a9aef1391bbdc18671711168f6dec3809c7 /sys/dev/aha | |
parent | 4a464d3b435ff2839d13677f2d2b9e73a3f2cc92 (diff) | |
download | FreeBSD-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.c | 64 | ||||
-rw-r--r-- | sys/dev/aha/aha_mca.c | 55 | ||||
-rw-r--r-- | sys/dev/aha/ahareg.h | 6 |
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; }; |