Author: jhb
Date: Mon Oct 15 16:29:08 2012
New Revision: 241593
URL: http://svn.freebsd.org/changeset/base/241593

Log:
  Add locking to the dpt(4) driver and mark it MPSAFE.
  - 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.
  - Remove the global dpt_softcs list and use devclass_get_device() instead.
  - Use pci_enable_busmaster() rather than frobbing the PCI command register
    directly.
  
  Tested by:    no one

Modified:
  head/sys/dev/dpt/dpt.h
  head/sys/dev/dpt/dpt_eisa.c
  head/sys/dev/dpt/dpt_isa.c
  head/sys/dev/dpt/dpt_pci.c
  head/sys/dev/dpt/dpt_scsi.c

Modified: head/sys/dev/dpt/dpt.h
==============================================================================
--- head/sys/dev/dpt/dpt.h      Mon Oct 15 16:13:55 2012        (r241592)
+++ head/sys/dev/dpt/dpt.h      Mon Oct 15 16:29:08 2012        (r241593)
@@ -876,6 +876,7 @@ typedef enum {
 typedef struct dpt_ccb {
        eata_ccb_t       eata_ccb;
        bus_dmamap_t     dmamap;
+       struct callout   timer;
        dpt_sg_t        *sg_list;
        u_int32_t        sg_busaddr;
        dccb_state       state;
@@ -1017,6 +1018,7 @@ struct sg_map_node {
 /* Main state machine and interface structure */
 typedef struct dpt_softc {
        device_t                dev;
+       struct mtx              lock;
 
        struct resource *       io_res;
        int                     io_rid;
@@ -1030,8 +1032,6 @@ typedef struct dpt_softc {
        struct resource *       drq_res;
        int                     drq_rid;
 
-       bus_space_tag_t    tag;
-       bus_space_handle_t bsh;
        bus_dma_tag_t      buffer_dmat;         /* dmat for buffer I/O */
        dpt_ccb_t         *dpt_dccbs;           /* Array of dpt ccbs */
        bus_addr_t         dpt_ccb_busbase;     /* phys base address of array */
@@ -1079,7 +1079,6 @@ typedef struct dpt_softc {
        u_int8_t  dma_channel;
 
        TAILQ_ENTRY(dpt_softc) links;
-       int       unit;
        int       init_level;
 
        /*
@@ -1275,9 +1274,6 @@ dpt_time_delta(struct timeval start,
             (end.tv_usec - start.tv_usec) );
 }
 
-extern TAILQ_HEAD(dpt_softc_list, dpt_softc) dpt_softcs;
-
-extern int             dpt_controllers_present;
 extern devclass_t      dpt_devclass;
 
 #ifdef _KERNEL

Modified: head/sys/dev/dpt/dpt_eisa.c
==============================================================================
--- head/sys/dev/dpt/dpt_eisa.c Mon Oct 15 16:13:55 2012        (r241592)
+++ head/sys/dev/dpt/dpt_eisa.c Mon Oct 15 16:29:08 2012        (r241593)
@@ -105,11 +105,11 @@ static int
 dpt_eisa_attach (device_t dev)
 {
        dpt_softc_t *   dpt;
-       int             s;
        int             error = 0;
 
        dpt = device_get_softc(dev);
        dpt->dev = dev;
+       dpt_alloc(dev);
 
        dpt->io_rid = 0;
        dpt->io_type = SYS_RES_IOPORT;
@@ -120,11 +120,8 @@ dpt_eisa_attach (device_t dev)
                goto bad;
        }
 
-       dpt_alloc(dev);
-
        /* Allocate a dmatag representing the capabilities of this attachment */
-       /* XXX Should be a child of the EISA bus dma tag */
-       if (bus_dma_tag_create( /* parent    */ NULL,
+       if (bus_dma_tag_create( /* parent    */ bus_get_dma_tag(dev),
                                /* alignemnt */ 1,
                                /* boundary  */ 0,
                                /* lowaddr   */ BUS_SPACE_MAXADDR_32BIT,
@@ -135,17 +132,14 @@ dpt_eisa_attach (device_t dev)
                                /* nsegments */ ~0,
                                /* maxsegsz  */ BUS_SPACE_MAXSIZE_32BIT,
                                /* flags     */ 0,
-                               /* lockfunc  */ busdma_lock_mutex,
-                               /* lockarg   */ &Giant,
+                               /* lockfunc  */ NULL,
+                               /* lockarg   */ NULL,
                                &dpt->parent_dmat) != 0) {
                error = ENXIO;
                goto bad;
        }
 
-       s = splcam();
-
        if (dpt_init(dpt) != 0) {
-               splx(s);
                error = ENXIO;
                goto bad;
        }
@@ -153,10 +147,8 @@ dpt_eisa_attach (device_t dev)
        /* Register with the XPT */
        dpt_attach(dpt);
 
-       splx(s);
-
-       if (bus_setup_intr(dev, dpt->irq_res, INTR_TYPE_CAM | INTR_ENTROPY,
-                          NULL, dpt_intr, dpt, &dpt->ih)) {
+       if (bus_setup_intr(dev, dpt->irq_res, INTR_TYPE_CAM | INTR_ENTROPY |
+           INTR_MPSAFE, NULL, dpt_intr, dpt, &dpt->ih)) {
                device_printf(dev, "Unable to register interrupt handler\n");
                error = ENXIO;
                goto bad;

Modified: head/sys/dev/dpt/dpt_isa.c
==============================================================================
--- head/sys/dev/dpt/dpt_isa.c  Mon Oct 15 16:13:55 2012        (r241592)
+++ head/sys/dev/dpt/dpt_isa.c  Mon Oct 15 16:29:08 2012        (r241593)
@@ -31,7 +31,9 @@ __FBSDID("$FreeBSD$");
 #include <sys/param.h>
 #include <sys/systm.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>
@@ -150,11 +152,11 @@ static int
 dpt_isa_attach (device_t dev)
 {
        dpt_softc_t *   dpt;
-       int             s;
        int             error = 0;
 
        dpt = device_get_softc(dev);
        dpt->dev = dev;
+       dpt_alloc(dev);
 
        dpt->io_rid = 0;
        dpt->io_type = SYS_RES_IOPORT;
@@ -176,10 +178,8 @@ dpt_isa_attach (device_t dev)
        isa_dma_acquire(rman_get_start(dpt->drq_res));
        isa_dmacascade(rman_get_start(dpt->drq_res));
 
-       dpt_alloc(dev);
-
        /* Allocate a dmatag representing the capabilities of this attachment */
-       if (bus_dma_tag_create( /* parent    */ NULL,
+       if (bus_dma_tag_create( /* parent    */ bus_get_dma_tag(dev),
                                /* alignemnt */ 1,
                                /* boundary  */ 0,
                                /* lowaddr   */ BUS_SPACE_MAXADDR_32BIT,
@@ -190,17 +190,14 @@ dpt_isa_attach (device_t dev)
                                /* nsegments */ ~0,
                                /* maxsegsz  */ BUS_SPACE_MAXSIZE_32BIT,
                                /* flags     */ 0,
-                               /* lockfunc  */ busdma_lock_mutex,
-                               /* lockarg   */ &Giant,
+                               /* lockfunc  */ NULL,
+                               /* lockarg   */ NULL,
                                &dpt->parent_dmat) != 0) {
                error = ENXIO;
                goto bad;
        }
 
-       s = splcam();
-
        if (dpt_init(dpt) != 0) {
-               splx(s);
                error = ENXIO;
                goto bad;
        }
@@ -208,10 +205,8 @@ dpt_isa_attach (device_t dev)
        /* Register with the XPT */
        dpt_attach(dpt);
 
-       splx(s);
-
-       if (bus_setup_intr(dev, dpt->irq_res, INTR_TYPE_CAM | INTR_ENTROPY,
-                          dpt_intr, dpt, &dpt->ih)) {
+       if (bus_setup_intr(dev, dpt->irq_res, INTR_TYPE_CAM | INTR_ENTROPY |
+           INTR_MPSAFE, NULL, dpt_intr, dpt, &dpt->ih)) {
                device_printf(dev, "Unable to register interrupt handler\n");
                error = ENXIO;
                goto bad;

Modified: head/sys/dev/dpt/dpt_pci.c
==============================================================================
--- head/sys/dev/dpt/dpt_pci.c  Mon Oct 15 16:13:55 2012        (r241592)
+++ head/sys/dev/dpt/dpt_pci.c  Mon Oct 15 16:29:08 2012        (r241593)
@@ -75,13 +75,13 @@ static int
 dpt_pci_attach (device_t dev)
 {
        dpt_softc_t *   dpt;
-       int             s;
        int             error = 0;
 
        u_int32_t       command;
 
        dpt = device_get_softc(dev);
        dpt->dev = dev;
+       dpt_alloc(dev);
 
        command = pci_read_config(dev, PCIR_COMMAND, /*bytes*/1);
 
@@ -117,8 +117,7 @@ dpt_pci_attach (device_t dev)
        }
 
        /* Ensure busmastering is enabled */
-       command |= PCIM_CMD_BUSMASTEREN;
-       pci_write_config(dev, PCIR_COMMAND, command, /*bytes*/1);
+       pci_enable_busmaster(dev);
 
        if (rman_get_start(dpt->io_res) == (ISA_PRIMARY_WD_ADDRESS - 0x10)) {
 #ifdef DPT_DEBUG_WARN
@@ -129,8 +128,6 @@ dpt_pci_attach (device_t dev)
                goto bad;
        }
 
-       dpt_alloc(dev);
-
        /* Allocate a dmatag representing the capabilities of this attachment */
        if (bus_dma_tag_create( /* PCI parent */ bus_get_dma_tag(dev),
                                /* alignemnt */ 1,
@@ -143,15 +140,13 @@ dpt_pci_attach (device_t dev)
                                /* nsegments */ ~0,
                                /* maxsegsz  */ BUS_SPACE_MAXSIZE_32BIT,
                                /* flags     */ 0,
-                               /* lockfunc  */ busdma_lock_mutex,
-                               /* lockarg   */ &Giant,
+                               /* lockfunc  */ NULL,
+                               /* lockarg   */ NULL,
                                &dpt->parent_dmat) != 0) {
                error = ENXIO;
                goto bad;
        }
 
-       s = splcam();
-
        if (dpt_init(dpt) != 0) {
                error = ENXIO;
                goto bad;
@@ -160,10 +155,8 @@ dpt_pci_attach (device_t dev)
        /* Register with the XPT */
        dpt_attach(dpt);
 
-       splx(s);
-
-       if (bus_setup_intr(dev, dpt->irq_res, INTR_TYPE_CAM | INTR_ENTROPY,
-                          NULL, dpt_intr, dpt, &dpt->ih)) {
+       if (bus_setup_intr(dev, dpt->irq_res, INTR_TYPE_CAM | INTR_ENTROPY |
+           INTR_MPSAFE, NULL, dpt_intr, dpt, &dpt->ih)) {
                device_printf(dev, "Unable to register interrupt handler\n");
                error = ENXIO;
                goto bad;

Modified: head/sys/dev/dpt/dpt_scsi.c
==============================================================================
--- head/sys/dev/dpt/dpt_scsi.c Mon Oct 15 16:13:55 2012        (r241592)
+++ head/sys/dev/dpt/dpt_scsi.c Mon Oct 15 16:29:08 2012        (r241593)
@@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
 #include <sys/systm.h>
+#include <sys/conf.h>
 #include <sys/eventhandler.h>
 #include <sys/malloc.h>
 #include <sys/kernel.h>
@@ -79,19 +80,18 @@ __FBSDID("$FreeBSD$");
 #include <dev/dpt/dpt.h>
 
 /* dpt_isa.c, dpt_eisa.c, and dpt_pci.c need this in a central place */
-int            dpt_controllers_present;
 devclass_t     dpt_devclass;
 
 #define microtime_now dpt_time_now()
 
 #define dpt_inl(dpt, port)                             \
-       bus_space_read_4((dpt)->tag, (dpt)->bsh, port)
+       bus_read_4((dpt)->io_res, (dpt)->io_offset + port)
 #define dpt_inb(dpt, port)                             \
-       bus_space_read_1((dpt)->tag, (dpt)->bsh, port)
+       bus_read_1((dpt)->io_res, (dpt)->io_offset + port)
 #define dpt_outl(dpt, port, value)                     \
-       bus_space_write_4((dpt)->tag, (dpt)->bsh, port, value)
+       bus_write_4((dpt)->io_res, (dpt)->io_offset + port, value)
 #define dpt_outb(dpt, port, value)                     \
-       bus_space_write_1((dpt)->tag, (dpt)->bsh, port, value)
+       bus_write_1((dpt)->io_res, (dpt)->io_offset + port, value)
 
 /*
  * These will have to be setup by parameters passed at boot/load time. For
@@ -142,6 +142,7 @@ static void         dpt_detect_cache(dpt_softc_
                                         u_int8_t *buff);
 
 static void            dpt_poll(struct cam_sim *sim);
+static void            dpt_intr_locked(dpt_softc_t *dpt);
 
 static void            dptexecuteccb(void *arg, bus_dma_segment_t *dm_segs,
                                      int nseg, int error);
@@ -222,9 +223,9 @@ static __inline struct dpt_ccb*
 dptgetccb(struct dpt_softc *dpt)
 {
        struct  dpt_ccb* dccb;
-       int     s;
 
-       s = splcam();
+       if (!dumping)
+               mtx_assert(&dpt->lock, MA_OWNED);
        if ((dccb = SLIST_FIRST(&dpt->free_dccb_list)) != NULL) {
                SLIST_REMOVE_HEAD(&dpt->free_dccb_list, links);
                dpt->free_dccbs--;
@@ -232,13 +233,12 @@ dptgetccb(struct dpt_softc *dpt)
                dptallocccbs(dpt);
                dccb = SLIST_FIRST(&dpt->free_dccb_list);
                if (dccb == NULL)
-                       printf("dpt%d: Can't malloc DCCB\n", dpt->unit);
+                       device_printf(dpt->dev, "Can't malloc DCCB\n");
                else {
                        SLIST_REMOVE_HEAD(&dpt->free_dccb_list, links);
                        dpt->free_dccbs--;
                }
        }
-       splx(s);
 
        return (dccb);
 }
@@ -246,9 +246,9 @@ dptgetccb(struct dpt_softc *dpt)
 static __inline void
 dptfreeccb(struct dpt_softc *dpt, struct dpt_ccb *dccb)
 {
-       int s;
 
-       s = splcam();
+       if (!dumping)
+               mtx_assert(&dpt->lock, MA_OWNED);
        if ((dccb->state & DCCB_ACTIVE) != 0)
                LIST_REMOVE(&dccb->ccb->ccb_h, sim_links.le);
        if ((dccb->state & DCCB_RELEASE_SIMQ) != 0)
@@ -261,7 +261,6 @@ dptfreeccb(struct dpt_softc *dpt, struct
        dccb->state = DCCB_FREE;
        SLIST_INSERT_HEAD(&dpt->free_dccb_list, dccb, links);
        ++dpt->free_dccbs;
-       splx(s);
 }
 
 static __inline bus_addr_t
@@ -332,7 +331,6 @@ dptallocsgmap(struct dpt_softc *dpt)
 
 /*
  * Allocate another chunk of CCB's. Return count of entries added.
- * Assumed to be called at splcam().
  */
 static int
 dptallocccbs(dpt_softc_t *dpt)
@@ -344,6 +342,8 @@ dptallocccbs(dpt_softc_t *dpt)
        int newcount;
        int i;
 
+       if (!dumping)
+               mtx_assert(&dpt->lock, MA_OWNED);
        next_ccb = &dpt->dpt_dccbs[dpt->total_dccbs];
 
        if (next_ccb == dpt->dpt_dccbs) {
@@ -371,6 +371,7 @@ dptallocccbs(dpt_softc_t *dpt)
                                          &next_ccb->dmamap);
                if (error != 0)
                        break;
+               callout_init_mtx(&next_ccb->timer, &dpt->lock, 0);
                next_ccb->sg_list = segs;
                next_ccb->sg_busaddr = htonl(physaddr);
                next_ccb->eata_ccb.cp_dataDMA = htonl(physaddr);
@@ -404,7 +405,7 @@ dpt_pio_get_conf (u_int32_t base)
         */
        if (!conf) {
                conf = (dpt_conf_t *)malloc(sizeof(dpt_conf_t),
-                                                M_DEVBUF, M_NOWAIT);
+                                                M_DEVBUF, M_NOWAIT | M_ZERO);
        }
        
        /*
@@ -416,11 +417,6 @@ dpt_pio_get_conf (u_int32_t base)
        }
 
        /*
-        * If we have one, clean it up.
-        */
-       bzero(conf, sizeof(dpt_conf_t));
-
-       /*
         * Reset the controller.
         */
        outb((base + HA_WCOMMAND), EATA_CMD_RESET);
@@ -498,9 +494,9 @@ dpt_get_conf(dpt_softc_t *dpt, dpt_ccb_t
        u_int8_t   status;
 
        int        ndx;
-       int        ospl;
        int        result;
 
+       mtx_assert(&dpt->lock, MA_OWNED);
        cp = &dccb->eata_ccb;
        bzero((void *)(uintptr_t)(volatile void *)dpt->sp, sizeof(*dpt->sp));
 
@@ -523,8 +519,6 @@ dpt_get_conf(dpt_softc_t *dpt, dpt_ccb_t
        cp->cp_identify = 1;
        cp->cp_datalen = htonl(size);
 
-       ospl = splcam();
-
        /*
         * This could be a simple for loop, but we suspected the compiler To
         * have optimized it a bit too much. Wait for the controller to
@@ -540,9 +534,8 @@ dpt_get_conf(dpt_softc_t *dpt, dpt_ccb_t
                 * the DPT controller is in a NON PC (PCI?) platform).
                 */
                if (dpt_raid_busy(dpt)) {
-                       printf("dpt%d WARNING: Get_conf() RSUS failed.\n",
-                              dpt->unit);
-                       splx(ospl);
+                       device_printf(dpt->dev,
+                           "WARNING: Get_conf() RSUS failed.\n");
                        return (0);
                }
        }
@@ -557,10 +550,10 @@ dpt_get_conf(dpt_softc_t *dpt, dpt_ccb_t
        if ((result = dpt_send_eata_command(dpt, cp, dccb_busaddr,
                                            EATA_CMD_DMA_SEND_CP,
                                            10000, 0, 0, 0)) != 0) {
-               printf("dpt%d WARNING: Get_conf() failed (%d) to send "
+               device_printf(dpt->dev,
+                      "WARNING: Get_conf() failed (%d) to send "
                       "EATA_CMD_DMA_READ_CONFIG\n",
-                      dpt->unit, result);
-               splx(ospl);
+                      result);
                return (0);
        }
        /* Wait for two seconds for a response.  This can be slow  */
@@ -574,8 +567,6 @@ dpt_get_conf(dpt_softc_t *dpt, dpt_ccb_t
        /* Grab the status and clear interrupts */
        status = dpt_inb(dpt, HA_RSTATUS);
 
-       splx(ospl);
-
        /*
         * Check the status carefully.  Return only if the
         * command was successful.
@@ -601,10 +592,11 @@ dpt_detect_cache(dpt_softc_t *dpt, dpt_c
        u_int8_t   *param;
        int         bytes;
        int         result;
-       int         ospl;
        int         ndx;
        u_int8_t    status;
 
+       mtx_assert(&dpt->lock, MA_OWNED);
+
        /*
         * Default setting, for best perfromance..
         * This is what virtually all cards default to..
@@ -646,14 +638,13 @@ dpt_detect_cache(dpt_softc_t *dpt, dpt_c
 
        cp->cp_datalen = htonl(512);
 
-       ospl = splcam();
        result = dpt_send_eata_command(dpt, cp, dccb_busaddr,
                                       EATA_CMD_DMA_SEND_CP,
                                       10000, 0, 0, 0);
        if (result != 0) {
-               printf("dpt%d WARNING: detect_cache() failed (%d) to send "
-                      "EATA_CMD_DMA_SEND_CP\n", dpt->unit, result);
-               splx(ospl);
+               device_printf(dpt->dev,
+                      "WARNING: detect_cache() failed (%d) to send "
+                      "EATA_CMD_DMA_SEND_CP\n", result);
                return;
        }
        /* Wait for two seconds for a response.  This can be slow... */
@@ -666,7 +657,6 @@ dpt_detect_cache(dpt_softc_t *dpt, dpt_c
 
        /* Grab the status and clear interrupts */
        status = dpt_inb(dpt, HA_RSTATUS);
-       splx(ospl);
 
        /*
         * Sanity check
@@ -681,8 +671,7 @@ dpt_detect_cache(dpt_softc_t *dpt, dpt_c
                /*
                 * DPT Log Page layout error
                 */
-               printf("dpt%d: NOTICE: Log Page (1) layout error\n",
-                      dpt->unit);
+               device_printf(dpt->dev, "NOTICE: Log Page (1) layout error\n");
                return;
        }
        if (!(param[4] & 0x4)) {
@@ -721,7 +710,7 @@ dpt_detect_cache(dpt_softc_t *dpt, dpt_c
 static void
 dpt_poll(struct cam_sim *sim)
 {
-       dpt_intr(cam_sim_softc(sim));
+       dpt_intr_locked(cam_sim_softc(sim));
 }
 
 static void
@@ -730,16 +719,18 @@ dptexecuteccb(void *arg, bus_dma_segment
        struct   dpt_ccb *dccb;
        union    ccb *ccb;
        struct   dpt_softc *dpt;
-       int      s;
 
+       if (!dumping)
+               mtx_assert(&dpt->lock, MA_OWNED);
        dccb = (struct dpt_ccb *)arg;
        ccb = dccb->ccb;
        dpt = (struct dpt_softc *)ccb->ccb_h.ccb_dpt_ptr;
 
        if (error != 0) {
                if (error != EFBIG)
-                       printf("dpt%d: Unexepected error 0x%x returned from "
-                              "bus_dmamap_load\n", dpt->unit, error);
+                       device_printf(dpt->dev,
+                              "Unexepected error 0x%x returned from "
+                              "bus_dmamap_load\n", error);
                if (ccb->ccb_h.status == CAM_REQ_INPROG) {
                        xpt_freeze_devq(ccb->ccb_h.path, /*count*/1);
                        ccb->ccb_h.status = CAM_REQ_TOO_BIG|CAM_DEV_QFRZN;
@@ -787,8 +778,6 @@ dptexecuteccb(void *arg, bus_dma_segment
                dccb->eata_ccb.cp_datalen = 0;
        }
 
-       s = splcam();
-
        /*
         * Last time we need to check if this CCB needs to
         * be aborted.
@@ -798,16 +787,14 @@ dptexecuteccb(void *arg, bus_dma_segment
                        bus_dmamap_unload(dpt->buffer_dmat, dccb->dmamap);
                dptfreeccb(dpt, dccb);
                xpt_done(ccb);
-               splx(s);
                return;
        }
                
        dccb->state |= DCCB_ACTIVE;
        ccb->ccb_h.status |= CAM_SIM_QUEUED;
        LIST_INSERT_HEAD(&dpt->pending_ccb_list, &ccb->ccb_h, sim_links.le);
-       ccb->ccb_h.timeout_ch =
-           timeout(dpttimeout, (caddr_t)dccb,
-                   (ccb->ccb_h.timeout * hz) / 1000);
+       callout_reset(&dccb->timer, (ccb->ccb_h.timeout * hz) / 1000,
+           dpttimeout, dccb);
        if (dpt_send_eata_command(dpt, &dccb->eata_ccb,
                                  dccb->eata_ccb.cp_busaddr,
                                  EATA_CMD_DMA_SEND_CP, 0, 0, 0, 0) != 0) {
@@ -817,8 +804,6 @@ dptexecuteccb(void *arg, bus_dma_segment
                dptfreeccb(dpt, dccb);
                xpt_done(ccb);
        }
-
-       splx(s);
 }
 
 static void
@@ -829,6 +814,7 @@ dpt_action(struct cam_sim *sim, union cc
        CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("dpt_action\n"));
        
        dpt = (struct dpt_softc *)cam_sim_softc(sim);
+       mtx_assert(&dpt->lock, MA_OWNED);
 
        if ((dpt->state & DPT_HA_SHUTDOWN_ACTIVE) != 0) {
                xpt_print_path(ccb->ccb_h.path);
@@ -856,11 +842,7 @@ dpt_action(struct cam_sim *sim, union cc
                        return;
                }
                if ((dccb = dptgetccb(dpt)) == NULL) {
-                       int s;
-       
-                       s = splcam();
                        dpt->resource_shortage = 1;
-                       splx(s);
                        xpt_freeze_simq(sim, /*count*/1);
                        ccb->ccb_h.status = CAM_REQUEUE_REQ;
                        xpt_done(ccb);
@@ -934,10 +916,8 @@ dpt_action(struct cam_sim *sim, union cc
                                 * to a single buffer.
                                 */
                                if ((ccbh->flags & CAM_DATA_PHYS) == 0) {
-                                       int s;
                                        int error;
 
-                                       s = splsoftvm();
                                        error =
                                            bus_dmamap_load(dpt->buffer_dmat,
                                                            dccb->dmamap,
@@ -955,7 +935,6 @@ dpt_action(struct cam_sim *sim, union cc
                                                xpt_freeze_simq(sim, 1);
                                                dccb->state |= CAM_RELEASE_SIMQ;
                                        }
-                                       splx(s);
                                } else {
                                        struct bus_dma_segment seg; 
 
@@ -1105,7 +1084,6 @@ dpt_action(struct cam_sim *sim, union cc
  * This routine will try to send an EATA command to the DPT HBA.
  * It will, by default, try 20,000 times, waiting 50us between tries.
  * It returns 0 on success and 1 on failure.
- * It is assumed to be called at splcam().
  */
 static int
 dpt_send_eata_command(dpt_softc_t *dpt, eata_ccb_t *cmd_block,
@@ -1183,9 +1161,7 @@ dpt_alloc(device_t dev)
        dpt_softc_t     *dpt = device_get_softc(dev);
        int    i;
 
-       dpt->tag = rman_get_bustag(dpt->io_res);
-       dpt->bsh = rman_get_bushandle(dpt->io_res) + dpt->io_offset;
-       dpt->unit = device_get_unit(dev);
+       mtx_init(&dpt->lock, "dpt", NULL, MTX_DEF);
        SLIST_INIT(&dpt->free_dccb_list);
        LIST_INIT(&dpt->pending_ccb_list);
        for (i = 0; i < MAX_CHANNELS; i++)
@@ -1229,6 +1205,7 @@ dpt_free(struct dpt_softc *dpt)
        case 0:
                break;
        }
+       mtx_destroy(&dpt->lock);
 }
 
 int
@@ -1301,9 +1278,10 @@ dpt_init(struct dpt_softc *dpt)
 
        dpt->init_level = 0;
        SLIST_INIT(&dpt->sg_maps);
+       mtx_lock(&dpt->lock);
 
 #ifdef DPT_RESET_BOARD
-       printf("dpt%d: resetting HBA\n", dpt->unit);
+       device_printf(dpt->dev, "resetting HBA\n");
        dpt_outb(dpt, HA_WCOMMAND, EATA_CMD_RESET);
        DELAY(750000);
        /* XXX Shouldn't we poll a status register or something??? */
@@ -1320,8 +1298,8 @@ dpt_init(struct dpt_softc *dpt)
                                /* nsegments    */ 1,
                                /* maxsegsz     */ BUS_SPACE_MAXSIZE_32BIT,
                                /* flags        */ 0,
-                               /* lockfunc     */ busdma_lock_mutex,
-                               /* lockarg      */ &Giant,
+                               /* lockfunc     */ NULL,
+                               /* lockarg      */ NULL,
                                &dpt->sg_dmat) != 0) {
                goto error_exit;
         }
@@ -1357,8 +1335,8 @@ dpt_init(struct dpt_softc *dpt)
                              sizeof(conf), 0xc1, 7, 1);
 
        if (retval != 0) {
-               printf("dpt%d: Failed to get board configuration\n", dpt->unit);
-               return (retval);
+               device_printf(dpt->dev, "Failed to get board configuration\n");
+               goto error_exit;
        }
        bcopy(&dccb[1], &conf, sizeof(conf));
 
@@ -1366,8 +1344,8 @@ dpt_init(struct dpt_softc *dpt)
        retval = dpt_get_conf(dpt, dccb, sg_map->sg_physaddr + sizeof(dpt_sp_t),
                              sizeof(dpt->board_data), 0, conf.scsi_id0, 0);
        if (retval != 0) {
-               printf("dpt%d: Failed to get inquiry information\n", dpt->unit);
-               return (retval);
+               device_printf(dpt->dev, "Failed to get inquiry information\n");
+               goto error_exit;
        }
        bcopy(&dccb[1], &dpt->board_data, sizeof(dpt->board_data));
 
@@ -1416,8 +1394,8 @@ dpt_init(struct dpt_softc *dpt)
        dpt->max_dccbs = ntohs(conf.queuesiz);
 
        if (dpt->max_dccbs > 256) {
-               printf("dpt%d: Max CCBs reduced from %d to "
-                      "256 due to tag algorithm\n", dpt->unit, dpt->max_dccbs);
+               device_printf(dpt->dev, "Max CCBs reduced from %d to "
+                      "256 due to tag algorithm\n", dpt->max_dccbs);
                dpt->max_dccbs = 256;
        }
 
@@ -1450,9 +1428,10 @@ dpt_init(struct dpt_softc *dpt)
                                /* maxsegsz     */ BUS_SPACE_MAXSIZE_32BIT,
                                /* flags        */ BUS_DMA_ALLOCNOW,
                                /* lockfunc     */ busdma_lock_mutex,
-                               /* lockarg      */ &Giant,
+                               /* lockarg      */ &dpt->lock,
                                &dpt->buffer_dmat) != 0) {
-               printf("dpt: bus_dma_tag_create(...,dpt->buffer_dmat) 
failed\n");
+               device_printf(dpt->dev,
+                   "bus_dma_tag_create(...,dpt->buffer_dmat) failed\n");
                goto error_exit;
        }
 
@@ -1472,10 +1451,11 @@ dpt_init(struct dpt_softc *dpt)
                                /* nsegments    */ 1,
                                /* maxsegsz     */ BUS_SPACE_MAXSIZE_32BIT,
                                /* flags        */ 0,
-                               /* lockfunc     */ busdma_lock_mutex,
-                               /* lockarg      */ &Giant,
+                               /* lockfunc     */ NULL,
+                               /* lockarg      */ NULL,
                                &dpt->dccb_dmat) != 0) {
-               printf("dpt: bus_dma_tag_create(...,dpt->dccb_dmat) failed\n");
+               device_printf(dpt->dev,
+                   "bus_dma_tag_create(...,dpt->dccb_dmat) failed\n");
                goto error_exit;
         }
 
@@ -1484,7 +1464,8 @@ dpt_init(struct dpt_softc *dpt)
        /* Allocation for our ccbs and interrupt status packet */
        if (bus_dmamem_alloc(dpt->dccb_dmat, (void **)&dpt->dpt_dccbs,
                             BUS_DMA_NOWAIT, &dpt->dccb_dmamap) != 0) {
-               printf("dpt: bus_dmamem_alloc(dpt->dccb_dmat,...) failed\n");
+               device_printf(dpt->dev,
+                   "bus_dmamem_alloc(dpt->dccb_dmat,...) failed\n");
                goto error_exit;
        }
 
@@ -1510,7 +1491,8 @@ dpt_init(struct dpt_softc *dpt)
 
        /* Allocate our first batch of ccbs */
        if (dptallocccbs(dpt) == 0) {
-               printf("dpt: dptallocccbs(dpt) == 0\n");
+               device_printf(dpt->dev, "dptallocccbs(dpt) == 0\n");
+               mtx_unlock(&dpt->lock);
                return (2);
        }
 
@@ -1526,8 +1508,8 @@ dpt_init(struct dpt_softc *dpt)
                strp += string_sizes[i];
        }
 
-       printf("dpt%d: %.8s %.16s FW Rev. %.4s, ",
-              dpt->unit, dpt->board_data.vendor,
+       device_printf(dpt->dev, "%.8s %.16s FW Rev. %.4s, ",
+              dpt->board_data.vendor,
               dpt->board_data.modelNum, dpt->board_data.firmware);
 
        printf("%d channel%s, ", dpt->channels, dpt->channels > 1 ? "s" : "");
@@ -1540,9 +1522,11 @@ dpt_init(struct dpt_softc *dpt)
        }
 
        printf("%d CCBs\n", dpt->max_dccbs);
+       mtx_unlock(&dpt->lock);
        return (0);
                
 error_exit:
+       mtx_unlock(&dpt->lock);
        return (1);
 }
 
@@ -1559,12 +1543,13 @@ dpt_attach(dpt_softc_t *dpt)
        if (devq == NULL)
                return (0);
 
+       mtx_lock(&dpt->lock);
        for (i = 0; i < dpt->channels; i++) {
                /*
                 * Construct our SIM entry
                 */
                dpt->sims[i] = cam_sim_alloc(dpt_action, dpt_poll, "dpt",
-                                            dpt, dpt->unit, &Giant,
+                   dpt, device_get_unit(dpt->dev), &dpt->lock,
                                             /*untagged*/2,
                                             /*tagged*/dpt->max_dccbs, devq);
                if (dpt->sims[i] == NULL) {
@@ -1594,6 +1579,7 @@ dpt_attach(dpt_softc_t *dpt)
                }
 
        }
+       mtx_unlock(&dpt->lock);
        if (i > 0)
                EVENTHANDLER_REGISTER(shutdown_final, dptshutdown,
                                      dpt, SHUTDOWN_PRI_DEFAULT);
@@ -1608,6 +1594,7 @@ dpt_detach (device_t dev)
 
        dpt = device_get_softc(dev);
 
+       mtx_lock(&dpt->lock);
        for (i = 0; i < dpt->channels; i++) {
 #if 0
                xpt_async(AC_LOST_DEVICE, dpt->paths[i], NULL);
@@ -1616,6 +1603,7 @@ dpt_detach (device_t dev)
                xpt_bus_deregister(cam_sim_path(dpt->sims[i]));
                cam_sim_free(dpt->sims[i], /*free_devq*/TRUE);
        }
+       mtx_unlock(&dpt->lock);
 
        dptshutdown((void *)dpt, SHUTDOWN_PRI_DEFAULT);
 
@@ -1633,6 +1621,16 @@ void
 dpt_intr(void *arg)
 {
        dpt_softc_t    *dpt;
+
+       dpt = arg;
+       mtx_lock(&dpt->lock);
+       dpt_intr_locked(dpt);
+       mtx_unlock(&dpt->lock);
+}
+
+void
+dpt_intr_locked(dpt_softc_t *dpt)
+{
        dpt_ccb_t      *dccb;
        union ccb      *ccb;
        u_int           status;
@@ -1641,8 +1639,6 @@ dpt_intr(void *arg)
        u_int           scsi_stat;
        u_int32_t       residue_len;    /* Number of bytes not transferred */
 
-       dpt = (dpt_softc_t *)arg;
-
        /* First order of business is to check if this interrupt is for us */
        while (((aux_status = dpt_inb(dpt, HA_RAUXSTAT)) & HA_AIRQ) != 0) {
 
@@ -1653,7 +1649,8 @@ dpt_intr(void *arg)
                 */
                if (dpt->sp->ccb_busaddr < dpt->dpt_ccb_busbase
                 || dpt->sp->ccb_busaddr >= dpt->dpt_ccb_busend) {
-                       printf("Encountered bogus status packet\n");
+                       device_printf(dpt->dev,
+                           "Encountered bogus status packet\n");
                        status = dpt_inb(dpt, HA_RSTATUS);
                        return;
                }
@@ -1664,9 +1661,10 @@ dpt_intr(void *arg)
 
                /* Ignore status packets with EOC not set */
                if (dpt->sp->EOC == 0) {
-                       printf("dpt%d ERROR: Request %d received with "
+                       device_printf(dpt->dev,
+                              "ERROR: Request %d received with "
                               "clear EOC.\n     Marking as LOST.\n",
-                              dpt->unit, dccb->transaction_id);
+                              dccb->transaction_id);
 
 #ifdef DPT_HANDLE_TIMEOUTS
                        dccb->state |= DPT_CCB_STATE_MARKED_LOST;
@@ -1696,20 +1694,20 @@ dpt_intr(void *arg)
 
                        /* Check that this is not a board reset interrupt */
                        if (dpt_just_reset(dpt)) {
-                               printf("dpt%d: HBA rebooted.\n"
+                               device_printf(dpt->dev, "HBA rebooted.\n"
                                       "      All transactions should be "
-                                      "resubmitted\n",
-                                      dpt->unit);
+                                      "resubmitted\n");
 
-                               printf("dpt%d: >>---->>  This is incomplete, "
-                                      "fix me....  <<----<<", dpt->unit);
+                               device_printf(dpt->dev,
+                                      ">>---->>  This is incomplete, "
+                                      "fix me....  <<----<<");
                                panic("DPT Rebooted");
 
                        }
                }
                /* Process CCB */
                ccb = dccb->ccb;
-               untimeout(dpttimeout, dccb, ccb->ccb_h.timeout_ch);
+               callout_stop(&dccb->timer);
                if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
                        bus_dmasync_op_t op;
 
@@ -1803,7 +1801,7 @@ dptprocesserror(dpt_softc_t *dpt, dpt_cc
                ccb->ccb_h.status = CAM_AUTOSENSE_FAIL;
                break;
        default:
-               printf("dpt%d: Undocumented Error %x\n", dpt->unit, hba_stat);
+               device_printf(dpt->dev, "Undocumented Error %x\n", hba_stat);
                printf("Please mail this message to 
shi...@simon-shapiro.org\n");
                ccb->ccb_h.status = CAM_REQ_CMP_ERR;
                break;
@@ -1818,29 +1816,26 @@ dpttimeout(void *arg)
        struct dpt_ccb   *dccb;
        union  ccb       *ccb;
        struct dpt_softc *dpt;
-       int               s;
 
        dccb = (struct dpt_ccb *)arg;
        ccb = dccb->ccb;
        dpt = (struct dpt_softc *)ccb->ccb_h.ccb_dpt_ptr;
+       mtx_assert(&dpt->lock, MA_OWNED);
        xpt_print_path(ccb->ccb_h.path);
        printf("CCB %p - timed out\n", (void *)dccb);
 
-       s = splcam();
-
        /*
         * Try to clear any pending jobs.  FreeBSD will lose interrupts,
         * leaving the controller suspended, and commands timed-out.
         * By calling the interrupt handler, any command thus stuck will be
         * completed.
         */
-       dpt_intr(dpt);
+       dpt_intr_locked(dpt);
        
        if ((dccb->state & DCCB_ACTIVE) == 0) {
                xpt_print_path(ccb->ccb_h.path);
                printf("CCB %p - timed out CCB already completed\n",
                       (void *)dccb);
-               splx(s);
                return;
        }
 
@@ -1848,7 +1843,6 @@ dpttimeout(void *arg)
        dpt_send_immediate(dpt, &dccb->eata_ccb, dccb->eata_ccb.cp_busaddr,
                           /*retries*/20000, EATA_SPECIFIC_ABORT, 0, 0);
        ccb->ccb_h.status = CAM_CMD_TIMEOUT;
-       splx(s);
 }
 
 /*
@@ -1862,16 +1856,18 @@ dptshutdown(void *arg, int howto)
 
        dpt = (dpt_softc_t *)arg;
 
-       printf("dpt%d: Shutting down (mode %x) HBA.     Please wait...\n",
-              dpt->unit, howto);
+       device_printf(dpt->dev,
+           "Shutting down (mode %x) HBA.       Please wait...\n", howto);
 
        /*
         * What we do for a shutdown, is give the DPT early power loss warning
         */
+       mtx_lock(&dpt->lock);
        dpt_send_immediate(dpt, NULL, 0, EATA_POWER_OFF_WARN, 0, 0, 0);
+       mtx_unlock(&dpt->lock);
        DELAY(1000 * 1000 * 5);
-       printf("dpt%d: Controller was warned of shutdown and is now "
-              "disabled\n", dpt->unit);
+       device_printf(dpt->dev, "Controller was warned of shutdown and is now "
+              "disabled\n");
 }
 
 
/*============================================================================*/
@@ -1890,11 +1886,12 @@ static void
 dpt_reset_hba(dpt_softc_t *dpt)
 {
        eata_ccb_t       *ccb;
-       int               ospl;
        dpt_ccb_t         dccb, *dccbp;
        int               result;
        struct scsi_xfer *xs;
-    
+
+       mtx_assert(&dpt->lock, MA_OWNED);
+
        /* Prepare a control block.  The SCSI command part is immaterial */
        dccb.xs = NULL;
        dccb.flags = 0;
@@ -1920,26 +1917,24 @@ dpt_reset_hba(dpt_softc_t *dpt)
        ccb->cp_scsi_cmd = 0;  /* Should be ignored */
 
        /* Lock up the submitted queue.  We are very persistant here */
-       ospl = splcam();
        while (dpt->queue_status & DPT_SUBMITTED_QUEUE_ACTIVE) {
                DELAY(100);
        }
        
        dpt->queue_status |= DPT_SUBMITTED_QUEUE_ACTIVE;
-       splx(ospl);
 
        /* Send the RESET message */
        if ((result = dpt_send_eata_command(dpt, &dccb.eata_ccb,
                                            EATA_CMD_RESET, 0, 0, 0, 0)) != 0) {
-               printf("dpt%d: Failed to send the RESET message.\n"
-                      "      Trying cold boot (ouch!)\n", dpt->unit);
+               device_printf(dpt->dev, "Failed to send the RESET message.\n"
+                      "     Trying cold boot (ouch!)\n");
        
        
                if ((result = dpt_send_eata_command(dpt, &dccb.eata_ccb,
                                                    EATA_COLD_BOOT, 0, 0,
                                                    0, 0)) != 0) {
-                       panic("dpt%d:  Faild to cold boot the HBA\n",
-                             dpt->unit);
+                       panic("%s:  Faild to cold boot the HBA\n",
+                           device_get_nameunit(dpt->dev));
                }
 #ifdef DPT_MEASURE_PERFORMANCE
                dpt->performance.cold_boots++;
@@ -1950,8 +1945,8 @@ dpt_reset_hba(dpt_softc_t *dpt)
        dpt->performance.warm_starts++;
 #endif /* DPT_MEASURE_PERFORMANCE */
        
-       printf("dpt%d:  Aborting pending requests.  O/S should re-submit\n",
-              dpt->unit);
+       device_printf(dpt->dev,
+           "Aborting pending requests.  O/S should re-submit\n");
 
        while ((dccbp = TAILQ_FIRST(&dpt->completed_ccbs)) != NULL) {
                struct scsi_xfer *xs = dccbp->xs;
@@ -1971,13 +1966,11 @@ dpt_reset_hba(dpt_softc_t *dpt)
                        (dccbp->std_callback)(dpt, dccbp->eata_ccb.cp_channel,
                                               dccbp);
                } else {
-                       ospl = splcam();
                        dpt_Qpush_free(dpt, dccbp);
-                       splx(ospl);
                }
        }
 
-       printf("dpt%d: reset done aborting all pending commands\n", dpt->unit);
+       device_printf(dpt->dev, "reset done aborting all pending commands\n");
        dpt->queue_status &= ~DPT_SUBMITTED_QUEUE_ACTIVE;

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
_______________________________________________
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