]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/message/fusion/mptscsih.c
[SCSI] mpt fusion: Changes in mptbase.c for logging support
[karo-tx-linux.git] / drivers / message / fusion / mptscsih.c
index 2a3e9e66d4ef7ed49c535597da34a8073417c219..fd3aa2619f427317c5d7afb1e73d472887bd2c7a 100644 (file)
@@ -4,7 +4,7 @@
  *      running LSI Logic Fusion MPT (Message Passing Technology) firmware.
  *
  *  Copyright (c) 1999-2007 LSI Logic Corporation
- *  (mailto:mpt_linux_developer@lsi.com)
+ *  (mailto:DL-MPTFusionLinux@lsi.com)
  *
  */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -44,7 +44,6 @@
 */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 
-#include "linux_compat.h"      /* linux-2.6 tweaks */
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -260,30 +259,13 @@ mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
        /* Map the data portion, if any.
         * sges_left  = 0 if no data transfer.
         */
-       if ( (sges_left = SCpnt->use_sg) ) {
-               sges_left = pci_map_sg(ioc->pcidev,
-                              (struct scatterlist *) SCpnt->request_buffer,
-                              SCpnt->use_sg,
-                              SCpnt->sc_data_direction);
-               if (sges_left == 0)
-                       return FAILED;
-       } else if (SCpnt->request_bufflen) {
-               SCpnt->SCp.dma_handle = pci_map_single(ioc->pcidev,
-                                     SCpnt->request_buffer,
-                                     SCpnt->request_bufflen,
-                                     SCpnt->sc_data_direction);
-               dsgprintk((MYIOC_s_INFO_FMT "SG: non-SG for %p, len=%d\n",
-                               ioc->name, SCpnt, SCpnt->request_bufflen));
-               mptscsih_add_sge((char *) &pReq->SGL,
-                       0xD1000000|MPT_SGE_FLAGS_ADDRESSING|sgdir|SCpnt->request_bufflen,
-                       SCpnt->SCp.dma_handle);
-
-               return SUCCESS;
-       }
+       sges_left = scsi_dma_map(SCpnt);
+       if (sges_left < 0)
+               return FAILED;
 
        /* Handle the SG case.
         */
-       sg = (struct scatterlist *) SCpnt->request_buffer;
+       sg = scsi_sglist(SCpnt);
        sg_done  = 0;
        sgeOffset = sizeof(SCSIIORequest_t) - sizeof(SGE_IO_UNION);
        chainSge = NULL;
@@ -465,7 +447,12 @@ mptscsih_issue_sep_command(MPT_ADAPTER *ioc, VirtTarget *vtarget,
        MPT_FRAME_HDR *mf;
        SEPRequest_t     *SEPMsg;
 
-       if (ioc->bus_type == FC)
+       if (ioc->bus_type != SAS)
+               return;
+
+       /* Not supported for hidden raid components
+        */
+       if (vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
                return;
 
        if ((mf = mpt_get_msg_frame(ioc->InternalCtx, ioc)) == NULL) {
@@ -662,7 +649,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
                scsi_state = pScsiReply->SCSIState;
                scsi_status = pScsiReply->SCSIStatus;
                xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
-               sc->resid = sc->request_bufflen - xfer_cnt;
+               scsi_set_resid(sc, scsi_bufflen(sc) - xfer_cnt);
                log_info = le32_to_cpu(pScsiReply->IOCLogInfo);
 
                /*
@@ -767,7 +754,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
                        break;
 
                case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:      /* 0x0049 */
-                       sc->resid = sc->request_bufflen - xfer_cnt;
+                       scsi_set_resid(sc, scsi_bufflen(sc) - xfer_cnt);
                        if((xfer_cnt==0)||(sc->underflow > xfer_cnt))
                                sc->result=DID_SOFT_ERROR << 16;
                        else /* Sufficient data transfer occurred */
@@ -816,13 +803,10 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
                        break;
 
                case MPI_IOCSTATUS_SCSI_DATA_OVERRUN:           /* 0x0044 */
-                       sc->resid=0;
+                       scsi_set_resid(sc, 0);
                case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR:        /* 0x0040 */
                case MPI_IOCSTATUS_SUCCESS:                     /* 0x0000 */
-                       if (scsi_status == MPI_SCSI_STATUS_BUSY)
-                               sc->result = (DID_BUS_BUSY << 16) | scsi_status;
-                       else
-                               sc->result = (DID_OK << 16) | scsi_status;
+                       sc->result = (DID_OK << 16) | scsi_status;
                        if (scsi_state == 0) {
                                ;
                        } else if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
@@ -902,23 +886,18 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
                            scsi_state, scsi_status, log_info));
 
                        dreplyprintk(("%s: [%d:%d:%d:%d] resid=%d "
-                           "bufflen=%d xfer_cnt=%d\n", __FUNCTION__,
-                           sc->device->host->host_no, sc->device->channel, sc->device->id,
-                           sc->device->lun, sc->resid, sc->request_bufflen,
-                           xfer_cnt));
+                                     "bufflen=%d xfer_cnt=%d\n", __FUNCTION__,
+                                     sc->device->host->host_no,
+                                     sc->device->channel, sc->device->id,
+                                     sc->device->lun, scsi_get_resid(sc),
+                                     scsi_bufflen(sc), xfer_cnt));
                }
 #endif
 
        } /* end of address reply case */
 
        /* Unmap the DMA buffers, if any. */
-       if (sc->use_sg) {
-               pci_unmap_sg(ioc->pcidev, (struct scatterlist *) sc->request_buffer,
-                           sc->use_sg, sc->sc_data_direction);
-       } else if (sc->request_bufflen) {
-               pci_unmap_single(ioc->pcidev, sc->SCp.dma_handle,
-                               sc->request_bufflen, sc->sc_data_direction);
-       }
+       scsi_dma_unmap(sc);
 
        sc->scsi_done(sc);              /* Issue the command callback */
 
@@ -973,17 +952,8 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
                        /* Set status, free OS resources (SG DMA buffers)
                         * Do OS callback
                         */
-                       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);
-                       }
+                       scsi_dma_unmap(SCpnt);
+
                        SCpnt->result = DID_RESET << 16;
                        SCpnt->host_scribble = NULL;
 
@@ -1026,14 +996,19 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
                        mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii);
                        if (mf == NULL)
                                continue;
+                       /* If the device is a hidden raid component, then its
+                        * expected that the mf->function will be RAID_SCSI_IO
+                        */
+                       if (vdevice->vtarget->tflags &
+                           MPT_TARGET_FLAGS_RAID_COMPONENT && mf->Function !=
+                           MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)
+                               continue;
+
                        int_to_scsilun(vdevice->lun, &lun);
                        if ((mf->Bus != vdevice->vtarget->channel) ||
                            (mf->TargetID != vdevice->vtarget->id) ||
                            memcmp(lun.scsi_lun, mf->LUN, 8))
                                continue;
-                       dsprintk(( "search_running: found (sc=%p, mf = %p) "
-                           "channel %d id %d, lun %d \n", hd->ScsiLookup[ii],
-                           mf, mf->Bus, mf->TargetID, vdevice->lun));
 
                        /* Cleanup
                         */
@@ -1042,19 +1017,12 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
                        mpt_free_msg_frame(hd->ioc, (MPT_FRAME_HDR *)mf);
                        if ((unsigned char *)mf != sc->host_scribble)
                                continue;
-                       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);
-                       }
+                       scsi_dma_unmap(sc);
                        sc->host_scribble = NULL;
                        sc->result = DID_NO_CONNECT << 16;
+                       dsprintk(( "search_running: found (sc=%p, mf = %p) "
+                           "channel %d id %d, lun %d \n", sc, mf,
+                           vdevice->vtarget->channel, vdevice->vtarget->id, vdevice->lun));
                        sc->scsi_done(sc);
                }
        }
@@ -1188,20 +1156,7 @@ mptscsih_suspend(struct pci_dev *pdev, pm_message_t state)
 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;
-
-       hd = (MPT_SCSI_HOST *)host->hostdata;
-       if(!hd)
-               return 0;
-
-       return 0;
+       return mpt_resume(pdev);
 }
 
 #endif
@@ -1396,10 +1351,10 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
         *    will be no data transfer!  GRRRRR...
         */
        if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
-               datalen = SCpnt->request_bufflen;
+               datalen = scsi_bufflen(SCpnt);
                scsidir = MPI_SCSIIO_CONTROL_READ;      /* DATA IN  (host<--ioc<--dev) */
        } else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
-               datalen = SCpnt->request_bufflen;
+               datalen = scsi_bufflen(SCpnt);
                scsidir = MPI_SCSIIO_CONTROL_WRITE;     /* DATA OUT (host-->ioc-->dev) */
        } else {
                datalen = 0;
@@ -1537,21 +1492,23 @@ mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /**
  *     mptscsih_TMHandler - Generic handler for SCSI Task Management.
- *     Fall through to mpt_HardResetHandler if: not operational, too many
- *     failed TM requests or handshake failure.
- *
- *     @ioc: Pointer to MPT_ADAPTER structure
+ *     @hd: Pointer to MPT SCSI HOST structure
  *     @type: Task Management type
+ *     @channel: channel number for task management
  *     @id: Logical Target ID for reset (if appropriate)
  *     @lun: Logical Unit for reset (if appropriate)
  *     @ctx2abort: Context for the task to be aborted (if appropriate)
+ *     @timeout: timeout for task management control
+ *
+ *     Fall through to mpt_HardResetHandler if: not operational, too many
+ *     failed TM requests or handshake failure.
  *
  *     Remark: Currently invoked from a non-interrupt thread (_bh).
  *
  *     Remark: With old EH code, at most 1 SCSI TaskMgmt function per IOC
  *     will be active.
  *
- *     Returns 0 for SUCCESS, or FAILED.
+ *     Returns 0 for SUCCESS, or %FAILED.
  **/
 int
 mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout)
@@ -1650,9 +1607,11 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int c
  *     mptscsih_IssueTaskMgmt - Generic send Task Management function.
  *     @hd: Pointer to MPT_SCSI_HOST structure
  *     @type: Task Management type
+ *     @channel: channel number for task management
  *     @id: Logical Target ID for reset (if appropriate)
  *     @lun: Logical Unit for reset (if appropriate)
  *     @ctx2abort: Context for the task to be aborted (if appropriate)
+ *     @timeout: timeout for task management control
  *
  *     Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
  *     or a non-interrupt thread.  In the former, must not call schedule().
@@ -1780,20 +1739,45 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
        u32              ctx2abort;
        int              scpnt_idx;
        int              retval;
-       VirtDevice       *vdev;
+       VirtDevice       *vdevice;
        ulong            sn = SCpnt->serial_number;
+       MPT_ADAPTER     *ioc;
 
        /* 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_INFO MYNAM ": mptscsih_abort: "
-                          "Can't locate host! (sc=%p)\n",
-                          SCpnt));
+               dfailprintk((KERN_INFO MYNAM ": mptscsih_abort: Can't locate "
+                   "host! (sc=%p)\n", SCpnt));
                return FAILED;
        }
 
+       ioc = hd->ioc;
+       printk(MYIOC_s_INFO_FMT "attempting task abort! (sc=%p)\n",
+              ioc->name, SCpnt);
+       scsi_print_command(SCpnt);
+
+       vdevice = SCpnt->device->hostdata;
+       if (!vdevice || !vdevice->vtarget) {
+               dtmprintk((MYIOC_s_DEBUG_FMT "task abort: device has been "
+                   "deleted (sc=%p)\n", ioc->name, SCpnt));
+               SCpnt->result = DID_NO_CONNECT << 16;
+               SCpnt->scsi_done(SCpnt);
+               retval = 0;
+               goto out;
+       }
+
+       /* Task aborts are not supported for hidden raid components.
+        */
+       if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
+               dtmprintk((MYIOC_s_DEBUG_FMT "task abort: hidden raid "
+                   "component (sc=%p)\n", ioc->name, SCpnt));
+               SCpnt->result = DID_RESET << 16;
+               retval = FAILED;
+               goto out;
+       }
+
        /* Find this command
         */
        if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) {
@@ -1802,21 +1786,20 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
                 */
                SCpnt->result = DID_RESET << 16;
                dtmprintk((KERN_INFO MYNAM ": %s: mptscsih_abort: "
-                          "Command not in the active list! (sc=%p)\n",
-                          hd->ioc->name, SCpnt));
-               return SUCCESS;
+                  "Command not in the active list! (sc=%p)\n", ioc->name,
+                  SCpnt));
+               retval = 0;
+               goto out;
        }
 
-       if (hd->resetPending)
-               return FAILED;
+       if (hd->resetPending) {
+               retval = FAILED;
+               goto out;
+       }
 
        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)
         *
@@ -1829,18 +1812,17 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
 
        hd->abortSCpnt = SCpnt;
 
-       vdev = SCpnt->device->hostdata;
        retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
-               vdev->vtarget->channel, vdev->vtarget->id, vdev->lun,
-               ctx2abort, mptscsih_get_tm_timeout(hd->ioc));
+           vdevice->vtarget->channel, vdevice->vtarget->id, vdevice->lun,
+           ctx2abort, mptscsih_get_tm_timeout(ioc));
 
        if (SCPNT_TO_LOOKUP_IDX(SCpnt) == scpnt_idx &&
            SCpnt->serial_number == sn)
                retval = FAILED;
 
-       printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n",
-               hd->ioc->name,
-               ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
+ out:
+       printk(MYIOC_s_INFO_FMT "task abort: %s (sc=%p)\n",
+           ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
 
        if (retval == 0)
                return SUCCESS;
@@ -1862,32 +1844,47 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
 {
        MPT_SCSI_HOST   *hd;
        int              retval;
-       VirtDevice       *vdev;
+       VirtDevice       *vdevice;
+       MPT_ADAPTER     *ioc;
 
        /* If we can't locate our host adapter structure, return FAILED status.
         */
        if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
-               dtmprintk((KERN_INFO MYNAM ": mptscsih_dev_reset: "
-                          "Can't locate host! (sc=%p)\n",
-                          SCpnt));
+               dtmprintk((KERN_INFO MYNAM ": mptscsih_dev_reset: Can't "
+                   "locate host! (sc=%p)\n", SCpnt));
                return FAILED;
        }
 
-       if (hd->resetPending)
-               return FAILED;
-
-       printk(KERN_WARNING MYNAM ": %s: attempting target reset! (sc=%p)\n",
-              hd->ioc->name, SCpnt);
+       ioc = hd->ioc;
+       printk(MYIOC_s_INFO_FMT "attempting target reset! (sc=%p)\n",
+              ioc->name, SCpnt);
        scsi_print_command(SCpnt);
 
-       vdev = SCpnt->device->hostdata;
+       if (hd->resetPending) {
+               retval = FAILED;
+               goto out;
+       }
+
+       vdevice = SCpnt->device->hostdata;
+       if (!vdevice || !vdevice->vtarget) {
+               retval = 0;
+               goto out;
+       }
+
+       /* Target reset to hidden raid component is not supported
+        */
+       if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
+               retval = FAILED;
+               goto out;
+       }
+
        retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
-               vdev->vtarget->channel, vdev->vtarget->id,
-               0, 0, mptscsih_get_tm_timeout(hd->ioc));
+           vdevice->vtarget->channel, vdevice->vtarget->id, 0, 0,
+           mptscsih_get_tm_timeout(ioc));
 
-       printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n",
-               hd->ioc->name,
-               ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
+ out:
+       printk (MYIOC_s_INFO_FMT "target reset: %s (sc=%p)\n",
+           ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
 
        if (retval == 0)
                return SUCCESS;
@@ -1911,18 +1908,19 @@ mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
        MPT_SCSI_HOST   *hd;
        int              retval;
        VirtDevice       *vdev;
+       MPT_ADAPTER     *ioc;
 
        /* If we can't locate our host adapter structure, return FAILED status.
         */
        if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
-               dtmprintk((KERN_INFO MYNAM ": mptscsih_bus_reset: "
-                          "Can't locate host! (sc=%p)\n",
-                          SCpnt ) );
+               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",
-              hd->ioc->name, SCpnt);
+       ioc = hd->ioc;
+       printk(MYIOC_s_INFO_FMT "attempting bus reset! (sc=%p)\n",
+              ioc->name, SCpnt);
        scsi_print_command(SCpnt);
 
        if (hd->timeouts < -1)
@@ -1930,11 +1928,10 @@ mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
 
        vdev = SCpnt->device->hostdata;
        retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
-               vdev->vtarget->channel, 0, 0, 0, mptscsih_get_tm_timeout(hd->ioc));
+           vdev->vtarget->channel, 0, 0, 0, mptscsih_get_tm_timeout(ioc));
 
-       printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n",
-               hd->ioc->name,
-               ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
+       printk(MYIOC_s_INFO_FMT "bus reset: %s (sc=%p)\n",
+           ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
 
        if (retval == 0)
                return SUCCESS;
@@ -1955,37 +1952,38 @@ int
 mptscsih_host_reset(struct scsi_cmnd *SCpnt)
 {
        MPT_SCSI_HOST *  hd;
-       int              status = SUCCESS;
+       int              retval;
+       MPT_ADAPTER     *ioc;
 
        /*  If we can't locate the host to reset, then we failed. */
        if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
-               dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
-                            "Can't locate host! (sc=%p)\n",
-                            SCpnt ) );
+               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",
-              hd->ioc->name, SCpnt);
+       ioc = hd->ioc;
+       printk(MYIOC_s_INFO_FMT "attempting host reset! (sc=%p)\n",
+           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.
         */
-       if (mpt_HardResetHandler(hd->ioc, CAN_SLEEP) < 0){
-               status = FAILED;
+       if (mpt_HardResetHandler(hd->ioc, CAN_SLEEP) < 0) {
+               retval = FAILED;
        } else {
                /*  Make sure TM pending is cleared and TM state is set to
                 *  NONE.
                 */
+               retval = 0;
                hd->tmPending = 0;
                hd->tmState = TM_STATE_NONE;
        }
 
-       dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
-                    "Status = %s\n",
-                    (status == SUCCESS) ? "SUCCESS" : "FAILED" ) );
+       printk(MYIOC_s_INFO_FMT "host reset: %s (sc=%p)\n",
+           ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
 
-       return status;
+       return retval;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -2022,6 +2020,7 @@ mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd)
 /**
  *     mptscsih_tm_wait_for_completion - wait for completion of TM task
  *     @hd: Pointer to MPT host structure.
+ *     @timeout: timeout value
  *
  *     Returns {SUCCESS,FAILED}.
  */
@@ -2474,11 +2473,11 @@ mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR
                                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) ||
-                                       (sc->device->channel << 8) || sc->device->id;
+                               ioc->events[idx].data[0] = (pReq->LUN[1] << 24) |
+                                       (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) |
+                                       (sc->device->channel << 8) | sc->device->id;
 
-                               ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12];
+                               ioc->events[idx].data[1] = (sense_data[13] << 8) | sense_data[12];
 
                                ioc->eventContext++;
                                if (hd->ioc->pcidev->vendor ==
@@ -3161,6 +3160,16 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
 {
        INTERNAL_CMD             iocmd;
 
+       /* Ignore hidden raid components, this is handled when the command
+        * is sent to the volume
+        */
+       if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
+               return;
+
+       if (vdevice->vtarget->type != TYPE_DISK || vdevice->vtarget->deleted ||
+           !vdevice->configured_lun)
+               return;
+
        /* Following parameters will not change
         * in this routine.
         */
@@ -3175,11 +3184,162 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
        iocmd.id = vdevice->vtarget->id;
        iocmd.lun = vdevice->lun;
 
-       if ((vdevice->vtarget->type == TYPE_DISK) &&
-           (vdevice->configured_lun))
-               mptscsih_do_cmd(hd, &iocmd);
+       mptscsih_do_cmd(hd, &iocmd);
 }
 
+static ssize_t
+mptscsih_version_fw_show(struct class_device *cdev, char *buf)
+{
+       struct Scsi_Host *host = class_to_shost(cdev);
+       MPT_SCSI_HOST   *hd = (MPT_SCSI_HOST *)host->hostdata;
+       MPT_ADAPTER *ioc = hd->ioc;
+
+       return snprintf(buf, PAGE_SIZE, "%02d.%02d.%02d.%02d\n",
+           (ioc->facts.FWVersion.Word & 0xFF000000) >> 24,
+           (ioc->facts.FWVersion.Word & 0x00FF0000) >> 16,
+           (ioc->facts.FWVersion.Word & 0x0000FF00) >> 8,
+           ioc->facts.FWVersion.Word & 0x000000FF);
+}
+static CLASS_DEVICE_ATTR(version_fw, S_IRUGO, mptscsih_version_fw_show, NULL);
+
+static ssize_t
+mptscsih_version_bios_show(struct class_device *cdev, char *buf)
+{
+       struct Scsi_Host *host = class_to_shost(cdev);
+       MPT_SCSI_HOST   *hd = (MPT_SCSI_HOST *)host->hostdata;
+       MPT_ADAPTER *ioc = hd->ioc;
+
+       return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x.%02x\n",
+           (ioc->biosVersion & 0xFF000000) >> 24,
+           (ioc->biosVersion & 0x00FF0000) >> 16,
+           (ioc->biosVersion & 0x0000FF00) >> 8,
+           ioc->biosVersion & 0x000000FF);
+}
+static CLASS_DEVICE_ATTR(version_bios, S_IRUGO, mptscsih_version_bios_show, NULL);
+
+static ssize_t
+mptscsih_version_mpi_show(struct class_device *cdev, char *buf)
+{
+       struct Scsi_Host *host = class_to_shost(cdev);
+       MPT_SCSI_HOST   *hd = (MPT_SCSI_HOST *)host->hostdata;
+       MPT_ADAPTER *ioc = hd->ioc;
+
+       return snprintf(buf, PAGE_SIZE, "%03x\n", ioc->facts.MsgVersion);
+}
+static CLASS_DEVICE_ATTR(version_mpi, S_IRUGO, mptscsih_version_mpi_show, NULL);
+
+static ssize_t
+mptscsih_version_product_show(struct class_device *cdev, char *buf)
+{
+       struct Scsi_Host *host = class_to_shost(cdev);
+       MPT_SCSI_HOST   *hd = (MPT_SCSI_HOST *)host->hostdata;
+       MPT_ADAPTER *ioc = hd->ioc;
+
+       return snprintf(buf, PAGE_SIZE, "%s\n", ioc->prod_name);
+}
+static CLASS_DEVICE_ATTR(version_product, S_IRUGO,
+    mptscsih_version_product_show, NULL);
+
+static ssize_t
+mptscsih_version_nvdata_persistent_show(struct class_device *cdev, char *buf)
+{
+       struct Scsi_Host *host = class_to_shost(cdev);
+       MPT_SCSI_HOST   *hd = (MPT_SCSI_HOST *)host->hostdata;
+       MPT_ADAPTER *ioc = hd->ioc;
+
+       return snprintf(buf, PAGE_SIZE, "%02xh\n",
+           ioc->nvdata_version_persistent);
+}
+static CLASS_DEVICE_ATTR(version_nvdata_persistent, S_IRUGO,
+    mptscsih_version_nvdata_persistent_show, NULL);
+
+static ssize_t
+mptscsih_version_nvdata_default_show(struct class_device *cdev, char *buf)
+{
+       struct Scsi_Host *host = class_to_shost(cdev);
+       MPT_SCSI_HOST   *hd = (MPT_SCSI_HOST *)host->hostdata;
+       MPT_ADAPTER *ioc = hd->ioc;
+
+       return snprintf(buf, PAGE_SIZE, "%02xh\n",ioc->nvdata_version_default);
+}
+static CLASS_DEVICE_ATTR(version_nvdata_default, S_IRUGO,
+    mptscsih_version_nvdata_default_show, NULL);
+
+static ssize_t
+mptscsih_board_name_show(struct class_device *cdev, char *buf)
+{
+       struct Scsi_Host *host = class_to_shost(cdev);
+       MPT_SCSI_HOST   *hd = (MPT_SCSI_HOST *)host->hostdata;
+       MPT_ADAPTER *ioc = hd->ioc;
+
+       return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_name);
+}
+static CLASS_DEVICE_ATTR(board_name, S_IRUGO, mptscsih_board_name_show, NULL);
+
+static ssize_t
+mptscsih_board_assembly_show(struct class_device *cdev, char *buf)
+{
+       struct Scsi_Host *host = class_to_shost(cdev);
+       MPT_SCSI_HOST   *hd = (MPT_SCSI_HOST *)host->hostdata;
+       MPT_ADAPTER *ioc = hd->ioc;
+
+       return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_assembly);
+}
+static CLASS_DEVICE_ATTR(board_assembly, S_IRUGO,
+    mptscsih_board_assembly_show, NULL);
+
+static ssize_t
+mptscsih_board_tracer_show(struct class_device *cdev, char *buf)
+{
+       struct Scsi_Host *host = class_to_shost(cdev);
+       MPT_SCSI_HOST   *hd = (MPT_SCSI_HOST *)host->hostdata;
+       MPT_ADAPTER *ioc = hd->ioc;
+
+       return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_tracer);
+}
+static CLASS_DEVICE_ATTR(board_tracer, S_IRUGO,
+    mptscsih_board_tracer_show, NULL);
+
+static ssize_t
+mptscsih_io_delay_show(struct class_device *cdev, char *buf)
+{
+       struct Scsi_Host *host = class_to_shost(cdev);
+       MPT_SCSI_HOST   *hd = (MPT_SCSI_HOST *)host->hostdata;
+       MPT_ADAPTER *ioc = hd->ioc;
+
+       return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->io_missing_delay);
+}
+static CLASS_DEVICE_ATTR(io_delay, S_IRUGO,
+    mptscsih_io_delay_show, NULL);
+
+static ssize_t
+mptscsih_device_delay_show(struct class_device *cdev, char *buf)
+{
+       struct Scsi_Host *host = class_to_shost(cdev);
+       MPT_SCSI_HOST   *hd = (MPT_SCSI_HOST *)host->hostdata;
+       MPT_ADAPTER *ioc = hd->ioc;
+
+       return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->device_missing_delay);
+}
+static CLASS_DEVICE_ATTR(device_delay, S_IRUGO,
+    mptscsih_device_delay_show, NULL);
+
+struct class_device_attribute *mptscsih_host_attrs[] = {
+       &class_device_attr_version_fw,
+       &class_device_attr_version_bios,
+       &class_device_attr_version_mpi,
+       &class_device_attr_version_product,
+       &class_device_attr_version_nvdata_persistent,
+       &class_device_attr_version_nvdata_default,
+       &class_device_attr_board_name,
+       &class_device_attr_board_assembly,
+       &class_device_attr_board_tracer,
+       &class_device_attr_io_delay,
+       &class_device_attr_device_delay,
+       NULL,
+};
+EXPORT_SYMBOL(mptscsih_host_attrs);
+
 EXPORT_SYMBOL(mptscsih_remove);
 EXPORT_SYMBOL(mptscsih_shutdown);
 #ifdef CONFIG_PM