Author: jhb
Date: Mon Oct 15 16:09:59 2012
New Revision: 241591
URL: http://svn.freebsd.org/changeset/base/241591

Log:
  Add locking to the aic(4) driver and mark it MPSAFE.
  - Move 'free_scbs' into the softc rather than having it be a global list
    and convert it to an SLIST instead of a hand-rolled linked-list.
  - Use device_printf() and device_get_unit() instead of storing the unit
    number in the softc.
  - Remove use of explicit bus space handles and tags.
  - Don't call device_set_desc() in the pccard attach routine, instead
    set a default description during the pccard probe if the matching
    product doesn't have a name.
  
  Tested by:    no one

Modified:
  head/sys/dev/aic/aic.c
  head/sys/dev/aic/aic_cbus.c
  head/sys/dev/aic/aic_isa.c
  head/sys/dev/aic/aic_pccard.c
  head/sys/dev/aic/aicvar.h

Modified: head/sys/dev/aic/aic.c
==============================================================================
--- head/sys/dev/aic/aic.c      Mon Oct 15 16:05:02 2012        (r241590)
+++ head/sys/dev/aic/aic.c      Mon Oct 15 16:09:59 2012        (r241591)
@@ -28,6 +28,7 @@
 __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
+#include <sys/conf.h>
 #include <sys/systm.h>
 #include <sys/kernel.h>
 #include <sys/lock.h>
@@ -36,6 +37,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/bus.h>
 
 #include <machine/bus.h>
+#include <sys/rman.h>
 
 #include <cam/cam.h>
 #include <cam/cam_ccb.h>
@@ -51,6 +53,7 @@ __FBSDID("$FreeBSD$");
 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 @@ static void aic_reset(struct aic_softc *
 
 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 @@ aic_action(struct cam_sim *sim, union cc
                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 @@ aic_action(struct cam_sim *sim, union cc
                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 @@ aic_action(struct cam_sim *sim, union cc
                 || (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 @@ aic_action(struct cam_sim *sim, union cc
                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 @@ aic_action(struct cam_sim *sim, union cc
                        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 @@ aic_execute_scb(void *arg, bus_dma_segme
        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 @@ aic_execute_scb(void *arg, bus_dma_segme
        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(struct aic_softc *aic, struct a
                  ("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 @@ aic_done(struct aic_softc *aic, struct a
                                    &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 @@ aic_done(struct aic_softc *aic, struct a
                                    &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 @@ aic_done(struct aic_softc *aic, struct a
 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 @@ aic_timeout(void *arg)
        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 @@ aic_timeout(void *arg)
 
        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 @@ aic_timeout(void *arg)
                }
 
                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_timeout(void *arg)
                }
                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 @@ aic_init(struct aic_softc *aic)
 
        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_init(struct aic_softc *aic)
                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 @@ aic_attach(struct aic_softc *aic)
         * 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 @@ aic_attach(struct aic_softc *aic)
                            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 @@ aic_attach(struct aic_softc *aic)
        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);
 }

Modified: head/sys/dev/aic/aic_cbus.c
==============================================================================
--- head/sys/dev/aic/aic_cbus.c Mon Oct 15 16:05:02 2012        (r241590)
+++ head/sys/dev/aic/aic_cbus.c Mon Oct 15 16:09:59 2012        (r241591)
@@ -28,8 +28,11 @@
 __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
+#include <sys/callout.h>
 #include <sys/kernel.h>
+#include <sys/lock.h>
 #include <sys/module.h>
+#include <sys/mutex.h>
 #include <sys/bus.h>
 
 #include <machine/bus.h>
@@ -92,7 +95,7 @@ aic_isa_alloc_resources(device_t dev)
        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 @@ aic_isa_alloc_resources(device_t dev)
                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 @@ aic_isa_alloc_resources(device_t dev)
        }
 
        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 @@ aic_isa_release_resources(device_t dev)
                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 @@ aic_isa_probe(device_t dev)
                        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 @@ aic_isa_probe(device_t dev)
                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 @@ aic_isa_attach(device_t dev)
                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);

Modified: head/sys/dev/aic/aic_isa.c
==============================================================================
--- head/sys/dev/aic/aic_isa.c  Mon Oct 15 16:05:02 2012        (r241590)
+++ head/sys/dev/aic/aic_isa.c  Mon Oct 15 16:09:59 2012        (r241591)
@@ -28,8 +28,11 @@
 __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
+#include <sys/callout.h>
 #include <sys/kernel.h>
+#include <sys/lock.h>
 #include <sys/module.h>
+#include <sys/mutex.h>
 #include <sys/bus.h>
 
 #include <machine/bus.h>
@@ -69,7 +72,7 @@ aic_isa_alloc_resources(device_t dev)
        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 @@ aic_isa_alloc_resources(device_t dev)
        }
 
        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 @@ aic_isa_release_resources(device_t dev)
                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 @@ aic_isa_probe(device_t dev)
                        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 @@ aic_isa_probe(device_t dev)
                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 @@ aic_isa_attach(device_t dev)
                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);

Modified: head/sys/dev/aic/aic_pccard.c
==============================================================================
--- head/sys/dev/aic/aic_pccard.c       Mon Oct 15 16:05:02 2012        
(r241590)
+++ head/sys/dev/aic/aic_pccard.c       Mon Oct 15 16:09:59 2012        
(r241591)
@@ -28,8 +28,11 @@
 __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
+#include <sys/callout.h>
 #include <sys/kernel.h>
+#include <sys/lock.h>
 #include <sys/module.h>
+#include <sys/mutex.h>
 #include <sys/bus.h>
 
 #include <machine/bus.h>
@@ -71,7 +74,7 @@ aic_pccard_alloc_resources(device_t dev)
        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 @@ aic_pccard_alloc_resources(device_t dev)
        }
 
        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 @@ aic_pccard_release_resources(device_t de
                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 @@ aic_pccard_probe(device_t dev)
            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 @@ aic_pccard_attach(device_t dev)
                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 @@ aic_pccard_attach(device_t dev)
                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);

Modified: head/sys/dev/aic/aicvar.h
==============================================================================
--- head/sys/dev/aic/aicvar.h   Mon Oct 15 16:05:02 2012        (r241590)
+++ head/sys/dev/aic/aicvar.h   Mon Oct 15 16:09:59 2012        (r241591)
@@ -47,6 +47,8 @@ struct aic_tinfo {
 
 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 @@ enum { AIC6260, AIC6360, AIC6370, GM82C7
 
 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 @@ struct aic_softc {
 #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 *);
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to