--- //depot/vendor/freebsd/src/sys/dev/aha/aha.c 2008-08-10 15:15:14.000000000 0000 +++ //depot/user/jhb/cleanup/sys/dev/aha/aha.c 2012-08-31 03:53:47.000000000 0000 @@ -147,6 +147,7 @@ static bus_dmamap_callback_t ahaexecuteccb; static void ahadone(struct aha_softc *aha, struct aha_ccb *accb, aha_mbi_comp_code_t comp_code); +static void aha_intr_locked(struct aha_softc *aha); /* Host adapter command functions */ static int ahareset(struct aha_softc* aha, int hard_reset); @@ -168,7 +169,7 @@ static void ahapoll(struct cam_sim *sim); /* Our timeout handler */ -static timeout_t ahatimeout; +static void ahatimeout(void *arg); /* Exported functions */ void @@ -179,11 +180,9 @@ SLIST_INIT(&aha->free_aha_ccbs); LIST_INIT(&aha->pending_ccbs); SLIST_INIT(&aha->sg_maps); - aha->unit = unit; - aha->tag = tag; - aha->bsh = bsh; aha->ccb_sg_opcode = INITIATOR_SG_CCB_WRESID; aha->ccb_ccb_opcode = INITIATOR_CCB_WRESID; + mtx_init(&aha->lock, "aha", NULL, MTX_DEF); } void @@ -225,6 +224,7 @@ case 0: break; } + mtx_destroy(&aha->lock); } /* @@ -464,7 +464,7 @@ /* maxsegsz */ BUS_SPACE_MAXSIZE_24BIT, /* flags */ BUS_DMA_ALLOCNOW, /* lockfunc */ busdma_lock_mutex, - /* lockarg */ &Giant, + /* lockarg */ &aha->lock, &aha->buffer_dmat) != 0) { goto error_exit; } @@ -484,8 +484,8 @@ /* nsegments */ 1, /* maxsegsz */ BUS_SPACE_MAXSIZE_24BIT, /* flags */ 0, - /* lockfunc */ busdma_lock_mutex, - /* lockarg */ &Giant, + /* lockfunc */ NULL, + /* lockarg */ NULL, &aha->mailbox_dmat) != 0) { goto error_exit; } @@ -523,8 +523,8 @@ /* nsegments */ 1, /* maxsegsz */ BUS_SPACE_MAXSIZE_24BIT, /* flags */ 0, - /* lockfunc */ busdma_lock_mutex, - /* lockarg */ &Giant, + /* lockfunc */ NULL, + /* lockarg */ NULL, &aha->ccb_dmat) != 0) { goto error_exit; } @@ -556,8 +556,8 @@ /* nsegments */ 1, /* maxsegsz */ BUS_SPACE_MAXSIZE_24BIT, /* flags */ 0, - /* lockfunc */ busdma_lock_mutex, - /* lockarg */ &Giant, + /* lockfunc */ NULL, + /* lockarg */ NULL, &aha->sg_dmat) != 0) goto error_exit; @@ -605,22 +605,27 @@ /* * Construct our SIM entry */ - aha->sim = cam_sim_alloc(ahaaction, ahapoll, "aha", aha, aha->unit, - &Giant, 2, tagged_dev_openings, devq); + aha->sim = cam_sim_alloc(ahaaction, ahapoll, "aha", aha, + device_get_unit(aha->dev), &aha->lock, 2, tagged_dev_openings, + devq); if (aha->sim == NULL) { cam_simq_free(devq); return (ENOMEM); } + mtx_lock(&aha->lock); if (xpt_bus_register(aha->sim, aha->dev, 0) != CAM_SUCCESS) { cam_sim_free(aha->sim, /*free_devq*/TRUE); + mtx_unlock(&aha->lock); return (ENXIO); } if (xpt_create_path(&aha->path, /*periph*/NULL, cam_sim_path(aha->sim), CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { xpt_bus_deregister(cam_sim_path(aha->sim)); cam_sim_free(aha->sim, /*free_devq*/TRUE); + mtx_unlock(&aha->lock); return (ENXIO); } + mtx_unlock(&aha->lock); return (0); } @@ -664,6 +669,7 @@ next_ccb->sg_list = segs; next_ccb->sg_list_phys = physaddr; next_ccb->flags = ACCB_FREE; + callout_init_mtx(&next_ccb->timer, &aha->lock, 0); error = bus_dmamap_create(aha->buffer_dmat, /*flags*/0, &next_ccb->dmamap); if (error != 0) @@ -685,9 +691,9 @@ static __inline void ahafreeccb(struct aha_softc *aha, struct aha_ccb *accb) { - int s; - s = splcam(); + if (!dumping) + mtx_assert(&aha->lock, MA_OWNED); if ((accb->flags & ACCB_ACTIVE) != 0) LIST_REMOVE(&accb->ccb->ccb_h, sim_links.le); if (aha->resource_shortage != 0 @@ -698,16 +704,15 @@ accb->flags = ACCB_FREE; SLIST_INSERT_HEAD(&aha->free_aha_ccbs, accb, links); aha->active_ccbs--; - splx(s); } static struct aha_ccb* ahagetccb(struct aha_softc *aha) { struct aha_ccb* accb; - int s; - s = splcam(); + if (!dumping) + mtx_assert(&aha->lock, MA_OWNED); if ((accb = SLIST_FIRST(&aha->free_aha_ccbs)) != NULL) { SLIST_REMOVE_HEAD(&aha->free_aha_ccbs, links); aha->active_ccbs++; @@ -721,7 +726,6 @@ aha->active_ccbs++; } } - splx(s); return (accb); } @@ -730,11 +734,11 @@ ahaaction(struct cam_sim *sim, union ccb *ccb) { struct aha_softc *aha; - int s; CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("ahaaction\n")); aha = (struct aha_softc *)cam_sim_softc(sim); + mtx_assert(&aha->lock, MA_OWNED); switch (ccb->ccb_h.func_code) { /* Common cases first */ @@ -747,9 +751,7 @@ * Get an accb to use. */ if ((accb = ahagetccb(aha)) == NULL) { - s = splcam(); aha->resource_shortage = TRUE; - splx(s); xpt_freeze_simq(aha->sim, /*count*/1); ccb->ccb_h.status = CAM_REQUEUE_REQ; xpt_done(ccb); @@ -818,7 +820,6 @@ if ((ccbh->flags & CAM_DATA_PHYS)==0) { int error; - s = splsoftvm(); error = bus_dmamap_load( aha->buffer_dmat, accb->dmamap, @@ -840,7 +841,6 @@ csio->ccb_h.status |= CAM_RELEASE_SIMQ; } - splx(s); } else { struct bus_dma_segment seg; @@ -1017,7 +1017,6 @@ struct aha_ccb *accb; union ccb *ccb; struct aha_softc *aha; - int s; uint32_t paddr; accb = (struct aha_ccb *)arg; @@ -1077,8 +1076,6 @@ ahautoa24(0, accb->hccb.data_addr); } - s = splcam(); - /* * Last time we need to check if this CCB needs to * be aborted. @@ -1088,7 +1085,6 @@ bus_dmamap_unload(aha->buffer_dmat, accb->dmamap); ahafreeccb(aha, accb); xpt_done(ccb); - splx(s); return; } @@ -1096,8 +1092,8 @@ ccb->ccb_h.status |= CAM_SIM_QUEUED; LIST_INSERT_HEAD(&aha->pending_ccbs, &ccb->ccb_h, sim_links.le); - ccb->ccb_h.timeout_ch = timeout(ahatimeout, (caddr_t)accb, - (ccb->ccb_h.timeout * hz) / 1000); + callout_reset(&accb->timer, (ccb->ccb_h.timeout * hz) / 1000, + ahatimeout, accb); /* Tell the adapter about this command */ if (aha->cur_outbox->action_code != AMBO_FREE) { @@ -1111,7 +1107,7 @@ device_printf(aha->dev, "Encountered busy mailbox with %d out of %d " "commands active!!!", aha->active_ccbs, aha->max_ccbs); - untimeout(ahatimeout, accb, ccb->ccb_h.timeout_ch); + callout_stop(&aacb->timer); if (nseg != 0) bus_dmamap_unload(aha->buffer_dmat, accb->dmamap); ahafreeccb(aha, accb); @@ -1127,17 +1123,25 @@ aha_outb(aha, COMMAND_REG, AOP_START_MBOX); ahanextoutbox(aha); - splx(s); } void aha_intr(void *arg) { struct aha_softc *aha; + + aha = arg; + mtx_lock(&aha->lock); + aha_intr_locked(aha); + mtx_unlock(&aha->lock); +} + +void +aha_intr_locked(struct aha_softc *aha) +{ u_int intstat; uint32_t paddr; - aha = (struct aha_softc *)arg; while (((intstat = aha_inb(aha, INTSTAT_REG)) & INTR_PENDING) != 0) { if ((intstat & CMD_COMPLETE) != 0) { aha->latched_status = aha_inb(aha, STATUS_REG); @@ -1220,9 +1224,9 @@ ccb_h = LIST_NEXT(ccb_h, sim_links.le); ahadone(aha, pending_accb, AMBI_ERROR); } else { - ccb_h->timeout_ch = timeout(ahatimeout, - (caddr_t)pending_accb, - (ccb_h->timeout * hz) / 1000); + callout_reset(&pending_accb->timer, + (ccb_h->timeout * hz) / 1000, + ahatimeout, pending_accb); ccb_h = LIST_NEXT(ccb_h, sim_links.le); } } @@ -1230,7 +1234,7 @@ return; } - untimeout(ahatimeout, accb, ccb->ccb_h.timeout_ch); + callout_stop(&accb->timer); switch (comp_code) { case AMBI_FREE: @@ -1446,7 +1450,6 @@ u_int saved_status; u_int intstat; u_int reply_buf_size; - int s; int cmd_complete; int error; @@ -1465,15 +1468,11 @@ * and wait for all completions to occur if necessary. */ timeout = 10000; - s = splcam(); while (LIST_FIRST(&aha->pending_ccbs) != NULL && --timeout) { /* Fire the interrupt handler in case interrupts are blocked */ aha_intr(aha); - splx(s); DELAY(10); - s = splcam(); } - splx(s); if (timeout == 0) { device_printf(aha->dev, @@ -1516,10 +1515,8 @@ timeout = 10000; while (param_len && --timeout) { DELAY(100); - s = splcam(); status = aha_inb(aha, STATUS_REG); intstat = aha_inb(aha, INTSTAT_REG); - splx(s); if ((intstat & (INTR_PENDING|CMD_COMPLETE)) == (INTR_PENDING|CMD_COMPLETE)) { @@ -1553,10 +1550,8 @@ */ while (cmd_complete == 0 && --cmd_timeout) { - s = splcam(); status = aha_inb(aha, STATUS_REG); intstat = aha_inb(aha, INTSTAT_REG); - splx(s); if (aha->command_cmp != 0) { cmd_complete = 1; @@ -1601,9 +1596,7 @@ * Clear any pending interrupts. Block interrupts so our * interrupt handler is not re-entered. */ - s = splcam(); aha_intr(aha); - splx(s); if (error != 0) return (error); @@ -1764,7 +1757,7 @@ static void ahapoll(struct cam_sim *sim) { - aha_intr(cam_sim_softc(sim)); + aha_intr_locked(cam_sim_softc(sim)); } static void @@ -1773,23 +1766,20 @@ struct aha_ccb *accb; union ccb *ccb; struct aha_softc *aha; - int s; uint32_t paddr; struct ccb_hdr *ccb_h; accb = (struct aha_ccb *)arg; ccb = accb->ccb; aha = (struct aha_softc *)ccb->ccb_h.ccb_aha_ptr; + mtx_assert(&aha->lock, MA_OWNED); xpt_print_path(ccb->ccb_h.path); printf("CCB %p - timed out\n", (void *)accb); - s = splcam(); - if ((accb->flags & ACCB_ACTIVE) == 0) { xpt_print_path(ccb->ccb_h.path); printf("CCB %p - timed out CCB already completed\n", (void *)accb); - splx(s); return; } @@ -1814,7 +1804,7 @@ struct aha_ccb *pending_accb; pending_accb = (struct aha_ccb *)ccb_h->ccb_accb_ptr; - untimeout(ahatimeout, pending_accb, ccb_h->timeout_ch); + callout_stop(&pending_accb->timer); ccb_h = LIST_NEXT(ccb_h, sim_links.le); } } @@ -1843,7 +1833,7 @@ * later which will attempt a bus reset. */ accb->flags |= ACCB_DEVICE_RESET; - ccb->ccb_h.timeout_ch = timeout(ahatimeout, (caddr_t)accb, 2 * hz); + callout_reset(&aacb->timer, 2 * hz, ahatimeout, accb); aha->recovery_accb->hccb.opcode = INITIATOR_BUS_DEV_RESET; /* No Data Transfer */ @@ -1860,17 +1850,18 @@ aha_outb(aha, COMMAND_REG, AOP_START_MBOX); ahanextoutbox(aha); } - - splx(s); } int aha_detach(struct aha_softc *aha) { + mtx_lock(&aha->lock); xpt_async(AC_LOST_DEVICE, aha->path, NULL); xpt_free_path(aha->path); xpt_bus_deregister(cam_sim_path(aha->sim)); cam_sim_free(aha->sim, /*free_devq*/TRUE); + mtx_unlock(&aha->lock); + /* XXX: Drain all timers? */ return (0); } MODULE_DEPEND(aha, cam, 1, 1, 1); --- //depot/vendor/freebsd/src/sys/dev/aha/aha_isa.c 2008-10-08 00:02:42.000000000 0000 +++ //depot/user/jhb/cleanup/sys/dev/aha/aha_isa.c 2012-08-31 03:53:47.000000000 0000 @@ -109,7 +109,6 @@ struct aha_softc *aha = device_get_softc(dev); int error; u_long port_start; - struct resource *port_res; int port_rid; int drq; int irq; @@ -121,20 +120,19 @@ return (ENXIO); port_rid = 0; - port_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &port_rid, - 0, ~0, AHA_NREGS, RF_ACTIVE); + aha->port = bus_alloc_resource(dev, SYS_RES_IOPORT, &port_rid, + 0ul, ~0ul, AHA_NREGS, RF_ACTIVE); - if (port_res == NULL) + if (aha->port == NULL) return (ENXIO); port_start = rman_get_start(port_res); - aha_alloc(aha, device_get_unit(dev), rman_get_bustag(port_res), - rman_get_bushandle(port_res)); + aha_alloc(aha); /* See if there is really a card present */ if (aha_probe(aha) || aha_fetch_adapter_info(aha)) { aha_free(aha); - bus_release_resource(dev, SYS_RES_IOPORT, port_rid, port_res); + bus_release_resource(dev, SYS_RES_IOPORT, port_rid, aha->port); return (ENXIO); } @@ -151,11 +149,12 @@ (uintmax_t)port_start); aha_free(aha); bus_release_resource(dev, SYS_RES_IOPORT, port_rid, - port_res); + aha->port); return (ENXIO); } - bus_release_resource(dev, SYS_RES_IOPORT, port_rid, port_res); + bus_release_resource(dev, SYS_RES_IOPORT, port_rid, aha->port); + aha->port = NULL; switch (config_data.dma_chan) { case DMA_CHAN_5: @@ -188,17 +187,12 @@ aha_isa_attach(device_t dev) { struct aha_softc *aha = device_get_softc(dev); - bus_dma_filter_t *filter; - void *filter_arg; - bus_addr_t lowaddr; - void *ih; int error = ENOMEM; - int aha_free_needed = 0; aha->dev = dev; aha->portrid = 0; aha->port = bus_alloc_resource(dev, SYS_RES_IOPORT, &aha->portrid, - 0, ~0, AHA_NREGS, RF_ACTIVE); + 0ul, ~0ul, AHA_NREGS, RF_ACTIVE); if (!aha->port) { device_printf(dev, "Unable to allocate I/O ports\n"); goto fail; @@ -227,23 +221,19 @@ isa_dmacascade(rman_get_start(aha->drq)); /* Allocate our parent dmatag */ - filter = NULL; - filter_arg = NULL; - lowaddr = BUS_SPACE_MAXADDR_24BIT; - if (bus_dma_tag_create( /* parent */ bus_get_dma_tag(dev), /* alignemnt */ 1, /* boundary */ 0, - /* lowaddr */ lowaddr, + /* lowaddr */ BUS_SPACE_MAXADDR_24BIT, /* highaddr */ BUS_SPACE_MAXADDR, - /* filter */ filter, - /* filterarg */ filter_arg, + /* filter */ NULL, + /* filterarg */ NULL, /* maxsize */ BUS_SPACE_MAXSIZE_24BIT, /* nsegments */ ~0, /* maxsegsz */ BUS_SPACE_MAXSIZE_24BIT, /* flags */ 0, - /* lockfunc */ busdma_lock_mutex, - /* lockarg */ &Giant, + /* lockfunc */ NULL, + /* lockarg */ NULL, &aha->parent_dmat) != 0) { device_printf(dev, "dma tag create failed.\n"); goto fail; @@ -263,7 +253,6 @@ aha->ccb_sg_opcode = INITIATOR_SG_CCB; aha->ccb_ccb_opcode = INITIATOR_CCB; } - aha_free_needed++; error = aha_attach(aha); if (error) { @@ -271,10 +260,11 @@ goto fail; } - error = bus_setup_intr(dev, aha->irq, INTR_TYPE_CAM|INTR_ENTROPY, - NULL, aha_intr, aha, &ih); + error = bus_setup_intr(dev, aha->irq, INTR_TYPE_CAM|INTR_ENTROPY| + INTR_MPSAFE, NULL, aha_intr, aha, &aha->ih); if (error) { device_printf(dev, "Unable to register interrupt handler\n"); + aha_detach(aha); goto fail; } @@ -283,8 +273,7 @@ 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); + aha_free(aha); return (error); } @@ -298,15 +287,15 @@ if (error) device_printf(dev, "failed to unregister interrupt handler\n"); - 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) { device_printf(dev, "detach failed\n"); return (error); } + 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); + aha_free(aha); return (0); @@ -319,7 +308,6 @@ bus_addr_t ioport; struct aha_softc aha; int rid; - struct resource *res; device_t child; /* Attempt to find an adapter */ @@ -334,12 +322,11 @@ * XXX kldload/kldunload. */ rid = 0; - res = bus_alloc_resource(parent, SYS_RES_IOPORT, &rid, + aha->port = bus_alloc_resource(parent, SYS_RES_IOPORT, &rid, ioport, ioport, AHA_NREGS, RF_ACTIVE); - if (res == NULL) + if (aha->port == NULL) continue; - aha_alloc(&aha, -1, rman_get_bustag(res), - rman_get_bushandle(res)); + aha_alloc(&aha); /* See if there is really a card present */ if (aha_probe(&aha) || aha_fetch_adapter_info(&aha)) goto not_this_one; @@ -350,7 +337,7 @@ * that. */ not_this_one:; - bus_release_resource(parent, SYS_RES_IOPORT, rid, res); + bus_release_resource(parent, SYS_RES_IOPORT, rid, aha->port); aha_free(&aha); } } --- //depot/vendor/freebsd/src/sys/dev/aha/aha_mca.c 2008-10-08 00:02:42.000000000 0000 +++ //depot/user/jhb/cleanup/sys/dev/aha/aha_mca.c 2012-08-31 03:53:47.000000000 0000 @@ -118,8 +118,6 @@ { struct aha_softc * sc = device_get_softc(dev); int error = ENOMEM; - int unit = device_get_unit(dev); - void * ih; sc->portrid = 0; sc->port = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &sc->portrid, @@ -145,8 +143,7 @@ goto bad; } - aha_alloc(sc, unit, rman_get_bustag(sc->port), - rman_get_bushandle(sc->port)); + aha_alloc(sc); error = aha_probe(sc); if (error) { device_printf(dev, "aha_probe() failed!\n"); @@ -173,8 +170,8 @@ /* nsegments */ ~0, /* maxsegsz */ BUS_SPACE_MAXSIZE_24BIT, /* flags */ 0, - /* lockfunc */ busdma_lock_mutex, - /* lockarg */ &Giant, + /* lockfunc */ NULL, + /* lockarg */ NULL, &sc->parent_dmat); if (error) { device_printf(dev, "bus_dma_tag_create() failed!\n"); @@ -193,20 +190,21 @@ goto bad; } - error = bus_setup_intr(dev, sc->irq, INTR_TYPE_CAM | INTR_ENTROPY, - NULL, aha_intr, sc, &ih); + error = bus_setup_intr(dev, sc->irq, INTR_TYPE_CAM | INTR_ENTROPY | + INTR_MPSAFE, NULL, aha_intr, sc, &aha->ih); if (error) { device_printf(dev, "Unable to register interrupt handler\n"); + aha_detach(sc); goto bad; } return (0); bad: - aha_free(sc); 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); + aha_free(sc); return (error); } --- //depot/vendor/freebsd/src/sys/dev/aha/ahareg.h 2006-11-09 02:22:25.000000000 0000 +++ //depot/user/jhb/cleanup/sys/dev/aha/ahareg.h 2012-08-31 03:53:47.000000000 0000 @@ -297,6 +297,7 @@ uint32_t flags; union ccb *ccb; bus_dmamap_t dmamap; + struct callout timer; aha_sg_t *sg_list; uint32_t sg_list_phys; }; @@ -309,8 +310,6 @@ }; struct aha_softc { - bus_space_tag_t tag; - bus_space_handle_t bsh; struct cam_sim *sim; struct cam_path *path; aha_mbox_out_t *cur_outbox; @@ -368,11 +367,12 @@ struct resource *irq; struct resource *port; struct resource *drq; - int irqrid; - int portrid; - int drqrid; + int irqrid; + int portrid; + int drqrid; void **ih; device_t dev; + struct mtx lock; }; void aha_alloc(struct aha_softc *, int, bus_space_tag_t, bus_space_handle_t); @@ -390,10 +390,10 @@ #define DEFAULT_CMD_TIMEOUT 10000 /* 1 sec */ #define aha_inb(aha, port) \ - bus_space_read_1((aha)->tag, (aha)->bsh, port) + bus_read_1((aha)->port, port) #define aha_outb(aha, port, value) \ - bus_space_write_1((aha)->tag, (aha)->bsh, port, value) + bus_write_1((aha)->port, port, value) #define ADP0100_PNP 0x00019004 /* ADP0100 */ #define AHA1540_PNP 0x40159004 /* ADP1540 */