Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / drivers / message / fusion / mptscsih.c
index 3a3ef12..84fa271 100644 (file)
@@ -1,32 +1,11 @@
 /*
  *  linux/drivers/message/fusion/mptscsih.c
- *      High performance SCSI / Fibre Channel SCSI Host device driver.
- *      For use with PCI chip/adapter(s):
- *          LSIFC9xx/LSI409xx Fibre Channel
+ *      For use with LSI Logic PCI chip/adapter(s)
  *      running LSI Logic Fusion MPT (Message Passing Technology) firmware.
  *
- *  Credits:
- *      This driver would not exist if not for Alan Cox's development
- *      of the linux i2o driver.
- *
- *      A special thanks to Pamela Delaney (LSI Logic) for tons of work
- *      and countless enhancements while adding support for the 1030
- *      chip family.  Pam has been instrumental in the development of
- *      of the 2.xx.xx series fusion drivers, and her contributions are
- *      far too numerous to hope to list in one place.
- *
- *      A huge debt of gratitude is owed to David S. Miller (DaveM)
- *      for fixing much of the stupid and broken stuff in the early
- *      driver while porting to sparc64 platform.  THANK YOU!
- *
- *      (see mptbase.c)
- *
- *  Copyright (c) 1999-2004 LSI Logic Corporation
- *  Original author: Steven J. Ralston
- *  (mailto:sjralston1@netscape.net)
+ *  Copyright (c) 1999-2005 LSI Logic Corporation
  *  (mailto:mpt_linux_developer@lsil.com)
  *
- *  $Id: mptscsih.c,v 1.104 2002/12/03 21:26:34 pdelaney Exp $
  */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
@@ -83,6 +62,7 @@
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_tcq.h>
+#include <scsi/scsi_dbg.h>
 
 #include "mptbase.h"
 #include "mptscsih.h"
@@ -96,27 +76,6 @@ MODULE_AUTHOR(MODULEAUTHOR);
 MODULE_DESCRIPTION(my_NAME);
 MODULE_LICENSE("GPL");
 
-/* Command line args */
-static int mpt_dv = MPTSCSIH_DOMAIN_VALIDATION;
-MODULE_PARM(mpt_dv, "i");
-MODULE_PARM_DESC(mpt_dv, " DV Algorithm: enhanced=1, basic=0 (default=MPTSCSIH_DOMAIN_VALIDATION=1)");
-
-static int mpt_width = MPTSCSIH_MAX_WIDTH;
-MODULE_PARM(mpt_width, "i");
-MODULE_PARM_DESC(mpt_width, " Max Bus Width: wide=1, narrow=0 (default=MPTSCSIH_MAX_WIDTH=1)");
-
-static int mpt_factor = MPTSCSIH_MIN_SYNC;
-MODULE_PARM(mpt_factor, "h");
-MODULE_PARM_DESC(mpt_factor, " Min Sync Factor (default=MPTSCSIH_MIN_SYNC=0x08)");
-
-static int mpt_saf_te = MPTSCSIH_SAF_TE;
-MODULE_PARM(mpt_saf_te, "i");
-MODULE_PARM_DESC(mpt_saf_te, " Force enabling SEP Processor: enable=1  (default=MPTSCSIH_SAF_TE=0)");
-
-static int mpt_pq_filter = 0;
-MODULE_PARM(mpt_pq_filter, "i");
-MODULE_PARM_DESC(mpt_pq_filter, " Enable peripheral qualifier filter: enable=1  (default=0)");
-
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 
 typedef struct _BIG_SENSE_BUF {
@@ -135,8 +94,9 @@ typedef struct _BIG_SENSE_BUF {
 
 #define MPT_ICFLAG_BUF_CAP     0x01    /* ReadBuffer Read Capacity format */
 #define MPT_ICFLAG_ECHO                0x02    /* ReadBuffer Echo buffer format */
-#define MPT_ICFLAG_PHYS_DISK   0x04    /* Any SCSI IO but do Phys Disk Format */
-#define MPT_ICFLAG_TAGGED_CMD  0x08    /* Do tagged IO */
+#define MPT_ICFLAG_EBOS                0x04    /* ReadBuffer Echo buffer has EBOS */
+#define MPT_ICFLAG_PHYS_DISK   0x08    /* Any SCSI IO but do Phys Disk Format */
+#define MPT_ICFLAG_TAGGED_CMD  0x10    /* Do tagged IO */
 #define MPT_ICFLAG_DID_RESET   0x20    /* Bus Reset occurred with this command */
 #define MPT_ICFLAG_RESERVED    0x40    /* Reserved has been issued */
 
@@ -154,110 +114,42 @@ typedef struct _internal_cmd {
        u8              rsvd;
 } INTERNAL_CMD;
 
-typedef struct _negoparms {
-       u8 width;
-       u8 offset;
-       u8 factor;
-       u8 flags;
-} NEGOPARMS;
-
-typedef struct _dv_parameters {
-       NEGOPARMS        max;
-       NEGOPARMS        now;
-       u8               cmd;
-       u8               id;
-       u16              pad1;
-} DVPARAMETERS;
-
-
 /*
  *  Other private/forward protos...
  */
-static int     mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
+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 int     mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
+int            mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
 
 static int     mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
                                 SCSIIORequest_t *pReq, int req_idx);
 static void    mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx);
-static void    copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply);
+static void    mptscsih_copy_sense_data(struct 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 int     mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout );
 static u32     SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc);
 
-static int     mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout);
 static int     mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout);
 
-static int     mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
-static int     mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
+int            mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
+int            mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
 
-static void    mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *data, int dlen);
-static void    mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56);
-static void    mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq);
-static void    mptscsih_setDevicePage1Flags (u8 width, u8 factor, u8 offset, int *requestedPtr, int *configurationPtr, u8 flags);
-static void    mptscsih_no_negotiate(MPT_SCSI_HOST *hd, int target_id);
-static int     mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target, int flags);
+static void    mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, struct scsi_device *sdev);
+static void    mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *vtarget, struct scsi_device *sdev);
 static int     mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus);
-static int     mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
-static void    mptscsih_timer_expired(unsigned long data);
+int            mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
 static int     mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
-static int     mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum);
-
-#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
-static int     mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io);
-static void    mptscsih_domainValidation(void *hd);
-static int     mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id);
-static void    mptscsih_qas_check(MPT_SCSI_HOST *hd, int id);
-static int     mptscsih_doDv(MPT_SCSI_HOST *hd, int channel, int target);
-static void    mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage);
-static void    mptscsih_fillbuf(char *buffer, int size, int index, int width);
-#endif
-/* module entry point */
-static int  __init   mptscsih_init  (void);
-static void __exit   mptscsih_exit  (void);
+static void    mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice);
 
-static int  mptscsih_probe (struct pci_dev *, const struct pci_device_id *);
-static void mptscsih_remove(struct pci_dev *);
-static void mptscsih_shutdown(struct device *);
+void           mptscsih_remove(struct pci_dev *);
+void           mptscsih_shutdown(struct pci_dev *);
 #ifdef CONFIG_PM
-static int mptscsih_suspend(struct pci_dev *pdev, pm_message_t state);
-static int mptscsih_resume(struct pci_dev *pdev);
+int            mptscsih_suspend(struct pci_dev *pdev, pm_message_t state);
+int            mptscsih_resume(struct pci_dev *pdev);
 #endif
 
-
-/*
- *     Private data...
- */
-
-static int     mpt_scsi_hosts = 0;
-
-static int     ScsiDoneCtx = -1;
-static int     ScsiTaskCtx = -1;
-static int     ScsiScanDvCtx = -1; /* Used only for bus scan and dv */
-
 #define SNS_LEN(scp)   sizeof((scp)->sense_buffer)
 
-#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
-/*
- * Domain Validation task structure
- */
-static DEFINE_SPINLOCK(dvtaskQ_lock);
-static int dvtaskQ_active = 0;
-static int dvtaskQ_release = 0;
-static struct work_struct      mptscsih_dvTask;
-#endif
-
-/*
- * Wait Queue setup
- */
-static DECLARE_WAIT_QUEUE_HEAD (scandv_waitq);
-static int scandv_wait_done = 1;
-
-
-/* Driver command line structure
- */
-static struct scsi_host_template driver_template;
-
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /**
  *     mptscsih_add_sge - Place a simple SGE at address pAddr.
@@ -351,12 +243,12 @@ mptscsih_getFreeChainBuffer(MPT_ADAPTER *ioc, int *retIndex)
                offset = (u8 *)chainBuf - (u8 *)ioc->ChainBuffer;
                chain_idx = offset / ioc->req_sz;
                rc = SUCCESS;
-               dsgprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer (index %d), got buf=%p\n",
-                       ioc->name, *retIndex, chainBuf));
+               dsgprintk((MYIOC_s_ERR_FMT "getFreeChainBuffer chainBuf=%p ChainBuffer=%p offset=%d chain_idx=%d\n",
+                       ioc->name, chainBuf, ioc->ChainBuffer, offset, chain_idx));
        } else {
                rc = FAILED;
                chain_idx = MPT_HOST_NO_CHAIN;
-               dfailprintk((MYIOC_s_ERR_FMT "getFreeChainBuffer failed\n",
+               dfailprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer failed\n",
                        ioc->name));
        }
        spin_unlock_irqrestore(&ioc->FreeQlock, flags);
@@ -502,7 +394,7 @@ nextSGEset:
                         */
                        pReq->ChainOffset = 0;
                        RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor)  + 1) & 0x03;
-                       dsgprintk((MYIOC_s_ERR_FMT 
+                       dsgprintk((MYIOC_s_INFO_FMT
                            "Single Buffer RequestNB=%x, sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
                        ioc->RequestNB[req_idx] = RequestNB;
                }
@@ -561,11 +453,12 @@ nextSGEset:
                /* NOTE: psge points to the beginning of the chain element
                 * in current buffer. Get a chain buffer.
                 */
-               dsgprintk((MYIOC_s_INFO_FMT 
-                   "calling getFreeChainBuffer SCSI cmd=%02x (%p)\n",
-                   ioc->name, pReq->CDB[0], SCpnt));
-               if ((mptscsih_getFreeChainBuffer(ioc, &newIndex)) == FAILED)
+               if ((mptscsih_getFreeChainBuffer(ioc, &newIndex)) == FAILED) {
+                       dfailprintk((MYIOC_s_INFO_FMT
+                           "getFreeChainBuffer FAILED SCSI cmd=%02x (%p)\n",
+                           ioc->name, pReq->CDB[0], SCpnt));
                        return FAILED;
+               }
 
                /* Update the tracking arrays.
                 * If chainSge == NULL, update ReqToChain, else ChainToChain
@@ -619,18 +512,31 @@ nextSGEset:
  *
  *     Returns 1 indicating alloc'd request frame ptr should be freed.
  */
-static int
+int
 mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
 {
        struct scsi_cmnd        *sc;
        MPT_SCSI_HOST   *hd;
        SCSIIORequest_t *pScsiReq;
        SCSIIOReply_t   *pScsiReply;
-       u16              req_idx;
+       u16              req_idx, req_idx_MR;
 
        hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
 
        req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
+       req_idx_MR = (mr != NULL) ?
+           le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx) : req_idx;
+       if ((req_idx != req_idx_MR) ||
+           (mf->u.frame.linkage.arg1 == 0xdeadbeaf)) {
+               printk(MYIOC_s_ERR_FMT "Received a mf that was already freed\n",
+                   ioc->name);
+               printk (MYIOC_s_ERR_FMT
+                   "req_idx=%x req_idx_MR=%x mf=%p mr=%p sc=%p\n",
+                   ioc->name, req_idx, req_idx_MR, mf, mr,
+                   hd->ScsiLookup[req_idx_MR]);
+               return 0;
+       }
+
        sc = hd->ScsiLookup[req_idx];
        if (sc == NULL) {
                MPIHeader_t *hdr = (MPIHeader_t *)mf;
@@ -647,14 +553,20 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
                return 1;
        }
 
-       dmfprintk((MYIOC_s_INFO_FMT
-               "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n",
-               ioc->name, mf, mr, sc, req_idx));
-
        sc->result = DID_OK << 16;              /* Set default reply as OK */
        pScsiReq = (SCSIIORequest_t *) mf;
        pScsiReply = (SCSIIOReply_t *) mr;
 
+       if((ioc->facts.MsgVersion >= MPI_VERSION_01_05) && pScsiReply){
+               dmfprintk((MYIOC_s_INFO_FMT
+                       "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d,task-tag=%d)\n",
+                       ioc->name, mf, mr, sc, req_idx, pScsiReply->TaskTag));
+       }else{
+               dmfprintk((MYIOC_s_INFO_FMT
+                       "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n",
+                       ioc->name, mf, mr, sc, req_idx));
+       }
+
        if (pScsiReply == NULL) {
                /* special context reply handling */
                ;
@@ -669,21 +581,37 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
                xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
                sc->resid = sc->request_bufflen - xfer_cnt;
 
+               /*
+                *  if we get a data underrun indication, yet no data was
+                *  transferred and the SCSI status indicates that the
+                *  command was never started, change the data underrun
+                *  to success
+                */
+               if (status == MPI_IOCSTATUS_SCSI_DATA_UNDERRUN && xfer_cnt == 0 &&
+                   (scsi_status == MPI_SCSI_STATUS_BUSY ||
+                    scsi_status == MPI_SCSI_STATUS_RESERVATION_CONFLICT ||
+                    scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)) {
+                       status = MPI_IOCSTATUS_SUCCESS;
+               }
+
                dreplyprintk((KERN_NOTICE "Reply ha=%d id=%d lun=%d:\n"
                        "IOCStatus=%04xh SCSIState=%02xh SCSIStatus=%02xh\n"
                        "resid=%d bufflen=%d xfer_cnt=%d\n",
-                       ioc->id, pScsiReq->TargetID, pScsiReq->LUN[1],
-                       status, scsi_state, scsi_status, sc->resid, 
+                       ioc->id, sc->device->id, sc->device->lun,
+                       status, scsi_state, scsi_status, sc->resid,
                        sc->request_bufflen, xfer_cnt));
 
                if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)
-                       copy_sense_data(sc, hd, mf, pScsiReply);
-                
+                       mptscsih_copy_sense_data(sc, hd, mf, pScsiReply);
+
                /*
                 *  Look for + dump FCP ResponseInfo[]!
                 */
-               if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID) {
-                       printk(KERN_NOTICE "  FCP_ResponseInfo=%08xh\n",
+               if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID &&
+                   pScsiReply->ResponseInfo) {
+                       printk(KERN_NOTICE "ha=%d id=%d lun=%d: "
+                       "FCP_ResponseInfo=%08xh\n",
+                       ioc->id, sc->device->id, sc->device->lun,
                        le32_to_cpu(pScsiReply->ResponseInfo));
                }
 
@@ -704,7 +632,11 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
 
                case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE:       /* 0x0043 */
                        /* Spoof to SCSI Selection Timeout! */
-                       sc->result = DID_NO_CONNECT << 16;
+                       if (ioc->bus_type != FC)
+                               sc->result = DID_NO_CONNECT << 16;
+                       /* else fibre, just stall until rescan event */
+                       else
+                               sc->result = DID_REQUEUE << 16;
 
                        if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF)
                                hd->sel_timeout[pScsiReq->TargetID]++;
@@ -718,29 +650,18 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
                         */
                        sc->result = DID_RESET << 16;
 
-                       /* GEM Workaround. */
-                       if (ioc->bus_type == SCSI)
-                               mptscsih_no_negotiate(hd, sc->device->id);
                        break;
 
                case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:      /* 0x0049 */
-                       if ( xfer_cnt >= sc->underflow ) {
-                               /* Sufficient data transfer occurred */
+                       sc->resid = sc->request_bufflen - xfer_cnt;
+                       if((xfer_cnt==0)||(sc->underflow > xfer_cnt))
+                               sc->result=DID_SOFT_ERROR << 16;
+                       else /* Sufficient data transfer occurred */
                                sc->result = (DID_OK << 16) | scsi_status;
-                       } else if ( xfer_cnt == 0 ) {
-                               /* A CRC Error causes this condition; retry */ 
-                               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;
-                       } else {
-                               sc->result = DID_SOFT_ERROR << 16;
-                       }
-                       dreplyprintk((KERN_NOTICE "RESIDUAL_MISMATCH: result=%x on id=%d\n", sc->result, sc->target));
+                       dreplyprintk((KERN_NOTICE 
+                           "RESIDUAL_MISMATCH: result=%x on id=%d\n", sc->result, sc->device->id));
                        break;
-               
+
                case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN:          /* 0x0045 */
                        /*
                         *  Do upfront check for valid SenseData and give it
@@ -753,7 +674,10 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
                                ;
                        } else {
                                if (xfer_cnt < sc->underflow) {
-                                       sc->result = DID_SOFT_ERROR << 16;
+                                       if (scsi_status == SAM_STAT_BUSY)
+                                               sc->result = SAM_STAT_BUSY;
+                                       else
+                                               sc->result = DID_SOFT_ERROR << 16;
                                }
                                if (scsi_state & (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)) {
                                        /* What to do?
@@ -773,13 +697,17 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
                         */
                        if (scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)
                                mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
-                       
+
                        break;
 
+               case MPI_IOCSTATUS_SCSI_DATA_OVERRUN:           /* 0x0044 */
+                       sc->resid=0;
                case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR:        /* 0x0040 */
                case MPI_IOCSTATUS_SUCCESS:                     /* 0x0000 */
-                       scsi_status = pScsiReply->SCSIStatus;
-                       sc->result = (DID_OK << 16) | scsi_status;
+                       if (scsi_status == MPI_SCSI_STATUS_BUSY)
+                               sc->result = (DID_BUS_BUSY << 16) | scsi_status;
+                       else
+                               sc->result = (DID_OK << 16) | scsi_status;
                        if (scsi_state == 0) {
                                ;
                        } else if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
@@ -833,7 +761,6 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
                case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES:      /* 0x0006 */
                case MPI_IOCSTATUS_INVALID_FIELD:               /* 0x0007 */
                case MPI_IOCSTATUS_INVALID_STATE:               /* 0x0008 */
-               case MPI_IOCSTATUS_SCSI_DATA_OVERRUN:           /* 0x0044 */
                case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR:          /* 0x0046 */
                case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED:       /* 0x004A */
                default:
@@ -866,7 +793,6 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
        return 1;
 }
 
-
 /*
  *     mptscsih_flush_running_cmds - For each command found, search
  *             Scsi_Host instance taskQ and reply to OS.
@@ -905,18 +831,16 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
                         * Do OS callback
                         * Free driver resources (chain, msg buffers)
                         */
-                       if (scsi_device_online(SCpnt->device)) {
-                               if (SCpnt->use_sg) {
-                                       pci_unmap_sg(ioc->pcidev,
-                                               (struct scatterlist *) SCpnt->request_buffer,
-                                               SCpnt->use_sg,
-                                               SCpnt->sc_data_direction);
-                               } else if (SCpnt->request_bufflen) {
-                                       pci_unmap_single(ioc->pcidev,
-                                               SCpnt->SCp.dma_handle,
-                                               SCpnt->request_bufflen,
-                                               SCpnt->sc_data_direction);
-                               }
+                       if (SCpnt->use_sg) {
+                               pci_unmap_sg(ioc->pcidev,
+                                       (struct scatterlist *) SCpnt->request_buffer,
+                                       SCpnt->use_sg,
+                                       SCpnt->sc_data_direction);
+                       } else if (SCpnt->request_bufflen) {
+                               pci_unmap_single(ioc->pcidev,
+                                       SCpnt->SCp.dma_handle,
+                                       SCpnt->request_bufflen,
+                                       SCpnt->sc_data_direction);
                        }
                        SCpnt->result = DID_RESET << 16;
                        SCpnt->host_scribble = NULL;
@@ -940,33 +864,34 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
  *             when a lun is disable by mid-layer.
  *             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
- *     @lun: lun
+ *             (BUT, BUT, BUT, the code does reference it! - mdr)
+ *      @hd: Pointer to a SCSI HOST structure
+ *     @vdevice: per device private data
  *
  *     Returns: None.
  *
  *     Called from slave_destroy.
  */
 static void
-mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, uint target, uint lun)
+mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
 {
        SCSIIORequest_t *mf = NULL;
        int              ii;
        int              max = hd->ioc->req_depth;
+       struct scsi_cmnd *sc;
 
        dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n",
-                       target, lun, max));
+                       vdevice->vtarget->target_id, vdevice->lun, max));
 
        for (ii=0; ii < max; ii++) {
-               if (hd->ScsiLookup[ii] != NULL) {
+               if ((sc = hd->ScsiLookup[ii]) != NULL) {
 
                        mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii);
 
                        dsprintk(( "search_running: found (sc=%p, mf = %p) target %d, lun %d \n",
                                        hd->ScsiLookup[ii], mf, mf->TargetID, mf->LUN[1]));
 
-                       if ((mf->TargetID != ((u8)target)) || (mf->LUN[1] != ((u8) lun)))
+                       if ((mf->TargetID != ((u8)vdevice->vtarget->target_id)) || (mf->LUN[1] != ((u8) vdevice->lun)))
                                continue;
 
                        /* Cleanup
@@ -974,18 +899,26 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, uint target, uint lun)
                        hd->ScsiLookup[ii] = NULL;
                        mptscsih_freeChainBuffers(hd->ioc, ii);
                        mpt_free_msg_frame(hd->ioc, (MPT_FRAME_HDR *)mf);
+                       if (sc->use_sg) {
+                               pci_unmap_sg(hd->ioc->pcidev,
+                               (struct scatterlist *) sc->request_buffer,
+                                       sc->use_sg,
+                                       sc->sc_data_direction);
+                       } else if (sc->request_bufflen) {
+                               pci_unmap_single(hd->ioc->pcidev,
+                                       sc->SCp.dma_handle,
+                                       sc->request_bufflen,
+                                       sc->sc_data_direction);
+                       }
+                       sc->host_scribble = NULL;
+                       sc->result = DID_NO_CONNECT << 16;
+                       sc->scsi_done(sc);
                }
        }
-
        return;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- *  Hack! It might be nice to report if a device is returning QUEUE_FULL
- *  but maybe not each and every time...
- */
-static long last_queue_full = 0;
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
@@ -1003,280 +936,20 @@ static void
 mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq)
 {
        long time = jiffies;
-
-       if (time - last_queue_full > 10 * HZ) {
-               char *ioc_str = "ioc?";
-
-               if (sc->device && sc->device->host != NULL && sc->device->host->hostdata != NULL)
-                       ioc_str = ((MPT_SCSI_HOST *)sc->device->host->hostdata)->ioc->name;
-               dprintk((MYIOC_s_WARN_FMT "Device (%d:%d:%d) reported QUEUE_FULL!\n",
-                               ioc_str, 0, sc->device->id, sc->device->lun));
-               last_queue_full = time;
-       }
-}
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-static char *info_kbuf = NULL;
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- *     mptscsih_probe - Installs scsi devices per bus.
- *     @pdev: Pointer to pci_dev structure
- *
- *     Returns 0 for success, non-zero for failure.
- *
- */
-
-static int
-mptscsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
-{
-       struct Scsi_Host        *sh;
        MPT_SCSI_HOST           *hd;
-       MPT_ADAPTER             *ioc = pci_get_drvdata(pdev);
-       unsigned long            flags;
-       int                      sz, ii;
-       int                      numSGE = 0;
-       int                      scale;
-       int                      ioc_cap;
-       u8                      *mem;
-       int                     error=0;
-
-
-       /* 20010202 -sralston
-        *  Added sanity check on readiness of the MPT adapter.
-        */
-       if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
-               printk(MYIOC_s_WARN_FMT
-                 "Skipping because it's not operational!\n",
-                 ioc->name);
-               return -ENODEV;
-       }
-
-       if (!ioc->active) {
-               printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
-                 ioc->name);
-               return -ENODEV;
-       }
-
-       /*  Sanity check - ensure at least 1 port is INITIATOR capable
-        */
-       ioc_cap = 0;
-       for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
-               if (ioc->pfacts[ii].ProtocolFlags &
-                   MPI_PORTFACTS_PROTOCOL_INITIATOR)
-                       ioc_cap ++;
-       }
-
-       if (!ioc_cap) {
-               printk(MYIOC_s_WARN_FMT
-                       "Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n",
-                       ioc->name, ioc);
-               return -ENODEV;
-       }
-
-       sh = scsi_host_alloc(&driver_template, sizeof(MPT_SCSI_HOST));
-        
-       if (!sh) {
-               printk(MYIOC_s_WARN_FMT
-                       "Unable to register controller with SCSI subsystem\n",
-                       ioc->name);
-                return -1;
-        }
-       
-       spin_lock_irqsave(&ioc->FreeQlock, flags);
-
-       /* Attach the SCSI Host to the IOC structure
-        */
-       ioc->sh = sh;
-
-       sh->io_port = 0;
-       sh->n_io_port = 0;
-       sh->irq = 0;
-
-       /* set 16 byte cdb's */
-       sh->max_cmd_len = 16;
-
-       /* Yikes!  This is important!
-        * Otherwise, by default, linux
-        * only scans target IDs 0-7!
-        * pfactsN->MaxDevices unreliable
-        * (not supported in early
-        *      versions of the FW).
-        * max_id = 1 + actual max id,
-        * max_lun = 1 + actual last lun,
-        *      see hosts.h :o(
-        */
-       if (ioc->bus_type == SCSI) {
-               sh->max_id = MPT_MAX_SCSI_DEVICES;
-       } else {
-       /* For FC, increase the queue depth
-        * from MPT_SCSI_CAN_QUEUE (31)
-        * to MPT_FC_CAN_QUEUE (63).
-        */
-               sh->can_queue = MPT_FC_CAN_QUEUE;
-               sh->max_id =
-                 MPT_MAX_FC_DEVICES<256 ? MPT_MAX_FC_DEVICES : 255;
-       }
-               
-       sh->max_lun = MPT_LAST_LUN + 1;
-       sh->max_channel = 0;
-       sh->this_id = ioc->pfacts[0].PortSCSIID;
-               
-       /* Required entry.
-        */
-       sh->unique_id = ioc->id;
-
-       /* Verify that we won't exceed the maximum
-        * number of chain buffers
-        * We can optimize:  ZZ = req_sz/sizeof(SGE)
-        * For 32bit SGE's:
-        *  numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
-        *               + (req_sz - 64)/sizeof(SGE)
-        * A slightly different algorithm is required for
-        * 64bit SGEs.
-        */
-       scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
-       if (sizeof(dma_addr_t) == sizeof(u64)) {
-               numSGE = (scale - 1) *
-                 (ioc->facts.MaxChainDepth-1) + scale +
-                 (ioc->req_sz - 60) / (sizeof(dma_addr_t) +
-                 sizeof(u32));
-       } else {
-               numSGE = 1 + (scale - 1) *
-                 (ioc->facts.MaxChainDepth-1) + scale +
-                 (ioc->req_sz - 64) / (sizeof(dma_addr_t) +
-                 sizeof(u32));
-       }
-               
-       if (numSGE < sh->sg_tablesize) {
-               /* Reset this value */
-               dprintk((MYIOC_s_INFO_FMT
-                 "Resetting sg_tablesize to %d from %d\n",
-                 ioc->name, numSGE, sh->sg_tablesize));
-               sh->sg_tablesize = numSGE;
-       }
-
-       /* Set the pci device pointer in Scsi_Host structure.
-        */
-       scsi_set_device(sh, &ioc->pcidev->dev);
-
-       spin_unlock_irqrestore(&ioc->FreeQlock, flags);
-
-       hd = (MPT_SCSI_HOST *) sh->hostdata;
-       hd->ioc = ioc;
-
-       /* SCSI needs scsi_cmnd lookup table!
-        * (with size equal to req_depth*PtrSz!)
-        */
-       sz = ioc->req_depth * sizeof(void *);
-       mem = kmalloc(sz, GFP_ATOMIC);
-       if (mem == NULL) {
-               error = -ENOMEM;
-               goto mptscsih_probe_failed;
-       }
-
-       memset(mem, 0, sz);
-       hd->ScsiLookup = (struct scsi_cmnd **) mem;
-
-       dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n",
-                ioc->name, hd->ScsiLookup, sz));
-               
-       /* Allocate memory for the device structures.
-        * A non-Null pointer at an offset
-        * indicates a device exists.
-        * max_id = 1 + maximum id (hosts.h)
-        */
-       sz = sh->max_id * sizeof(void *);
-       mem = kmalloc(sz, GFP_ATOMIC);
-       if (mem == NULL) {
-               error = -ENOMEM;
-               goto mptscsih_probe_failed;
-       }
 
-       memset(mem, 0, sz);
-       hd->Targets = (VirtDevice **) mem;
-
-       dprintk((KERN_INFO
-         "  Targets @ %p, sz=%d\n", hd->Targets, sz));
-
-       /* Clear the TM flags
-        */
-       hd->tmPending = 0;
-       hd->tmState = TM_STATE_NONE;
-       hd->resetPending = 0;
-       hd->abortSCpnt = NULL;
-
-       /* Clear the pointer used to store
-        * single-threaded commands, i.e., those
-        * issued during a bus scan, dv and
-        * configuration pages.
-        */
-       hd->cmdPtr = NULL;
-
-       /* Initialize this SCSI Hosts' timers
-        * To use, set the timer expires field
-        * and add_timer
-        */
-       init_timer(&hd->timer);
-       hd->timer.data = (unsigned long) hd;
-       hd->timer.function = mptscsih_timer_expired;
-
-       if (ioc->bus_type == SCSI) {
-               /* Update with the driver setup
-                * values.
-                */
-               if (ioc->spi_data.maxBusWidth > mpt_width)
-                       ioc->spi_data.maxBusWidth = mpt_width;
-               if (ioc->spi_data.minSyncFactor < mpt_factor)
-                       ioc->spi_data.minSyncFactor = mpt_factor;
-
-               if (ioc->spi_data.minSyncFactor == MPT_ASYNC) {
-                       ioc->spi_data.maxSyncOffset = 0;
-               }
-
-               ioc->spi_data.Saf_Te = mpt_saf_te;
-
-               hd->negoNvram = 0;
-#ifndef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
-               hd->negoNvram = MPT_SCSICFG_USE_NVRAM;
-#endif
-               ioc->spi_data.forceDv = 0;
-               ioc->spi_data.noQas = 0;
-               for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
-                       ioc->spi_data.dvStatus[ii] =
-                         MPT_SCSICFG_NEGOTIATE;
-               }
-
-               for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++)
-                       ioc->spi_data.dvStatus[ii] |=
-                         MPT_SCSICFG_DV_NOT_DONE;
-
-               dinitprintk((MYIOC_s_INFO_FMT
-                       "dv %x width %x factor %x saf_te %x\n",
-                       ioc->name, mpt_dv,
-                       mpt_width,
-                       mpt_factor,
-                       mpt_saf_te));
-       }
-
-       mpt_scsi_hosts++;
+       if (sc->device == NULL)
+               return;
+       if (sc->device->host == NULL)
+               return;
+       if ((hd = (MPT_SCSI_HOST *)sc->device->host->hostdata) == NULL)
+               return;
 
-       error = scsi_add_host (sh, &ioc->pcidev->dev);
-       if(error) {
-               dprintk((KERN_ERR MYNAM
-                 "scsi_add_host failed\n"));
-               goto mptscsih_probe_failed;
+       if (time - hd->last_queue_full > 10 * HZ) {
+               dprintk((MYIOC_s_WARN_FMT "Device (%d:%d:%d) reported QUEUE_FULL!\n",
+                               hd->ioc->name, 0, sc->device->id, sc->device->lun));
+               hd->last_queue_full = time;
        }
-
-       scsi_scan_host(sh);
-       return 0;
-
-mptscsih_probe_failed:
-
-       mptscsih_remove(pdev);
-       return error;
-
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -1286,74 +959,53 @@ mptscsih_probe_failed:
  *
  *
  */
-static void
+void
 mptscsih_remove(struct pci_dev *pdev)
 {
        MPT_ADAPTER             *ioc = pci_get_drvdata(pdev);
        struct Scsi_Host        *host = ioc->sh;
        MPT_SCSI_HOST           *hd;
-       int                     count;
-       unsigned long           flags;
+       int sz1;
 
-       if(!host)
+       if(!host) {
+               mpt_detach(pdev);
                return;
+       }
 
        scsi_remove_host(host);
 
-#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
-       /* Check DV thread active */
-       count = 10 * HZ;
-       spin_lock_irqsave(&dvtaskQ_lock, flags);
-       if (dvtaskQ_active) {
-               spin_unlock_irqrestore(&dvtaskQ_lock, flags);
-               while(dvtaskQ_active && --count) {
-                       set_current_state(TASK_INTERRUPTIBLE);
-                       schedule_timeout(1);
-               }
-       } else {
-               spin_unlock_irqrestore(&dvtaskQ_lock, flags);
-       }
-       if (!count)
-               printk(KERN_ERR MYNAM ": ERROR - DV thread still active!\n");
-#if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY)
-       else
-               printk(KERN_ERR MYNAM ": DV thread orig %d, count %d\n", 10 * HZ, count);
-#endif
-#endif
+       if((hd = (MPT_SCSI_HOST *)host->hostdata) == NULL)
+               return;
 
-       hd = (MPT_SCSI_HOST *)host->hostdata;
-       if (hd != NULL) {
-               int sz1;
+       mptscsih_shutdown(pdev);
 
-               mptscsih_shutdown(&pdev->dev);
+       sz1=0;
 
-               sz1=0;
+       if (hd->ScsiLookup != NULL) {
+               sz1 = hd->ioc->req_depth * sizeof(void *);
+               kfree(hd->ScsiLookup);
+               hd->ScsiLookup = NULL;
+       }
 
-               if (hd->ScsiLookup != NULL) {
-                       sz1 = hd->ioc->req_depth * sizeof(void *);
-                       kfree(hd->ScsiLookup);
-                       hd->ScsiLookup = NULL;
-               }
+       /*
+        * Free pointer array.
+        */
+       kfree(hd->Targets);
+       hd->Targets = NULL;
 
-               if (hd->Targets != NULL) {
-                       /*
-                        * Free pointer array.
-                        */
-                       kfree(hd->Targets);
-                       hd->Targets = NULL;
-               }
+       dprintk((MYIOC_s_INFO_FMT
+           "Free'd ScsiLookup (%d) memory\n",
+           hd->ioc->name, sz1));
 
-               dprintk((MYIOC_s_INFO_FMT 
-                   "Free'd ScsiLookup (%d) memory\n",
-                   hd->ioc->name, sz1));
+       kfree(hd->info_kbuf);
 
-               /* NULL the Scsi_Host pointer
-                */
-               hd->ioc->sh = NULL;
-       }
+       /* NULL the Scsi_Host pointer
+        */
+       hd->ioc->sh = NULL;
 
        scsi_host_put(host);
-       mpt_scsi_hosts--;
+
+       mpt_detach(pdev);
 
 }
 
@@ -1362,10 +1014,10 @@ mptscsih_remove(struct pci_dev *pdev)
  *     mptscsih_shutdown - reboot notifier
  *
  */
-static void
-mptscsih_shutdown(struct device * dev)
+void
+mptscsih_shutdown(struct pci_dev *pdev)
 {
-       MPT_ADAPTER             *ioc = pci_get_drvdata(to_pci_dev(dev));
+       MPT_ADAPTER             *ioc = pci_get_drvdata(pdev);
        struct Scsi_Host        *host = ioc->sh;
        MPT_SCSI_HOST           *hd;
 
@@ -1374,25 +1026,20 @@ mptscsih_shutdown(struct device * dev)
 
        hd = (MPT_SCSI_HOST *)host->hostdata;
 
-       /* Flush the cache of this adapter
-        */
-       if(hd != NULL)
-               mptscsih_synchronize_cache(hd, 0);
-
 }
 
 #ifdef CONFIG_PM
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
- *     mptscsih_suspend - Fusion MPT scsie driver suspend routine.
+ *     mptscsih_suspend - Fusion MPT scsi driver suspend routine.
  *
  *
  */
-static int
+int
 mptscsih_suspend(struct pci_dev *pdev, pm_message_t state)
 {
-       mptscsih_shutdown(&pdev->dev);
-       return 0;
+       mptscsih_shutdown(pdev);
+       return mpt_suspend(pdev,state);
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -1401,13 +1048,15 @@ mptscsih_suspend(struct pci_dev *pdev, pm_message_t state)
  *
  *
  */
-static int
+int
 mptscsih_resume(struct pci_dev *pdev)
 {
        MPT_ADAPTER             *ioc = pci_get_drvdata(pdev);
        struct Scsi_Host        *host = ioc->sh;
        MPT_SCSI_HOST           *hd;
 
+       mpt_resume(pdev);
+
        if(!host)
                return 0;
 
@@ -1415,102 +1064,11 @@ mptscsih_resume(struct pci_dev *pdev)
        if(!hd)
                return 0;
 
-#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
-       {
-       unsigned long lflags;
-       spin_lock_irqsave(&dvtaskQ_lock, lflags);
-       if (!dvtaskQ_active) {
-               dvtaskQ_active = 1;
-               spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
-               INIT_WORK(&mptscsih_dvTask,
-                 mptscsih_domainValidation, (void *) hd);
-               schedule_work(&mptscsih_dvTask);
-       } else {
-               spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
-       }
-       }
-#endif
        return 0;
 }
 
 #endif
 
-static struct mpt_pci_driver mptscsih_driver = {
-       .probe          = mptscsih_probe,
-       .remove         = mptscsih_remove,
-       .shutdown       = mptscsih_shutdown,
-#ifdef CONFIG_PM
-       .suspend        = mptscsih_suspend,
-       .resume         = mptscsih_resume,
-#endif
-};
-
-/*  SCSI host fops start here...  */
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/**
- *     mptscsih_init - Register MPT adapter(s) as SCSI host(s) with
- *     linux scsi mid-layer.
- *
- *     Returns 0 for success, non-zero for failure.
- */
-static int __init
-mptscsih_init(void)
-{
-
-       show_mptmod_ver(my_NAME, my_VERSION);
-
-       ScsiDoneCtx = mpt_register(mptscsih_io_done, MPTSCSIH_DRIVER);
-       ScsiTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSCSIH_DRIVER);
-       ScsiScanDvCtx = mpt_register(mptscsih_scandv_complete, MPTSCSIH_DRIVER);
-
-       if (mpt_event_register(ScsiDoneCtx, mptscsih_event_process) == 0) {
-               devtprintk((KERN_INFO MYNAM
-                 ": Registered for IOC event notifications\n"));
-       }
-
-       if (mpt_reset_register(ScsiDoneCtx, mptscsih_ioc_reset) == 0) {
-               dprintk((KERN_INFO MYNAM
-                 ": Registered for IOC reset notifications\n"));
-       }
-
-       if(mpt_device_driver_register(&mptscsih_driver,
-         MPTSCSIH_DRIVER) != 0 ) {
-               dprintk((KERN_INFO MYNAM
-               ": failed to register dd callbacks\n"));
-       }
-
-       return 0;
-
-}
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/**
- *     mptscsih_exit - Unregisters MPT adapter(s)
- *
- */
-static void __exit
-mptscsih_exit(void)
-{
-       mpt_device_driver_deregister(MPTSCSIH_DRIVER);
-
-       mpt_reset_deregister(ScsiDoneCtx);
-       dprintk((KERN_INFO MYNAM
-         ": Deregistered for IOC reset notifications\n"));
-
-       mpt_event_deregister(ScsiDoneCtx);
-       dprintk((KERN_INFO MYNAM
-         ": Deregistered for IOC event notifications\n"));
-
-       mpt_deregister(ScsiScanDvCtx);
-       mpt_deregister(ScsiTaskCtx);
-       mpt_deregister(ScsiDoneCtx);
-
-       if (info_kbuf != NULL)
-               kfree(info_kbuf);
-
-}
-
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /**
  *     mptscsih_info - Return information about MPT adapter
@@ -1520,24 +1078,25 @@ mptscsih_exit(void)
  *
  *     Returns pointer to buffer where information was written.
  */
-static const char *
+const char *
 mptscsih_info(struct Scsi_Host *SChost)
 {
        MPT_SCSI_HOST *h;
        int size = 0;
 
-       if (info_kbuf == NULL)
-               if ((info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)
-                       return info_kbuf;
-
        h = (MPT_SCSI_HOST *)SChost->hostdata;
-       info_kbuf[0] = '\0';
+
        if (h) {
-               mpt_print_ioc_summary(h->ioc, info_kbuf, &size, 0, 0);
-               info_kbuf[size-1] = '\0';
+               if (h->info_kbuf == NULL)
+                       if ((h->info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)
+                               return h->info_kbuf;
+               h->info_kbuf[0] = '\0';
+
+               mpt_print_ioc_summary(h->ioc, h->info_kbuf, &size, 0, 0);
+               h->info_kbuf[size-1] = '\0';
        }
 
-       return info_kbuf;
+       return h->info_kbuf;
 }
 
 struct info_str {
@@ -1547,7 +1106,8 @@ struct info_str {
        int   pos;
 };
 
-static void copy_mem_info(struct info_str *info, char *data, int len)
+static void
+mptscsih_copy_mem_info(struct info_str *info, char *data, int len)
 {
        if (info->pos + len > info->length)
                len = info->length - info->pos;
@@ -1568,7 +1128,8 @@ static void copy_mem_info(struct info_str *info, char *data, int len)
        }
 }
 
-static int copy_info(struct info_str *info, char *fmt, ...)
+static int
+mptscsih_copy_info(struct info_str *info, char *fmt, ...)
 {
        va_list args;
        char buf[81];
@@ -1578,11 +1139,12 @@ static int copy_info(struct info_str *info, char *fmt, ...)
        len = vsprintf(buf, fmt, args);
        va_end(args);
 
-       copy_mem_info(info, buf, len);
+       mptscsih_copy_mem_info(info, buf, len);
        return len;
 }
 
-static int mptscsih_host_info(MPT_ADAPTER *ioc, char *pbuf, off_t offset, int len)
+static int
+mptscsih_host_info(MPT_ADAPTER *ioc, char *pbuf, off_t offset, int len)
 {
        struct info_str info;
 
@@ -1591,10 +1153,10 @@ static int mptscsih_host_info(MPT_ADAPTER *ioc, char *pbuf, off_t offset, int le
        info.offset     = offset;
        info.pos        = 0;
 
-       copy_info(&info, "%s: %s, ", ioc->name, ioc->prod_name);
-       copy_info(&info, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING, ioc->facts.FWVersion.Word);
-       copy_info(&info, "Ports=%d, ", ioc->facts.NumberOfPorts);
-       copy_info(&info, "MaxQ=%d\n", ioc->req_depth);
+       mptscsih_copy_info(&info, "%s: %s, ", ioc->name, ioc->prod_name);
+       mptscsih_copy_info(&info, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING, ioc->facts.FWVersion.Word);
+       mptscsih_copy_info(&info, "Ports=%d, ", ioc->facts.NumberOfPorts);
+       mptscsih_copy_info(&info, "MaxQ=%d\n", ioc->req_depth);
 
        return ((info.pos > info.offset) ? info.pos - info.offset : 0);
 }
@@ -1612,7 +1174,7 @@ static int mptscsih_host_info(MPT_ADAPTER *ioc, char *pbuf, off_t offset, int le
  *     hostno: scsi host number
  *     func:   if write = 1; if read = 0
  */
-static int
+int
 mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
                        int length, int func)
 {
@@ -1621,8 +1183,8 @@ mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t off
        int size = 0;
 
        if (func) {
-               /* 
-                * write is not supported 
+               /*
+                * write is not supported
                 */
        } else {
                if (start)
@@ -1649,14 +1211,13 @@ mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t off
  *
  *     Returns 0. (rtn value discarded by linux scsi mid-layer)
  */
-static int
+int
 mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
 {
        MPT_SCSI_HOST           *hd;
        MPT_FRAME_HDR           *mf;
        SCSIIORequest_t         *pScsiReq;
-       VirtDevice              *pTarget;
-       int      target;
+       VirtDevice              *vdev = SCpnt->device->hostdata;
        int      lun;
        u32      datalen;
        u32      scsictl;
@@ -1666,12 +1227,9 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
        int      ii;
 
        hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata;
-       target = SCpnt->device->id;
        lun = SCpnt->device->lun;
        SCpnt->scsi_done = done;
 
-       pTarget = hd->Targets[target];
-
        dmfprintk((MYIOC_s_INFO_FMT "qcmd: SCpnt=%p, done()=%p\n",
                        (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt, done));
 
@@ -1681,10 +1239,18 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
                return SCSI_MLQUEUE_HOST_BUSY;
        }
 
+       if ((hd->ioc->bus_type == SPI) &&
+           vdev->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT &&
+           mptscsih_raid_id_to_num(hd, SCpnt->device->id) < 0) {
+               SCpnt->result = DID_NO_CONNECT << 16;
+               done(SCpnt);
+               return 0;
+       }
+
        /*
         *  Put together a MPT SCSI request...
         */
-       if ((mf = mpt_get_msg_frame(ScsiDoneCtx, hd->ioc)) == NULL) {
+       if ((mf = mpt_get_msg_frame(hd->ioc->DoneCtx, hd->ioc)) == NULL) {
                dprintk((MYIOC_s_WARN_FMT "QueueCmd, no msg frames!!\n",
                                hd->ioc->name));
                return SCSI_MLQUEUE_HOST_BUSY;
@@ -1696,8 +1262,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
 
        ADD_INDEX_LOG(my_idx);
 
-       /*  BUG FIX!  19991030 -sralston
-        *    TUR's being issued with scsictl=0x02000000 (DATA_IN)!
+       /*    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...
         */
@@ -1715,8 +1280,8 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
        /* Default to untagged. Once a target structure has been allocated,
         * use the Inquiry data to determine if device supports tagged.
         */
-       if (   pTarget
-           && (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)
+       if (vdev
+           && (vdev->vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)
            && (SCpnt->device->tagged_supported)) {
                scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
        } else {
@@ -1725,10 +1290,13 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
 
        /* Use the above information to set up the message frame
         */
-       pScsiReq->TargetID = (u8) target;
-       pScsiReq->Bus = (u8) SCpnt->device->channel;
+       pScsiReq->TargetID = (u8) vdev->vtarget->target_id;
+       pScsiReq->Bus = vdev->vtarget->bus_id;
        pScsiReq->ChainOffset = 0;
-       pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
+       if (vdev->vtarget->tflags &  MPT_TARGET_FLAGS_RAID_COMPONENT)
+               pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
+       else
+               pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
        pScsiReq->CDBLength = SCpnt->cmd_len;
        pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
        pScsiReq->Reserved = 0;
@@ -1776,56 +1344,14 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
        hd->ScsiLookup[my_idx] = SCpnt;
        SCpnt->host_scribble = NULL;
 
-#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
-       if (hd->ioc->bus_type == SCSI) {
-               int dvStatus = hd->ioc->spi_data.dvStatus[target];
-               int issueCmd = 1;
-
-               if (dvStatus || hd->ioc->spi_data.forceDv) {
-
-                       if ((dvStatus & MPT_SCSICFG_NEED_DV) ||
-                               (hd->ioc->spi_data.forceDv & MPT_SCSICFG_NEED_DV)) {
-                               unsigned long lflags;
-                               /* Schedule DV if necessary */
-                               spin_lock_irqsave(&dvtaskQ_lock, lflags);
-                               if (!dvtaskQ_active) {
-                                       dvtaskQ_active = 1;
-                                       spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
-                                       INIT_WORK(&mptscsih_dvTask, mptscsih_domainValidation, (void *) hd);
-
-                                       schedule_work(&mptscsih_dvTask);
-                               } else {
-                                       spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
-                               }
-                               hd->ioc->spi_data.forceDv &= ~MPT_SCSICFG_NEED_DV;
-                       }
-
-                       /* Trying to do DV to this target, extend timeout.
-                        * Wait to issue until flag is clear
-                        */
-                       if (dvStatus & MPT_SCSICFG_DV_PENDING) {
-                               mod_timer(&SCpnt->eh_timeout, jiffies + 40 * HZ);
-                               issueCmd = 0;
-                       }
-
-                       /* Set the DV flags.
-                        */
-                       if (dvStatus & MPT_SCSICFG_DV_NOT_DONE)
-                               mptscsih_set_dvflags(hd, pScsiReq);
-
-                       if (!issueCmd)
-                               goto fail;
-               }
-       }
-#endif
-
-       mpt_put_msg_frame(ScsiDoneCtx, hd->ioc, mf);
+       mpt_put_msg_frame(hd->ioc->DoneCtx, hd->ioc, mf);
        dmfprintk((MYIOC_s_INFO_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n",
                        hd->ioc->name, SCpnt, mf, my_idx));
        DBG_DUMP_REQUEST_FRAME(mf)
        return 0;
 
  fail:
+       hd->ScsiLookup[my_idx] = NULL;
        mptscsih_freeChainBuffers(hd->ioc, my_idx);
        mpt_free_msg_frame(hd->ioc, mf);
        return SCSI_MLQUEUE_HOST_BUSY;
@@ -1905,7 +1431,7 @@ mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
  *
  *     Returns 0 for SUCCESS or -1 if FAILED.
  */
-static int
+int
 mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout)
 {
        MPT_ADAPTER     *ioc;
@@ -1943,17 +1469,17 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, in
         */
        if (mptscsih_tm_pending_wait(hd) == FAILED) {
                if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
-                       dtmprintk((KERN_WARNING MYNAM ": %s: TMHandler abort: "
+                       dtmprintk((KERN_INFO MYNAM ": %s: TMHandler abort: "
                           "Timed out waiting for last TM (%d) to complete! \n",
                           hd->ioc->name, hd->tmPending));
                        return FAILED;
                } else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) {
-                       dtmprintk((KERN_WARNING MYNAM ": %s: TMHandler target reset: "
+                       dtmprintk((KERN_INFO MYNAM ": %s: TMHandler target reset: "
                           "Timed out waiting for last TM (%d) to complete! \n",
                           hd->ioc->name, hd->tmPending));
                        return FAILED;
                } else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
-                       dtmprintk((KERN_WARNING MYNAM ": %s: TMHandler bus reset: "
+                       dtmprintk((KERN_INFO MYNAM ": %s: TMHandler bus reset: "
                           "Timed out waiting for last TM (%d) to complete! \n",
                           hd->ioc->name, hd->tmPending));
                        if (hd->tmPending & (1 << MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS))
@@ -2036,11 +1562,10 @@ 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(hd->ioc->TaskCtx, hd->ioc)) == NULL) {
                dfailprintk((MYIOC_s_ERR_FMT "IssueTaskMgmt, no msg frames!!\n",
                                hd->ioc->name));
-               //return FAILED;
-               return -999;
+               return FAILED;
        }
        dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt request @ %p\n",
                        hd->ioc->name, mf));
@@ -2069,13 +1594,12 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun
 
        pScsiTm->TaskMsgContext = ctx2abort;
 
-       dtmprintk((MYIOC_s_INFO_FMT
-               "IssueTaskMgmt: ctx2abort (0x%08x) type=%d\n",
-               hd->ioc->name, ctx2abort, type));
+       dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt: ctx2abort (0x%08x) type=%d\n",
+                       hd->ioc->name, ctx2abort, type));
 
        DBG_DUMP_TM_REQUEST_FRAME((u32 *)pScsiTm);
 
-       if ((retval = mpt_send_handshake_request(ScsiTaskCtx, hd->ioc,
+       if ((retval = mpt_send_handshake_request(hd->ioc->TaskCtx, hd->ioc,
                sizeof(SCSITaskMgmt_t), (u32*)pScsiTm,
                CAN_SLEEP)) != 0) {
                dfailprintk((MYIOC_s_ERR_FMT "_send_handshake FAILED!"
@@ -2098,6 +1622,20 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun
        return retval;
 }
 
+static int
+mptscsih_get_tm_timeout(MPT_ADAPTER *ioc)
+{
+       switch (ioc->bus_type) {
+       case FC:
+               return 40;
+       case SAS:
+               return 10;
+       case SPI:
+       default:
+               return 2;
+       }
+}
+
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /**
  *     mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant
@@ -2107,50 +1645,51 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun
  *
  *     Returns SUCCESS or FAILED.
  */
-static int
+int
 mptscsih_abort(struct scsi_cmnd * SCpnt)
 {
        MPT_SCSI_HOST   *hd;
-       MPT_ADAPTER     *ioc;
        MPT_FRAME_HDR   *mf;
        u32              ctx2abort;
        int              scpnt_idx;
-       spinlock_t      *host_lock = SCpnt->device->host->host_lock;
+       int              retval;
+       VirtDevice       *vdev;
 
        /* If we can't locate our host adapter structure, return FAILED status.
         */
        if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL) {
                SCpnt->result = DID_RESET << 16;
                SCpnt->scsi_done(SCpnt);
-               dfailprintk((KERN_WARNING MYNAM ": mptscsih_abort: "
+               dfailprintk((KERN_INFO MYNAM ": mptscsih_abort: "
                           "Can't locate host! (sc=%p)\n",
                           SCpnt));
                return FAILED;
        }
 
-       ioc = hd->ioc;
-       if (hd->resetPending)
-               return FAILED;
-
-       printk(KERN_WARNING MYNAM ": %s: >> Attempting task abort! (sc=%p)\n",
-              hd->ioc->name, SCpnt);
-
-       if (hd->timeouts < -1)
-               hd->timeouts++;
-
        /* Find this command
         */
        if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) {
-               /* Cmd not found in ScsiLookup. 
+               /* Cmd not found in ScsiLookup.
                 * Do OS callback.
                 */
                SCpnt->result = DID_RESET << 16;
-               dtmprintk((KERN_WARNING MYNAM ": %s: mptscsih_abort: "
+               dtmprintk((KERN_INFO MYNAM ": %s: mptscsih_abort: "
                           "Command not in the active list! (sc=%p)\n",
                           hd->ioc->name, SCpnt));
                return SUCCESS;
        }
 
+       if (hd->resetPending) {
+               return FAILED;
+       }
+
+       if (hd->timeouts < -1)
+               hd->timeouts++;
+
+       printk(KERN_WARNING MYNAM ": %s: attempting task abort! (sc=%p)\n",
+              hd->ioc->name, SCpnt);
+       scsi_print_command(SCpnt);
+
        /* Most important!  Set TaskMsgContext to SCpnt's MsgContext!
         * (the IO to be ABORT'd)
         *
@@ -2163,42 +1702,23 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
 
        hd->abortSCpnt = SCpnt;
 
-       spin_unlock_irq(host_lock);
-       if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
-               SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun,
-               ctx2abort, 2 /* 2 second timeout */)
-               < 0) {
+       vdev = SCpnt->device->hostdata;
+       retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
+               vdev->vtarget->bus_id, vdev->vtarget->target_id, vdev->lun,
+               ctx2abort, mptscsih_get_tm_timeout(hd->ioc));
 
-               /* The TM request failed and the subsequent FW-reload failed!
-                * Fatal error case.
-                */
-               printk(MYIOC_s_WARN_FMT "Error issuing abort task! (sc=%p)\n",
-                      hd->ioc->name, SCpnt);
+       printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n",
+               hd->ioc->name,
+               ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
 
-               /* We must clear our pending flag before clearing our state.
-                */
+       if (retval == 0)
+               return SUCCESS;
+
+       if(retval != FAILED ) {
                hd->tmPending = 0;
                hd->tmState = TM_STATE_NONE;
-
-               spin_lock_irq(host_lock);
-
-               /* Unmap the DMA buffers, if any. */
-               if (SCpnt->use_sg) {
-                       pci_unmap_sg(ioc->pcidev, (struct scatterlist *) SCpnt->request_buffer,
-                                   SCpnt->use_sg, SCpnt->sc_data_direction);
-               } else if (SCpnt->request_bufflen) {
-                       pci_unmap_single(ioc->pcidev, SCpnt->SCp.dma_handle,
-                               SCpnt->request_bufflen, SCpnt->sc_data_direction);
-               }
-               hd->ScsiLookup[scpnt_idx] = NULL;
-               SCpnt->result = DID_RESET << 16;
-               SCpnt->scsi_done(SCpnt);                /* Issue the command callback */
-               mptscsih_freeChainBuffers(ioc, scpnt_idx);
-               mpt_free_msg_frame(ioc, mf);
-               return FAILED;
        }
-       spin_lock_irq(host_lock);
-       return SUCCESS;
+       return FAILED;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -2210,16 +1730,17 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
  *
  *     Returns SUCCESS or FAILED.
  */
-static int
+int
 mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
 {
        MPT_SCSI_HOST   *hd;
-       spinlock_t      *host_lock = SCpnt->device->host->host_lock;
+       int              retval;
+       VirtDevice       *vdev;
 
        /* If we can't locate our host adapter structure, return FAILED status.
         */
        if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
-               dtmprintk((KERN_WARNING MYNAM ": mptscsih_dev_reset: "
+               dtmprintk((KERN_INFO MYNAM ": mptscsih_dev_reset: "
                           "Can't locate host! (sc=%p)\n",
                           SCpnt));
                return FAILED;
@@ -2228,27 +1749,27 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
        if (hd->resetPending)
                return FAILED;
 
-       printk(KERN_WARNING MYNAM ": %s: >> Attempting target reset! (sc=%p)\n",
+       printk(KERN_WARNING MYNAM ": %s: attempting target reset! (sc=%p)\n",
               hd->ioc->name, SCpnt);
+       scsi_print_command(SCpnt);
 
-       spin_unlock_irq(host_lock);
-       if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
-               SCpnt->device->channel, SCpnt->device->id,
-               0, 0, 5 /* 5 second timeout */)
-               < 0){
-               /* The TM request failed and the subsequent FW-reload failed!
-                * Fatal error case.
-                */
-               printk(MYIOC_s_WARN_FMT "Error processing TaskMgmt request (sc=%p)\n",
-                               hd->ioc->name, SCpnt);
+       vdev = SCpnt->device->hostdata;
+       retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
+               vdev->vtarget->bus_id, vdev->vtarget->target_id,
+               0, 0, mptscsih_get_tm_timeout(hd->ioc));
+
+       printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n",
+               hd->ioc->name,
+               ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
+
+       if (retval == 0)
+               return SUCCESS;
+
+       if(retval != FAILED ) {
                hd->tmPending = 0;
                hd->tmState = TM_STATE_NONE;
-               spin_lock_irq(host_lock);
-               return FAILED;
        }
-       spin_lock_irq(host_lock);
-       return SUCCESS;
-
+       return FAILED;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -2260,46 +1781,45 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
  *
  *     Returns SUCCESS or FAILED.
  */
-static int
+int
 mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
 {
        MPT_SCSI_HOST   *hd;
-       spinlock_t      *host_lock = SCpnt->device->host->host_lock;
+       int              retval;
+       VirtDevice       *vdev;
 
        /* If we can't locate our host adapter structure, return FAILED status.
         */
        if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
-               dtmprintk((KERN_WARNING MYNAM ": mptscsih_bus_reset: "
+               dtmprintk((KERN_INFO MYNAM ": mptscsih_bus_reset: "
                           "Can't locate host! (sc=%p)\n",
                           SCpnt ) );
                return FAILED;
        }
 
-       printk(KERN_WARNING MYNAM ": %s: >> Attempting bus reset! (sc=%p)\n",
+       printk(KERN_WARNING MYNAM ": %s: attempting bus reset! (sc=%p)\n",
               hd->ioc->name, SCpnt);
+       scsi_print_command(SCpnt);
 
        if (hd->timeouts < -1)
                hd->timeouts++;
 
-       /* We are now ready to execute the task management request. */
-       spin_unlock_irq(host_lock);
-       if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
-               SCpnt->device->channel, 0, 0, 0, 5 /* 5 second timeout */)
-           < 0){
+       vdev = SCpnt->device->hostdata;
+       retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
+               vdev->vtarget->bus_id, 0, 0, 0, mptscsih_get_tm_timeout(hd->ioc));
 
-               /* The TM request failed and the subsequent FW-reload failed!
-                * Fatal error case.
-                */
-               printk(MYIOC_s_WARN_FMT
-                      "Error processing TaskMgmt request (sc=%p)\n",
-                      hd->ioc->name, SCpnt);
+       printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n",
+               hd->ioc->name,
+               ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
+
+       if (retval == 0)
+               return SUCCESS;
+
+       if(retval != FAILED ) {
                hd->tmPending = 0;
                hd->tmState = TM_STATE_NONE;
-               spin_lock_irq(host_lock);
-               return FAILED;
        }
-       spin_lock_irq(host_lock);
-       return SUCCESS;
+       return FAILED;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -2312,28 +1832,26 @@ mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
  *
  *     Returns SUCCESS or FAILED.
  */
-static int
+int
 mptscsih_host_reset(struct scsi_cmnd *SCpnt)
 {
        MPT_SCSI_HOST *  hd;
        int              status = SUCCESS;
-       spinlock_t      *host_lock = SCpnt->device->host->host_lock;
 
        /*  If we can't locate the host to reset, then we failed. */
        if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
-               dtmprintk( ( KERN_WARNING MYNAM ": mptscsih_host_reset: "
+               dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
                             "Can't locate host! (sc=%p)\n",
                             SCpnt ) );
                return FAILED;
        }
 
-       printk(KERN_WARNING MYNAM ": %s: >> Attempting host reset! (sc=%p)\n",
+       printk(KERN_WARNING MYNAM ": %s: Attempting host reset! (sc=%p)\n",
               hd->ioc->name, SCpnt);
 
        /*  If our attempts to reset the host failed, then return a failed
         *  status.  The host will be taken off line by the SCSI mid-layer.
         */
-       spin_unlock_irq(host_lock);
        if (mpt_HardResetHandler(hd->ioc, CAN_SLEEP) < 0){
                status = FAILED;
        } else {
@@ -2343,10 +1861,8 @@ mptscsih_host_reset(struct scsi_cmnd *SCpnt)
                hd->tmPending = 0;
                hd->tmState = TM_STATE_NONE;
        }
-       spin_lock_irq(host_lock);
-
 
-       dtmprintk( ( KERN_WARNING MYNAM ": mptscsih_host_reset: "
+       dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
                     "Status = %s\n",
                     (status == SUCCESS) ? "SUCCESS" : "FAILED" ) );
 
@@ -2373,8 +1889,8 @@ mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd)
                if (hd->tmState == TM_STATE_NONE) {
                        hd->tmState = TM_STATE_IN_PROGRESS;
                        hd->tmPending = 1;
-                       status = SUCCESS;
                        spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
+                       status = SUCCESS;
                        break;
                }
                spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
@@ -2402,7 +1918,7 @@ mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout )
                spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
                if(hd->tmPending == 0) {
                        status = SUCCESS;
-                       spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
+                       spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
                        break;
                }
                spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
@@ -2412,6 +1928,42 @@ mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout )
        return status;
 }
 
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+static void
+mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code)
+{
+       char *desc;
+
+       switch (response_code) {
+       case MPI_SCSITASKMGMT_RSP_TM_COMPLETE:
+               desc = "The task completed.";
+               break;
+       case MPI_SCSITASKMGMT_RSP_INVALID_FRAME:
+               desc = "The IOC received an invalid frame status.";
+               break;
+       case MPI_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED:
+               desc = "The task type is not supported.";
+               break;
+       case MPI_SCSITASKMGMT_RSP_TM_FAILED:
+               desc = "The requested task failed.";
+               break;
+       case MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED:
+               desc = "The task completed successfully.";
+               break;
+       case MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN:
+               desc = "The LUN request is invalid.";
+               break;
+       case MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC:
+               desc = "The task is in the IOC queue and has not been sent to target.";
+               break;
+       default:
+               desc = "unknown";
+               break;
+       }
+       printk(MYIOC_s_INFO_FMT "Response Code(0x%08x): F/W: %s\n",
+               ioc->name, response_code, desc);
+}
+
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /**
  *     mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
@@ -2426,7 +1978,7 @@ mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout )
  *
  *     Returns 1 indicating alloc'd request frame ptr should be freed.
  */
-static int
+int
 mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
 {
        SCSITaskMgmtReply_t     *pScsiTmReply;
@@ -2461,6 +2013,11 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *m
                /* Figure out if this was ABORT_TASK, TARGET_RESET, or BUS_RESET! */
                tmType = pScsiTmReq->TaskType;
 
+               if (ioc->facts.MsgVersion >= MPI_VERSION_01_05 &&
+                   pScsiTmReply->ResponseCode)
+                       mptscsih_taskmgmt_response_code(ioc,
+                           pScsiTmReply->ResponseCode);
+
                dtmprintk((MYIOC_s_WARN_FMT "  TaskType = %d, TerminationCount=%d\n",
                                ioc->name, tmType, le32_to_cpu(pScsiTmReply->TerminationCount)));
                DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply);
@@ -2509,7 +2066,7 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *m
 /*
  *     This is anyones guess quite frankly.
  */
-static int
+int
 mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
                sector_t capacity, int geom[])
 {
@@ -2549,132 +2106,176 @@ mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
        return 0;
 }
 
+/* Search IOC page 3 to determine if this is hidden physical disk
+ *
+ */
+int
+mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id)
+{
+       int i;
+
+       if (!ioc->raid_data.isRaid || !ioc->raid_data.pIocPg3)
+               return 0;
+       for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
+                if (id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID)
+                        return 1;
+        }
+        return 0;
+}
+EXPORT_SYMBOL(mptscsih_is_phys_disk);
+
+int
+mptscsih_raid_id_to_num(MPT_SCSI_HOST *hd, uint physdiskid)
+{
+       int i;
+
+       if (!hd->ioc->raid_data.isRaid || !hd->ioc->raid_data.pIocPg3)
+               return -ENXIO;
+
+       for (i = 0; i < hd->ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
+               if (physdiskid ==
+                   hd->ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID)
+                       return hd->ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum;
+       }
+
+       return -ENXIO;
+}
+EXPORT_SYMBOL(mptscsih_raid_id_to_num);
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ *     OS entry point to allow host driver to alloc memory
+ *     for each scsi target. Called once per device the bus scan.
+ *     Return non-zero if allocation fails.
+ */
+int
+mptscsih_target_alloc(struct scsi_target *starget)
+{
+       VirtTarget              *vtarget;
+
+       vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
+       if (!vtarget)
+               return -ENOMEM;
+       starget->hostdata = vtarget;
+       vtarget->starget = starget;
+       return 0;
+}
+
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  *     OS entry point to allow host driver to alloc memory
  *     for each scsi device. Called once per device the bus scan.
  *     Return non-zero if allocation fails.
- *     Init memory once per id (not LUN).
  */
-static int
-mptscsih_slave_alloc(struct scsi_device *device)
+int
+mptscsih_slave_alloc(struct scsi_device *sdev)
 {
-       struct Scsi_Host        *host = device->host;
+       struct Scsi_Host        *host = sdev->host;
        MPT_SCSI_HOST           *hd = (MPT_SCSI_HOST *)host->hostdata;
+       VirtTarget              *vtarget;
        VirtDevice              *vdev;
-       uint                    target = device->id;
+       struct scsi_target      *starget;
 
-       if (hd == NULL)
-               return -ENODEV;
-
-       if ((vdev = hd->Targets[target]) != NULL)
-               goto out;
-
-       vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL);
+       vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
        if (!vdev) {
                printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
                                hd->ioc->name, sizeof(VirtDevice));
                return -ENOMEM;
        }
 
-       memset(vdev, 0, sizeof(VirtDevice));
-       vdev->tflags = MPT_TARGET_FLAGS_Q_YES;
-       vdev->ioc_id = hd->ioc->id;
-       vdev->target_id = device->id;
-       vdev->bus_id = device->channel;
-       vdev->raidVolume = 0;
-       hd->Targets[device->id] = vdev;
-       if (hd->ioc->bus_type == SCSI) {
-               if (hd->ioc->spi_data.isRaid & (1 << device->id)) {
-                       vdev->raidVolume = 1;
+       vdev->lun = sdev->lun;
+       sdev->hostdata = vdev;
+
+       starget = scsi_target(sdev);
+       vtarget = starget->hostdata;
+
+       vdev->vtarget = vtarget;
+
+       if (vtarget->num_luns == 0) {
+               hd->Targets[sdev->id] = vtarget;
+               vtarget->ioc_id = hd->ioc->id;
+               vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
+               vtarget->target_id = sdev->id;
+               vtarget->bus_id = sdev->channel;
+               if (hd->ioc->bus_type == SPI && sdev->channel == 0 &&
+                   hd->ioc->raid_data.isRaid & (1 << sdev->id)) {
+                       vtarget->raidVolume = 1;
                        ddvtprintk((KERN_INFO
-                           "RAID Volume @ id %d\n", device->id));
+                                   "RAID Volume @ id %d\n", sdev->id));
                }
-       } else {
-               vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
        }
-
- out:
-       vdev->num_luns++;
+       vtarget->num_luns++;
        return 0;
 }
 
-static int mptscsih_is_raid_volume(MPT_SCSI_HOST *hd, uint id)
+/*
+ *     OS entry point to allow for host driver to free allocated memory
+ *     Called if no device present or device being unloaded
+ */
+void
+mptscsih_target_destroy(struct scsi_target *starget)
 {
-       int i;
-
-       if (!hd->ioc->spi_data.isRaid || !hd->ioc->spi_data.pIocPg3)
-               return 0;
-
-       for (i = 0; i < hd->ioc->spi_data.pIocPg3->NumPhysDisks; i++) {
-               if (id == hd->ioc->spi_data.pIocPg3->PhysDisk[i].PhysDiskID)
-                       return 1;
-       }
-
-       return 0;
+       if (starget->hostdata)
+               kfree(starget->hostdata);
+       starget->hostdata = NULL;
 }
 
 /*
  *     OS entry point to allow for host driver to free allocated memory
  *     Called if no device present or device being unloaded
  */
-static void
-mptscsih_slave_destroy(struct scsi_device *device)
+void
+mptscsih_slave_destroy(struct scsi_device *sdev)
 {
-       struct Scsi_Host        *host = device->host;
+       struct Scsi_Host        *host = sdev->host;
        MPT_SCSI_HOST           *hd = (MPT_SCSI_HOST *)host->hostdata;
-       VirtDevice              *vdev;
-       uint                    target = device->id;
-       uint                    lun = device->lun;
-
-       if (hd == NULL)
-               return;
-
-       mptscsih_search_running_cmds(hd, target, lun);
-
-       vdev = hd->Targets[target];
-       vdev->luns[0] &= ~(1 << lun);
-       if (--vdev->num_luns)
-               return;
-
-       kfree(hd->Targets[target]);
-       hd->Targets[target] = NULL;
-       
-       if (hd->ioc->bus_type == SCSI) {
-               if (mptscsih_is_raid_volume(hd, target)) {
-                       hd->ioc->spi_data.forceDv |= MPT_SCSICFG_RELOAD_IOC_PG3;
-               } else {
-                       hd->ioc->spi_data.dvStatus[target] =
-                               MPT_SCSICFG_NEGOTIATE;
-
-                       if (!hd->negoNvram) {
-                               hd->ioc->spi_data.dvStatus[target] |=
-                                       MPT_SCSICFG_DV_NOT_DONE;
-                       }
-               }
-       }
+       VirtTarget              *vtarget;
+       VirtDevice              *vdevice;
+       struct scsi_target      *starget;
+
+       starget = scsi_target(sdev);
+       vtarget = starget->hostdata;
+       vdevice = sdev->hostdata;
+
+       mptscsih_search_running_cmds(hd, vdevice);
+       vtarget->luns[0] &= ~(1 << vdevice->lun);
+       vtarget->num_luns--;
+       if (vtarget->num_luns == 0) {
+               hd->Targets[sdev->id] = NULL;
+       }
+       mptscsih_synchronize_cache(hd, vdevice);
+       kfree(vdevice);
+       sdev->hostdata = NULL;
 }
 
-static void
-mptscsih_set_queue_depth(struct scsi_device *device, MPT_SCSI_HOST *hd,
-       VirtDevice *pTarget, int qdepth)
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ *     mptscsih_change_queue_depth - This function will set a devices queue depth
+ *     @sdev: per scsi_device pointer
+ *     @qdepth: requested queue depth
+ *
+ *     Adding support for new 'change_queue_depth' api.
+*/
+int
+mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
 {
-       int     max_depth;
-       int     tagged;
-
-       if (hd->ioc->bus_type == SCSI) {
-               if (pTarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) {
-                       if (!(pTarget->tflags & MPT_TARGET_FLAGS_Q_YES))
-                               max_depth = 1;
-                       else if (((pTarget->inq_data[0] & 0x1f) == 0x00) &&
-                                (pTarget->minSyncFactor <= MPT_ULTRA160 ))
-                               max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
-                       else
-                               max_depth = MPT_SCSI_CMD_PER_DEV_LOW;
-               } else {
-                       /* error case - No Inq. Data */
+       MPT_SCSI_HOST           *hd = (MPT_SCSI_HOST *)sdev->host->hostdata;
+       VirtTarget              *vtarget;
+       struct scsi_target      *starget;
+       int                     max_depth;
+       int                     tagged;
+
+       starget = scsi_target(sdev);
+       vtarget = starget->hostdata;
+
+       if (hd->ioc->bus_type == SPI) {
+               if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
                        max_depth = 1;
-               }
+               else if (sdev->type == TYPE_DISK &&
+                        vtarget->minSyncFactor <= MPT_ULTRA160)
+                       max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
+               else
+                       max_depth = MPT_SCSI_CMD_PER_DEV_LOW;
        } else
                max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
 
@@ -2685,98 +2286,72 @@ mptscsih_set_queue_depth(struct scsi_device *device, MPT_SCSI_HOST *hd,
        else
                tagged = MSG_SIMPLE_TAG;
 
-       scsi_adjust_queue_depth(device, tagged, qdepth);
+       scsi_adjust_queue_depth(sdev, tagged, qdepth);
+       return sdev->queue_depth;
 }
 
-
 /*
  *     OS entry point to adjust the queue_depths on a per-device basis.
  *     Called once per device the bus scan. Use it to force the queue_depth
  *     member to 1 if a device does not support Q tags.
  *     Return non-zero if fails.
  */
-static int
-mptscsih_slave_configure(struct scsi_device *device)
+int
+mptscsih_slave_configure(struct scsi_device *sdev)
 {
-       struct Scsi_Host        *sh = device->host;
-       VirtDevice              *pTarget;
+       struct Scsi_Host        *sh = sdev->host;
+       VirtTarget              *vtarget;
+       VirtDevice              *vdevice;
+       struct scsi_target      *starget;
        MPT_SCSI_HOST           *hd = (MPT_SCSI_HOST *)sh->hostdata;
+       int                     indexed_lun, lun_index;
 
-       if ((hd == NULL) || (hd->Targets == NULL)) {
-               return 0;
-       }
+       starget = scsi_target(sdev);
+       vtarget = starget->hostdata;
+       vdevice = sdev->hostdata;
 
        dsprintk((MYIOC_s_INFO_FMT
                "device @ %p, id=%d, LUN=%d, channel=%d\n",
-               hd->ioc->name, device, device->id, device->lun, device->channel));
-       dsprintk((MYIOC_s_INFO_FMT
-               "sdtr %d wdtr %d ppr %d inq length=%d\n",
-               hd->ioc->name, device->sdtr, device->wdtr,
-               device->ppr, device->inquiry_len));
-
-       if (device->id > sh->max_id) {
+               hd->ioc->name, sdev, sdev->id, sdev->lun, sdev->channel));
+       if (hd->ioc->bus_type == SPI)
+               dsprintk((MYIOC_s_INFO_FMT
+                   "sdtr %d wdtr %d ppr %d inq length=%d\n",
+                   hd->ioc->name, sdev->sdtr, sdev->wdtr,
+                   sdev->ppr, sdev->inquiry_len));
+
+       if (sdev->id > sh->max_id) {
                /* error case, should never happen */
-               scsi_adjust_queue_depth(device, 0, 1);
-               goto slave_configure_exit;
-       }
-
-       pTarget = hd->Targets[device->id];
-
-       if (pTarget == NULL) {
-               /* Driver doesn't know about this device.
-                * Kernel may generate a "Dummy Lun 0" which
-                * may become a real Lun if a 
-                * "scsi add-single-device" command is executed
-                * while the driver is active (hot-plug a 
-                * device).  LSI Raid controllers need 
-                * queue_depth set to DEV_HIGH for this reason.
-                */
-               scsi_adjust_queue_depth(device, MSG_SIMPLE_TAG,
-                       MPT_SCSI_CMD_PER_DEV_HIGH);
+               scsi_adjust_queue_depth(sdev, 0, 1);
                goto slave_configure_exit;
        }
 
-       mptscsih_initTarget(hd, device->channel, device->id, device->lun,
-               device->inquiry, device->inquiry_len );
-       mptscsih_set_queue_depth(device, hd, pTarget, MPT_SCSI_CMD_PER_DEV_HIGH);
+       vdevice->configured_lun=1;
+       lun_index = (vdevice->lun >> 5);  /* 32 luns per lun_index */
+       indexed_lun = (vdevice->lun % 32);
+       vtarget->luns[lun_index] |= (1 << indexed_lun);
+       mptscsih_initTarget(hd, vtarget, sdev);
+       mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH);
 
        dsprintk((MYIOC_s_INFO_FMT
                "Queue depth=%d, tflags=%x\n",
-               hd->ioc->name, device->queue_depth, pTarget->tflags));
+               hd->ioc->name, sdev->queue_depth, vtarget->tflags));
 
-       dsprintk((MYIOC_s_INFO_FMT
-               "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
-               hd->ioc->name, pTarget->negoFlags, pTarget->maxOffset, pTarget->minSyncFactor));
+       if (hd->ioc->bus_type == SPI)
+               dsprintk((MYIOC_s_INFO_FMT
+                   "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
+                   hd->ioc->name, vtarget->negoFlags, vtarget->maxOffset,
+                   vtarget->minSyncFactor));
 
 slave_configure_exit:
 
        dsprintk((MYIOC_s_INFO_FMT
                "tagged %d, simple %d, ordered %d\n",
-               hd->ioc->name,device->tagged_supported, device->simple_tags,
-               device->ordered_tags));
+               hd->ioc->name,sdev->tagged_supported, sdev->simple_tags,
+               sdev->ordered_tags));
 
        return 0;
 }
 
-static ssize_t
-mptscsih_store_queue_depth(struct device *dev, const char *buf, size_t count)
-{
-       int                      depth;
-       struct scsi_device      *sdev = to_scsi_device(dev);
-       MPT_SCSI_HOST           *hd = (MPT_SCSI_HOST *) sdev->host->hostdata;
-       VirtDevice              *pTarget;
-
-       depth = simple_strtoul(buf, NULL, 0);
-       if (depth == 0)
-               return -EINVAL;
-       pTarget = hd->Targets[sdev->id];
-       if (pTarget == NULL)
-               return -EINVAL;
-       mptscsih_set_queue_depth(sdev, (MPT_SCSI_HOST *) sdev->host->hostdata,
-               pTarget, depth);
-       return count;
-}
-
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  *  Private routines...
@@ -2788,18 +2363,16 @@ mptscsih_store_queue_depth(struct device *dev, const char *buf, size_t count)
  *
  */
 static void
-copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
+mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
 {
-       VirtDevice      *target;
+       VirtDevice      *vdev;
        SCSIIORequest_t *pReq;
        u32              sense_count = le32_to_cpu(pScsiReply->SenseCount);
-       int              index;
 
        /* Get target structure
         */
        pReq = (SCSIIORequest_t *) mf;
-       index = (int) pReq->TargetID;
-       target = hd->Targets[index];
+       vdev = sc->device->hostdata;
 
        if (sense_count) {
                u8 *sense_data;
@@ -2813,17 +2386,17 @@ copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSI
                /* Log SMART data (asc = 0x5D, non-IM case only) if required.
                 */
                if ((hd->ioc->events) && (hd->ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) {
-                       if ((sense_data[12] == 0x5D) && (target->raidVolume == 0)) {
+                       if ((sense_data[12] == 0x5D) && (vdev->vtarget->raidVolume == 0)) {
                                int idx;
                                MPT_ADAPTER *ioc = hd->ioc;
 
-                               idx = ioc->eventContext % ioc->eventLogSize;
+                               idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
                                ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
                                ioc->events[idx].eventContext = ioc->eventContext;
 
                                ioc->events[idx].data[0] = (pReq->LUN[1] << 24) ||
                                        (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) ||
-                                       (pReq->Bus << 8) || pReq->TargetID;
+                                       (sc->device->channel << 8) || sc->device->id;
 
                                ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12];
 
@@ -2854,11 +2427,12 @@ SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc)
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-static int
+int
 mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
 {
        MPT_SCSI_HOST   *hd;
        unsigned long    flags;
+       int             ii;
 
        dtmprintk((KERN_WARNING MYNAM
                        ": IOC %s_reset routed to SCSI host driver!\n",
@@ -2916,21 +2490,14 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
 
                /* ScsiLookup initialization
                 */
-               {
-                       int ii;
-                       for (ii=0; ii < hd->ioc->req_depth; ii++)
-                               hd->ScsiLookup[ii] = NULL;
-               }
+               for (ii=0; ii < hd->ioc->req_depth; ii++)
+                       hd->ScsiLookup[ii] = NULL;
 
                /* 2. Chain Buffer initialization
                 */
 
-               /* 4. Renegotiate to all devices, if SCSI
+               /* 4. Renegotiate to all devices, if SPI
                 */
-               if (ioc->bus_type == SCSI) {
-                       dnegoprintk(("writeSDP1: ALL_IDS USE_NVRAM\n"));
-                       mptscsih_writeSDP1(hd, 0, 0, MPT_SCSICFG_ALL_IDS | MPT_SCSICFG_USE_NVRAM);
-               }
 
                /* 5. Enable new commands to be posted
                 */
@@ -2949,18 +2516,23 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
                         */
                        hd->pLocal = &hd->localReply;
                        hd->pLocal->completion = MPT_SCANDV_DID_RESET;
-                       scandv_wait_done = 1;
-                       wake_up(&scandv_waitq);
+                       hd->scandv_wait_done = 1;
+                       wake_up(&hd->scandv_waitq);
                        hd->cmdPtr = NULL;
                }
 
-               /* 7. Set flag to force DV and re-read IOC Page 3
+               /* 7. FC: Rescan for blocked rports which might have returned.
                 */
-               if (ioc->bus_type == SCSI) {
-                       ioc->spi_data.forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
-                       ddvtprintk(("Set reload IOC Pg3 Flag\n"));
+               if (ioc->bus_type == FC) {
+                       spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
+                       if (ioc->fc_rescan_work_q) {
+                               if (ioc->fc_rescan_work_count++ == 0) {
+                                       queue_work(ioc->fc_rescan_work_q,
+                                                  &ioc->fc_rescan_work);
+                               }
+                       }
+                       spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
                }
-
                dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name));
 
        }
@@ -2969,37 +2541,48 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-static int
+int
 mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
 {
        MPT_SCSI_HOST *hd;
        u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
+       unsigned long flags;
 
-       devtprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
+       devtverboseprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
                        ioc->name, event));
 
+       if (ioc->sh == NULL ||
+               ((hd = (MPT_SCSI_HOST *)ioc->sh->hostdata) == NULL))
+               return 1;
+
        switch (event) {
        case MPI_EVENT_UNIT_ATTENTION:                  /* 03 */
                /* FIXME! */
                break;
        case MPI_EVENT_IOC_BUS_RESET:                   /* 04 */
        case MPI_EVENT_EXT_BUS_RESET:                   /* 05 */
-               hd = NULL;
-               if (ioc->sh) {
-                       hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
-                       if (hd && (ioc->bus_type == SCSI) && (hd->soft_resets < -1))
-                               hd->soft_resets++;
-               }
+               if (hd && (ioc->bus_type == SPI) && (hd->soft_resets < -1))
+                       hd->soft_resets++;
                break;
        case MPI_EVENT_LOGOUT:                          /* 09 */
                /* FIXME! */
                break;
 
+       case MPI_EVENT_RESCAN:                          /* 06 */
+               spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
+               if (ioc->fc_rescan_work_q) {
+                       if (ioc->fc_rescan_work_count++ == 0) {
+                               queue_work(ioc->fc_rescan_work_q,
+                                          &ioc->fc_rescan_work);
+                       }
+               }
+               spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
+               break;
+
                /*
                 *  CHECKME! Don't think we need to do
                 *  anything for these, but...
                 */
-       case MPI_EVENT_RESCAN:                          /* 06 */
        case MPI_EVENT_LINK_STATUS_CHANGE:              /* 07 */
        case MPI_EVENT_LOOP_STATE_CHANGE:               /* 08 */
                /*
@@ -3008,69 +2591,6 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
                break;
 
        case MPI_EVENT_INTEGRATED_RAID:                 /* 0B */
-#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
-               /* negoNvram set to 0 if DV enabled and to USE_NVRAM if
-                * if DV disabled. Need to check for target mode.
-                */
-               hd = NULL;
-               if (ioc->sh)
-                       hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
-
-               if (hd && (ioc->bus_type == SCSI) && (hd->negoNvram == 0)) {
-                       ScsiCfgData     *pSpi;
-                       Ioc3PhysDisk_t  *pPDisk;
-                       int              numPDisk;
-                       u8               reason;
-                       u8               physDiskNum;
-
-                       reason = (le32_to_cpu(pEvReply->Data[0]) & 0x00FF0000) >> 16;
-                       if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
-                               /* New or replaced disk.
-                                * Set DV flag and schedule DV.
-                                */
-                               pSpi = &ioc->spi_data;
-                               physDiskNum = (le32_to_cpu(pEvReply->Data[0]) & 0xFF000000) >> 24;
-                               ddvtprintk(("DV requested for phys disk id %d\n", physDiskNum));
-                               if (pSpi->pIocPg3) {
-                                       pPDisk =  pSpi->pIocPg3->PhysDisk;
-                                       numPDisk =pSpi->pIocPg3->NumPhysDisks;
-
-                                       while (numPDisk) {
-                                               if (physDiskNum == pPDisk->PhysDiskNum) {
-                                                       pSpi->dvStatus[pPDisk->PhysDiskID] = (MPT_SCSICFG_NEED_DV | MPT_SCSICFG_DV_NOT_DONE);
-                                                       pSpi->forceDv = MPT_SCSICFG_NEED_DV;
-                                                       ddvtprintk(("NEED_DV set for phys disk id %d\n", pPDisk->PhysDiskID));
-                                                       break;
-                                               }
-                                               pPDisk++;
-                                               numPDisk--;
-                                       }
-
-                                       if (numPDisk == 0) {
-                                               /* The physical disk that needs DV was not found
-                                                * in the stored IOC Page 3. The driver must reload
-                                                * this page. DV routine will set the NEED_DV flag for
-                                                * all phys disks that have DV_NOT_DONE set.
-                                                */
-                                               pSpi->forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
-                                               ddvtprintk(("phys disk %d not found. Setting reload IOC Pg3 Flag\n", physDiskNum));
-                                       }
-                               }
-                       }
-               }
-#endif
-
-#if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY)
-               printk("Raid Event RF: ");
-               {
-                       u32 *m = (u32 *)pEvReply;
-                       int ii;
-                       int n = (int)pEvReply->MsgLength;
-                       for (ii=6; ii < n; ii++)
-                               printk(" %08x", le32_to_cpu(m[ii]));
-                       printk("\n");
-               }
-#endif
                break;
 
        case MPI_EVENT_NONE:                            /* 00 */
@@ -3085,51 +2605,12 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
        return 1;               /* currently means nothing really */
 }
 
-static struct device_attribute mptscsih_queue_depth_attr = {
-       .attr = {
-               .name =         "queue_depth",
-               .mode =         S_IWUSR,
-       },
-       .store = mptscsih_store_queue_depth,
-};
-
-static struct device_attribute *mptscsih_dev_attrs[] = {
-       &mptscsih_queue_depth_attr,
-       NULL,
-};
-
-static struct scsi_host_template driver_template = {
-       .proc_name                      = "mptscsih",
-       .proc_info                      = mptscsih_proc_info,
-       .name                           = "MPT SCSI Host",
-       .info                           = mptscsih_info,
-       .queuecommand                   = mptscsih_qcmd,
-       .slave_alloc                    = mptscsih_slave_alloc,
-       .slave_configure                = mptscsih_slave_configure,
-       .slave_destroy                  = mptscsih_slave_destroy,
-       .eh_abort_handler               = mptscsih_abort,
-       .eh_device_reset_handler        = mptscsih_dev_reset,
-       .eh_bus_reset_handler           = mptscsih_bus_reset,
-       .eh_host_reset_handler          = mptscsih_host_reset,
-       .bios_param                     = mptscsih_bios_param,
-       .can_queue                      = MPT_SCSI_CAN_QUEUE,
-       .this_id                        = -1,
-       .sg_tablesize                   = MPT_SCSI_SG_DEPTH,
-       .max_sectors                    = 8192,
-       .cmd_per_lun                    = 7,
-       .use_clustering                 = ENABLE_CLUSTERING,
-       .sdev_attrs                     = mptscsih_dev_attrs,
-};
-
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  *     mptscsih_initTarget - Target, LUN alloc/free functionality.
  *     @hd: Pointer to MPT_SCSI_HOST structure
- *     @bus_id: Bus number (?)
- *     @target_id: SCSI target id
- *     @lun: SCSI LUN id
- *     @data: Pointer to data
- *     @dlen: Number of INQUIRY bytes
+ *     @vtarget: per target private data
+ *     @sdev: SCSI device
  *
  *     NOTE: It's only SAFE to call this routine if data points to
  *     sane & valid STANDARD INQUIRY data!
@@ -3139,106 +2620,46 @@ static struct scsi_host_template driver_template = {
  *
  */
 static void
-mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *data, int dlen)
+mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget,
+                   struct scsi_device *sdev)
 {
-       int             indexed_lun, lun_index;
-       VirtDevice      *vdev;
-       ScsiCfgData     *pSpi;
-       char            data_56;
-
        dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n",
-                       hd->ioc->name, bus_id, target_id, lun, hd));
+               hd->ioc->name, vtarget->bus_id, vtarget->target_id, lun, hd));
 
-       /*
-        * If the peripheral qualifier filter is enabled then if the target reports a 0x1
-        * (i.e. The targer is capable of supporting the specified peripheral device type
-        * on this logical unit; however, the physical device is not currently connected
-        * to this logical unit) it will be converted to a 0x3 (i.e. The target is not 
-        * capable of supporting a physical device on this logical unit). This is to work
-        * around a bug in th emid-layer in some distributions in which the mid-layer will
-        * continue to try to communicate to the LUN and evntually create a dummy LUN.
-       */
-       if (mpt_pq_filter && dlen && (data[0] & 0xE0))
-               data[0] |= 0x40;
-       
        /* Is LUN supported? If so, upper 2 bits will be 0
        * in first byte of inquiry data.
        */
-       if (data[0] & 0xe0)
+       if (sdev->inq_periph_qual != 0)
                return;
 
-       if ((vdev = hd->Targets[target_id]) == NULL) {
+       if (vtarget == NULL)
                return;
-       }
-
-       lun_index = (lun >> 5);  /* 32 luns per lun_index */
-       indexed_lun = (lun % 32);
-       vdev->luns[lun_index] |= (1 << indexed_lun);
-
-       if (hd->ioc->bus_type == SCSI) {
-               if ((data[0] == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) {
-                       /* Treat all Processors as SAF-TE if
-                        * command line option is set */
-                       vdev->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
-                       mptscsih_writeIOCPage4(hd, target_id, bus_id);
-               }else if ((data[0] == TYPE_PROCESSOR) &&
-                       !(vdev->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) {
-                       if ( dlen > 49 ) {
-                               vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
-                               if ( data[44] == 'S' &&
-                                    data[45] == 'A' &&
-                                    data[46] == 'F' &&
-                                    data[47] == '-' &&
-                                    data[48] == 'T' &&
-                                    data[49] == 'E' ) {
-                                       vdev->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
-                                       mptscsih_writeIOCPage4(hd, target_id, bus_id);
-                               }
-                       }
-               }
-               if (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY)) {
-                       if ( dlen > 8 ) {
-                               memcpy (vdev->inq_data, data, 8);
-                       } else {
-                               memcpy (vdev->inq_data, data, dlen);
-                       }
-
-                       /* If have not done DV, set the DV flag.
-                        */
-                       pSpi = &hd->ioc->spi_data;
-                       if ((data[0] == TYPE_TAPE) || (data[0] == TYPE_PROCESSOR)) {
-                               if (pSpi->dvStatus[target_id] & MPT_SCSICFG_DV_NOT_DONE)
-                                       pSpi->dvStatus[target_id] |= MPT_SCSICFG_NEED_DV;
-                       }
 
-                       vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
+       vtarget->type = sdev->type;
 
+       if (hd->ioc->bus_type != SPI)
+               return;
 
-                       data_56 = 0x0F;  /* Default to full capabilities if Inq data length is < 57 */
-                       if (dlen > 56) {
-                               if ( (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_56))) {
-                               /* Update the target capabilities
-                                */
-                                       data_56 = data[56];
-                                       vdev->tflags |= MPT_TARGET_FLAGS_VALID_56;
-                               }
-                       }
-                       mptscsih_setTargetNegoParms(hd, vdev, data_56);
-               } else {
-                       /* Initial Inquiry may not request enough data bytes to
-                        * obtain byte 57.  DV will; if target doesn't return
-                        * at least 57 bytes, data[56] will be zero. */
-                       if (dlen > 56) {
-                               if ( (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_56))) {
-                               /* Update the target capabilities
-                                */
-                                       data_56 = data[56];
-                                       vdev->tflags |= MPT_TARGET_FLAGS_VALID_56;
-                                       mptscsih_setTargetNegoParms(hd, vdev, data_56);
-                               }
+       if ((sdev->type == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) {
+               /* Treat all Processors as SAF-TE if
+                * command line option is set */
+               vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
+               mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id);
+       }else if ((sdev->type == TYPE_PROCESSOR) &&
+               !(vtarget->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) {
+               if (sdev->inquiry_len > 49 ) {
+                       if (sdev->inquiry[44] == 'S' &&
+                           sdev->inquiry[45] == 'A' &&
+                           sdev->inquiry[46] == 'F' &&
+                           sdev->inquiry[47] == '-' &&
+                           sdev->inquiry[48] == 'T' &&
+                           sdev->inquiry[49] == 'E' ) {
+                               vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
+                               mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id);
                        }
                }
        }
+       mptscsih_setTargetNegoParms(hd, vtarget, sdev);
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -3248,66 +2669,51 @@ mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *
  *
  */
 static void
-mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56)
+mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target,
+                           struct scsi_device *sdev)
 {
-       ScsiCfgData *pspi_data = &hd->ioc->spi_data;
+       SpiCfgData *pspi_data = &hd->ioc->spi_data;
        int  id = (int) target->target_id;
        int  nvram;
-       VirtDevice      *vdev;
-       int ii;
        u8 width = MPT_NARROW;
        u8 factor = MPT_ASYNC;
        u8 offset = 0;
-       u8 version, nfactor;
+       u8 nfactor;
        u8 noQas = 1;
 
        target->negoFlags = pspi_data->noQas;
 
-       /* noQas == 0 => device supports QAS. Need byte 56 of Inq to determine
-        * support. If available, default QAS to off and allow enabling.
-        * If not available, default QAS to on, turn off for non-disks.
-        */
+       /* noQas == 0 => device supports QAS. */
 
-       /* Set flags based on Inquiry data
-        */
-       version = target->inq_data[2] & 0x07;
-       if (version < 2) {
+       if (sdev->scsi_level < SCSI_2) {
                width = 0;
                factor = MPT_ULTRA2;
                offset = pspi_data->maxSyncOffset;
                target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
        } else {
-               if (target->inq_data[7] & 0x20) {
+               if (scsi_device_wide(sdev)) {
                        width = 1;
                }
 
-               if (target->inq_data[7] & 0x10) {
+               if (scsi_device_sync(sdev)) {
                        factor = pspi_data->minSyncFactor;
-                       if (target->tflags & MPT_TARGET_FLAGS_VALID_56) {
-                               /* bits 2 & 3 show Clocking support */
-                               if ((byte56 & 0x0C) == 0)
+                       if (!scsi_device_dt(sdev))
                                        factor = MPT_ULTRA2;
+                       else {
+                               if (!scsi_device_ius(sdev) &&
+                                   !scsi_device_qas(sdev))
+                                       factor = MPT_ULTRA160;
                                else {
-                                       if ((byte56 & 0x03) == 0)
-                                               factor = MPT_ULTRA160;
-                                       else {
-                                               factor = MPT_ULTRA320;
-                                               if (byte56 & 0x02)
-                                               {
-                                                       ddvtprintk((KERN_INFO "Enabling QAS due to byte56=%02x on id=%d!\n", byte56, id));
-                                                       noQas = 0;
-                                               }
-                                               if (target->inq_data[0] == TYPE_TAPE) {
-                                                       if (byte56 & 0x01)
-                                                               target->negoFlags |= MPT_TAPE_NEGO_IDP;
-                                               }
+                                       factor = MPT_ULTRA320;
+                                       if (scsi_device_qas(sdev)) {
+                                               ddvtprintk((KERN_INFO "Enabling QAS due to byte56=%02x on id=%d!\n", byte56, id));
+                                               noQas = 0;
                                        }
+                                       if (sdev->type == TYPE_TAPE &&
+                                           scsi_device_ius(sdev))
+                                               target->negoFlags |= MPT_TAPE_NEGO_IDP;
                                }
-                       } else {
-                               ddvtprintk((KERN_INFO "Enabling QAS on id=%d due to ~TARGET_FLAGS_VALID_56!\n", id));
-                               noQas = 0;
                        }
-                               
                        offset = pspi_data->maxSyncOffset;
 
                        /* If RAID, never disable QAS
@@ -3325,7 +2731,7 @@ mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56)
                }
        }
 
-       if ( (target->inq_data[7] & 0x02) == 0) {
+       if (!sdev->tagged_supported) {
                target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
        }
 
@@ -3383,345 +2789,23 @@ mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56)
        if ( factor > MPT_ULTRA320 )
                noQas = 0;
 
-       /* GEM, processor WORKAROUND
-        */
-       if ((target->inq_data[0] == TYPE_PROCESSOR) || (target->inq_data[0] > 0x08)) {
-               target->negoFlags |= (MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC);
-               pspi_data->dvStatus[id] |= MPT_SCSICFG_BLK_NEGO;
-       } else {
-               if (noQas && (pspi_data->noQas == 0)) {
-                       pspi_data->noQas |= MPT_TARGET_NO_NEGO_QAS;
-                       target->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
-
-                       /* Disable QAS in a mixed configuration case
-                       */
-
-                       ddvtprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id));
-                       for (ii = 0; ii < id; ii++) {
-                               if ( (vdev = hd->Targets[ii]) ) {
-                                       vdev->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
-                                       mptscsih_writeSDP1(hd, 0, ii, vdev->negoFlags);
-                               }       
-                       }
-               }
-       }
+       if (noQas && (pspi_data->noQas == 0)) {
+               pspi_data->noQas |= MPT_TARGET_NO_NEGO_QAS;
+               target->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
 
-       /* Write SDP1 on this I/O to this target */
-       if (pspi_data->dvStatus[id] & MPT_SCSICFG_NEGOTIATE) {
-               ddvtprintk((KERN_INFO "MPT_SCSICFG_NEGOTIATE on id=%d!\n", id));
-               mptscsih_writeSDP1(hd, 0, id, hd->negoNvram);
-               pspi_data->dvStatus[id] &= ~MPT_SCSICFG_NEGOTIATE;
-       } else if (pspi_data->dvStatus[id] & MPT_SCSICFG_BLK_NEGO) {
-               ddvtprintk((KERN_INFO "MPT_SCSICFG_BLK_NEGO on id=%d!\n", id));
-               mptscsih_writeSDP1(hd, 0, id, MPT_SCSICFG_BLK_NEGO);
-               pspi_data->dvStatus[id] &= ~MPT_SCSICFG_BLK_NEGO;
+               /* Disable QAS in a mixed configuration case
+                */
+
+               ddvtprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id));
        }
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/* If DV disabled (negoNvram set to USE_NVARM) or if not LUN 0, return.
- * Else set the NEED_DV flag after Read Capacity Issued (disks)
- * or Mode Sense (cdroms).
- *
- * Tapes, initTarget will set this flag on completion of Inquiry command.
- * Called only if DV_NOT_DONE flag is set
- */
-static void mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq)
-{
-       u8 cmd;
-       ScsiCfgData *pSpi;
-
-       ddvtprintk((" set_dvflags: id=%d lun=%d negoNvram=%x cmd=%x\n", 
-               pReq->TargetID, pReq->LUN[1], hd->negoNvram, pReq->CDB[0]));
-       
-       if ((pReq->LUN[1] != 0) || (hd->negoNvram != 0))
-               return;
-
-       cmd = pReq->CDB[0];
-
-       if ((cmd == READ_CAPACITY) || (cmd == MODE_SENSE)) {
-               pSpi = &hd->ioc->spi_data;
-               if ((pSpi->isRaid & (1 << pReq->TargetID)) && pSpi->pIocPg3) {
-                       /* Set NEED_DV for all hidden disks
-                        */
-                       Ioc3PhysDisk_t *pPDisk =  pSpi->pIocPg3->PhysDisk;
-                       int             numPDisk = pSpi->pIocPg3->NumPhysDisks;
-
-                       while (numPDisk) {
-                               pSpi->dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV;
-                               ddvtprintk(("NEED_DV set for phys disk id %d\n", pPDisk->PhysDiskID));
-                               pPDisk++;
-                               numPDisk--;
-                       }
-               }
-               pSpi->dvStatus[pReq->TargetID] |= MPT_SCSICFG_NEED_DV;
-               ddvtprintk(("NEED_DV set for visible disk id %d\n", pReq->TargetID));
-       }
-}
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
- * If no Target, bus reset on 1st I/O. Set the flag to
- * prevent any future negotiations to this device.
+ *  SCSI Config Page functionality ...
  */
-static void mptscsih_no_negotiate(MPT_SCSI_HOST *hd, int target_id)
-{
-
-       if ((hd->Targets) && (hd->Targets[target_id] == NULL))
-               hd->ioc->spi_data.dvStatus[target_id] |= MPT_SCSICFG_BLK_NEGO;
-
-       return;
-}
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- *  SCSI Config Page functionality ...
- */
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*     mptscsih_setDevicePage1Flags  - add Requested and Configuration fields flags
- *     based on width, factor and offset parameters.
- *     @width: bus width
- *     @factor: sync factor
- *     @offset: sync offset
- *     @requestedPtr: pointer to requested values (updated)
- *     @configurationPtr: pointer to configuration values (updated)
- *     @flags: flags to block WDTR or SDTR negotiation
- *
- *     Return: None.
- *
- *     Remark: Called by writeSDP1 and _dv_params
- */
-static void
-mptscsih_setDevicePage1Flags (u8 width, u8 factor, u8 offset, int *requestedPtr, int *configurationPtr, u8 flags)
-{
-       u8 nowide = flags & MPT_TARGET_NO_NEGO_WIDE;
-       u8 nosync = flags & MPT_TARGET_NO_NEGO_SYNC;
-
-       *configurationPtr = 0;
-       *requestedPtr = width ? MPI_SCSIDEVPAGE1_RP_WIDE : 0;
-       *requestedPtr |= (offset << 16) | (factor << 8);
-
-       if (width && offset && !nowide && !nosync) {
-               if (factor < MPT_ULTRA160) {
-                       *requestedPtr |= (MPI_SCSIDEVPAGE1_RP_IU + MPI_SCSIDEVPAGE1_RP_DT);
-                       if ((flags & MPT_TARGET_NO_NEGO_QAS) == 0)
-                               *requestedPtr |= MPI_SCSIDEVPAGE1_RP_QAS;
-                       if (flags & MPT_TAPE_NEGO_IDP)
-                               *requestedPtr |= 0x08000000;
-               } else if (factor < MPT_ULTRA2) {
-                       *requestedPtr |= MPI_SCSIDEVPAGE1_RP_DT;
-               }
-       }
-
-       if (nowide)
-               *configurationPtr |= MPI_SCSIDEVPAGE1_CONF_WDTR_DISALLOWED;
-
-       if (nosync)
-               *configurationPtr |= MPI_SCSIDEVPAGE1_CONF_SDTR_DISALLOWED;
-
-       return;
-}
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*     mptscsih_writeSDP1  - write SCSI Device Page 1
- *     @hd: Pointer to a SCSI Host Strucutre
- *     @portnum: IOC port number
- *     @target_id: writeSDP1 for single ID
- *     @flags: MPT_SCSICFG_ALL_IDS, MPT_SCSICFG_USE_NVRAM, MPT_SCSICFG_BLK_NEGO
- *
- *     Return: -EFAULT if read of config page header fails
- *             or 0 if success.
- *
- *     Remark: If a target has been found, the settings from the
- *             target structure are used, else the device is set
- *             to async/narrow.
- *
- *     Remark: Called during init and after a FW reload.
- *     Remark: We do not wait for a return, write pages sequentially.
- */
-static int
-mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
-{
-       MPT_ADAPTER             *ioc = hd->ioc;
-       Config_t                *pReq;
-       SCSIDevicePage1_t       *pData;
-       VirtDevice              *pTarget;
-       MPT_FRAME_HDR           *mf;
-       dma_addr_t               dataDma;
-       u16                      req_idx;
-       u32                      frameOffset;
-       u32                      requested, configuration, flagsLength;
-       int                      ii, nvram;
-       int                      id = 0, maxid = 0;
-       u8                       width;
-       u8                       factor;
-       u8                       offset;
-       u8                       bus = 0;
-       u8                       negoFlags;
-       u8                       maxwidth, maxoffset, maxfactor;
-
-       if (ioc->spi_data.sdp1length == 0)
-               return 0;
-
-       if (flags & MPT_SCSICFG_ALL_IDS) {
-               id = 0;
-               maxid = ioc->sh->max_id - 1;
-       } else if (ioc->sh) {
-               id = target_id;
-               maxid = min_t(int, id, ioc->sh->max_id - 1);
-       }
-
-       for (; id <= maxid; id++) {
-
-               if (id == ioc->pfacts[portnum].PortSCSIID)
-                       continue;
-
-               /* Use NVRAM to get adapter and target maximums
-                * Data over-riden by target structure information, if present
-                */
-               maxwidth = ioc->spi_data.maxBusWidth;
-               maxoffset = ioc->spi_data.maxSyncOffset;
-               maxfactor = ioc->spi_data.minSyncFactor;
-               if (ioc->spi_data.nvram && (ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
-                       nvram = ioc->spi_data.nvram[id];
-
-                       if (maxwidth)
-                               maxwidth = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
-
-                       if (maxoffset > 0) {
-                               maxfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
-                               if (maxfactor == 0) {
-                                       /* Key for async */
-                                       maxfactor = MPT_ASYNC;
-                                       maxoffset = 0;
-                               } else if (maxfactor < ioc->spi_data.minSyncFactor) {
-                                       maxfactor = ioc->spi_data.minSyncFactor;
-                               }
-                       } else
-                               maxfactor = MPT_ASYNC;
-               }
-
-               /* Set the negotiation flags.
-                */
-               negoFlags = ioc->spi_data.noQas;
-               if (!maxwidth)
-                       negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
-
-               if (!maxoffset)
-                       negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
-
-               if (flags & MPT_SCSICFG_USE_NVRAM) {
-                       width = maxwidth;
-                       factor = maxfactor;
-                       offset = maxoffset;
-               } else {
-                       width = 0;
-                       factor = MPT_ASYNC;
-                       offset = 0;
-                       //negoFlags = 0;
-                       //negoFlags = MPT_TARGET_NO_NEGO_SYNC;
-               }
-
-               /* If id is not a raid volume, get the updated
-                * transmission settings from the target structure.
-                */
-               if (hd->Targets && (pTarget = hd->Targets[id]) && !pTarget->raidVolume) {
-                       width = pTarget->maxWidth;
-                       factor = pTarget->minSyncFactor;
-                       offset = pTarget->maxOffset;
-                       negoFlags = pTarget->negoFlags;
-               }
-               
-#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
-               /* Force to async and narrow if DV has not been executed
-                * for this ID
-                */
-               if ((hd->ioc->spi_data.dvStatus[id] & MPT_SCSICFG_DV_NOT_DONE) != 0) {
-                       width = 0;
-                       factor = MPT_ASYNC;
-                       offset = 0;
-               }
-#endif
-
-               if (flags & MPT_SCSICFG_BLK_NEGO)
-                       negoFlags = MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC;
-
-               mptscsih_setDevicePage1Flags(width, factor, offset,
-                                       &requested, &configuration, negoFlags);
-               dnegoprintk(("writeSDP1: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
-                       target_id, width, factor, offset, negoFlags, requested, configuration));
-
-               /* Get a MF for this command.
-                */
-               if ((mf = mpt_get_msg_frame(ScsiDoneCtx, ioc)) == NULL) {
-                       dprintk((MYIOC_s_WARN_FMT "write SDP1: no msg frames!\n",
-                                               ioc->name));
-                       return -EAGAIN;
-               }
-
-               ddvprintk((MYIOC_s_INFO_FMT "WriteSDP1 (mf=%p, id=%d, req=0x%x, cfg=0x%x)\n",
-                       hd->ioc->name, mf, id, requested, configuration));
-
-
-               /* Set the request and the data pointers.
-                * Request takes: 36 bytes (32 bit SGE)
-                * SCSI Device Page 1 requires 16 bytes
-                * 40 + 16 <= size of SCSI IO Request = 56 bytes
-                * and MF size >= 64 bytes.
-                * Place data at end of MF.
-                */
-               pReq = (Config_t *)mf;
-
-               req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
-               frameOffset = ioc->req_sz - sizeof(SCSIDevicePage1_t);
-
-               pData = (SCSIDevicePage1_t *)((u8 *) mf + frameOffset);
-               dataDma = ioc->req_frames_dma + (req_idx * ioc->req_sz) + frameOffset;
-
-               /* Complete the request frame (same for all requests).
-                */
-               pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
-               pReq->Reserved = 0;
-               pReq->ChainOffset = 0;
-               pReq->Function = MPI_FUNCTION_CONFIG;
-               pReq->ExtPageLength = 0;
-               pReq->ExtPageType = 0;
-               pReq->MsgFlags = 0;
-               for (ii=0; ii < 8; ii++) {
-                       pReq->Reserved2[ii] = 0;
-               }
-               pReq->Header.PageVersion = ioc->spi_data.sdp1version;
-               pReq->Header.PageLength = ioc->spi_data.sdp1length;
-               pReq->Header.PageNumber = 1;
-               pReq->Header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
-               pReq->PageAddress = cpu_to_le32(id | (bus << 8 ));
-
-               /* Add a SGE to the config request.
-                */
-               flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE | ioc->spi_data.sdp1length * 4;
-
-               mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma);
-
-               /* Set up the common data portion
-                */
-               pData->Header.PageVersion = pReq->Header.PageVersion;
-               pData->Header.PageLength = pReq->Header.PageLength;
-               pData->Header.PageNumber = pReq->Header.PageNumber;
-               pData->Header.PageType = pReq->Header.PageType;
-               pData->RequestedParameters = cpu_to_le32(requested);
-               pData->Reserved = 0;
-               pData->Configuration = cpu_to_le32(configuration);
-
-               dprintk((MYIOC_s_INFO_FMT
-                       "write SDP1: id %d pgaddr 0x%x req 0x%x config 0x%x\n",
-                               ioc->name, id, (id | (bus<<8)),
-                               requested, configuration));
-
-               mpt_put_msg_frame(ScsiDoneCtx, ioc, mf);
-       }
-
-       return 0;
-}
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*     mptscsih_writeIOCPage4  - write IOC Page 4
@@ -3748,8 +2832,8 @@ 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) {
-               dprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n",
+       if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
+               dfailprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n",
                                        ioc->name));
                return -EAGAIN;
        }
@@ -3794,7 +2878,7 @@ mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus)
                "writeIOCPage4: MaxSEP=%d ActiveSEP=%d id=%d bus=%d\n",
                        ioc->name, IOCPage4Ptr->MaxSEP, IOCPage4Ptr->ActiveSEP, target_id, bus));
 
-       mpt_put_msg_frame(ScsiDoneCtx, ioc, mf);
+       mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
 
        return 0;
 }
@@ -3824,7 +2908,7 @@ mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus)
  *     in the IOC member localReply structure.
  *     Used ONLY for DV and other internal commands.
  */
-static int
+int
 mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
 {
        MPT_SCSI_HOST   *hd;
@@ -3832,6 +2916,8 @@ mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
        int              completionCode;
        u16              req_idx;
 
+       hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
+
        if ((mf == NULL) ||
            (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) {
                printk(MYIOC_s_ERR_FMT
@@ -3840,7 +2926,6 @@ mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
                goto wakeup;
        }
 
-       hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
        del_timer(&hd->timer);
        req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
        hd->ScsiLookup[req_idx] = NULL;
@@ -3906,10 +2991,11 @@ mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
                                 * some type of error occurred.
                                 */
                                MpiRaidActionReply_t    *pr = (MpiRaidActionReply_t *)mr;
-                               if (pr->ActionStatus == MPI_RAID_ACTION_ASTATUS_SUCCESS)
+                               if (le16_to_cpu(pr->ActionStatus) == MPI_RAID_ACTION_ASTATUS_SUCCESS)
                                        completionCode = MPT_SCANDV_GOOD;
                                else
                                        completionCode = MPT_SCANDV_SOME_ERROR;
+                               memcpy(hd->pLocal->sense, pr, sizeof(hd->pLocal->sense));
 
                        } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID) {
                                u8              *sense_data;
@@ -3972,8 +3058,8 @@ wakeup:
        /*
         * Wake up the original calling thread
         */
-       scandv_wait_done = 1;
-       wake_up(&scandv_waitq);
+       hd->scandv_wait_done = 1;
+       wake_up(&hd->scandv_waitq);
 
        return 1;
 }
@@ -3984,7 +3070,8 @@ wakeup:
  *     @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
  *
  */
-static void mptscsih_timer_expired(unsigned long data)
+void
+mptscsih_timer_expired(unsigned long data)
 {
        MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) data;
 
@@ -4022,78 +3109,6 @@ static void mptscsih_timer_expired(unsigned long data)
        return;
 }
 
-#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*     mptscsih_do_raid - Format and Issue a RAID volume request message.
- *     @hd: Pointer to scsi host structure
- *     @action: What do be done.
- *     @id: Logical target id.
- *     @bus: Target locations bus.
- *
- *     Returns: < 0 on a fatal error
- *             0 on success
- *
- *     Remark: Wait to return until reply processed by the ISR.
- */
-static int
-mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io)
-{
-       MpiRaidActionRequest_t  *pReq;
-       MPT_FRAME_HDR           *mf;
-       int                     in_isr;
-
-       in_isr = in_interrupt();
-       if (in_isr) {
-               dprintk((MYIOC_s_WARN_FMT "Internal raid request not allowed in ISR context!\n",
-                                       hd->ioc->name));
-               return -EPERM;
-       }
-
-       /* Get and Populate a free Frame
-        */
-       if ((mf = mpt_get_msg_frame(ScsiScanDvCtx, hd->ioc)) == NULL) {
-               ddvprintk((MYIOC_s_WARN_FMT "_do_raid: no msg frames!\n",
-                                       hd->ioc->name));
-               return -EAGAIN;
-       }
-       pReq = (MpiRaidActionRequest_t *)mf;
-       pReq->Action = action;
-       pReq->Reserved1 = 0;
-       pReq->ChainOffset = 0;
-       pReq->Function = MPI_FUNCTION_RAID_ACTION;
-       pReq->VolumeID = io->id;
-       pReq->VolumeBus = io->bus;
-       pReq->PhysDiskNum = io->physDiskNum;
-       pReq->MsgFlags = 0;
-       pReq->Reserved2 = 0;
-       pReq->ActionDataWord = 0; /* Reserved for this action */
-       //pReq->ActionDataSGE = 0;
-
-       mpt_add_sge((char *)&pReq->ActionDataSGE,
-               MPT_SGE_FLAGS_SSIMPLE_READ | 0, (dma_addr_t) -1);
-
-       ddvprintk((MYIOC_s_INFO_FMT "RAID Volume action %x id %d\n",
-                       hd->ioc->name, action, io->id));
-
-       hd->pLocal = NULL;
-       hd->timer.expires = jiffies + HZ*10; /* 10 second timeout */
-       scandv_wait_done = 0;
-
-       /* Save cmd pointer, for resource free if timeout or
-        * FW reload occurs
-        */
-       hd->cmdPtr = mf;
-
-       add_timer(&hd->timer);
-       mpt_put_msg_frame(ScsiScanDvCtx, hd->ioc, mf);
-       wait_event(scandv_waitq, scandv_wait_done);
-
-       if ((hd->pLocal == NULL) || (hd->pLocal->completion != MPT_SCANDV_GOOD))
-               return -1;
-
-       return 0;
-}
-#endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /**
@@ -4232,7 +3247,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(hd->ioc->InternalCtx, hd->ioc)) == NULL) {
                ddvprintk((MYIOC_s_WARN_FMT "No msg frames!\n",
                                        hd->ioc->name));
                return -EBUSY;
@@ -4314,7 +3329,7 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
         */
        hd->pLocal = NULL;
        hd->timer.expires = jiffies + HZ*cmdTimeout;
-       scandv_wait_done = 0;
+       hd->scandv_wait_done = 0;
 
        /* Save cmd pointer, for resource free if timeout or
         * FW reload occurs
@@ -4322,8 +3337,8 @@ 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);
-       wait_event(scandv_waitq, scandv_wait_done);
+       mpt_put_msg_frame(hd->ioc->InternalCtx, hd->ioc, mf);
+       wait_event(hd->scandv_waitq, hd->scandv_wait_done);
 
        if (hd->pLocal) {
                rc = hd->pLocal->completion;
@@ -4348,35 +3363,18 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /**
  *     mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
- *     @hd: Pointer to MPT_SCSI_HOST structure
- *     @portnum: IOC port number
+ *     @hd: Pointer to a SCSI HOST structure
+ *     @vtarget: per device private data
+ *     @lun: lun
  *
  *     Uses the ISR, but with special processing.
  *     MUST be single-threaded.
  *
- *     Return: 0 on completion
  */
-static int
-mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum)
+static void
+mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
 {
-       MPT_ADAPTER             *ioc= hd->ioc;
-       VirtDevice              *pTarget;
-       SCSIDevicePage1_t       *pcfg1Data = NULL;
        INTERNAL_CMD             iocmd;
-       CONFIGPARMS              cfg;
-       dma_addr_t               cfg1_dma_addr = -1;
-       ConfigPageHeader_t       header1;
-       int                      bus = 0;
-       int                      id = 0;
-       int                      lun;
-       int                      indexed_lun, lun_index;
-       int                      hostId = ioc->pfacts[portnum].PortSCSIID;
-       int                      max_id;
-       int                      requested, configuration, data;
-       int                      doConfig = 0;
-       u8                       flags, factor;
-
-       max_id = ioc->sh->max_id - 1;
 
        /* Following parameters will not change
         * in this routine.
@@ -4388,1634 +3386,41 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum)
        iocmd.data_dma = -1;
        iocmd.size = 0;
        iocmd.rsvd = iocmd.rsvd2 = 0;
+       iocmd.bus = vdevice->vtarget->bus_id;
+       iocmd.id = vdevice->vtarget->target_id;
+       iocmd.lun = (u8)vdevice->lun;
 
-       /* No SCSI hosts
-        */
-       if (hd->Targets == NULL)
-               return 0;
-
-       /* Skip the host
-        */
-       if (id == hostId)
-               id++;
-
-       /* Write SDP1 for all SCSI devices
-        * Alloc memory and set up config buffer
-        */
-       if (ioc->bus_type == SCSI) {
-               if (ioc->spi_data.sdp1length > 0) {
-                       pcfg1Data = (SCSIDevicePage1_t *)pci_alloc_consistent(ioc->pcidev,
-                                        ioc->spi_data.sdp1length * 4, &cfg1_dma_addr);
-
-                       if (pcfg1Data != NULL) {
-                               doConfig = 1;
-                               header1.PageVersion = ioc->spi_data.sdp1version;
-                               header1.PageLength = ioc->spi_data.sdp1length;
-                               header1.PageNumber = 1;
-                               header1.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
-                               cfg.hdr = &header1;
-                               cfg.physAddr = cfg1_dma_addr;
-                               cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
-                               cfg.dir = 1;
-                               cfg.timeout = 0;
-                       }
-               }
-       }
-
-       /* loop through all devices on this port
-        */
-       while (bus < MPT_MAX_BUS) {
-               iocmd.bus = bus;
-               iocmd.id = id;
-               pTarget = hd->Targets[(int)id];
-
-               if (doConfig) {
-
-                       /* Set the negotiation flags */
-                       if (pTarget && (pTarget = hd->Targets[id]) && !pTarget->raidVolume) {
-                               flags = pTarget->negoFlags;
-                       } else {
-                               flags = hd->ioc->spi_data.noQas;
-                               if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
-                                       data = hd->ioc->spi_data.nvram[id];
-
-                                       if (data & MPT_NVRAM_WIDE_DISABLE)
-                                               flags |= MPT_TARGET_NO_NEGO_WIDE;
-
-                                       factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT;
-                                       if ((factor == 0) || (factor == MPT_ASYNC))
-                                               flags |= MPT_TARGET_NO_NEGO_SYNC;
-                               }
-                       }
-
-                       /* Force to async, narrow */
-                       mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested,
-                                       &configuration, flags);
-                       dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC "
-                               "offset=0 negoFlags=%x request=%x config=%x\n",
-                               id, flags, requested, configuration));
-                       pcfg1Data->RequestedParameters = le32_to_cpu(requested);
-                       pcfg1Data->Reserved = 0;
-                       pcfg1Data->Configuration = le32_to_cpu(configuration);
-                       cfg.pageAddr = (bus<<8) | id;
-                       mpt_config(hd->ioc, &cfg);
-               }
-
-               /* If target Ptr NULL or if this target is NOT a disk, skip.
-                */
-               if ((pTarget) && (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)){
-                       for (lun=0; lun <= MPT_LAST_LUN; lun++) {
-                               /* If LUN present, issue the command
-                                */
-                               lun_index = (lun >> 5);  /* 32 luns per lun_index */
-                               indexed_lun = (lun % 32);
-                               if (pTarget->luns[lun_index] & (1<<indexed_lun)) {
-                                       iocmd.lun = lun;
-                                       (void) mptscsih_do_cmd(hd, &iocmd);
-                               }
-                       }
-               }
-
-               /* get next relevant device */
-               id++;
-
-               if (id == hostId)
-                       id++;
-
-               if (id > max_id) {
-                       id = 0;
-                       bus++;
-               }
-       }
-
-       if (pcfg1Data) {
-               pci_free_consistent(ioc->pcidev, header1.PageLength * 4, pcfg1Data, cfg1_dma_addr);
-       }
-
-       return 0;
-}
-
-#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/**
- *     mptscsih_domainValidation - Top level handler for domain validation.
- *     @hd: Pointer to MPT_SCSI_HOST structure.
- *
- *     Uses the ISR, but with special processing.
- *     Called from schedule, should not be in interrupt mode.
- *     While thread alive, do dv for all devices needing dv
- *
- *     Return: None.
- */
-static void
-mptscsih_domainValidation(void *arg)
-{
-       MPT_SCSI_HOST           *hd;
-       MPT_ADAPTER             *ioc;
-       unsigned long            flags;
-       int                      id, maxid, dvStatus, did;
-       int                      ii, isPhysDisk;
-
-       spin_lock_irqsave(&dvtaskQ_lock, flags);
-       dvtaskQ_active = 1;
-       if (dvtaskQ_release) {
-               dvtaskQ_active = 0;
-               spin_unlock_irqrestore(&dvtaskQ_lock, flags);
-               return;
-       }
-       spin_unlock_irqrestore(&dvtaskQ_lock, flags);
-
-       /* For this ioc, loop through all devices and do dv to each device.
-        * When complete with this ioc, search through the ioc list, and
-        * for each scsi ioc found, do dv for all devices. Exit when no
-        * device needs dv.
-        */
-       did = 1;
-       while (did) {
-               did = 0;
-               list_for_each_entry(ioc, &ioc_list, list) {
-                       spin_lock_irqsave(&dvtaskQ_lock, flags);
-                       if (dvtaskQ_release) {
-                               dvtaskQ_active = 0;
-                               spin_unlock_irqrestore(&dvtaskQ_lock, flags);
-                               return;
-                       }
-                       spin_unlock_irqrestore(&dvtaskQ_lock, flags);
-
-                       msleep(250);
-
-                       /* DV only to SCSI adapters */
-                       if (ioc->bus_type != SCSI)
-                               continue;
-
-                       /* Make sure everything looks ok */
-                       if (ioc->sh == NULL)
-                               continue;
-
-                       hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
-                       if (hd == NULL)
-                               continue;
-
-                       if ((ioc->spi_data.forceDv & MPT_SCSICFG_RELOAD_IOC_PG3) != 0) {
-                               mpt_read_ioc_pg_3(ioc);
-                               if (ioc->spi_data.pIocPg3) {
-                                       Ioc3PhysDisk_t *pPDisk = ioc->spi_data.pIocPg3->PhysDisk;
-                                       int             numPDisk = ioc->spi_data.pIocPg3->NumPhysDisks;
-
-                                       while (numPDisk) {
-                                               if (ioc->spi_data.dvStatus[pPDisk->PhysDiskID] & MPT_SCSICFG_DV_NOT_DONE)
-                                                       ioc->spi_data.dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV;
-
-                                               pPDisk++;
-                                               numPDisk--;
-                                       }
-                               }
-                               ioc->spi_data.forceDv &= ~MPT_SCSICFG_RELOAD_IOC_PG3;
-                       }
-
-                       maxid = min_t(int, ioc->sh->max_id, MPT_MAX_SCSI_DEVICES);
-
-                       for (id = 0; id < maxid; id++) {
-                               spin_lock_irqsave(&dvtaskQ_lock, flags);
-                               if (dvtaskQ_release) {
-                                       dvtaskQ_active = 0;
-                                       spin_unlock_irqrestore(&dvtaskQ_lock, flags);
-                                       return;
-                               }
-                               spin_unlock_irqrestore(&dvtaskQ_lock, flags);
-                               dvStatus = hd->ioc->spi_data.dvStatus[id];
-
-                               if (dvStatus & MPT_SCSICFG_NEED_DV) {
-                                       did++;
-                                       hd->ioc->spi_data.dvStatus[id] |= MPT_SCSICFG_DV_PENDING;
-                                       hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_NEED_DV;
-
-                                       msleep(250);
-
-                                       /* If hidden phys disk, block IO's to all
-                                        *      raid volumes
-                                        * else, process normally
-                                        */
-                                       isPhysDisk = mptscsih_is_phys_disk(ioc, id);
-                                       if (isPhysDisk) {
-                                               for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
-                                                       if (hd->ioc->spi_data.isRaid & (1 << ii)) {
-                                                               hd->ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_DV_PENDING;
-                                                       }
-                                               }
-                                       }
-
-                                       if (mptscsih_doDv(hd, 0, id) == 1) {
-                                               /* Untagged device was busy, try again
-                                                */
-                                               hd->ioc->spi_data.dvStatus[id] |= MPT_SCSICFG_NEED_DV;
-                                               hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_PENDING;
-                                       } else {
-                                               /* DV is complete. Clear flags.
-                                                */
-                                               hd->ioc->spi_data.dvStatus[id] &= ~(MPT_SCSICFG_DV_NOT_DONE | MPT_SCSICFG_DV_PENDING);
-                                       }
-
-                                       if (isPhysDisk) {
-                                               for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
-                                                       if (hd->ioc->spi_data.isRaid & (1 << ii)) {
-                                                               hd->ioc->spi_data.dvStatus[ii] &= ~MPT_SCSICFG_DV_PENDING;
-                                                       }
-                                               }
-                                       }
-
-                                       if (hd->ioc->spi_data.noQas)
-                                               mptscsih_qas_check(hd, id);
-                               }
-                       }
-               }
-       }
-
-       spin_lock_irqsave(&dvtaskQ_lock, flags);
-       dvtaskQ_active = 0;
-       spin_unlock_irqrestore(&dvtaskQ_lock, flags);
-
-       return;
-}
-
-/* Search IOC page 3 to determine if this is hidden physical disk
- */
-static int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id)
-{
-       if (ioc->spi_data.pIocPg3) {
-               Ioc3PhysDisk_t *pPDisk =  ioc->spi_data.pIocPg3->PhysDisk;
-               int             numPDisk = ioc->spi_data.pIocPg3->NumPhysDisks;
-
-               while (numPDisk) {
-                       if (pPDisk->PhysDiskID == id) {
-                               return 1;
-                       }
-                       pPDisk++;
-                       numPDisk--;
-               }
-       }
-       return 0;
-}
-
-/* Write SDP1 if no QAS has been enabled
- */
-static void mptscsih_qas_check(MPT_SCSI_HOST *hd, int id)
-{
-       VirtDevice *pTarget;
-       int ii;
-
-       if (hd->Targets == NULL)
-               return;
-
-       for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
-               if (ii == id)
-                       continue;
-
-               if ((hd->ioc->spi_data.dvStatus[ii] & MPT_SCSICFG_DV_NOT_DONE) != 0)
-                       continue;
-
-               pTarget = hd->Targets[ii];
-
-               if ((pTarget != NULL) && (!pTarget->raidVolume)) {
-                       if ((pTarget->negoFlags & hd->ioc->spi_data.noQas) == 0) {
-                               pTarget->negoFlags |= hd->ioc->spi_data.noQas;
-                               dnegoprintk(("writeSDP1: id=%d flags=0\n", id));
-                               mptscsih_writeSDP1(hd, 0, ii, 0);
-                       }
-               } else {
-                       if (mptscsih_is_phys_disk(hd->ioc, ii) == 1) {
-                               dnegoprintk(("writeSDP1: id=%d SCSICFG_USE_NVRAM\n", id));
-                               mptscsih_writeSDP1(hd, 0, ii, MPT_SCSICFG_USE_NVRAM);
-                       }
-               }
-       }
-       return;
+       if ((vdevice->vtarget->type == TYPE_DISK) &&
+           (vdevice->configured_lun))
+               mptscsih_do_cmd(hd, &iocmd);
 }
 
-
-
-#define MPT_GET_NVRAM_VALS     0x01
-#define MPT_UPDATE_MAX         0x02
-#define MPT_SET_MAX            0x04
-#define MPT_SET_MIN            0x08
-#define MPT_FALLBACK           0x10
-#define MPT_SAVE               0x20
+EXPORT_SYMBOL(mptscsih_remove);
+EXPORT_SYMBOL(mptscsih_shutdown);
+#ifdef CONFIG_PM
+EXPORT_SYMBOL(mptscsih_suspend);
+EXPORT_SYMBOL(mptscsih_resume);
+#endif
+EXPORT_SYMBOL(mptscsih_proc_info);
+EXPORT_SYMBOL(mptscsih_info);
+EXPORT_SYMBOL(mptscsih_qcmd);
+EXPORT_SYMBOL(mptscsih_target_alloc);
+EXPORT_SYMBOL(mptscsih_slave_alloc);
+EXPORT_SYMBOL(mptscsih_target_destroy);
+EXPORT_SYMBOL(mptscsih_slave_destroy);
+EXPORT_SYMBOL(mptscsih_slave_configure);
+EXPORT_SYMBOL(mptscsih_abort);
+EXPORT_SYMBOL(mptscsih_dev_reset);
+EXPORT_SYMBOL(mptscsih_bus_reset);
+EXPORT_SYMBOL(mptscsih_host_reset);
+EXPORT_SYMBOL(mptscsih_bios_param);
+EXPORT_SYMBOL(mptscsih_io_done);
+EXPORT_SYMBOL(mptscsih_taskmgmt_complete);
+EXPORT_SYMBOL(mptscsih_scandv_complete);
+EXPORT_SYMBOL(mptscsih_event_process);
+EXPORT_SYMBOL(mptscsih_ioc_reset);
+EXPORT_SYMBOL(mptscsih_change_queue_depth);
+EXPORT_SYMBOL(mptscsih_timer_expired);
+EXPORT_SYMBOL(mptscsih_TMHandler);
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/**
- *     mptscsih_doDv - Perform domain validation to a target.
- *     @hd: Pointer to MPT_SCSI_HOST structure.
- *     @portnum: IOC port number.
- *     @target: Physical ID of this target
- *
- *     Uses the ISR, but with special processing.
- *     MUST be single-threaded.
- *     Test will exit if target is at async & narrow.
- *
- *     Return: None.
- */
-static int
-mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
-{
-       MPT_ADAPTER             *ioc = hd->ioc;
-       VirtDevice              *pTarget;
-       SCSIDevicePage1_t       *pcfg1Data;
-       SCSIDevicePage0_t       *pcfg0Data;
-       u8                      *pbuf1;
-       u8                      *pbuf2;
-       u8                      *pDvBuf;
-       dma_addr_t               dvbuf_dma = -1;
-       dma_addr_t               buf1_dma = -1;
-       dma_addr_t               buf2_dma = -1;
-       dma_addr_t               cfg1_dma_addr = -1;
-       dma_addr_t               cfg0_dma_addr = -1;
-       ConfigPageHeader_t       header1;
-       ConfigPageHeader_t       header0;
-       DVPARAMETERS             dv;
-       INTERNAL_CMD             iocmd;
-       CONFIGPARMS              cfg;
-       int                      dv_alloc = 0;
-       int                      rc, sz = 0;
-       int                      bufsize = 0;
-       int                      dataBufSize = 0;
-       int                      echoBufSize = 0;
-       int                      notDone;
-       int                      patt;
-       int                      repeat;
-       int                      retcode = 0;
-       int                      nfactor =  MPT_ULTRA320;
-       char                     firstPass = 1;
-       char                     doFallback = 0;
-       char                     readPage0;
-       char                     bus, lun;
-       char                     inq0 = 0;
-
-       if (ioc->spi_data.sdp1length == 0)
-               return 0;
-
-       if (ioc->spi_data.sdp0length == 0)
-               return 0;
-
-       /* If multiple buses are used, require that the initiator
-        * id be the same on all buses.
-        */
-       if (id == ioc->pfacts[0].PortSCSIID)
-               return 0;
-
-       lun = 0;
-       bus = (u8) bus_number;
-       ddvtprintk((MYIOC_s_NOTE_FMT
-                       "DV started: bus=%d, id=%d dv @ %p\n",
-                       ioc->name, bus, id, &dv));
-
-       /* Prep DV structure
-        */
-       memset (&dv, 0, sizeof(DVPARAMETERS));
-       dv.id = id;
-
-       /* Populate tmax with the current maximum
-        * transfer parameters for this target.
-        * Exit if narrow and async.
-        */
-       dv.cmd = MPT_GET_NVRAM_VALS;
-       mptscsih_dv_parms(hd, &dv, NULL);
-
-       /* Prep SCSI IO structure
-        */
-       iocmd.id = id;
-       iocmd.bus = bus;
-       iocmd.lun = lun;
-       iocmd.flags = 0;
-       iocmd.physDiskNum = -1;
-       iocmd.rsvd = iocmd.rsvd2 = 0;
-
-       pTarget = hd->Targets[id];
-
-       /* Use tagged commands if possible.
-        */
-       if (pTarget) {
-               if (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)
-                       iocmd.flags |= MPT_ICFLAG_TAGGED_CMD;
-               else {
-                       if (hd->ioc->facts.FWVersion.Word < 0x01000600)
-                               return 0;
-
-                       if ((hd->ioc->facts.FWVersion.Word >= 0x01010000) &&
-                               (hd->ioc->facts.FWVersion.Word < 0x01010B00))
-                               return 0;
-               }
-       }
-
-       /* Prep cfg structure
-        */
-       cfg.pageAddr = (bus<<8) | id;
-       cfg.hdr = NULL;
-
-       /* Prep SDP0 header
-        */
-       header0.PageVersion = ioc->spi_data.sdp0version;
-       header0.PageLength = ioc->spi_data.sdp0length;
-       header0.PageNumber = 0;
-       header0.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
-
-       /* Prep SDP1 header
-        */
-       header1.PageVersion = ioc->spi_data.sdp1version;
-       header1.PageLength = ioc->spi_data.sdp1length;
-       header1.PageNumber = 1;
-       header1.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
-
-       if (header0.PageLength & 1)
-               dv_alloc = (header0.PageLength * 4) + 4;
-
-       dv_alloc +=  (2048 + (header1.PageLength * 4));
-
-       pDvBuf = pci_alloc_consistent(ioc->pcidev, dv_alloc, &dvbuf_dma);
-       if (pDvBuf == NULL)
-               return 0;
-
-       sz = 0;
-       pbuf1 = (u8 *)pDvBuf;
-       buf1_dma = dvbuf_dma;
-       sz +=1024;
-
-       pbuf2 = (u8 *) (pDvBuf + sz);
-       buf2_dma = dvbuf_dma + sz;
-       sz +=1024;
-
-       pcfg0Data = (SCSIDevicePage0_t *) (pDvBuf + sz);
-       cfg0_dma_addr = dvbuf_dma + sz;
-       sz += header0.PageLength * 4;
-
-       /* 8-byte alignment
-        */
-       if (header0.PageLength & 1)
-               sz += 4;
-
-       pcfg1Data = (SCSIDevicePage1_t *) (pDvBuf + sz);
-       cfg1_dma_addr = dvbuf_dma + sz;
-
-       /* Skip this ID? Set cfg.hdr to force config page write
-        */
-       {
-               ScsiCfgData *pspi_data = &hd->ioc->spi_data;
-               if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
-                       /* Set the factor from nvram */
-                       nfactor = (pspi_data->nvram[id] & MPT_NVRAM_SYNC_MASK) >> 8;
-                       if (nfactor < pspi_data->minSyncFactor )
-                               nfactor = pspi_data->minSyncFactor;
-
-                       if (!(pspi_data->nvram[id] & MPT_NVRAM_ID_SCAN_ENABLE) ||
-                               (pspi_data->PortFlags == MPI_SCSIPORTPAGE2_PORT_FLAGS_OFF_DV) ) {
-
-                               ddvprintk((MYIOC_s_NOTE_FMT "DV Skipped: bus, id, lun (%d, %d, %d)\n",
-                                       ioc->name, bus, id, lun));
-
-                               dv.cmd = MPT_SET_MAX;
-                               mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
-                               cfg.hdr = &header1;
-
-                               /* Save the final negotiated settings to
-                                * SCSI device page 1.
-                                */
-                               cfg.physAddr = cfg1_dma_addr;
-                               cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
-                               cfg.dir = 1;
-                               mpt_config(hd->ioc, &cfg);
-                               goto target_done;
-                       }
-               }
-       }
-
-       /* Finish iocmd inititialization - hidden or visible disk? */
-       if (ioc->spi_data.pIocPg3) {
-               /* Search IOC page 3 for matching id
-                */
-               Ioc3PhysDisk_t *pPDisk =  ioc->spi_data.pIocPg3->PhysDisk;
-               int             numPDisk = ioc->spi_data.pIocPg3->NumPhysDisks;
-
-               while (numPDisk) {
-                       if (pPDisk->PhysDiskID == id) {
-                               /* match */
-                               iocmd.flags |= MPT_ICFLAG_PHYS_DISK;
-                               iocmd.physDiskNum = pPDisk->PhysDiskNum;
-
-                               /* Quiesce the IM
-                                */
-                               if (mptscsih_do_raid(hd, MPI_RAID_ACTION_QUIESCE_PHYS_IO, &iocmd) < 0) {
-                                       ddvprintk((MYIOC_s_ERR_FMT "RAID Queisce FAILED!\n", ioc->name));
-                                       goto target_done;
-                               }
-                               break;
-                       }
-                       pPDisk++;
-                       numPDisk--;
-               }
-       }
-
-       /* RAID Volume ID's may double for a physical device. If RAID but
-        * not a physical ID as well, skip DV.
-        */
-       if ((hd->ioc->spi_data.isRaid & (1 << id)) && !(iocmd.flags & MPT_ICFLAG_PHYS_DISK))
-               goto target_done;
-
-
-       /* Basic Test.
-        * Async & Narrow - Inquiry
-        * Async & Narrow - Inquiry
-        * Maximum transfer rate - Inquiry
-        * Compare buffers:
-        *      If compare, test complete.
-        *      If miscompare and first pass, repeat
-        *      If miscompare and not first pass, fall back and repeat
-        */
-       hd->pLocal = NULL;
-       readPage0 = 0;
-       sz = SCSI_MAX_INQUIRY_BYTES;
-       rc = MPT_SCANDV_GOOD;
-       while (1) {
-               ddvprintk((MYIOC_s_NOTE_FMT "DV: Start Basic test on id=%d\n", ioc->name, id));
-               retcode = 0;
-               dv.cmd = MPT_SET_MIN;
-               mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
-
-               cfg.hdr = &header1;
-               cfg.physAddr = cfg1_dma_addr;
-               cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
-               cfg.dir = 1;
-               if (mpt_config(hd->ioc, &cfg) != 0)
-                       goto target_done;
-
-               /* Wide - narrow - wide workaround case
-                */
-               if ((rc == MPT_SCANDV_ISSUE_SENSE) && dv.max.width) {
-                       /* Send an untagged command to reset disk Qs corrupted
-                        * when a parity error occurs on a Request Sense.
-                        */
-                       if ((hd->ioc->facts.FWVersion.Word >= 0x01000600) ||
-                               ((hd->ioc->facts.FWVersion.Word >= 0x01010000) &&
-                               (hd->ioc->facts.FWVersion.Word < 0x01010B00)) ) {
-
-                               iocmd.cmd = REQUEST_SENSE;
-                               iocmd.data_dma = buf1_dma;
-                               iocmd.data = pbuf1;
-                               iocmd.size = 0x12;
-                               if (mptscsih_do_cmd(hd, &iocmd) < 0)
-                                       goto target_done;
-                               else {
-                                       if (hd->pLocal == NULL)
-                                               goto target_done;
-                                       rc = hd->pLocal->completion;
-                                       if ((rc == MPT_SCANDV_GOOD) || (rc == MPT_SCANDV_SENSE)) {
-                                               dv.max.width = 0;
-                                               doFallback = 0;
-                                       } else
-                                               goto target_done;
-                               }
-                       } else
-                               goto target_done;
-               }
-
-               iocmd.cmd = INQUIRY;
-               iocmd.data_dma = buf1_dma;
-               iocmd.data = pbuf1;
-               iocmd.size = sz;
-               memset(pbuf1, 0x00, sz);
-               if (mptscsih_do_cmd(hd, &iocmd) < 0)
-                       goto target_done;
-               else {
-                       if (hd->pLocal == NULL)
-                               goto target_done;
-                       rc = hd->pLocal->completion;
-                       if (rc == MPT_SCANDV_GOOD) {
-                               if (hd->pLocal->scsiStatus == SAM_STAT_BUSY) {
-                                       if ((iocmd.flags & MPT_ICFLAG_TAGGED_CMD) == 0)
-                                               retcode = 1;
-                                       else
-                                               retcode = 0;
-
-                                       goto target_done;
-                               }
-                       } else if  (rc == MPT_SCANDV_SENSE) {
-                               ;
-                       } else {
-                               /* If first command doesn't complete
-                                * with a good status or with a check condition,
-                                * exit.
-                                */
-                               goto target_done;
-                       }
-               }
-
-               /* Reset the size for disks
-                */
-               inq0 = (*pbuf1) & 0x1F;
-               if ((inq0 == 0) && pTarget && !pTarget->raidVolume) {
-                       sz = 0x40;
-                       iocmd.size = sz;
-               }
-
-               /* Another GEM workaround. Check peripheral device type,
-                * if PROCESSOR, quit DV.
-                */
-               if (inq0 == TYPE_PROCESSOR) {
-                       mptscsih_initTarget(hd,
-                               bus,
-                               id,
-                               lun,
-                               pbuf1,
-                               sz);
-                       goto target_done;
-               }
-
-               if (inq0 > 0x08)
-                       goto target_done;
-
-               if (mptscsih_do_cmd(hd, &iocmd) < 0)
-                       goto target_done;
-
-               if (sz == 0x40) {
-                       if ((pTarget->maxWidth == 1) && (pTarget->maxOffset) && (nfactor < 0x0A)
-                               && (pTarget->minSyncFactor > 0x09)) {
-                               if ((pbuf1[56] & 0x04) == 0)
-                                       ;
-                               else if ((pbuf1[56] & 0x01) == 1) {
-                                       pTarget->minSyncFactor =
-                                           nfactor > MPT_ULTRA320 ? nfactor : MPT_ULTRA320;
-                               } else {
-                                       pTarget->minSyncFactor =
-                                           nfactor > MPT_ULTRA160 ? nfactor : MPT_ULTRA160;
-                               }
-
-                               dv.max.factor = pTarget->minSyncFactor;
-
-                               if ((pbuf1[56] & 0x02) == 0) {
-                                       pTarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
-                                       hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS;
-                                       ddvprintk((MYIOC_s_NOTE_FMT 
-                                           "DV: Start Basic noQas on id=%d due to pbuf1[56]=%x\n", 
-                                           ioc->name, id, pbuf1[56]));
-                               }
-                       }
-               }
-
-               if (doFallback)
-                       dv.cmd = MPT_FALLBACK;
-               else
-                       dv.cmd = MPT_SET_MAX;
-
-               mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
-               if (mpt_config(hd->ioc, &cfg) != 0)
-                       goto target_done;
-
-               if ((!dv.now.width) && (!dv.now.offset))
-                       goto target_done;
-
-               iocmd.cmd = INQUIRY;
-               iocmd.data_dma = buf2_dma;
-               iocmd.data = pbuf2;
-               iocmd.size = sz;
-               memset(pbuf2, 0x00, sz);
-               if (mptscsih_do_cmd(hd, &iocmd) < 0)
-                       goto target_done;
-               else if (hd->pLocal == NULL)
-                       goto target_done;
-               else {
-                       /* Save the return code.
-                        * If this is the first pass,
-                        * read SCSI Device Page 0
-                        * and update the target max parameters.
-                        */
-                       rc = hd->pLocal->completion;
-                       doFallback = 0;
-                       if (rc == MPT_SCANDV_GOOD) {
-                               if (!readPage0) {
-                                       u32 sdp0_info;
-                                       u32 sdp0_nego;
-
-                                       cfg.hdr = &header0;
-                                       cfg.physAddr = cfg0_dma_addr;
-                                       cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
-                                       cfg.dir = 0;
-
-                                       if (mpt_config(hd->ioc, &cfg) != 0)
-                                               goto target_done;
-
-                                       sdp0_info = le32_to_cpu(pcfg0Data->Information) & 0x0E;
-                                       sdp0_nego = (le32_to_cpu(pcfg0Data->NegotiatedParameters) & 0xFF00 ) >> 8;
-
-                                       /* Quantum and Fujitsu workarounds.
-                                        * Quantum: PPR U320 -> PPR reply with Ultra2 and wide
-                                        * Fujitsu: PPR U320 -> Msg Reject and Ultra2 and wide
-                                        * Resetart with a request for U160.
-                                        */
-                                       if ((dv.now.factor == MPT_ULTRA320) && (sdp0_nego == MPT_ULTRA2)) {
-                                                       doFallback = 1;
-                                       } else {
-                                               dv.cmd = MPT_UPDATE_MAX;
-                                               mptscsih_dv_parms(hd, &dv, (void *)pcfg0Data);
-                                               /* Update the SCSI device page 1 area
-                                                */
-                                               pcfg1Data->RequestedParameters = pcfg0Data->NegotiatedParameters;
-                                               readPage0 = 1;
-                                       }
-                               }
-
-                               /* Quantum workaround. Restart this test will the fallback
-                                * flag set.
-                                */
-                               if (doFallback == 0) {
-                                       if (memcmp(pbuf1, pbuf2, sz) != 0) {
-                                               if (!firstPass)
-                                                       doFallback = 1;
-                                       } else {
-                                               ddvprintk((MYIOC_s_NOTE_FMT 
-                                                   "DV:Inquiry compared id=%d, calling initTarget\n", ioc->name, id));
-                                               hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_NOT_DONE;
-                                               mptscsih_initTarget(hd,
-                                                       bus,
-                                                       id,
-                                                       lun,
-                                                       pbuf1,
-                                                       sz);
-                                               break;  /* test complete */
-                                       }
-                               }
-
-
-                       } else if (rc == MPT_SCANDV_ISSUE_SENSE)
-                               doFallback = 1; /* set fallback flag */
-                       else if ((rc == MPT_SCANDV_DID_RESET) || 
-                                (rc == MPT_SCANDV_SENSE) || 
-                                (rc == MPT_SCANDV_FALLBACK))
-                               doFallback = 1; /* set fallback flag */
-                       else
-                               goto target_done;
-
-                       firstPass = 0;
-               }
-       }
-       ddvprintk((MYIOC_s_NOTE_FMT "DV: Basic test on id=%d completed OK.\n", ioc->name, id));
-
-       if (mpt_dv == 0)
-               goto target_done;
-
-       inq0 = (*pbuf1) & 0x1F;
-
-       /* Continue only for disks
-        */
-       if (inq0 != 0)
-               goto target_done;
-
-       if ( ioc->spi_data.PortFlags == MPI_SCSIPORTPAGE2_PORT_FLAGS_BASIC_DV_ONLY )
-               goto target_done;
-
-       /* Start the Enhanced Test.
-        * 0) issue TUR to clear out check conditions
-        * 1) read capacity of echo (regular) buffer
-        * 2) reserve device
-        * 3) do write-read-compare data pattern test
-        * 4) release
-        * 5) update nego parms to target struct
-        */
-       cfg.hdr = &header1;
-       cfg.physAddr = cfg1_dma_addr;
-       cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
-       cfg.dir = 1;
-
-       iocmd.cmd = TEST_UNIT_READY;
-       iocmd.data_dma = -1;
-       iocmd.data = NULL;
-       iocmd.size = 0;
-       notDone = 1;
-       while (notDone) {
-               if (mptscsih_do_cmd(hd, &iocmd) < 0)
-                       goto target_done;
-
-               if (hd->pLocal == NULL)
-                       goto target_done;
-
-               rc = hd->pLocal->completion;
-               if (rc == MPT_SCANDV_GOOD)
-                       notDone = 0;
-               else if (rc == MPT_SCANDV_SENSE) {
-                       u8 skey = hd->pLocal->sense[2] & 0x0F;
-                       u8 asc = hd->pLocal->sense[12];
-                       u8 ascq = hd->pLocal->sense[13];
-                       ddvprintk((MYIOC_s_INFO_FMT
-                               "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
-                               ioc->name, skey, asc, ascq));
-
-                       if (skey == UNIT_ATTENTION)
-                               notDone++; /* repeat */
-                       else if ((skey == NOT_READY) &&
-                                       (asc == 0x04)&&(ascq == 0x01)) {
-                               /* wait then repeat */
-                               mdelay (2000);
-                               notDone++;
-                       } else if ((skey == NOT_READY) && (asc == 0x3A)) {
-                               /* no medium, try read test anyway */
-                               notDone = 0;
-                       } else {
-                               /* All other errors are fatal.
-                                */
-                               ddvprintk((MYIOC_s_INFO_FMT "DV: fatal error.",
-                                               ioc->name));
-                               goto target_done;
-                       }
-               } else
-                       goto target_done;
-       }
-
-       iocmd.cmd = READ_BUFFER;
-       iocmd.data_dma = buf1_dma;
-       iocmd.data = pbuf1;
-       iocmd.size = 4;
-       iocmd.flags |= MPT_ICFLAG_BUF_CAP;
-
-       dataBufSize = 0;
-       echoBufSize = 0;
-       for (patt = 0; patt < 2; patt++) {
-               if (patt == 0)
-                       iocmd.flags |= MPT_ICFLAG_ECHO;
-               else
-                       iocmd.flags &= ~MPT_ICFLAG_ECHO;
-
-               notDone = 1;
-               while (notDone) {
-                       bufsize = 0;
-
-                       /* If not ready after 8 trials,
-                        * give up on this device.
-                        */
-                       if (notDone > 8)
-                               goto target_done;
-
-                       if (mptscsih_do_cmd(hd, &iocmd) < 0)
-                               goto target_done;
-                       else if (hd->pLocal == NULL)
-                               goto target_done;
-                       else {
-                               rc = hd->pLocal->completion;
-                               ddvprintk(("ReadBuffer Comp Code %d", rc));
-                               ddvprintk(("  buff: %0x %0x %0x %0x\n",
-                                       pbuf1[0], pbuf1[1], pbuf1[2], pbuf1[3]));
-
-                               if (rc == MPT_SCANDV_GOOD) {
-                                       notDone = 0;
-                                       if (iocmd.flags & MPT_ICFLAG_ECHO) {
-                                               bufsize =  ((pbuf1[2] & 0x1F) <<8) | pbuf1[3];
-                                       } else {
-                                               bufsize =  pbuf1[1]<<16 | pbuf1[2]<<8 | pbuf1[3];
-                                       }
-                               } else if (rc == MPT_SCANDV_SENSE) {
-                                       u8 skey = hd->pLocal->sense[2] & 0x0F;
-                                       u8 asc = hd->pLocal->sense[12];
-                                       u8 ascq = hd->pLocal->sense[13];
-                                       ddvprintk((MYIOC_s_INFO_FMT
-                                               "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
-                                               ioc->name, skey, asc, ascq));
-                                       if (skey == ILLEGAL_REQUEST) {
-                                               notDone = 0;
-                                       } else if (skey == UNIT_ATTENTION) {
-                                               notDone++; /* repeat */
-                                       } else if ((skey == NOT_READY) &&
-                                               (asc == 0x04)&&(ascq == 0x01)) {
-                                               /* wait then repeat */
-                                               mdelay (2000);
-                                               notDone++;
-                                       } else {
-                                               /* All other errors are fatal.
-                                                */
-                                               ddvprintk((MYIOC_s_INFO_FMT "DV: fatal error.",
-                                                       ioc->name));
-                                               goto target_done;
-                                       }
-                               } else {
-                                       /* All other errors are fatal
-                                        */
-                                       goto target_done;
-                               }
-                       }
-               }
-
-               if (iocmd.flags & MPT_ICFLAG_ECHO)
-                       echoBufSize = bufsize;
-               else
-                       dataBufSize = bufsize;
-       }
-       sz = 0;
-       iocmd.flags &= ~MPT_ICFLAG_BUF_CAP;
-
-       /* Use echo buffers if possible,
-        * Exit if both buffers are 0.
-        */
-       if (echoBufSize > 0) {
-               iocmd.flags |= MPT_ICFLAG_ECHO;
-               if (dataBufSize > 0)
-                       bufsize = min(echoBufSize, dataBufSize);
-               else
-                       bufsize = echoBufSize;
-       } else if (dataBufSize == 0)
-               goto target_done;
-
-       ddvprintk((MYIOC_s_INFO_FMT "%s Buffer Capacity %d\n", ioc->name,
-               (iocmd.flags & MPT_ICFLAG_ECHO) ? "Echo" : " ", bufsize));
-
-       /* Data buffers for write-read-compare test max 1K.
-        */
-       sz = min(bufsize, 1024);
-
-       /* --- loop ----
-        * On first pass, always issue a reserve.
-        * On additional loops, only if a reset has occurred.
-        * iocmd.flags indicates if echo or regular buffer
-        */
-       for (patt = 0; patt < 4; patt++) {
-               ddvprintk(("Pattern %d\n", patt));
-               if ((iocmd.flags & MPT_ICFLAG_RESERVED) && (iocmd.flags & MPT_ICFLAG_DID_RESET)) {
-                       iocmd.cmd = TEST_UNIT_READY;
-                       iocmd.data_dma = -1;
-                       iocmd.data = NULL;
-                       iocmd.size = 0;
-                       if (mptscsih_do_cmd(hd, &iocmd) < 0)
-                               goto target_done;
-
-                       iocmd.cmd = RELEASE;
-                       iocmd.data_dma = -1;
-                       iocmd.data = NULL;
-                       iocmd.size = 0;
-                       if (mptscsih_do_cmd(hd, &iocmd) < 0)
-                               goto target_done;
-                       else if (hd->pLocal == NULL)
-                               goto target_done;
-                       else {
-                               rc = hd->pLocal->completion;
-                               ddvprintk(("Release rc %d\n", rc));
-                               if (rc == MPT_SCANDV_GOOD)
-                                       iocmd.flags &= ~MPT_ICFLAG_RESERVED;
-                               else
-                                       goto target_done;
-                       }
-                       iocmd.flags &= ~MPT_ICFLAG_RESERVED;
-               }
-               iocmd.flags &= ~MPT_ICFLAG_DID_RESET;
-
-               repeat = 5;
-               while (repeat && (!(iocmd.flags & MPT_ICFLAG_RESERVED))) {
-                       iocmd.cmd = RESERVE;
-                       iocmd.data_dma = -1;
-                       iocmd.data = NULL;
-                       iocmd.size = 0;
-                       if (mptscsih_do_cmd(hd, &iocmd) < 0)
-                               goto target_done;
-                       else if (hd->pLocal == NULL)
-                               goto target_done;
-                       else {
-                               rc = hd->pLocal->completion;
-                               if (rc == MPT_SCANDV_GOOD) {
-                                       iocmd.flags |= MPT_ICFLAG_RESERVED;
-                               } else if (rc == MPT_SCANDV_SENSE) {
-                                       /* Wait if coming ready
-                                        */
-                                       u8 skey = hd->pLocal->sense[2] & 0x0F;
-                                       u8 asc = hd->pLocal->sense[12];
-                                       u8 ascq = hd->pLocal->sense[13];
-                                       ddvprintk((MYIOC_s_INFO_FMT
-                                               "DV: Reserve Failed: ", ioc->name));
-                                       ddvprintk(("SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
-                                                       skey, asc, ascq));
-
-                                       if ((skey == NOT_READY) && (asc == 0x04)&&
-                                                                       (ascq == 0x01)) {
-                                               /* wait then repeat */
-                                               mdelay (2000);
-                                               notDone++;
-                                       } else {
-                                               ddvprintk((MYIOC_s_INFO_FMT
-                                                       "DV: Reserved Failed.", ioc->name));
-                                               goto target_done;
-                                       }
-                               } else {
-                                       ddvprintk((MYIOC_s_INFO_FMT "DV: Reserved Failed.",
-                                                        ioc->name));
-                                       goto target_done;
-                               }
-                       }
-               }
-
-               mptscsih_fillbuf(pbuf1, sz, patt, 1);
-               iocmd.cmd = WRITE_BUFFER;
-               iocmd.data_dma = buf1_dma;
-               iocmd.data = pbuf1;
-               iocmd.size = sz;
-               if (mptscsih_do_cmd(hd, &iocmd) < 0)
-                       goto target_done;
-               else if (hd->pLocal == NULL)
-                       goto target_done;
-               else {
-                       rc = hd->pLocal->completion;
-                       if (rc == MPT_SCANDV_GOOD)
-                               ;               /* Issue read buffer */
-                       else if (rc == MPT_SCANDV_DID_RESET) {
-                               /* If using echo buffers, reset to data buffers.
-                                * Else do Fallback and restart
-                                * this test (re-issue reserve
-                                * because of bus reset).
-                                */
-                               if ((iocmd.flags & MPT_ICFLAG_ECHO) && (dataBufSize >= bufsize)) {
-                                       iocmd.flags &= ~MPT_ICFLAG_ECHO;
-                               } else {
-                                       dv.cmd = MPT_FALLBACK;
-                                       mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
-
-                                       if (mpt_config(hd->ioc, &cfg) != 0)
-                                               goto target_done;
-
-                                       if ((!dv.now.width) && (!dv.now.offset))
-                                               goto target_done;
-                               }
-
-                               iocmd.flags |= MPT_ICFLAG_DID_RESET;
-                               patt = -1;
-                               continue;
-                       } else if (rc == MPT_SCANDV_SENSE) {
-                               /* Restart data test if UA, else quit.
-                                */
-                               u8 skey = hd->pLocal->sense[2] & 0x0F;
-                               ddvprintk((MYIOC_s_INFO_FMT
-                                       "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n", ioc->name, skey,
-                                       hd->pLocal->sense[12], hd->pLocal->sense[13]));
-                               if (skey == UNIT_ATTENTION) {
-                                       patt = -1;
-                                       continue;
-                               } else if (skey == ILLEGAL_REQUEST) {
-                                       if (iocmd.flags & MPT_ICFLAG_ECHO) {
-                                               if (dataBufSize >= bufsize) {
-                                                       iocmd.flags &= ~MPT_ICFLAG_ECHO;
-                                                       patt = -1;
-                                                       continue;
-                                               }
-                                       }
-                                       goto target_done;
-                               }
-                               else
-                                       goto target_done;
-                       } else {
-                               /* fatal error */
-                               goto target_done;
-                       }
-               }
-
-               iocmd.cmd = READ_BUFFER;
-               iocmd.data_dma = buf2_dma;
-               iocmd.data = pbuf2;
-               iocmd.size = sz;
-               if (mptscsih_do_cmd(hd, &iocmd) < 0)
-                       goto target_done;
-               else if (hd->pLocal == NULL)
-                       goto target_done;
-               else {
-                       rc = hd->pLocal->completion;
-                       if (rc == MPT_SCANDV_GOOD) {
-                                /* If buffers compare,
-                                 * go to next pattern,
-                                 * else, do a fallback and restart
-                                 * data transfer test.
-                                 */
-                               if (memcmp (pbuf1, pbuf2, sz) == 0) {
-                                       ; /* goto next pattern */
-                               } else {
-                                       /* Miscompare with Echo buffer, go to data buffer,
-                                        * if that buffer exists.
-                                        * Miscompare with Data buffer, check first 4 bytes,
-                                        * some devices return capacity. Exit in this case.
-                                        */
-                                       if (iocmd.flags & MPT_ICFLAG_ECHO) {
-                                               if (dataBufSize >= bufsize)
-                                                       iocmd.flags &= ~MPT_ICFLAG_ECHO;
-                                               else
-                                                       goto target_done;
-                                       } else {
-                                               if (dataBufSize == (pbuf2[1]<<16 | pbuf2[2]<<8 | pbuf2[3])) {
-                                                       /* Argh. Device returning wrong data.
-                                                        * Quit DV for this device.
-                                                        */
-                                                       goto target_done;
-                                               }
-
-                                               /* Had an actual miscompare. Slow down.*/
-                                               dv.cmd = MPT_FALLBACK;
-                                               mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
-
-                                               if (mpt_config(hd->ioc, &cfg) != 0)
-                                                       goto target_done;
-
-                                               if ((!dv.now.width) && (!dv.now.offset))
-                                                       goto target_done;
-                                       }
-
-                                       patt = -1;
-                                       continue;
-                               }
-                       } else if (rc == MPT_SCANDV_DID_RESET) {
-                               /* Do Fallback and restart
-                                * this test (re-issue reserve
-                                * because of bus reset).
-                                */
-                               dv.cmd = MPT_FALLBACK;
-                               mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
-
-                               if (mpt_config(hd->ioc, &cfg) != 0)
-                                        goto target_done;
-
-                               if ((!dv.now.width) && (!dv.now.offset))
-                                       goto target_done;
-
-                               iocmd.flags |= MPT_ICFLAG_DID_RESET;
-                               patt = -1;
-                               continue;
-                       } else if (rc == MPT_SCANDV_SENSE) {
-                               /* Restart data test if UA, else quit.
-                                */
-                               u8 skey = hd->pLocal->sense[2] & 0x0F;
-                               ddvprintk((MYIOC_s_INFO_FMT
-                                       "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n", ioc->name, skey,
-                                       hd->pLocal->sense[12], hd->pLocal->sense[13]));
-                               if (skey == UNIT_ATTENTION) {
-                                       patt = -1;
-                                       continue;
-                               }
-                               else
-                                       goto target_done;
-                       } else {
-                               /* fatal error */
-                               goto target_done;
-                       }
-               }
-
-       } /* --- end of patt loop ---- */
-
-target_done:
-       if (iocmd.flags & MPT_ICFLAG_RESERVED) {
-               iocmd.cmd = RELEASE;
-               iocmd.data_dma = -1;
-               iocmd.data = NULL;
-               iocmd.size = 0;
-               if (mptscsih_do_cmd(hd, &iocmd) < 0)
-                       printk(MYIOC_s_INFO_FMT "DV: Release failed. id %d",
-                                       ioc->name, id);
-               else if (hd->pLocal) {
-                       if (hd->pLocal->completion == MPT_SCANDV_GOOD)
-                               iocmd.flags &= ~MPT_ICFLAG_RESERVED;
-               } else {
-                       printk(MYIOC_s_INFO_FMT "DV: Release failed. id %d",
-                                               ioc->name, id);
-               }
-       }
-
-
-       /* Set if cfg1_dma_addr contents is valid
-        */
-       if ((cfg.hdr != NULL) && (retcode == 0)){
-               /* If disk, not U320, disable QAS
-                */
-               if ((inq0 == 0) && (dv.now.factor > MPT_ULTRA320)) {
-                       hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS;
-                       ddvprintk((MYIOC_s_NOTE_FMT 
-                           "noQas set due to id=%d has factor=%x\n", ioc->name, id, dv.now.factor));
-               }
-
-               dv.cmd = MPT_SAVE;
-               mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
-
-               /* Double writes to SDP1 can cause problems,
-                * skip save of the final negotiated settings to
-                * SCSI device page 1.
-                *
-               cfg.hdr = &header1;
-               cfg.physAddr = cfg1_dma_addr;
-               cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
-               cfg.dir = 1;
-               mpt_config(hd->ioc, &cfg);
-                */
-       }
-
-       /* If this is a RAID Passthrough, enable internal IOs
-        */
-       if (iocmd.flags & MPT_ICFLAG_PHYS_DISK) {
-               if (mptscsih_do_raid(hd, MPI_RAID_ACTION_ENABLE_PHYS_IO, &iocmd) < 0)
-                       ddvprintk((MYIOC_s_ERR_FMT "RAID Enable FAILED!\n", ioc->name));
-       }
-
-       /* Done with the DV scan of the current target
-        */
-       if (pDvBuf)
-               pci_free_consistent(ioc->pcidev, dv_alloc, pDvBuf, dvbuf_dma);
-
-       ddvtprintk((MYIOC_s_INFO_FMT "DV Done id=%d\n",
-                       ioc->name, id));
-
-       return retcode;
-}
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*     mptscsih_dv_parms - perform a variety of operations on the
- *     parameters used for negotiation.
- *     @hd: Pointer to a SCSI host.
- *     @dv: Pointer to a structure that contains the maximum and current
- *             negotiated parameters.
- */
-static void
-mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
-{
-       VirtDevice              *pTarget;
-       SCSIDevicePage0_t       *pPage0;
-       SCSIDevicePage1_t       *pPage1;
-       int                     val = 0, data, configuration;
-       u8                      width = 0;
-       u8                      offset = 0;
-       u8                      factor = 0;
-       u8                      negoFlags = 0;
-       u8                      cmd = dv->cmd;
-       u8                      id = dv->id;
-
-       switch (cmd) {
-       case MPT_GET_NVRAM_VALS:
-               ddvprintk((MYIOC_s_NOTE_FMT "Getting NVRAM: ",
-                                                        hd->ioc->name));
-               /* Get the NVRAM values and save in tmax
-                * If not an LVD bus, the adapter minSyncFactor has been
-                * already throttled back.
-                */
-               if ((hd->Targets)&&((pTarget = hd->Targets[(int)id]) != NULL) && !pTarget->raidVolume) {
-                       width = pTarget->maxWidth;
-                       offset = pTarget->maxOffset;
-                       factor = pTarget->minSyncFactor;
-                       negoFlags = pTarget->negoFlags;
-               } else {
-                       if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
-                               data = hd->ioc->spi_data.nvram[id];
-                               width = data & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
-                               if ((offset = hd->ioc->spi_data.maxSyncOffset) == 0)
-                                       factor = MPT_ASYNC;
-                               else {
-                                       factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT;
-                                       if ((factor == 0) || (factor == MPT_ASYNC)){
-                                               factor = MPT_ASYNC;
-                                               offset = 0;
-                                       }
-                               }
-                       } else {
-                               width = MPT_NARROW;
-                               offset = 0;
-                               factor = MPT_ASYNC;
-                       }
-
-                       /* Set the negotiation flags */
-                       negoFlags = hd->ioc->spi_data.noQas;
-                       if (!width)
-                               negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
-
-                       if (!offset)
-                               negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
-               }
-
-               /* limit by adapter capabilities */
-               width = min(width, hd->ioc->spi_data.maxBusWidth);
-               offset = min(offset, hd->ioc->spi_data.maxSyncOffset);
-               factor = max(factor, hd->ioc->spi_data.minSyncFactor);
-
-               /* Check Consistency */
-               if (offset && (factor < MPT_ULTRA2) && !width)
-                       factor = MPT_ULTRA2;
-
-               dv->max.width = width;
-               dv->max.offset = offset;
-               dv->max.factor = factor;
-               dv->max.flags = negoFlags;
-               ddvprintk((" id=%d width=%d factor=%x offset=%x flags=%x\n",
-                               id, width, factor, offset, negoFlags));
-               break;
-
-       case MPT_UPDATE_MAX:
-               ddvprintk((MYIOC_s_NOTE_FMT
-                       "Updating with SDP0 Data: ", hd->ioc->name));
-               /* Update tmax values with those from Device Page 0.*/
-               pPage0 = (SCSIDevicePage0_t *) pPage;
-               if (pPage0) {
-                       val = cpu_to_le32(pPage0->NegotiatedParameters);
-                       dv->max.width = val & MPI_SCSIDEVPAGE0_NP_WIDE ? 1 : 0;
-                       dv->max.offset = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK) >> 16;
-                       dv->max.factor = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK) >> 8;
-               }
-
-               dv->now.width = dv->max.width;
-               dv->now.offset = dv->max.offset;
-               dv->now.factor = dv->max.factor;
-               ddvprintk(("id=%d width=%d factor=%x offset=%x flags=%x\n",
-                               id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags));
-               break;
-
-       case MPT_SET_MAX:
-               ddvprintk((MYIOC_s_NOTE_FMT "Setting Max: ",
-                                                               hd->ioc->name));
-               /* Set current to the max values. Update the config page.*/
-               dv->now.width = dv->max.width;
-               dv->now.offset = dv->max.offset;
-               dv->now.factor = dv->max.factor;
-               dv->now.flags = dv->max.flags;
-
-               pPage1 = (SCSIDevicePage1_t *)pPage;
-               if (pPage1) {
-                       mptscsih_setDevicePage1Flags (dv->now.width, dv->now.factor,
-                               dv->now.offset, &val, &configuration, dv->now.flags);
-                       dnegoprintk(("Setting Max: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
-                               id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags, val, configuration));
-                       pPage1->RequestedParameters = le32_to_cpu(val);
-                       pPage1->Reserved = 0;
-                       pPage1->Configuration = le32_to_cpu(configuration);
-               }
-
-               ddvprintk(("id=%d width=%d factor=%x offset=%x flags=%x request=%x configuration=%x\n",
-                               id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags, val, configuration));
-               break;
-
-       case MPT_SET_MIN:
-               ddvprintk((MYIOC_s_NOTE_FMT "Setting Min: ",
-                                                               hd->ioc->name));
-               /* Set page to asynchronous and narrow
-                * Do not update now, breaks fallback routine. */
-               width = MPT_NARROW;
-               offset = 0;
-               factor = MPT_ASYNC;
-               negoFlags = dv->max.flags;
-
-               pPage1 = (SCSIDevicePage1_t *)pPage;
-               if (pPage1) {
-                       mptscsih_setDevicePage1Flags (width, factor,
-                               offset, &val, &configuration, negoFlags);
-                       dnegoprintk(("Setting Min: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
-                               id, width, factor, offset, negoFlags, val, configuration));
-                       pPage1->RequestedParameters = le32_to_cpu(val);
-                       pPage1->Reserved = 0;
-                       pPage1->Configuration = le32_to_cpu(configuration);
-               }
-               ddvprintk(("id=%d width=%d factor=%x offset=%x request=%x config=%x negoFlags=%x\n",
-                               id, width, factor, offset, val, configuration, negoFlags));
-               break;
-
-       case MPT_FALLBACK:
-               ddvprintk((MYIOC_s_NOTE_FMT
-                       "Fallback: Start: offset %d, factor %x, width %d \n",
-                               hd->ioc->name, dv->now.offset,
-                               dv->now.factor, dv->now.width));
-               width = dv->now.width;
-               offset = dv->now.offset;
-               factor = dv->now.factor;
-               if ((offset) && (dv->max.width)) {
-                       if (factor < MPT_ULTRA160)
-                               factor = MPT_ULTRA160;
-                       else if (factor < MPT_ULTRA2) {
-                               factor = MPT_ULTRA2;
-                               width = MPT_WIDE;
-                       } else if ((factor == MPT_ULTRA2) && width) {
-                               factor = MPT_ULTRA2;
-                               width = MPT_NARROW;
-                       } else if (factor < MPT_ULTRA) {
-                               factor = MPT_ULTRA;
-                               width = MPT_WIDE;
-                       } else if ((factor == MPT_ULTRA) && width) {
-                               width = MPT_NARROW;
-                       } else if (factor < MPT_FAST) {
-                               factor = MPT_FAST;
-                               width = MPT_WIDE;
-                       } else if ((factor == MPT_FAST) && width) {
-                               factor = MPT_FAST;
-                               width = MPT_NARROW;
-                       } else if (factor < MPT_SCSI) {
-                               factor = MPT_SCSI;
-                               width = MPT_WIDE;
-                       } else if ((factor == MPT_SCSI) && width) {
-                               factor = MPT_SCSI;
-                               width = MPT_NARROW;
-                       } else {
-                               factor = MPT_ASYNC;
-                               offset = 0;
-                       }
-
-               } else if (offset) {
-                       width = MPT_NARROW;
-                       if (factor < MPT_ULTRA)
-                               factor = MPT_ULTRA;
-                       else if (factor < MPT_FAST)
-                               factor = MPT_FAST;
-                       else if (factor < MPT_SCSI)
-                               factor = MPT_SCSI;
-                       else {
-                               factor = MPT_ASYNC;
-                               offset = 0;
-                       }
-
-               } else {
-                       width = MPT_NARROW;
-                       factor = MPT_ASYNC;
-               }
-               dv->max.flags |= MPT_TARGET_NO_NEGO_QAS;
-               dv->max.flags &= ~MPT_TAPE_NEGO_IDP;
-
-               dv->now.width = width;
-               dv->now.offset = offset;
-               dv->now.factor = factor;
-               dv->now.flags = dv->max.flags;
-
-               pPage1 = (SCSIDevicePage1_t *)pPage;
-               if (pPage1) {
-                       mptscsih_setDevicePage1Flags (width, factor, offset, &val,
-                                               &configuration, dv->now.flags);
-                       dnegoprintk(("Finish: id=%d width=%d offset=%d factor=%x flags=%x request=%x config=%x\n",
-                            id, width, offset, factor, dv->now.flags, val, configuration));
-
-                       pPage1->RequestedParameters = le32_to_cpu(val);
-                       pPage1->Reserved = 0;
-                       pPage1->Configuration = le32_to_cpu(configuration);
-               }
-
-               ddvprintk(("Finish: id=%d offset=%d factor=%x width=%d request=%x config=%x\n",
-                            id, dv->now.offset, dv->now.factor, dv->now.width, val, configuration));
-               break;
-
-       case MPT_SAVE:
-               ddvprintk((MYIOC_s_NOTE_FMT
-                       "Saving to Target structure: ", hd->ioc->name));
-               ddvprintk(("id=%d width=%x factor=%x offset=%d flags=%x\n",
-                            id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags));
-
-               /* Save these values to target structures
-                * or overwrite nvram (phys disks only).
-                */
-
-               if ((hd->Targets)&&((pTarget = hd->Targets[(int)id]) != NULL) && !pTarget->raidVolume ) {
-                       pTarget->maxWidth = dv->now.width;
-                       pTarget->maxOffset = dv->now.offset;
-                       pTarget->minSyncFactor = dv->now.factor;
-                       pTarget->negoFlags = dv->now.flags;
-               } else {
-                       /* Preserv all flags, use
-                        * read-modify-write algorithm
-                        */
-                       if (hd->ioc->spi_data.nvram) {
-                               data = hd->ioc->spi_data.nvram[id];
-
-                               if (dv->now.width)
-                                       data &= ~MPT_NVRAM_WIDE_DISABLE;
-                               else
-                                       data |= MPT_NVRAM_WIDE_DISABLE;
-
-                               if (!dv->now.offset)
-                                       factor = MPT_ASYNC;
-
-                               data &= ~MPT_NVRAM_SYNC_MASK;
-                               data |= (dv->now.factor << MPT_NVRAM_SYNC_SHIFT) & MPT_NVRAM_SYNC_MASK;
-
-                               hd->ioc->spi_data.nvram[id] = data;
-                       }
-               }
-               break;
-       }
-}
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*     mptscsih_fillbuf - fill a buffer with a special data pattern
- *             cleanup. For bus scan only.
- *
- *     @buffer: Pointer to data buffer to be filled.
- *     @size: Number of bytes to fill
- *     @index: Pattern index
- *     @width: bus width, 0 (8 bits) or 1 (16 bits)
- */
-static void
-mptscsih_fillbuf(char *buffer, int size, int index, int width)
-{
-       char *ptr = buffer;
-       int ii;
-       char byte;
-       short val;
-
-       switch (index) {
-       case 0:
-
-               if (width) {
-                       /* Pattern:  0000 FFFF 0000 FFFF
-                        */
-                       for (ii=0; ii < size; ii++, ptr++) {
-                               if (ii & 0x02)
-                                       *ptr = 0xFF;
-                               else
-                                       *ptr = 0x00;
-                       }
-               } else {
-                       /* Pattern:  00 FF 00 FF
-                        */
-                       for (ii=0; ii < size; ii++, ptr++) {
-                               if (ii & 0x01)
-                                       *ptr = 0xFF;
-                               else
-                                       *ptr = 0x00;
-                       }
-               }
-               break;
-
-       case 1:
-               if (width) {
-                       /* Pattern:  5555 AAAA 5555 AAAA 5555
-                        */
-                       for (ii=0; ii < size; ii++, ptr++) {
-                               if (ii & 0x02)
-                                       *ptr = 0xAA;
-                               else
-                                       *ptr = 0x55;
-                       }
-               } else {
-                       /* Pattern:  55 AA 55 AA 55
-                        */
-                       for (ii=0; ii < size; ii++, ptr++) {
-                               if (ii & 0x01)
-                                       *ptr = 0xAA;
-                               else
-                                       *ptr = 0x55;
-                       }
-               }
-               break;
-
-       case 2:
-               /* Pattern:  00 01 02 03 04 05
-                * ... FE FF 00 01..
-                */
-               for (ii=0; ii < size; ii++, ptr++)
-                       *ptr = (char) ii;
-               break;
-
-       case 3:
-               if (width) {
-                       /* Wide Pattern:  FFFE 0001 FFFD 0002
-                        * ...  4000 DFFF 8000 EFFF
-                        */
-                       byte = 0;
-                       for (ii=0; ii < size/2; ii++) {
-                               /* Create the base pattern
-                                */
-                               val = (1 << byte);
-                               /* every 64 (0x40) bytes flip the pattern
-                                * since we fill 2 bytes / iteration,
-                                * test for ii = 0x20
-                                */
-                               if (ii & 0x20)
-                                       val = ~(val);
-
-                               if (ii & 0x01) {
-                                       *ptr = (char)( (val & 0xFF00) >> 8);
-                                       ptr++;
-                                       *ptr = (char)(val & 0xFF);
-                                       byte++;
-                                       byte &= 0x0F;
-                               } else {
-                                       val = ~val;
-                                       *ptr = (char)( (val & 0xFF00) >> 8);
-                                       ptr++;
-                                       *ptr = (char)(val & 0xFF);
-                               }
-
-                               ptr++;
-                       }
-               } else {
-                       /* Narrow Pattern:  FE 01 FD 02 FB 04
-                        * .. 7F 80 01 FE 02 FD ...  80 7F
-                        */
-                       byte = 0;
-                       for (ii=0; ii < size; ii++, ptr++) {
-                               /* Base pattern - first 32 bytes
-                                */
-                               if (ii & 0x01) {
-                                       *ptr = (1 << byte);
-                                       byte++;
-                                       byte &= 0x07;
-                               } else {
-                                       *ptr = (char) (~(1 << byte));
-                               }
-
-                               /* Flip the pattern every 32 bytes
-                                */
-                               if (ii & 0x20)
-                                       *ptr = ~(*ptr);
-                       }
-               }
-               break;
-       }
-}
-#endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-
-module_init(mptscsih_init);
-module_exit(mptscsih_exit);