This commit was manufactured by cvs2svn to create tag
[linux-2.6.git] / drivers / message / fusion / mptscsih.c
index 8c82254..dce5ba1 100644 (file)
@@ -65,7 +65,6 @@
 */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 
-#include "linux_compat.h"      /* linux-2.6 tweaks */
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/reboot.h>      /* notifier code */
 #include <linux/sched.h>
 #include <linux/workqueue.h>
-
-#include <scsi/scsi.h>
-#include <scsi/scsi_cmnd.h>
-#include <scsi/scsi_device.h>
+#include "../../scsi/scsi.h"
 #include <scsi/scsi_host.h>
-#include <scsi/scsi_tcq.h>
+
 
 #include "mptbase.h"
 #include "mptscsih.h"
@@ -99,7 +95,7 @@ MODULE_LICENSE("GPL");
 
 /* Set string for command line args from insmod */
 #ifdef MODULE
-char *mptscsih = NULL;
+char *mptscsih = 0;
 #endif
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -158,16 +154,16 @@ typedef struct _dv_parameters {
  *  Other private/forward protos...
  */
 static int     mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
-static void    mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq);
+static void    mptscsih_report_queue_full(Scsi_Cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq);
 static int     mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
 
-static int     mptscsih_AddSGE(MPT_SCSI_HOST *hd, struct scsi_cmnd *SCpnt,
+static int     mptscsih_AddSGE(MPT_SCSI_HOST *hd, Scsi_Cmnd *SCpnt,
                                 SCSIIORequest_t *pReq, int req_idx);
 static void    mptscsih_freeChainBuffers(MPT_SCSI_HOST *hd, int req_idx);
 static int     mptscsih_initChainBuffers (MPT_SCSI_HOST *hd, int init);
-static void    copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply);
+static void    copy_sense_data(Scsi_Cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply);
 static int     mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd);
-static u32     SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc);
+static u32     SCPNT_TO_LOOKUP_IDX(Scsi_Cmnd *sc);
 static MPT_FRAME_HDR *mptscsih_search_pendingQ(MPT_SCSI_HOST *hd, int scpnt_idx);
 static void    post_pendingQ_commands(MPT_SCSI_HOST *hd);
 
@@ -252,11 +248,104 @@ static struct mptscsih_driver_setup
        driver_setup = MPTSCSIH_DRIVER_SETUP;
 
 #ifdef MPTSCSIH_DBG_TIMEOUT
-static struct scsi_cmnd *foo_to[8];
+static Scsi_Cmnd *foo_to[8];
 #endif
 
 static struct scsi_host_template driver_template;
 
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ *  Private inline routines...
+ */
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/* 19991030 -sralston
+ *  Return absolute SCSI data direction:
+ *     1 = _DATA_OUT
+ *     0 = _DIR_NONE
+ *    -1 = _DATA_IN
+ *
+ * Changed: 3-20-2002 pdelaney to use the default data
+ * direction and the defines set up in the
+ * 2.4 kernel series
+ *     1 = _DATA_OUT   changed to SCSI_DATA_WRITE (1)
+ *     0 = _DIR_NONE   changed to SCSI_DATA_NONE (3)
+ *    -1 = _DATA_IN    changed to SCSI_DATA_READ (2)
+ * If the direction is unknown, fall through to original code.
+ *
+ * Mid-layer bug fix(): sg interface generates the wrong data
+ * direction in some cases. Set the direction the hard way for
+ * the most common commands.
+ */
+static inline int
+mptscsih_io_direction(Scsi_Cmnd *cmd)
+{
+       switch (cmd->cmnd[0]) {
+       case WRITE_6:
+       case WRITE_10:
+       case WRITE_16:
+               return SCSI_DATA_WRITE;
+               break;
+       case READ_6:
+       case READ_10:
+       case READ_16:
+               return SCSI_DATA_READ;
+               break;
+       }
+
+       if (cmd->sc_data_direction != SCSI_DATA_UNKNOWN)
+               return cmd->sc_data_direction;
+
+       switch (cmd->cmnd[0]) {
+       /*  _DATA_OUT commands  */
+       case WRITE_6:           case WRITE_10:          case WRITE_12:
+       case WRITE_16:
+       case WRITE_LONG:        case WRITE_SAME:        case WRITE_BUFFER:
+       case WRITE_VERIFY:      case WRITE_VERIFY_12:
+       case COMPARE:           case COPY:              case COPY_VERIFY:
+       case SEARCH_EQUAL:      case SEARCH_HIGH:       case SEARCH_LOW:
+       case SEARCH_EQUAL_12:   case SEARCH_HIGH_12:    case SEARCH_LOW_12:
+       case MODE_SELECT:       case MODE_SELECT_10:    case LOG_SELECT:
+       case SEND_DIAGNOSTIC:   case CHANGE_DEFINITION: case UPDATE_BLOCK:
+       case SET_WINDOW:        case MEDIUM_SCAN:       case SEND_VOLUME_TAG:
+       case REASSIGN_BLOCKS:
+       case PERSISTENT_RESERVE_OUT:
+       case 0xea:
+       case 0xa3:
+               return SCSI_DATA_WRITE;
+
+       /*  No data transfer commands  */
+       case SEEK_6:            case SEEK_10:
+       case RESERVE:           case RELEASE:
+       case TEST_UNIT_READY:
+       case START_STOP:
+       case ALLOW_MEDIUM_REMOVAL:
+               return SCSI_DATA_NONE;
+
+       /*  Conditional data transfer commands  */
+       case FORMAT_UNIT:
+               if (cmd->cmnd[1] & 0x10)        /* FmtData (data out phase)? */
+                       return SCSI_DATA_WRITE;
+               else
+                       return SCSI_DATA_NONE;
+
+       case VERIFY:
+               if (cmd->cmnd[1] & 0x02)        /* VERIFY:BYTCHK (data out phase)? */
+                       return SCSI_DATA_WRITE;
+               else
+                       return SCSI_DATA_NONE;
+
+       case RESERVE_10:
+               if (cmd->cmnd[1] & 0x03)        /* RESERVE:{LongID|Extent} (data out phase)? */
+                       return SCSI_DATA_WRITE;
+               else
+                       return SCSI_DATA_NONE;
+
+       /*  Must be data _IN!  */
+       default:
+               return SCSI_DATA_READ;
+       }
+} /* mptscsih_io_direction() */
+
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /**
  *     mptscsih_add_sge - Place a simple SGE at address pAddr.
@@ -369,13 +458,13 @@ mptscsih_getFreeChainBuffer(MPT_SCSI_HOST *hd, int *retIndex)
  *     mptscsih_AddSGE - Add a SGE (plus chain buffers) to the
  *     SCSIIORequest_t Message Frame.
  *     @hd: Pointer to MPT_SCSI_HOST structure
- *     @SCpnt: Pointer to scsi_cmnd structure
+ *     @SCpnt: Pointer to Scsi_Cmnd structure
  *     @pReq: Pointer to SCSIIORequest_t structure
  *
  *     Returns ...
  */
 static int
-mptscsih_AddSGE(MPT_SCSI_HOST *hd, struct scsi_cmnd *SCpnt,
+mptscsih_AddSGE(MPT_SCSI_HOST *hd, Scsi_Cmnd *SCpnt,
                SCSIIORequest_t *pReq, int req_idx)
 {
        char    *psge;
@@ -408,20 +497,29 @@ mptscsih_AddSGE(MPT_SCSI_HOST *hd, struct scsi_cmnd *SCpnt,
        if ( (sges_left = SCpnt->use_sg) ) {
                sges_left = pci_map_sg(hd->ioc->pcidev,
                               (struct scatterlist *) SCpnt->request_buffer,
-                              SCpnt->use_sg,
-                              SCpnt->sc_data_direction);
+                              SCpnt->use_sg,
+                              scsi_to_pci_dma_dir(SCpnt->sc_data_direction));
                if (sges_left == 0)
                        return FAILED;
        } else if (SCpnt->request_bufflen) {
-               SCpnt->SCp.dma_handle = pci_map_single(hd->ioc->pcidev,
+               dma_addr_t       buf_dma_addr;
+               scPrivate       *my_priv;
+
+               buf_dma_addr = pci_map_single(hd->ioc->pcidev,
                                      SCpnt->request_buffer,
                                      SCpnt->request_bufflen,
-                                     SCpnt->sc_data_direction);
+                                     scsi_to_pci_dma_dir(SCpnt->sc_data_direction));
+
+               /* We hide it here for later unmap. */
+               my_priv = (scPrivate *) &SCpnt->SCp;
+               my_priv->p1 = (void *)(ulong) buf_dma_addr;
+
                dsgprintk((MYIOC_s_INFO_FMT "SG: non-SG for %p, len=%d\n",
                                hd->ioc->name, SCpnt, SCpnt->request_bufflen));
+
                mptscsih_add_sge((char *) &pReq->SGL,
                        0xD1000000|MPT_SGE_FLAGS_ADDRESSING|sgdir|SCpnt->request_bufflen,
-                       SCpnt->SCp.dma_handle);
+                       buf_dma_addr);
 
                return SUCCESS;
        }
@@ -610,7 +708,7 @@ nextSGEset:
 static int
 mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
 {
-       struct scsi_cmnd        *sc;
+       Scsi_Cmnd       *sc;
        MPT_SCSI_HOST   *hd;
        SCSIIORequest_t *pScsiReq;
        SCSIIOReply_t   *pScsiReply;
@@ -731,15 +829,6 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
                        break;
 
                case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:      /* 0x0049 */
-                       sc->result = (DRIVER_SENSE << 24) | (DID_OK << 16) | 
-                                       (CHECK_CONDITION << 1);
-                       sc->sense_buffer[0] = 0x70;
-                       sc->sense_buffer[2] = NO_SENSE;
-                       sc->sense_buffer[12] = 0;
-                       sc->sense_buffer[13] = 0;
-                       dprintk((KERN_NOTICE "RESIDUAL_MISMATCH: result=%x on id=%d\n", sc->result, sc->target));
-                       break;
-               
                case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN:          /* 0x0045 */
                        /*
                         *  Do upfront check for valid SenseData and give it
@@ -857,10 +946,14 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
        /* Unmap the DMA buffers, if any. */
        if (sc->use_sg) {
                pci_unmap_sg(ioc->pcidev, (struct scatterlist *) sc->request_buffer,
-                           sc->use_sg, sc->sc_data_direction);
+                           sc->use_sg, scsi_to_pci_dma_dir(sc->sc_data_direction));
        } else if (sc->request_bufflen) {
-               pci_unmap_single(ioc->pcidev, sc->SCp.dma_handle,
-                               sc->request_bufflen, sc->sc_data_direction);
+               scPrivate       *my_priv;
+
+               my_priv = (scPrivate *) &sc->SCp;
+               pci_unmap_single(ioc->pcidev, (dma_addr_t)(ulong)my_priv->p1,
+                          sc->request_bufflen,
+                          scsi_to_pci_dma_dir(sc->sc_data_direction));
        }
 
        hd->ScsiLookup[req_idx] = NULL;
@@ -881,7 +974,7 @@ static void
 flush_doneQ(MPT_SCSI_HOST *hd)
 {
        MPT_DONE_Q      *buffer;
-       struct scsi_cmnd        *SCpnt;
+       Scsi_Cmnd       *SCpnt;
        unsigned long    flags;
 
        /* Flush the doneQ.
@@ -899,9 +992,9 @@ flush_doneQ(MPT_SCSI_HOST *hd)
                 */
                Q_DEL_ITEM(buffer);
 
-               /* Set the struct scsi_cmnd pointer
+               /* Set the Scsi_Cmnd pointer
                 */
-               SCpnt = (struct scsi_cmnd *) buffer->argp;
+               SCpnt = (Scsi_Cmnd *) buffer->argp;
                buffer->argp = NULL;
 
                /* Add to the freeQ
@@ -922,7 +1015,7 @@ flush_doneQ(MPT_SCSI_HOST *hd)
  * Calling function will finish processing.
  */
 static void
-search_doneQ_for_cmd(MPT_SCSI_HOST *hd, struct scsi_cmnd *SCpnt)
+search_doneQ_for_cmd(MPT_SCSI_HOST *hd, Scsi_Cmnd *SCpnt)
 {
        unsigned long    flags;
        MPT_DONE_Q      *buffer;
@@ -931,12 +1024,12 @@ search_doneQ_for_cmd(MPT_SCSI_HOST *hd, struct scsi_cmnd *SCpnt)
        if (!Q_IS_EMPTY(&hd->doneQ)) {
                buffer = hd->doneQ.head;
                do {
-                       struct scsi_cmnd *sc = (struct scsi_cmnd *) buffer->argp;
+                       Scsi_Cmnd *sc = (Scsi_Cmnd *) buffer->argp;
                        if (SCpnt == sc) {
                                Q_DEL_ITEM(buffer);
                                SCpnt->result = sc->result;
 
-                               /* Set the struct scsi_cmnd pointer
+                               /* Set the Scsi_Cmnd pointer
                                 */
                                buffer->argp = NULL;
 
@@ -964,7 +1057,7 @@ search_doneQ_for_cmd(MPT_SCSI_HOST *hd, struct scsi_cmnd *SCpnt)
 static void
 mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
 {
-       struct scsi_cmnd        *SCpnt;
+       Scsi_Cmnd       *SCpnt;
        MPT_FRAME_HDR   *mf;
        MPT_DONE_Q      *buffer;
        int              ii;
@@ -1000,12 +1093,15 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
                                        pci_unmap_sg(hd->ioc->pcidev,
                                                (struct scatterlist *) SCpnt->request_buffer,
                                                SCpnt->use_sg,
-                                               SCpnt->sc_data_direction);
+                                               scsi_to_pci_dma_dir(SCpnt->sc_data_direction));
                                } else if (SCpnt->request_bufflen) {
+                                       scPrivate       *my_priv;
+
+                                       my_priv = (scPrivate *) &SCpnt->SCp;
                                        pci_unmap_single(hd->ioc->pcidev,
-                                               SCpnt->SCp.dma_handle,
+                                               (dma_addr_t)(ulong)my_priv->p1,
                                                SCpnt->request_bufflen,
-                                               SCpnt->sc_data_direction);
+                                               scsi_to_pci_dma_dir(SCpnt->sc_data_direction));
                                }
                        }
                        SCpnt->result = DID_RESET << 16;
@@ -1015,7 +1111,7 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
                        mptscsih_freeChainBuffers(hd, ii);
 
                        /* Free Message frames */
-                       mpt_free_msg_frame(ScsiDoneCtx, hd->ioc, mf);
+                       mpt_free_msg_frame(ScsiDoneCtx, hd->ioc->id, mf);
 
 #if 1
                        /* Post to doneQ, do not reply until POST phase
@@ -1027,7 +1123,7 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
                                buffer = hd->freeQ.head;
                                Q_DEL_ITEM(buffer);
 
-                               /* Set the struct scsi_cmnd pointer
+                               /* Set the Scsi_Cmnd pointer
                                 */
                                buffer->argp = (void *)SCpnt;
 
@@ -1053,7 +1149,7 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
  *     mptscsih_search_running_cmds - Delete any commands associated
  *             with the specified target and lun. Function called only
  *             when a lun is disable by mid-layer.
- *             Do NOT access the referenced scsi_cmnd structure or
+ *             Do NOT access the referenced Scsi_Cmnd structure or
  *             members. Will cause either a paging or NULL ptr error.
  *     @hd: Pointer to a SCSI HOST structure
  *     @target: target id
@@ -1088,7 +1184,7 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, uint target, uint lun)
                         */
                        hd->ScsiLookup[ii] = NULL;
                        mptscsih_freeChainBuffers(hd, ii);
-                       mpt_free_msg_frame(ScsiDoneCtx, hd->ioc, (MPT_FRAME_HDR *)mf);
+                       mpt_free_msg_frame(ScsiDoneCtx, hd->ioc->id, (MPT_FRAME_HDR *)mf);
                }
        }
 
@@ -1211,7 +1307,7 @@ static long last_queue_full = 0;
 /*
  *     mptscsih_report_queue_full - Report QUEUE_FULL status returned
  *     from a SCSI target device.
- *     @sc: Pointer to scsi_cmnd structure
+ *     @sc: Pointer to Scsi_Cmnd structure
  *     @pScsiReply: Pointer to SCSIIOReply_t
  *     @pScsiReq: Pointer to original SCSI request
  *
@@ -1220,7 +1316,7 @@ static long last_queue_full = 0;
  *     printk() API call, not more than once every 10 seconds.
  */
 static void
-mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq)
+mptscsih_report_queue_full(Scsi_Cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq)
 {
        long time = jiffies;
 
@@ -1396,7 +1492,7 @@ mptscsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
                hd->is_multipath = 1;
        }
 
-       /* SCSI needs scsi_cmnd lookup table!
+       /* SCSI needs Scsi_Cmnd lookup table!
         * (with size equal to req_depth*PtrSz!)
         */
        sz = hd->ioc->req_depth * sizeof(void *);
@@ -1836,7 +1932,16 @@ mptscsih_init(void)
 static void __exit
 mptscsih_exit(void)
 {
-       mpt_device_driver_deregister(MPTSCSIH_DRIVER);
+       MPT_ADAPTER     *ioc;
+
+       /* removing devices */
+       for(ioc = mpt_adapter_find_first(); ioc != NULL;
+         ioc = mpt_adapter_find_next(ioc)) {
+               if ((ioc->last_state != MPI_IOC_STATE_OPERATIONAL) ||
+                 (ioc->sh == NULL))
+                       continue;
+               mptscsih_remove(ioc->pcidev);
+       }
 
        mpt_reset_deregister(ScsiDoneCtx);
        dprintk((KERN_INFO MYNAM
@@ -1846,6 +1951,7 @@ mptscsih_exit(void)
        dprintk((KERN_INFO MYNAM
          ": Deregistered for IOC event notifications\n"));
 
+       mpt_device_driver_deregister(MPTSCSIH_DRIVER);
        mpt_deregister(ScsiScanDvCtx);
        mpt_deregister(ScsiTaskCtx);
        mpt_deregister(ScsiDoneCtx);
@@ -1860,7 +1966,7 @@ mptscsih_exit(void)
  *     mptscsih_info - Return information about MPT adapter
  *     @SChost: Pointer to Scsi_Host structure
  *
- *     (linux scsi_host_template.info routine)
+ *     (linux Scsi_Host_Template.info routine)
  *
  *     Returns pointer to buffer where information was written.
  */
@@ -2070,7 +2176,7 @@ static int mptscsih_user_command(MPT_ADAPTER *ioc, char *buffer, int length)
 /**
  *     mptscsih_proc_info - Return information about MPT adapter
  *
- *     (linux scsi_host_template.info routine)
+ *     (linux Scsi_Host_Template.info routine)
  *
  *     buffer: if write, user data; if read, buffer for user
  *     length: if write, return length;
@@ -2082,10 +2188,23 @@ static int mptscsih_user_command(MPT_ADAPTER *ioc, char *buffer, int length)
 int mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
                        int length, int func)
 {
-       MPT_SCSI_HOST   *hd = (MPT_SCSI_HOST *)host->hostdata;
-       MPT_ADAPTER     *ioc = hd->ioc;
+       MPT_ADAPTER     *ioc;
+       MPT_SCSI_HOST   *hd = NULL;
        int size = 0;
 
+       dprintk(("Called mptscsih_proc_info: hostno=%d, func=%d\n", host->host_no, func));
+       dprintk(("buffer %p, start=%p (%p) offset=%ld length = %d\n",
+                       buffer, start, *start, offset, length));
+
+       for (ioc = mpt_adapter_find_first(); ioc != NULL; ioc = mpt_adapter_find_next(ioc)) {
+               if ((ioc->sh) && (ioc->sh == host)) {
+                       hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
+                       break;
+               }
+       }
+       if ((ioc == NULL) || (ioc->sh == NULL) || (hd == NULL))
+               return 0;
+
        if (func) {
                size = mptscsih_user_command(ioc, buffer, length);
        } else {
@@ -2105,17 +2224,17 @@ int mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /**
  *     mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine.
- *     @SCpnt: Pointer to scsi_cmnd structure
+ *     @SCpnt: Pointer to Scsi_Cmnd structure
  *     @done: Pointer SCSI mid-layer IO completion function
  *
- *     (linux scsi_host_template.queuecommand routine)
+ *     (linux Scsi_Host_Template.queuecommand routine)
  *     This is the primary SCSI IO start routine.  Create a MPI SCSIIORequest
- *     from a linux scsi_cmnd request and send it to the IOC.
+ *     from a linux Scsi_Cmnd request and send it to the IOC.
  *
  *     Returns 0. (rtn value discarded by linux scsi mid-layer)
  */
 int
-mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
+mptscsih_qcmd(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
 {
        MPT_SCSI_HOST           *hd;
        MPT_FRAME_HDR           *mf;
@@ -2125,6 +2244,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
        unsigned long            flags;
        int      target;
        int      lun;
+       int      datadir;
        u32      datalen;
        u32      scsictl;
        u32      scsidir;
@@ -2162,7 +2282,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
        /*
         *  Put together a MPT SCSI request...
         */
-       if ((mf = mpt_get_msg_frame(ScsiDoneCtx, hd->ioc)) == NULL) {
+       if ((mf = mpt_get_msg_frame(ScsiDoneCtx, hd->ioc->id)) == NULL) {
                dprintk((MYIOC_s_WARN_FMT "QueueCmd, no msg frames!!\n",
                                hd->ioc->name));
                did_errcode = 2;
@@ -2175,15 +2295,21 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
 
        ADD_INDEX_LOG(my_idx);
 
+       /*
+        *  The scsi layer should be handling this stuff
+        *  (In 2.3.x it does -DaveM)
+        */
+
        /*  BUG FIX!  19991030 -sralston
         *    TUR's being issued with scsictl=0x02000000 (DATA_IN)!
         *    Seems we may receive a buffer (datalen>0) even when there
         *    will be no data transfer!  GRRRRR...
         */
-       if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
+       datadir = mptscsih_io_direction(SCpnt);
+       if (datadir == SCSI_DATA_READ) {
                datalen = SCpnt->request_bufflen;
                scsidir = MPI_SCSIIO_CONTROL_READ;      /* DATA IN  (host<--ioc<--dev) */
-       } else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
+       } else if (datadir == SCSI_DATA_WRITE) {
                datalen = SCpnt->request_bufflen;
                scsidir = MPI_SCSIIO_CONTROL_WRITE;     /* DATA OUT (host-->ioc-->dev) */
        } else {
@@ -2264,6 +2390,17 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
 
                        if (dvStatus || hd->ioc->spi_data.forceDv) {
 
+                               /* Write SDP1 on this I/O to this target */
+                               if (dvStatus & MPT_SCSICFG_NEGOTIATE) {
+                                       mptscsih_writeSDP1(hd, 0, target, hd->negoNvram);
+                                       dvStatus &= ~MPT_SCSICFG_NEGOTIATE;
+                                       hd->ioc->spi_data.dvStatus[target] =  dvStatus;
+                               } else if (dvStatus & MPT_SCSICFG_BLK_NEGO) {
+                                       mptscsih_writeSDP1(hd, 0, target, MPT_SCSICFG_BLK_NEGO);
+                                       dvStatus &= ~MPT_SCSICFG_BLK_NEGO;
+                                       hd->ioc->spi_data.dvStatus[target] =  dvStatus;
+                               }
+
 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
                                if ((dvStatus & MPT_SCSICFG_NEED_DV) ||
                                        (hd->ioc->spi_data.forceDv & MPT_SCSICFG_NEED_DV)) {
@@ -2311,7 +2448,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
 #endif
 
                if (issueCmd) {
-                       mpt_put_msg_frame(ScsiDoneCtx, hd->ioc, mf);
+                       mpt_put_msg_frame(ScsiDoneCtx, hd->ioc->id, mf);
                        dmfprintk((MYIOC_s_INFO_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n",
                                        hd->ioc->name, SCpnt, mf, my_idx));
                } else {
@@ -2339,7 +2476,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
                }
        } else {
                mptscsih_freeChainBuffers(hd, my_idx);
-               mpt_free_msg_frame(ScsiDoneCtx, hd->ioc, mf);
+               mpt_free_msg_frame(ScsiDoneCtx, hd->ioc->id, mf);
                did_errcode = 3;
                goto did_error;
        }
@@ -2358,7 +2495,7 @@ did_error:
                buffer = hd->freeQ.head;
                Q_DEL_ITEM(buffer);
 
-               /* Set the scsi_cmnd pointer
+               /* Set the Scsi_Cmnd pointer
                 */
                buffer->argp = (void *)SCpnt;
 
@@ -2592,7 +2729,7 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun
 
        /* Return Fail to calling function if no message frames available.
         */
-       if ((mf = mpt_get_msg_frame(ScsiTaskCtx, hd->ioc)) == NULL) {
+       if ((mf = mpt_get_msg_frame(ScsiTaskCtx, hd->ioc->id)) == NULL) {
                dtmprintk((MYIOC_s_WARN_FMT "IssueTaskMgmt, no msg frames!!\n",
                                hd->ioc->name));
                //return FAILED;
@@ -2636,7 +2773,7 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun
        hd->TMtimer.expires = jiffies + timeout;
        add_timer(&hd->TMtimer);
 
-       if ((retval = mpt_send_handshake_request(ScsiTaskCtx, hd->ioc,
+       if ((retval = mpt_send_handshake_request(ScsiTaskCtx, hd->ioc->id,
                                sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, sleepFlag))
        != 0) {
                dtmprintk((MYIOC_s_WARN_FMT "_send_handshake FAILED!"
@@ -2644,7 +2781,7 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun
                hd->numTMrequests--;
                hd->tmPtr = NULL;
                del_timer(&hd->TMtimer);
-               mpt_free_msg_frame(ScsiTaskCtx, hd->ioc, mf);
+               mpt_free_msg_frame(ScsiTaskCtx, hd->ioc->id, mf);
        }
 
        return retval;
@@ -2652,15 +2789,15 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /**
- *     mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant
- *     @SCpnt: Pointer to scsi_cmnd structure, IO to be aborted
+ *     mptscsih_abort - Abort linux Scsi_Cmnd routine, new_eh variant
+ *     @SCpnt: Pointer to Scsi_Cmnd structure, IO to be aborted
  *
- *     (linux scsi_host_template.eh_abort_handler routine)
+ *     (linux Scsi_Host_Template.eh_abort_handler routine)
  *
  *     Returns SUCCESS or FAILED.
  */
 int
-mptscsih_abort(struct scsi_cmnd * SCpnt)
+mptscsih_abort(Scsi_Cmnd * SCpnt)
 {
        MPT_SCSI_HOST   *hd;
        MPT_FRAME_HDR   *mf;
@@ -2708,7 +2845,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
         * and then following up with the reset request.
         */
        if ((mf = mptscsih_search_pendingQ(hd, scpnt_idx)) != NULL) {
-               mpt_put_msg_frame(ScsiDoneCtx, hd->ioc, mf);
+               mpt_put_msg_frame(ScsiDoneCtx, hd->ioc->id, mf);
                post_pendingQ_commands(hd);
                dtmprintk((KERN_WARNING MYNAM ": %s: mptscsih_abort: "
                           "Posting pended cmd! (sc=%p)\n",
@@ -2755,14 +2892,14 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /**
  *     mptscsih_dev_reset - Perform a SCSI TARGET_RESET!  new_eh variant
- *     @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
+ *     @SCpnt: Pointer to Scsi_Cmnd structure, IO which reset is due to
  *
- *     (linux scsi_host_template.eh_dev_reset_handler routine)
+ *     (linux Scsi_Host_Template.eh_dev_reset_handler routine)
  *
  *     Returns SUCCESS or FAILED.
  */
 int
-mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
+mptscsih_dev_reset(Scsi_Cmnd * SCpnt)
 {
        MPT_SCSI_HOST   *hd;
        spinlock_t      *host_lock = SCpnt->device->host->host_lock;
@@ -2810,14 +2947,14 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /**
  *     mptscsih_bus_reset - Perform a SCSI BUS_RESET!  new_eh variant
- *     @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
+ *     @SCpnt: Pointer to Scsi_Cmnd structure, IO which reset is due to
  *
- *     (linux scsi_host_template.eh_bus_reset_handler routine)
+ *     (linux Scsi_Host_Template.eh_bus_reset_handler routine)
  *
  *     Returns SUCCESS or FAILED.
  */
 int
-mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
+mptscsih_bus_reset(Scsi_Cmnd * SCpnt)
 {
        MPT_SCSI_HOST   *hd;
        spinlock_t      *host_lock = SCpnt->device->host->host_lock;
@@ -2865,14 +3002,14 @@ mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
 /**
  *     mptscsih_host_reset - Perform a SCSI host adapter RESET!
  *     new_eh variant
- *     @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
+ *     @SCpnt: Pointer to Scsi_Cmnd structure, IO which reset is due to
  *
- *     (linux scsi_host_template.eh_host_reset_handler routine)
+ *     (linux Scsi_Host_Template.eh_host_reset_handler routine)
  *
  *     Returns SUCCESS or FAILED.
  */
 int
-mptscsih_host_reset(struct scsi_cmnd *SCpnt)
+mptscsih_host_reset(Scsi_Cmnd *SCpnt)
 {
        MPT_SCSI_HOST *  hd;
        int              status = SUCCESS;
@@ -3108,7 +3245,7 @@ mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
  *     Init memory once per id (not LUN).
  */
 int
-mptscsih_slave_alloc(struct scsi_device *device)
+mptscsih_slave_alloc(Scsi_Device *device)
 {
        struct Scsi_Host        *host = device->host;
        MPT_SCSI_HOST           *hd;
@@ -3148,7 +3285,7 @@ mptscsih_slave_alloc(struct scsi_device *device)
  *     Called if no device present or device being unloaded
  */
 void
-mptscsih_slave_destroy(struct scsi_device *device)
+mptscsih_slave_destroy(Scsi_Device *device)
 {
        struct Scsi_Host        *host = device->host;
        MPT_SCSI_HOST           *hd;
@@ -3213,7 +3350,7 @@ mptscsih_slave_destroy(struct scsi_device *device)
  *     Return non-zero if fails.
  */
 int
-mptscsih_slave_configure(struct scsi_device *device)
+mptscsih_slave_configure(Scsi_Device *device)
 {
        struct Scsi_Host        *sh = device->host;
        VirtDevice              *pTarget;
@@ -3296,7 +3433,7 @@ slave_configure_exit:
  *
  */
 static void
-copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
+copy_sense_data(Scsi_Cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
 {
        VirtDevice      *target;
        SCSIIORequest_t *pReq;
@@ -3374,7 +3511,7 @@ copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSI
 }
 
 static u32
-SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc)
+SCPNT_TO_LOOKUP_IDX(Scsi_Cmnd *sc)
 {
        MPT_SCSI_HOST *hd;
        int i;
@@ -3471,12 +3608,12 @@ post_pendingQ_commands(MPT_SCSI_HOST *hd)
                        continue;
                }
 
-               mpt_put_msg_frame(ScsiDoneCtx, hd->ioc, mf);
+               mpt_put_msg_frame(ScsiDoneCtx, hd->ioc->id, mf);
 
 #if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY)
                {
                        u16              req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
-                       struct scsi_cmnd        *sc = hd->ScsiLookup[req_idx];
+                       Scsi_Cmnd       *sc = hd->ScsiLookup[req_idx];
                        printk(MYIOC_s_INFO_FMT "Issued SCSI cmd (sc=%p) idx=%d (mf=%p)\n",
                                        hd->ioc->name, sc, req_idx, mf);
                }
@@ -3538,7 +3675,7 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
                 */
                if (hd->cmdPtr) {
                        del_timer(&hd->timer);
-                       mpt_free_msg_frame(ScsiScanDvCtx, ioc, hd->cmdPtr);
+                       mpt_free_msg_frame(ScsiScanDvCtx, ioc->id, hd->cmdPtr);
                }
 
                /* 2d. If a task management has not completed,
@@ -3546,7 +3683,7 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
                 */
                if (hd->tmPtr) {
                        del_timer(&hd->TMtimer);
-                       mpt_free_msg_frame(ScsiTaskCtx, ioc, hd->tmPtr);
+                       mpt_free_msg_frame(ScsiTaskCtx, ioc->id, hd->tmPtr);
                }
 
 #ifdef MPTSCSIH_DBG_TIMEOUT
@@ -4240,7 +4377,7 @@ mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *
                        }
                }
 
-               data_56 = 0x0F;  /* Default to full capabilities if Inq data length is < 57 */
+               data_56 = 0;
                if (dlen > 56) {
                        if ( (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_56))) {
                        /* Update the target capabilities
@@ -4305,16 +4442,14 @@ void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byt
                        }
 
                        if (target->inq_data[7] & 0x10) {
-                               /* bits 2 & 3 show Clocking support
+                               /* bits 2 & 3 show DT support
                                 */
-                               if ((byte56 & 0x0C) == 0)
+                               if ((byte56 & 0x04) == 0)
                                        factor = MPT_ULTRA2;
-                               else {
-                                       if ((byte56 & 0x03) == 0)
-                                               factor = MPT_ULTRA160;
-                                       else
-                                               factor = MPT_ULTRA320;
-                               }
+                               else if ((byte56 & 0x03) == 0)
+                                       factor = MPT_ULTRA160;
+                               else
+                                       factor = MPT_ULTRA320;
                                offset = pspi_data->maxSyncOffset;
 
                                /* If RAID, never disable QAS
@@ -4323,9 +4458,8 @@ void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byt
                                 * bit 1 QAS support, non-raid only
                                 * bit 0 IU support
                                 */
-                               if ((target->raidVolume == 1) || (byte56 & 0x02)) {
+                               if ((target->raidVolume == 1) || ((byte56 & 0x02) != 0))
                                        noQas = 0;
-                               }
                        } else {
                                factor = MPT_ASYNC;
                                offset = 0;
@@ -4404,7 +4538,7 @@ void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byt
                                /* Disable QAS in a mixed configuration case
                                */
 
-                               ddvtprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id));
+//                             ddvtprintk((KERN_INFO "Disabling QAS!\n"));
                                for (ii = 0; ii < id; ii++) {
                                        if ( (vdev = hd->Targets[ii]) ) {
                                                vdev->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
@@ -4412,15 +4546,6 @@ void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byt
                                }
                        }
                }
-               
-               /* Write SDP1 on this I/O to this target */
-               if (pspi_data->dvStatus[id] & MPT_SCSICFG_NEGOTIATE) {
-                       mptscsih_writeSDP1(hd, 0, id, hd->negoNvram);
-                       pspi_data->dvStatus[id] &= ~MPT_SCSICFG_NEGOTIATE;
-               } else if (pspi_data->dvStatus[id] & MPT_SCSICFG_BLK_NEGO) {
-                       mptscsih_writeSDP1(hd, 0, id, MPT_SCSICFG_BLK_NEGO);
-                       pspi_data->dvStatus[id] &= ~MPT_SCSICFG_BLK_NEGO;
-               }
        }
 
        return;
@@ -4653,7 +4778,7 @@ mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
 
                /* Get a MF for this command.
                 */
-               if ((mf = mpt_get_msg_frame(ScsiDoneCtx, ioc)) == NULL) {
+               if ((mf = mpt_get_msg_frame(ScsiDoneCtx, ioc->id)) == NULL) {
                        dprintk((MYIOC_s_WARN_FMT "write SDP1: no msg frames!\n",
                                                ioc->name));
                        return -EAGAIN;
@@ -4717,7 +4842,7 @@ mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
                                ioc->name, id, (id | (bus<<8)),
                                requested, configuration));
 
-               mpt_put_msg_frame(ScsiDoneCtx, ioc, mf);
+               mpt_put_msg_frame(ScsiDoneCtx, ioc->id, mf);
        }
 
        return 0;
@@ -4748,7 +4873,7 @@ mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus)
 
        /* Get a MF for this command.
         */
-       if ((mf = mpt_get_msg_frame(ScsiDoneCtx, ioc)) == NULL) {
+       if ((mf = mpt_get_msg_frame(ScsiDoneCtx, ioc->id)) == NULL) {
                dprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n",
                                        ioc->name));
                return -EAGAIN;
@@ -4797,7 +4922,7 @@ mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus)
                "writeIOCPage4: pgaddr 0x%x\n",
                        ioc->name, (target_id | (bus<<8))));
 
-       mpt_put_msg_frame(ScsiDoneCtx, ioc, mf);
+       mpt_put_msg_frame(ScsiDoneCtx, ioc->id, mf);
 
        return 0;
 }
@@ -5109,7 +5234,7 @@ mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io)
 
        /* Get and Populate a free Frame
         */
-       if ((mf = mpt_get_msg_frame(ScsiScanDvCtx, hd->ioc)) == NULL) {
+       if ((mf = mpt_get_msg_frame(ScsiScanDvCtx, hd->ioc->id)) == NULL) {
                ddvprintk((MYIOC_s_WARN_FMT "_do_raid: no msg frames!\n",
                                        hd->ioc->name));
                return -EAGAIN;
@@ -5134,7 +5259,7 @@ mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io)
                        hd->ioc->name, action, io->id));
 
        hd->pLocal = NULL;
-       hd->timer.expires = jiffies + HZ*10; /* 10 second timeout */
+       hd->timer.expires = jiffies + HZ*2; /* 2 second timeout */
        scandv_wait_done = 0;
 
        /* Save cmd pointer, for resource free if timeout or
@@ -5143,7 +5268,7 @@ mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io)
        hd->cmdPtr = mf;
 
        add_timer(&hd->timer);
-       mpt_put_msg_frame(ScsiScanDvCtx, hd->ioc, mf);
+       mpt_put_msg_frame(ScsiScanDvCtx, hd->ioc->id, mf);
        wait_event(scandv_waitq, scandv_wait_done);
 
        if ((hd->pLocal == NULL) || (hd->pLocal->completion != MPT_SCANDV_GOOD))
@@ -5290,7 +5415,7 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
 
        /* Get and Populate a free Frame
         */
-       if ((mf = mpt_get_msg_frame(ScsiScanDvCtx, hd->ioc)) == NULL) {
+       if ((mf = mpt_get_msg_frame(ScsiScanDvCtx, hd->ioc->id)) == NULL) {
                ddvprintk((MYIOC_s_WARN_FMT "No msg frames!\n",
                                        hd->ioc->name));
                return -EBUSY;
@@ -5380,7 +5505,7 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
        hd->cmdPtr = mf;
 
        add_timer(&hd->timer);
-       mpt_put_msg_frame(ScsiScanDvCtx, hd->ioc, mf);
+       mpt_put_msg_frame(ScsiScanDvCtx, hd->ioc->id, mf);
        wait_event(scandv_waitq, scandv_wait_done);
 
        if (hd->pLocal) {
@@ -5588,7 +5713,7 @@ mptscsih_domainValidation(void *arg)
        did = 1;
        while (did) {
                did = 0;
-               list_for_each_entry(ioc, &ioc_list, list) {
+               for (ioc = mpt_adapter_find_first(); ioc != NULL; ioc = mpt_adapter_find_next(ioc)) {
                        spin_lock_irqsave(&dvtaskQ_lock, flags);
                        if (dvtaskQ_release) {
                                dvtaskQ_active = 0;