--- //depot/vendor/freebsd/src/sys/dev/aic/aic.c 2009-05-13 22:35:15.000000000 0000 +++ //depot/user/jhb/cleanup/sys/dev/aic/aic.c 2012-09-01 12:00:08.000000000 0000 @@ -28,6 +28,7 @@ __FBSDID("$FreeBSD: src/sys/dev/aic/aic.c,v 1.28 2009/05/13 22:31:25 des Exp $"); #include +#include #include #include #include @@ -36,6 +37,7 @@ #include #include +#include #include #include @@ -51,6 +53,7 @@ static void aic_action(struct cam_sim *sim, union ccb *ccb); static void aic_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error); +static void aic_intr_locked(struct aic_softc *aic); static void aic_start(struct aic_softc *aic); static void aic_select(struct aic_softc *aic); static void aic_selected(struct aic_softc *aic); @@ -71,43 +74,42 @@ devclass_t aic_devclass; -static struct aic_scb *free_scbs; - static struct aic_scb * aic_get_scb(struct aic_softc *aic) { struct aic_scb *scb; - int s = splcam(); - if ((scb = free_scbs) != NULL) - free_scbs = (struct aic_scb *)free_scbs->ccb; - splx(s); + + if (!dumping) + mtx_assert(&aic->lock, MA_OWNED); + if ((scb = SLIST_FIRST(&aic->free_scbs)) != NULL) + SLIST_REMOVE_HEAD(&aic->free_scbs, link); return (scb); } static void aic_free_scb(struct aic_softc *aic, struct aic_scb *scb) { - int s = splcam(); + + if (!dumping) + mtx_assert(&aic->lock, MA_OWNED); if ((aic->flags & AIC_RESOURCE_SHORTAGE) != 0 && (scb->ccb->ccb_h.status & CAM_RELEASE_SIMQ) == 0) { scb->ccb->ccb_h.status |= CAM_RELEASE_SIMQ; aic->flags &= ~AIC_RESOURCE_SHORTAGE; } scb->flags = 0; - scb->ccb = (union ccb *)free_scbs; - free_scbs = scb; - splx(s); + SLIST_INSERT_HEAD(&aic->free_scbs, scb, link); } static void aic_action(struct cam_sim *sim, union ccb *ccb) { struct aic_softc *aic; - int s; CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("aic_action\n")); aic = (struct aic_softc *)cam_sim_softc(sim); + mtx_assert(&aic->lock, MA_OWNED); switch (ccb->ccb_h.func_code) { case XPT_SCSI_IO: /* Execute the requested I/O operation */ @@ -116,9 +118,7 @@ struct aic_scb *scb; if ((scb = aic_get_scb(aic)) == NULL) { - s = splcam(); aic->flags |= AIC_RESOURCE_SHORTAGE; - splx(s); xpt_freeze_simq(aic->sim, /*count*/1); ccb->ccb_h.status = CAM_REQUEUE_REQ; xpt_done(ccb); @@ -175,8 +175,6 @@ struct ccb_trans_settings_spi *spi = &cts->xport_specific.spi; - s = splcam(); - if ((spi->valid & CTS_SPI_VALID_DISC) != 0 && (aic->flags & AIC_DISC_ENABLE) != 0) { if ((spi->flags & CTS_SPI_FLAGS_DISC_ENB) != 0) @@ -214,7 +212,6 @@ || (ti->goal.offset != ti->current.offset)) ti->flags |= TINFO_SDTR_NEGO; - splx(s); ccb->ccb_h.status = CAM_REQ_CMP; xpt_done(ccb); break; @@ -235,7 +232,6 @@ scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB; spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB; - s = splcam(); if ((ti->flags & TINFO_DISC_ENB) != 0) spi->flags |= CTS_SPI_FLAGS_DISC_ENB; if ((ti->flags & TINFO_TAG_ENB) != 0) @@ -248,7 +244,6 @@ spi->sync_period = ti->user.period; spi->sync_offset = ti->user.offset; } - splx(s); spi->bus_width = MSG_EXT_WDTR_BUS_8_BIT; spi->valid = CTS_SPI_VALID_SYNC_RATE @@ -311,12 +306,10 @@ struct aic_scb *scb = (struct aic_scb *)arg; union ccb *ccb = scb->ccb; struct aic_softc *aic = (struct aic_softc *)ccb->ccb_h.ccb_aic_ptr; - int s; - s = splcam(); - + if (!dumping) + mtx_assert(&aic->lock, MA_OWNED); if (ccb->ccb_h.status != CAM_REQ_INPROG) { - splx(s); aic_free_scb(aic, scb); xpt_done(ccb); return; @@ -326,11 +319,10 @@ ccb->ccb_h.status |= CAM_SIM_QUEUED; TAILQ_INSERT_TAIL(&aic->pending_ccbs, &ccb->ccb_h, sim_links.tqe); - ccb->ccb_h.timeout_ch = timeout(aic_timeout, (caddr_t)scb, - (ccb->ccb_h.timeout * hz) / 1000); + callout_reset(&scb->timer, (ccb->ccb_h.timeout * hz) / 1000, + aic_timeout, scb); aic_start(aic); - splx(s); } /* @@ -1053,7 +1045,7 @@ ("aic_done - ccb %p status %x resid %d\n", ccb, ccb->ccb_h.status, ccb->csio.resid)); - untimeout(aic_timeout, (caddr_t)scb, ccb->ccb_h.timeout_ch); + callout_stop(&scb->timer); if ((scb->flags & SCB_DEVICE_RESET) != 0 && ccb->ccb_h.func_code != XPT_RESET_DEV) { @@ -1083,9 +1075,9 @@ &pending_scb->ccb->ccb_h, sim_links.tqe); aic_done(aic, pending_scb); } else { - ccb_h->timeout_ch = - timeout(aic_timeout, (caddr_t)pending_scb, - (ccb_h->timeout * hz) / 1000); + callout_reset(&pending_scb->timer, + (ccb_h->timeout * hz) / 1000, aic_timeout, + pending_scb); ccb_h = TAILQ_NEXT(ccb_h, sim_links.tqe); } } @@ -1102,9 +1094,9 @@ &nexus_scb->ccb->ccb_h, sim_links.tqe); aic_done(aic, nexus_scb); } else { - ccb_h->timeout_ch = - timeout(aic_timeout, (caddr_t)nexus_scb, - (ccb_h->timeout * hz) / 1000); + callout_reset(&nexus_scb->timer, + (ccb_h->timeout * hz) / 1000, aic_timeout, + nexus_scb); ccb_h = TAILQ_NEXT(ccb_h, sim_links.tqe); } } @@ -1123,7 +1115,7 @@ static void aic_poll(struct cam_sim *sim) { - aic_intr(cam_sim_softc(sim)); + aic_intr_locked(cam_sim_softc(sim)); } static void @@ -1132,18 +1124,15 @@ struct aic_scb *scb = (struct aic_scb *)arg; union ccb *ccb = scb->ccb; struct aic_softc *aic = (struct aic_softc *)ccb->ccb_h.ccb_aic_ptr; - int s; + mtx_assert(&aic->lock, MA_OWNED); xpt_print_path(ccb->ccb_h.path); printf("ccb %p - timed out", ccb); if (aic->nexus && aic->nexus != scb) printf(", nexus %p", aic->nexus->ccb); printf(", phase 0x%x, state %d\n", aic_inb(aic, SCSISIGI), aic->state); - s = splcam(); - if ((scb->flags & SCB_ACTIVE) == 0) { - splx(s); xpt_print_path(ccb->ccb_h.path); printf("ccb %p - timed out already completed\n", ccb); return; @@ -1151,6 +1140,7 @@ if ((scb->flags & SCB_DEVICE_RESET) == 0 && aic->nexus == scb) { struct ccb_hdr *ccb_h = &scb->ccb->ccb_h; + struct aic_scb *pending_scb; if ((ccb_h->status & CAM_RELEASE_SIMQ) == 0) { xpt_freeze_simq(aic->sim, /*count*/1); @@ -1158,18 +1148,17 @@ } TAILQ_FOREACH(ccb_h, &aic->pending_ccbs, sim_links.tqe) { - untimeout(aic_timeout, (caddr_t)ccb_h->ccb_scb_ptr, - ccb_h->timeout_ch); + pending_scb = ccb_h->ccb_scb_ptr; + callout_stop(&pending_scb->timer); } TAILQ_FOREACH(ccb_h, &aic->nexus_ccbs, sim_links.tqe) { - untimeout(aic_timeout, (caddr_t)ccb_h->ccb_scb_ptr, - ccb_h->timeout_ch); + pending_scb = ccb_h->ccb_scb_ptr; + callout_stop(&pending_scb->timer); } scb->flags |= SCB_DEVICE_RESET; - ccb->ccb_h.timeout_ch = - timeout(aic_timeout, (caddr_t)scb, 5 * hz); + callout_reset(&scb->timer, 5 * hz, aic_timeout, scb); aic_sched_msgout(aic, MSG_BUS_DEV_RESET); } else { if (aic->nexus == scb) { @@ -1178,14 +1167,21 @@ } aic_reset(aic, /*initiate_reset*/TRUE); } - - splx(s); } void aic_intr(void *arg) { struct aic_softc *aic = (struct aic_softc *)arg; + + mtx_lock(&aic->lock); + aic_intr_locked(aic); + mtx_unlock(&aic->lock); +} + +void +aic_intr_locked(struct aic_softc *aic) +{ u_int8_t sstat0, sstat1; union ccb *ccb; struct aic_scb *scb; @@ -1434,6 +1430,7 @@ TAILQ_INIT(&aic->pending_ccbs); TAILQ_INIT(&aic->nexus_ccbs); + SLIST_INIT(&aic->free_scbs); aic->nexus = NULL; aic->state = AIC_IDLE; aic->prev_phase = -1; @@ -1481,10 +1478,10 @@ aic->max_period = AIC_SYNC_PERIOD; aic->min_period = AIC_MIN_SYNC_PERIOD; - free_scbs = NULL; for (i = 255; i >= 0; i--) { scb = &aic->scbs[i]; scb->tag = i; + callout_init_mtx(&scb->timer, &aic->lock, 0); aic_free_scb(aic, scb); } @@ -1543,14 +1540,16 @@ * Construct our SIM entry */ aic->sim = cam_sim_alloc(aic_action, aic_poll, "aic", aic, - aic->unit, &Giant, 2, 256, devq); + device_get_unit(aic->dev), &aic->lock, 2, 256, devq); if (aic->sim == NULL) { cam_simq_free(devq); return (ENOMEM); } + mtx_lock(&aic->lock); if (xpt_bus_register(aic->sim, aic->dev, 0) != CAM_SUCCESS) { cam_sim_free(aic->sim, /*free_devq*/TRUE); + mtx_unlock(&aic->lock); return (ENXIO); } @@ -1559,12 +1558,13 @@ CAM_LUN_WILDCARD) != CAM_REQ_CMP) { xpt_bus_deregister(cam_sim_path(aic->sim)); cam_sim_free(aic->sim, /*free_devq*/TRUE); + mtx_unlock(&aic->lock); return (ENXIO); } aic_init(aic); - printf("aic%d: %s", aic->unit, aic_chip_names[aic->chip_type]); + device_printf(aic->dev, "%s", aic_chip_names[aic->chip_type]); if (aic->flags & AIC_DMA_ENABLE) printf(", dma"); if (aic->flags & AIC_DISC_ENABLE) @@ -1574,15 +1574,25 @@ if (aic->flags & AIC_FAST_ENABLE) printf(", fast SCSI"); printf("\n"); + mtx_unlock(&aic->lock); return (0); } int aic_detach(struct aic_softc *aic) { + struct aic_scb *scb; + int i; + + mtx_lock(&aic->lock); xpt_async(AC_LOST_DEVICE, aic->path, NULL); xpt_free_path(aic->path); xpt_bus_deregister(cam_sim_path(aic->sim)); cam_sim_free(aic->sim, /*free_devq*/TRUE); + mtx_unlock(&aic->lock); + for (i = 255; i >= 0; i--) { + scb = &aic->scbs[i]; + callout_drain(&scb->timer); + } return (0); } --- //depot/vendor/freebsd/src/sys/dev/aic/aic_cbus.c 2007-06-17 05:59:18.000000000 0000 +++ //depot/user/jhb/cleanup/sys/dev/aic/aic_cbus.c 2012-09-01 12:00:08.000000000 0000 @@ -28,8 +28,11 @@ __FBSDID("$FreeBSD: src/sys/dev/aic/aic_cbus.c,v 1.13 2007/06/17 05:55:46 scottl Exp $"); #include +#include #include +#include #include +#include #include #include @@ -92,7 +95,7 @@ else bs_iat = aicport_generic; - sc->sc_port = sc->sc_irq = sc->sc_drq = 0; + sc->sc_port = sc->sc_irq = sc->sc_drq = NULL; rid = 0; sc->sc_port = isa_alloc_resourcev(dev, SYS_RES_IOPORT, &rid, @@ -102,6 +105,7 @@ return (ENOMEM); } isa_load_resourcev(sc->sc_port, bs_iat, AIC_ISA_PORTSIZE); + mtx_init(&sc->sc_aic.lock, "aic", NULL, MTX_DEF); if (isa_get_irq(dev) != -1) { rid = 0; @@ -126,9 +130,7 @@ } sc->sc_aic.dev = dev; - sc->sc_aic.unit = device_get_unit(dev); - sc->sc_aic.tag = rman_get_bustag(sc->sc_port); - sc->sc_aic.bsh = rman_get_bushandle(sc->sc_port); + sc->sc_aic.res = sc->sc_port; return (0); } @@ -143,7 +145,8 @@ bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq); if (sc->sc_drq) bus_release_resource(dev, SYS_RES_DRQ, 0, sc->sc_drq); - sc->sc_port = sc->sc_irq = sc->sc_drq = 0; + sc->sc_port = sc->sc_irq = sc->sc_drq = NULL; + mtx_destroy(&sc->sc_aic.lock); } static int @@ -172,10 +175,8 @@ continue; if (aic_isa_alloc_resources(dev)) continue; - if (!aic_probe(aic)) { - aic_isa_release_resources(dev); + if (aic_probe(aic) == 0) break; - } aic_isa_release_resources(dev); } @@ -183,6 +184,7 @@ return (ENXIO); porta = aic_inb(aic, PORTA); + aic_isa_release_resources(dev); if (isa_get_irq(dev) == -1) bus_set_resource(dev, SYS_RES_IRQ, 0, PORTA_IRQ(porta), 1); if ((aic->flags & AIC_DMA_ENABLE) && isa_get_drq(dev) == -1) @@ -211,8 +213,8 @@ return (error); } - error = bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_CAM|INTR_ENTROPY, - NULL, aic_intr, aic, &sc->sc_ih); + error = bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_CAM | INTR_ENTROPY | + INTR_MPSAFE, NULL, aic_intr, aic, &sc->sc_ih); if (error) { device_printf(dev, "failed to register interrupt handler\n"); aic_isa_release_resources(dev); --- //depot/vendor/freebsd/src/sys/dev/aic/aic_isa.c 2007-06-17 05:59:18.000000000 0000 +++ //depot/user/jhb/cleanup/sys/dev/aic/aic_isa.c 2012-09-01 12:00:08.000000000 0000 @@ -28,8 +28,11 @@ __FBSDID("$FreeBSD: src/sys/dev/aic/aic_isa.c,v 1.14 2007/06/17 05:55:46 scottl Exp $"); #include +#include #include +#include #include +#include #include #include @@ -69,7 +72,7 @@ struct aic_isa_softc *sc = device_get_softc(dev); int rid; - sc->sc_port = sc->sc_irq = sc->sc_drq = 0; + sc->sc_port = sc->sc_irq = sc->sc_drq = NULL; rid = 0; sc->sc_port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, @@ -102,9 +105,8 @@ } sc->sc_aic.dev = dev; - sc->sc_aic.unit = device_get_unit(dev); - sc->sc_aic.tag = rman_get_bustag(sc->sc_port); - sc->sc_aic.bsh = rman_get_bushandle(sc->sc_port); + sc->sc_aic.res = sc->sc_port; + mtx_init(&sc->sc_aic.lock, "aic", NULL, MTX_DEF); return (0); } @@ -119,7 +121,8 @@ bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq); if (sc->sc_drq) bus_release_resource(dev, SYS_RES_DRQ, 0, sc->sc_drq); - sc->sc_port = sc->sc_irq = sc->sc_drq = 0; + sc->sc_port = sc->sc_irq = sc->sc_drq = NULL; + mtx_destroy(&sc->sc_aic.lock); } static int @@ -149,10 +152,8 @@ continue; if (aic_isa_alloc_resources(dev)) continue; - if (!aic_probe(aic)) { - aic_isa_release_resources(dev); + if (aic_probe(aic) == 0) break; - } aic_isa_release_resources(dev); } @@ -160,6 +161,7 @@ return (ENXIO); porta = aic_inb(aic, PORTA); + aic_isa_release_resources(dev); if (isa_get_irq(dev) == -1) bus_set_resource(dev, SYS_RES_IRQ, 0, PORTA_IRQ(porta), 1); if ((aic->flags & AIC_DMA_ENABLE) && isa_get_drq(dev) == -1) @@ -188,8 +190,8 @@ return (error); } - error = bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_CAM|INTR_ENTROPY, - NULL, aic_intr, aic, &sc->sc_ih); + error = bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_CAM | INTR_ENTROPY | + INTR_MPSAFE, NULL, aic_intr, aic, &sc->sc_ih); if (error) { device_printf(dev, "failed to register interrupt handler\n"); aic_isa_release_resources(dev); --- //depot/vendor/freebsd/src/sys/dev/aic/aic_pccard.c 2007-06-17 05:59:18.000000000 0000 +++ //depot/user/jhb/cleanup/sys/dev/aic/aic_pccard.c 2012-09-01 12:00:08.000000000 0000 @@ -28,8 +28,11 @@ __FBSDID("$FreeBSD: src/sys/dev/aic/aic_pccard.c,v 1.20 2007/06/17 05:55:46 scottl Exp $"); #include +#include #include +#include #include +#include #include #include @@ -71,7 +74,7 @@ struct aic_pccard_softc *sc = device_get_softc(dev); int rid; - sc->sc_port = sc->sc_irq = 0; + sc->sc_port = sc->sc_irq = NULL; rid = 0; sc->sc_port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, @@ -87,9 +90,8 @@ } sc->sc_aic.dev = dev; - sc->sc_aic.unit = device_get_unit(dev); - sc->sc_aic.tag = rman_get_bustag(sc->sc_port); - sc->sc_aic.bsh = rman_get_bushandle(sc->sc_port); + sc->sc_aic.res = sc->sc_port; + mtx_init(&sc->sc_aic.lock, "aic", NULL, MTX_DEF); return (0); } @@ -102,7 +104,8 @@ bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->sc_port); if (sc->sc_irq) bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq); - sc->sc_port = sc->sc_irq = 0; + sc->sc_port = sc->sc_irq = NULL; + mtx_destroy(&sc->sc_aic.lock); } static int @@ -114,9 +117,12 @@ sizeof(aic_pccard_products[0]), NULL)) != NULL) { if (pp->pp_name != NULL) device_set_desc(dev, pp->pp_name); - return 0; + else + device_set_desc(dev, + "Adaptec 6260/6360 SCSI controller"); + return (BUS_PROBE_DEFAULT); } - return EIO; + return (ENXIO); } static int @@ -133,8 +139,6 @@ return (ENXIO); } - device_set_desc(dev, "Adaptec 6260/6360 SCSI controller"); - error = aic_attach(aic); if (error) { device_printf(dev, "attach failed\n"); @@ -142,8 +146,8 @@ return (error); } - error = bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_CAM|INTR_ENTROPY, - NULL, aic_intr, aic, &sc->sc_ih); + error = bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_CAM | INTR_ENTROPY | + INTR_MPSAFE, NULL, aic_intr, aic, &sc->sc_ih); if (error) { device_printf(dev, "failed to register interrupt handler\n"); aic_pccard_release_resources(dev); --- //depot/vendor/freebsd/src/sys/dev/aic/aicvar.h 2007-06-17 05:59:18.000000000 0000 +++ //depot/user/jhb/cleanup/sys/dev/aic/aicvar.h 2012-09-01 12:00:08.000000000 0000 @@ -47,6 +47,8 @@ struct aic_scb { union ccb *ccb; + SLIST_ENTRY(aic_scb) link; + struct callout timer; u_int8_t flags; u_int8_t tag; u_int8_t target; @@ -70,14 +72,14 @@ struct aic_softc { device_t dev; - int unit; - bus_space_tag_t tag; - bus_space_handle_t bsh; + struct mtx lock; + struct resource *res; bus_dma_tag_t dmat; struct cam_sim *sim; struct cam_path *path; TAILQ_HEAD(,ccb_hdr) pending_ccbs, nexus_ccbs; + SLIST_HEAD(,aic_scb) free_scbs; struct aic_scb *nexus; u_int32_t flags; @@ -127,32 +129,28 @@ #define AIC_SYNC_OFFSET 8 #define aic_inb(aic, port) \ - bus_space_read_1((aic)->tag, (aic)->bsh, (port)) + bus_read_1((aic)->res, (port)) #define aic_outb(aic, port, value) \ - bus_space_write_1((aic)->tag, (aic)->bsh, (port), (value)) + bus_write_1((aic)->res, (port), (value)) #define aic_insb(aic, port, addr, count) \ - bus_space_read_multi_1((aic)->tag, (aic)->bsh, (port), (addr), (count)) + bus_read_multi_1((aic)->res, (port), (addr), (count)) #define aic_outsb(aic, port, addr, count) \ - bus_space_write_multi_1((aic)->tag, (aic)->bsh, (port), (addr), (count)) + bus_write_multi_1((aic)->res, (port), (addr), (count)) #define aic_insw(aic, port, addr, count) \ - bus_space_read_multi_2((aic)->tag, (aic)->bsh, (port), \ - (u_int16_t *)(addr), (count)) + bus_read_multi_2((aic)->res, (port), (u_int16_t *)(addr), (count)) #define aic_outsw(aic, port, addr, count) \ - bus_space_write_multi_2((aic)->tag, (aic)->bsh, (port), \ - (u_int16_t *)(addr), (count)) + bus_write_multi_2((aic)->res, (port), (u_int16_t *)(addr), (count)) #define aic_insl(aic, port, addr, count) \ - bus_space_read_multi_4((aic)->tag, (aic)->bsh, (port), \ - (u_int32_t *)(addr), (count)) + bus_read_multi_4((aic)->res, (port), (u_int32_t *)(addr), (count)) #define aic_outsl(aic, port, addr, count) \ - bus_space_write_multi_4((aic)->tag, (aic)->bsh, (port), \ - (u_int32_t *)(addr), (count)) + bus_write_multi_4((aic)->res, (port), (u_int32_t *)(addr), (count)) extern int aic_probe(struct aic_softc *); extern int aic_attach(struct aic_softc *);