Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  *  linux/drivers/message/fusion/mptscsih.c
0003  *      For use with LSI PCI chip/adapter(s)
0004  *      running LSI Fusion MPT (Message Passing Technology) firmware.
0005  *
0006  *  Copyright (c) 1999-2008 LSI Corporation
0007  *  (mailto:DL-MPTFusionLinux@lsi.com)
0008  *
0009  */
0010 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
0011 /*
0012     This program is free software; you can redistribute it and/or modify
0013     it under the terms of the GNU General Public License as published by
0014     the Free Software Foundation; version 2 of the License.
0015 
0016     This program is distributed in the hope that it will be useful,
0017     but WITHOUT ANY WARRANTY; without even the implied warranty of
0018     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0019     GNU General Public License for more details.
0020 
0021     NO WARRANTY
0022     THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
0023     CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
0024     LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
0025     MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
0026     solely responsible for determining the appropriateness of using and
0027     distributing the Program and assumes all risks associated with its
0028     exercise of rights under this Agreement, including but not limited to
0029     the risks and costs of program errors, damage to or loss of data,
0030     programs or equipment, and unavailability or interruption of operations.
0031 
0032     DISCLAIMER OF LIABILITY
0033     NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
0034     DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
0035     DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
0036     ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
0037     TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
0038     USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
0039     HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
0040 
0041     You should have received a copy of the GNU General Public License
0042     along with this program; if not, write to the Free Software
0043     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
0044 */
0045 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
0046 
0047 #include <linux/module.h>
0048 #include <linux/kernel.h>
0049 #include <linux/slab.h>
0050 #include <linux/init.h>
0051 #include <linux/errno.h>
0052 #include <linux/kdev_t.h>
0053 #include <linux/blkdev.h>
0054 #include <linux/delay.h>    /* for mdelay */
0055 #include <linux/interrupt.h>
0056 #include <linux/reboot.h>   /* notifier code */
0057 #include <linux/workqueue.h>
0058 
0059 #include <scsi/scsi.h>
0060 #include <scsi/scsi_cmnd.h>
0061 #include <scsi/scsi_device.h>
0062 #include <scsi/scsi_host.h>
0063 #include <scsi/scsi_tcq.h>
0064 #include <scsi/scsi_dbg.h>
0065 
0066 #include "mptbase.h"
0067 #include "mptscsih.h"
0068 #include "lsi/mpi_log_sas.h"
0069 
0070 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
0071 #define my_NAME     "Fusion MPT SCSI Host driver"
0072 #define my_VERSION  MPT_LINUX_VERSION_COMMON
0073 #define MYNAM       "mptscsih"
0074 
0075 MODULE_AUTHOR(MODULEAUTHOR);
0076 MODULE_DESCRIPTION(my_NAME);
0077 MODULE_LICENSE("GPL");
0078 MODULE_VERSION(my_VERSION);
0079 
0080 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
0081 /*
0082  *  Other private/forward protos...
0083  */
0084 struct scsi_cmnd    *mptscsih_get_scsi_lookup(MPT_ADAPTER *ioc, int i);
0085 static struct scsi_cmnd * mptscsih_getclear_scsi_lookup(MPT_ADAPTER *ioc, int i);
0086 static void mptscsih_set_scsi_lookup(MPT_ADAPTER *ioc, int i, struct scsi_cmnd *scmd);
0087 static int  SCPNT_TO_LOOKUP_IDX(MPT_ADAPTER *ioc, struct scsi_cmnd *scmd);
0088 int     mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
0089 static void mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq);
0090 int     mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
0091 
0092 static int  mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
0093                  SCSIIORequest_t *pReq, int req_idx);
0094 static void mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx);
0095 static void mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply);
0096 
0097 int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id,
0098         u64 lun, int ctx2abort, ulong timeout);
0099 
0100 int     mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
0101 int     mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
0102 
0103 void
0104 mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code);
0105 static int  mptscsih_get_completion_code(MPT_ADAPTER *ioc,
0106         MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply);
0107 int     mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
0108 static int  mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
0109 static void mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice);
0110 
0111 static int
0112 mptscsih_taskmgmt_reply(MPT_ADAPTER *ioc, u8 type,
0113                 SCSITaskMgmtReply_t *pScsiTmReply);
0114 void        mptscsih_remove(struct pci_dev *);
0115 void        mptscsih_shutdown(struct pci_dev *);
0116 #ifdef CONFIG_PM
0117 int         mptscsih_suspend(struct pci_dev *pdev, pm_message_t state);
0118 int         mptscsih_resume(struct pci_dev *pdev);
0119 #endif
0120 
0121 
0122 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
0123 /*
0124  *  mptscsih_getFreeChainBuffer - Function to get a free chain
0125  *  from the MPT_SCSI_HOST FreeChainQ.
0126  *  @ioc: Pointer to MPT_ADAPTER structure
0127  *  @req_idx: Index of the SCSI IO request frame. (output)
0128  *
0129  *  return SUCCESS or FAILED
0130  */
0131 static inline int
0132 mptscsih_getFreeChainBuffer(MPT_ADAPTER *ioc, int *retIndex)
0133 {
0134     MPT_FRAME_HDR *chainBuf;
0135     unsigned long flags;
0136     int rc;
0137     int chain_idx;
0138 
0139     dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "getFreeChainBuffer called\n",
0140         ioc->name));
0141     spin_lock_irqsave(&ioc->FreeQlock, flags);
0142     if (!list_empty(&ioc->FreeChainQ)) {
0143         int offset;
0144 
0145         chainBuf = list_entry(ioc->FreeChainQ.next, MPT_FRAME_HDR,
0146                 u.frame.linkage.list);
0147         list_del(&chainBuf->u.frame.linkage.list);
0148         offset = (u8 *)chainBuf - (u8 *)ioc->ChainBuffer;
0149         chain_idx = offset / ioc->req_sz;
0150         rc = SUCCESS;
0151         dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT
0152             "getFreeChainBuffer chainBuf=%p ChainBuffer=%p offset=%d chain_idx=%d\n",
0153             ioc->name, chainBuf, ioc->ChainBuffer, offset, chain_idx));
0154     } else {
0155         rc = FAILED;
0156         chain_idx = MPT_HOST_NO_CHAIN;
0157         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "getFreeChainBuffer failed\n",
0158             ioc->name));
0159     }
0160     spin_unlock_irqrestore(&ioc->FreeQlock, flags);
0161 
0162     *retIndex = chain_idx;
0163     return rc;
0164 } /* mptscsih_getFreeChainBuffer() */
0165 
0166 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
0167 /*
0168  *  mptscsih_AddSGE - Add a SGE (plus chain buffers) to the
0169  *  SCSIIORequest_t Message Frame.
0170  *  @ioc: Pointer to MPT_ADAPTER structure
0171  *  @SCpnt: Pointer to scsi_cmnd structure
0172  *  @pReq: Pointer to SCSIIORequest_t structure
0173  *
0174  *  Returns ...
0175  */
0176 static int
0177 mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
0178         SCSIIORequest_t *pReq, int req_idx)
0179 {
0180     char    *psge;
0181     char    *chainSge;
0182     struct scatterlist *sg;
0183     int  frm_sz;
0184     int  sges_left, sg_done;
0185     int  chain_idx = MPT_HOST_NO_CHAIN;
0186     int  sgeOffset;
0187     int  numSgeSlots, numSgeThisFrame;
0188     u32  sgflags, sgdir, thisxfer = 0;
0189     int  chain_dma_off = 0;
0190     int  newIndex;
0191     int  ii;
0192     dma_addr_t v2;
0193     u32 RequestNB;
0194 
0195     sgdir = le32_to_cpu(pReq->Control) & MPI_SCSIIO_CONTROL_DATADIRECTION_MASK;
0196     if (sgdir == MPI_SCSIIO_CONTROL_WRITE)  {
0197         sgdir = MPT_TRANSFER_HOST_TO_IOC;
0198     } else {
0199         sgdir = MPT_TRANSFER_IOC_TO_HOST;
0200     }
0201 
0202     psge = (char *) &pReq->SGL;
0203     frm_sz = ioc->req_sz;
0204 
0205     /* Map the data portion, if any.
0206      * sges_left  = 0 if no data transfer.
0207      */
0208     sges_left = scsi_dma_map(SCpnt);
0209     if (sges_left < 0)
0210         return FAILED;
0211 
0212     /* Handle the SG case.
0213      */
0214     sg = scsi_sglist(SCpnt);
0215     sg_done  = 0;
0216     sgeOffset = sizeof(SCSIIORequest_t) - sizeof(SGE_IO_UNION);
0217     chainSge = NULL;
0218 
0219     /* Prior to entering this loop - the following must be set
0220      * current MF:  sgeOffset (bytes)
0221      *              chainSge (Null if original MF is not a chain buffer)
0222      *              sg_done (num SGE done for this MF)
0223      */
0224 
0225 nextSGEset:
0226     numSgeSlots = ((frm_sz - sgeOffset) / ioc->SGE_size);
0227     numSgeThisFrame = (sges_left < numSgeSlots) ? sges_left : numSgeSlots;
0228 
0229     sgflags = MPT_SGE_FLAGS_SIMPLE_ELEMENT | sgdir;
0230 
0231     /* Get first (num - 1) SG elements
0232      * Skip any SG entries with a length of 0
0233      * NOTE: at finish, sg and psge pointed to NEXT data/location positions
0234      */
0235     for (ii=0; ii < (numSgeThisFrame-1); ii++) {
0236         thisxfer = sg_dma_len(sg);
0237         if (thisxfer == 0) {
0238             /* Get next SG element from the OS */
0239             sg = sg_next(sg);
0240             sg_done++;
0241             continue;
0242         }
0243 
0244         v2 = sg_dma_address(sg);
0245         ioc->add_sge(psge, sgflags | thisxfer, v2);
0246 
0247         /* Get next SG element from the OS */
0248         sg = sg_next(sg);
0249         psge += ioc->SGE_size;
0250         sgeOffset += ioc->SGE_size;
0251         sg_done++;
0252     }
0253 
0254     if (numSgeThisFrame == sges_left) {
0255         /* Add last element, end of buffer and end of list flags.
0256          */
0257         sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT |
0258                 MPT_SGE_FLAGS_END_OF_BUFFER |
0259                 MPT_SGE_FLAGS_END_OF_LIST;
0260 
0261         /* Add last SGE and set termination flags.
0262          * Note: Last SGE may have a length of 0 - which should be ok.
0263          */
0264         thisxfer = sg_dma_len(sg);
0265 
0266         v2 = sg_dma_address(sg);
0267         ioc->add_sge(psge, sgflags | thisxfer, v2);
0268         sgeOffset += ioc->SGE_size;
0269         sg_done++;
0270 
0271         if (chainSge) {
0272             /* The current buffer is a chain buffer,
0273              * but there is not another one.
0274              * Update the chain element
0275              * Offset and Length fields.
0276              */
0277             ioc->add_chain((char *)chainSge, 0, sgeOffset,
0278                 ioc->ChainBufferDMA + chain_dma_off);
0279         } else {
0280             /* The current buffer is the original MF
0281              * and there is no Chain buffer.
0282              */
0283             pReq->ChainOffset = 0;
0284             RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor)  + 1) & 0x03;
0285             dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT
0286                 "Single Buffer RequestNB=%x, sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
0287             ioc->RequestNB[req_idx] = RequestNB;
0288         }
0289     } else {
0290         /* At least one chain buffer is needed.
0291          * Complete the first MF
0292          *  - last SGE element, set the LastElement bit
0293          *  - set ChainOffset (words) for orig MF
0294          *             (OR finish previous MF chain buffer)
0295          *  - update MFStructPtr ChainIndex
0296          *  - Populate chain element
0297          * Also
0298          * Loop until done.
0299          */
0300 
0301         dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SG: Chain Required! sg done %d\n",
0302                 ioc->name, sg_done));
0303 
0304         /* Set LAST_ELEMENT flag for last non-chain element
0305          * in the buffer. Since psge points at the NEXT
0306          * SGE element, go back one SGE element, update the flags
0307          * and reset the pointer. (Note: sgflags & thisxfer are already
0308          * set properly).
0309          */
0310         if (sg_done) {
0311             u32 *ptmp = (u32 *) (psge - ioc->SGE_size);
0312             sgflags = le32_to_cpu(*ptmp);
0313             sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT;
0314             *ptmp = cpu_to_le32(sgflags);
0315         }
0316 
0317         if (chainSge) {
0318             /* The current buffer is a chain buffer.
0319              * chainSge points to the previous Chain Element.
0320              * Update its chain element Offset and Length (must
0321              * include chain element size) fields.
0322              * Old chain element is now complete.
0323              */
0324             u8 nextChain = (u8) (sgeOffset >> 2);
0325             sgeOffset += ioc->SGE_size;
0326             ioc->add_chain((char *)chainSge, nextChain, sgeOffset,
0327                      ioc->ChainBufferDMA + chain_dma_off);
0328         } else {
0329             /* The original MF buffer requires a chain buffer -
0330              * set the offset.
0331              * Last element in this MF is a chain element.
0332              */
0333             pReq->ChainOffset = (u8) (sgeOffset >> 2);
0334             RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor)  + 1) & 0x03;
0335             dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Chain Buffer Needed, RequestNB=%x sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
0336             ioc->RequestNB[req_idx] = RequestNB;
0337         }
0338 
0339         sges_left -= sg_done;
0340 
0341 
0342         /* NOTE: psge points to the beginning of the chain element
0343          * in current buffer. Get a chain buffer.
0344          */
0345         if ((mptscsih_getFreeChainBuffer(ioc, &newIndex)) == FAILED) {
0346             dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
0347                 "getFreeChainBuffer FAILED SCSI cmd=%02x (%p)\n",
0348                 ioc->name, pReq->CDB[0], SCpnt));
0349             return FAILED;
0350         }
0351 
0352         /* Update the tracking arrays.
0353          * If chainSge == NULL, update ReqToChain, else ChainToChain
0354          */
0355         if (chainSge) {
0356             ioc->ChainToChain[chain_idx] = newIndex;
0357         } else {
0358             ioc->ReqToChain[req_idx] = newIndex;
0359         }
0360         chain_idx = newIndex;
0361         chain_dma_off = ioc->req_sz * chain_idx;
0362 
0363         /* Populate the chainSGE for the current buffer.
0364          * - Set chain buffer pointer to psge and fill
0365          *   out the Address and Flags fields.
0366          */
0367         chainSge = (char *) psge;
0368         dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "  Current buff @ %p (index 0x%x)",
0369             ioc->name, psge, req_idx));
0370 
0371         /* Start the SGE for the next buffer
0372          */
0373         psge = (char *) (ioc->ChainBuffer + chain_dma_off);
0374         sgeOffset = 0;
0375         sg_done = 0;
0376 
0377         dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "  Chain buff @ %p (index 0x%x)\n",
0378             ioc->name, psge, chain_idx));
0379 
0380         /* Start the SGE for the next buffer
0381          */
0382 
0383         goto nextSGEset;
0384     }
0385 
0386     return SUCCESS;
0387 } /* mptscsih_AddSGE() */
0388 
0389 static void
0390 mptscsih_issue_sep_command(MPT_ADAPTER *ioc, VirtTarget *vtarget,
0391     U32 SlotStatus)
0392 {
0393     MPT_FRAME_HDR *mf;
0394     SEPRequest_t     *SEPMsg;
0395 
0396     if (ioc->bus_type != SAS)
0397         return;
0398 
0399     /* Not supported for hidden raid components
0400      */
0401     if (vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
0402         return;
0403 
0404     if ((mf = mpt_get_msg_frame(ioc->InternalCtx, ioc)) == NULL) {
0405         dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: no msg frames!!\n",
0406             ioc->name,__func__));
0407         return;
0408     }
0409 
0410     SEPMsg = (SEPRequest_t *)mf;
0411     SEPMsg->Function = MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR;
0412     SEPMsg->Bus = vtarget->channel;
0413     SEPMsg->TargetID = vtarget->id;
0414     SEPMsg->Action = MPI_SEP_REQ_ACTION_WRITE_STATUS;
0415     SEPMsg->SlotStatus = SlotStatus;
0416     devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
0417         "Sending SEP cmd=%x channel=%d id=%d\n",
0418         ioc->name, SlotStatus, SEPMsg->Bus, SEPMsg->TargetID));
0419     mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
0420 }
0421 
0422 #ifdef CONFIG_FUSION_LOGGING
0423 /**
0424  *  mptscsih_info_scsiio - debug print info on reply frame
0425  *  @ioc: Pointer to MPT_ADAPTER structure
0426  *  @sc: original scsi cmnd pointer
0427  *  @pScsiReply: Pointer to MPT reply frame
0428  *
0429  *  MPT_DEBUG_REPLY needs to be enabled to obtain this info
0430  *
0431  *  Refer to lsi/mpi.h.
0432  **/
0433 static void
0434 mptscsih_info_scsiio(MPT_ADAPTER *ioc, struct scsi_cmnd *sc, SCSIIOReply_t * pScsiReply)
0435 {
0436     char    *desc = NULL;
0437     char    *desc1 = NULL;
0438     u16 ioc_status;
0439     u8  skey, asc, ascq;
0440 
0441     ioc_status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK;
0442 
0443     switch (ioc_status) {
0444 
0445     case MPI_IOCSTATUS_SUCCESS:
0446         desc = "success";
0447         break;
0448     case MPI_IOCSTATUS_SCSI_INVALID_BUS:
0449         desc = "invalid bus";
0450         break;
0451     case MPI_IOCSTATUS_SCSI_INVALID_TARGETID:
0452         desc = "invalid target_id";
0453         break;
0454     case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE:
0455         desc = "device not there";
0456         break;
0457     case MPI_IOCSTATUS_SCSI_DATA_OVERRUN:
0458         desc = "data overrun";
0459         break;
0460     case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN:
0461         desc = "data underrun";
0462         break;
0463     case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR:
0464         desc = "I/O data error";
0465         break;
0466     case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR:
0467         desc = "protocol error";
0468         break;
0469     case MPI_IOCSTATUS_SCSI_TASK_TERMINATED:
0470         desc = "task terminated";
0471         break;
0472     case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:
0473         desc = "residual mismatch";
0474         break;
0475     case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED:
0476         desc = "task management failed";
0477         break;
0478     case MPI_IOCSTATUS_SCSI_IOC_TERMINATED:
0479         desc = "IOC terminated";
0480         break;
0481     case MPI_IOCSTATUS_SCSI_EXT_TERMINATED:
0482         desc = "ext terminated";
0483         break;
0484     default:
0485         desc = "";
0486         break;
0487     }
0488 
0489     switch (pScsiReply->SCSIStatus)
0490     {
0491 
0492     case MPI_SCSI_STATUS_SUCCESS:
0493         desc1 = "success";
0494         break;
0495     case MPI_SCSI_STATUS_CHECK_CONDITION:
0496         desc1 = "check condition";
0497         break;
0498     case MPI_SCSI_STATUS_CONDITION_MET:
0499         desc1 = "condition met";
0500         break;
0501     case MPI_SCSI_STATUS_BUSY:
0502         desc1 = "busy";
0503         break;
0504     case MPI_SCSI_STATUS_INTERMEDIATE:
0505         desc1 = "intermediate";
0506         break;
0507     case MPI_SCSI_STATUS_INTERMEDIATE_CONDMET:
0508         desc1 = "intermediate condmet";
0509         break;
0510     case MPI_SCSI_STATUS_RESERVATION_CONFLICT:
0511         desc1 = "reservation conflict";
0512         break;
0513     case MPI_SCSI_STATUS_COMMAND_TERMINATED:
0514         desc1 = "command terminated";
0515         break;
0516     case MPI_SCSI_STATUS_TASK_SET_FULL:
0517         desc1 = "task set full";
0518         break;
0519     case MPI_SCSI_STATUS_ACA_ACTIVE:
0520         desc1 = "aca active";
0521         break;
0522     case MPI_SCSI_STATUS_FCPEXT_DEVICE_LOGGED_OUT:
0523         desc1 = "fcpext device logged out";
0524         break;
0525     case MPI_SCSI_STATUS_FCPEXT_NO_LINK:
0526         desc1 = "fcpext no link";
0527         break;
0528     case MPI_SCSI_STATUS_FCPEXT_UNASSIGNED:
0529         desc1 = "fcpext unassigned";
0530         break;
0531     default:
0532         desc1 = "";
0533         break;
0534     }
0535 
0536     scsi_print_command(sc);
0537     printk(MYIOC_s_DEBUG_FMT "\tfw_channel = %d, fw_id = %d, lun = %llu\n",
0538         ioc->name, pScsiReply->Bus, pScsiReply->TargetID, sc->device->lun);
0539     printk(MYIOC_s_DEBUG_FMT "\trequest_len = %d, underflow = %d, "
0540         "resid = %d\n", ioc->name, scsi_bufflen(sc), sc->underflow,
0541         scsi_get_resid(sc));
0542     printk(MYIOC_s_DEBUG_FMT "\ttag = %d, transfer_count = %d, "
0543         "sc->result = %08X\n", ioc->name, le16_to_cpu(pScsiReply->TaskTag),
0544         le32_to_cpu(pScsiReply->TransferCount), sc->result);
0545 
0546     printk(MYIOC_s_DEBUG_FMT "\tiocstatus = %s (0x%04x), "
0547         "scsi_status = %s (0x%02x), scsi_state = (0x%02x)\n",
0548         ioc->name, desc, ioc_status, desc1, pScsiReply->SCSIStatus,
0549         pScsiReply->SCSIState);
0550 
0551     if (pScsiReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID) {
0552         skey = sc->sense_buffer[2] & 0x0F;
0553         asc = sc->sense_buffer[12];
0554         ascq = sc->sense_buffer[13];
0555 
0556         printk(MYIOC_s_DEBUG_FMT "\t[sense_key,asc,ascq]: "
0557             "[0x%02x,0x%02x,0x%02x]\n", ioc->name, skey, asc, ascq);
0558     }
0559 
0560     /*
0561      *  Look for + dump FCP ResponseInfo[]!
0562      */
0563     if (pScsiReply->SCSIState & MPI_SCSI_STATE_RESPONSE_INFO_VALID &&
0564         pScsiReply->ResponseInfo)
0565         printk(MYIOC_s_DEBUG_FMT "response_info = %08xh\n",
0566             ioc->name, le32_to_cpu(pScsiReply->ResponseInfo));
0567 }
0568 #endif
0569 
0570 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
0571 /*
0572  *  mptscsih_io_done - Main SCSI IO callback routine registered to
0573  *  Fusion MPT (base) driver
0574  *  @ioc: Pointer to MPT_ADAPTER structure
0575  *  @mf: Pointer to original MPT request frame
0576  *  @r: Pointer to MPT reply frame (NULL if TurboReply)
0577  *
0578  *  This routine is called from mpt.c::mpt_interrupt() at the completion
0579  *  of any SCSI IO request.
0580  *  This routine is registered with the Fusion MPT (base) driver at driver
0581  *  load/init time via the mpt_register() API call.
0582  *
0583  *  Returns 1 indicating alloc'd request frame ptr should be freed.
0584  */
0585 int
0586 mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
0587 {
0588     struct scsi_cmnd    *sc;
0589     MPT_SCSI_HOST   *hd;
0590     SCSIIORequest_t *pScsiReq;
0591     SCSIIOReply_t   *pScsiReply;
0592     u16      req_idx, req_idx_MR;
0593     VirtDevice   *vdevice;
0594     VirtTarget   *vtarget;
0595 
0596     hd = shost_priv(ioc->sh);
0597     req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
0598     req_idx_MR = (mr != NULL) ?
0599         le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx) : req_idx;
0600 
0601     /* Special case, where already freed message frame is received from
0602      * Firmware. It happens with Resetting IOC.
0603      * Return immediately. Do not care
0604      */
0605     if ((req_idx != req_idx_MR) ||
0606         (le32_to_cpu(mf->u.frame.linkage.arg1) == 0xdeadbeaf))
0607         return 0;
0608 
0609     sc = mptscsih_getclear_scsi_lookup(ioc, req_idx);
0610     if (sc == NULL) {
0611         MPIHeader_t *hdr = (MPIHeader_t *)mf;
0612 
0613         /* Remark: writeSDP1 will use the ScsiDoneCtx
0614          * If a SCSI I/O cmd, device disabled by OS and
0615          * completion done. Cannot touch sc struct. Just free mem.
0616          */
0617         if (hdr->Function == MPI_FUNCTION_SCSI_IO_REQUEST)
0618             printk(MYIOC_s_ERR_FMT "NULL ScsiCmd ptr!\n",
0619             ioc->name);
0620 
0621         mptscsih_freeChainBuffers(ioc, req_idx);
0622         return 1;
0623     }
0624 
0625     if ((unsigned char *)mf != sc->host_scribble) {
0626         mptscsih_freeChainBuffers(ioc, req_idx);
0627         return 1;
0628     }
0629 
0630     if (ioc->bus_type == SAS) {
0631         VirtDevice *vdevice = sc->device->hostdata;
0632 
0633         if (!vdevice || !vdevice->vtarget ||
0634             vdevice->vtarget->deleted) {
0635             sc->result = DID_NO_CONNECT << 16;
0636             goto out;
0637         }
0638     }
0639 
0640     sc->host_scribble = NULL;
0641     sc->result = DID_OK << 16;      /* Set default reply as OK */
0642     pScsiReq = (SCSIIORequest_t *) mf;
0643     pScsiReply = (SCSIIOReply_t *) mr;
0644 
0645     if((ioc->facts.MsgVersion >= MPI_VERSION_01_05) && pScsiReply){
0646         dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT
0647             "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d,task-tag=%d)\n",
0648             ioc->name, mf, mr, sc, req_idx, pScsiReply->TaskTag));
0649     }else{
0650         dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT
0651             "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n",
0652             ioc->name, mf, mr, sc, req_idx));
0653     }
0654 
0655     if (pScsiReply == NULL) {
0656         /* special context reply handling */
0657         ;
0658     } else {
0659         u32  xfer_cnt;
0660         u16  status;
0661         u8   scsi_state, scsi_status;
0662         u32  log_info;
0663 
0664         status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK;
0665 
0666         scsi_state = pScsiReply->SCSIState;
0667         scsi_status = pScsiReply->SCSIStatus;
0668         xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
0669         scsi_set_resid(sc, scsi_bufflen(sc) - xfer_cnt);
0670         log_info = le32_to_cpu(pScsiReply->IOCLogInfo);
0671 
0672         /*
0673          *  if we get a data underrun indication, yet no data was
0674          *  transferred and the SCSI status indicates that the
0675          *  command was never started, change the data underrun
0676          *  to success
0677          */
0678         if (status == MPI_IOCSTATUS_SCSI_DATA_UNDERRUN && xfer_cnt == 0 &&
0679             (scsi_status == MPI_SCSI_STATUS_BUSY ||
0680              scsi_status == MPI_SCSI_STATUS_RESERVATION_CONFLICT ||
0681              scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)) {
0682             status = MPI_IOCSTATUS_SUCCESS;
0683         }
0684 
0685         if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)
0686             mptscsih_copy_sense_data(sc, hd, mf, pScsiReply);
0687 
0688         /*
0689          *  Look for + dump FCP ResponseInfo[]!
0690          */
0691         if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID &&
0692             pScsiReply->ResponseInfo) {
0693             printk(MYIOC_s_NOTE_FMT "[%d:%d:%d:%llu] "
0694             "FCP_ResponseInfo=%08xh\n", ioc->name,
0695             sc->device->host->host_no, sc->device->channel,
0696             sc->device->id, sc->device->lun,
0697             le32_to_cpu(pScsiReply->ResponseInfo));
0698         }
0699 
0700         switch(status) {
0701         case MPI_IOCSTATUS_BUSY:            /* 0x0002 */
0702         case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES:  /* 0x0006 */
0703             /* CHECKME!
0704              * Maybe: DRIVER_BUSY | SUGGEST_RETRY | DID_SOFT_ERROR (retry)
0705              * But not: DID_BUS_BUSY lest one risk
0706              * killing interrupt handler:-(
0707              */
0708             sc->result = SAM_STAT_BUSY;
0709             break;
0710 
0711         case MPI_IOCSTATUS_SCSI_INVALID_BUS:        /* 0x0041 */
0712         case MPI_IOCSTATUS_SCSI_INVALID_TARGETID:   /* 0x0042 */
0713             sc->result = DID_BAD_TARGET << 16;
0714             break;
0715 
0716         case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE:   /* 0x0043 */
0717             /* Spoof to SCSI Selection Timeout! */
0718             if (ioc->bus_type != FC)
0719                 sc->result = DID_NO_CONNECT << 16;
0720             /* else fibre, just stall until rescan event */
0721             else
0722                 sc->result = DID_REQUEUE << 16;
0723 
0724             if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF)
0725                 hd->sel_timeout[pScsiReq->TargetID]++;
0726 
0727             vdevice = sc->device->hostdata;
0728             if (!vdevice)
0729                 break;
0730             vtarget = vdevice->vtarget;
0731             if (vtarget->tflags & MPT_TARGET_FLAGS_LED_ON) {
0732                 mptscsih_issue_sep_command(ioc, vtarget,
0733                     MPI_SEP_REQ_SLOTSTATUS_UNCONFIGURED);
0734                 vtarget->tflags &= ~MPT_TARGET_FLAGS_LED_ON;
0735             }
0736             break;
0737 
0738         case MPI_IOCSTATUS_SCSI_IOC_TERMINATED:     /* 0x004B */
0739             if ( ioc->bus_type == SAS ) {
0740                 u16 ioc_status =
0741                     le16_to_cpu(pScsiReply->IOCStatus);
0742                 if ((ioc_status &
0743                     MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE)
0744                     &&
0745                     ((log_info & SAS_LOGINFO_MASK) ==
0746                     SAS_LOGINFO_NEXUS_LOSS)) {
0747                         VirtDevice *vdevice =
0748                         sc->device->hostdata;
0749 
0750                         /* flag the device as being in
0751                          * device removal delay so we can
0752                          * notify the midlayer to hold off
0753                          * on timeout eh */
0754                         if (vdevice && vdevice->
0755                             vtarget &&
0756                             vdevice->vtarget->
0757                             raidVolume)
0758                             printk(KERN_INFO
0759                             "Skipping Raid Volume"
0760                             "for inDMD\n");
0761                         else if (vdevice &&
0762                             vdevice->vtarget)
0763                             vdevice->vtarget->
0764                                 inDMD = 1;
0765 
0766                         sc->result =
0767                             (DID_TRANSPORT_DISRUPTED
0768                             << 16);
0769                         break;
0770                 }
0771             } else if (ioc->bus_type == FC) {
0772                 /*
0773                  * The FC IOC may kill a request for variety of
0774                  * reasons, some of which may be recovered by a
0775                  * retry, some which are unlikely to be
0776                  * recovered. Return DID_ERROR instead of
0777                  * DID_RESET to permit retry of the command,
0778                  * just not an infinite number of them
0779                  */
0780                 sc->result = DID_ERROR << 16;
0781                 break;
0782             }
0783 
0784             /*
0785              * Allow non-SAS & non-NEXUS_LOSS to drop into below code
0786              */
0787             fallthrough;
0788 
0789         case MPI_IOCSTATUS_SCSI_TASK_TERMINATED:    /* 0x0048 */
0790             /* Linux handles an unsolicited DID_RESET better
0791              * than an unsolicited DID_ABORT.
0792              */
0793             sc->result = DID_RESET << 16;
0794             break;
0795 
0796         case MPI_IOCSTATUS_SCSI_EXT_TERMINATED:     /* 0x004C */
0797             if (ioc->bus_type == FC)
0798                 sc->result = DID_ERROR << 16;
0799             else
0800                 sc->result = DID_RESET << 16;
0801             break;
0802 
0803         case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:  /* 0x0049 */
0804             scsi_set_resid(sc, scsi_bufflen(sc) - xfer_cnt);
0805             if((xfer_cnt==0)||(sc->underflow > xfer_cnt))
0806                 sc->result=DID_SOFT_ERROR << 16;
0807             else /* Sufficient data transfer occurred */
0808                 sc->result = (DID_OK << 16) | scsi_status;
0809             dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT
0810                 "RESIDUAL_MISMATCH: result=%x on channel=%d id=%d\n",
0811                 ioc->name, sc->result, sc->device->channel, sc->device->id));
0812             break;
0813 
0814         case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN:      /* 0x0045 */
0815             /*
0816              *  Do upfront check for valid SenseData and give it
0817              *  precedence!
0818              */
0819             sc->result = (DID_OK << 16) | scsi_status;
0820             if (!(scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)) {
0821 
0822                 /*
0823                  * For an Errata on LSI53C1030
0824                  * When the length of request data
0825                  * and transfer data are different
0826                  * with result of command (READ or VERIFY),
0827                  * DID_SOFT_ERROR is set.
0828                  */
0829                 if (ioc->bus_type == SPI) {
0830                     if ((pScsiReq->CDB[0] == READ_6  && ((pScsiReq->CDB[1] & 0x02) == 0)) ||
0831                         pScsiReq->CDB[0] == READ_10 ||
0832                         pScsiReq->CDB[0] == READ_12 ||
0833                         (pScsiReq->CDB[0] == READ_16 &&
0834                         ((pScsiReq->CDB[1] & 0x02) == 0)) ||
0835                         pScsiReq->CDB[0] == VERIFY  ||
0836                         pScsiReq->CDB[0] == VERIFY_16) {
0837                         if (scsi_bufflen(sc) !=
0838                             xfer_cnt) {
0839                             sc->result =
0840                             DID_SOFT_ERROR << 16;
0841                             printk(KERN_WARNING "Errata"
0842                             "on LSI53C1030 occurred."
0843                             "sc->req_bufflen=0x%02x,"
0844                             "xfer_cnt=0x%02x\n",
0845                             scsi_bufflen(sc),
0846                             xfer_cnt);
0847                         }
0848                     }
0849                 }
0850 
0851                 if (xfer_cnt < sc->underflow) {
0852                     if (scsi_status == SAM_STAT_BUSY)
0853                         sc->result = SAM_STAT_BUSY;
0854                     else
0855                         sc->result = DID_SOFT_ERROR << 16;
0856                 }
0857                 if (scsi_state & (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)) {
0858                     /* What to do?
0859                     */
0860                     sc->result = DID_SOFT_ERROR << 16;
0861                 }
0862                 else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
0863                     /*  Not real sure here either...  */
0864                     sc->result = DID_RESET << 16;
0865                 }
0866             }
0867 
0868 
0869             dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT
0870                 "  sc->underflow={report ERR if < %02xh bytes xfer'd}\n",
0871                 ioc->name, sc->underflow));
0872             dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT
0873                 "  ActBytesXferd=%02xh\n", ioc->name, xfer_cnt));
0874 
0875             /* Report Queue Full
0876              */
0877             if (scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)
0878                 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
0879 
0880             break;
0881 
0882         case MPI_IOCSTATUS_SCSI_DATA_OVERRUN:       /* 0x0044 */
0883             scsi_set_resid(sc, 0);
0884             fallthrough;
0885         case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR:    /* 0x0040 */
0886         case MPI_IOCSTATUS_SUCCESS:         /* 0x0000 */
0887             sc->result = (DID_OK << 16) | scsi_status;
0888             if (scsi_state == 0) {
0889                 ;
0890             } else if (scsi_state &
0891                 MPI_SCSI_STATE_AUTOSENSE_VALID) {
0892 
0893                 /*
0894                  * For potential trouble on LSI53C1030.
0895                  * (date:2007.xx.)
0896                  * It is checked whether the length of
0897                  * request data is equal to
0898                  * the length of transfer and residual.
0899                  * MEDIUM_ERROR is set by incorrect data.
0900                  */
0901                 if ((ioc->bus_type == SPI) &&
0902                     (sc->sense_buffer[2] & 0x20)) {
0903                     u32  difftransfer;
0904                     difftransfer =
0905                     sc->sense_buffer[3] << 24 |
0906                     sc->sense_buffer[4] << 16 |
0907                     sc->sense_buffer[5] << 8 |
0908                     sc->sense_buffer[6];
0909                     if (((sc->sense_buffer[3] & 0x80) ==
0910                         0x80) && (scsi_bufflen(sc)
0911                         != xfer_cnt)) {
0912                         sc->sense_buffer[2] =
0913                             MEDIUM_ERROR;
0914                         sc->sense_buffer[12] = 0xff;
0915                         sc->sense_buffer[13] = 0xff;
0916                         printk(KERN_WARNING"Errata"
0917                         "on LSI53C1030 occurred."
0918                         "sc->req_bufflen=0x%02x,"
0919                         "xfer_cnt=0x%02x\n" ,
0920                         scsi_bufflen(sc),
0921                         xfer_cnt);
0922                     }
0923                     if (((sc->sense_buffer[3] & 0x80)
0924                         != 0x80) &&
0925                         (scsi_bufflen(sc) !=
0926                         xfer_cnt + difftransfer)) {
0927                         sc->sense_buffer[2] =
0928                             MEDIUM_ERROR;
0929                         sc->sense_buffer[12] = 0xff;
0930                         sc->sense_buffer[13] = 0xff;
0931                         printk(KERN_WARNING
0932                         "Errata on LSI53C1030 occurred"
0933                         "sc->req_bufflen=0x%02x,"
0934                         " xfer_cnt=0x%02x,"
0935                         "difftransfer=0x%02x\n",
0936                         scsi_bufflen(sc),
0937                         xfer_cnt,
0938                         difftransfer);
0939                     }
0940                 }
0941 
0942                 /*
0943                  * If running against circa 200003dd 909 MPT f/w,
0944                  * may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL
0945                  * (QUEUE_FULL) returned from device! --> get 0x0000?128
0946                  * and with SenseBytes set to 0.
0947                  */
0948                 if (pScsiReply->SCSIStatus == MPI_SCSI_STATUS_TASK_SET_FULL)
0949                     mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
0950 
0951             }
0952             else if (scsi_state &
0953                      (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)
0954                ) {
0955                 /*
0956                  * What to do?
0957                  */
0958                 sc->result = DID_SOFT_ERROR << 16;
0959             }
0960             else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
0961                 /*  Not real sure here either...  */
0962                 sc->result = DID_RESET << 16;
0963             }
0964             else if (scsi_state & MPI_SCSI_STATE_QUEUE_TAG_REJECTED) {
0965                 /* Device Inq. data indicates that it supports
0966                  * QTags, but rejects QTag messages.
0967                  * This command completed OK.
0968                  *
0969                  * Not real sure here either so do nothing...  */
0970             }
0971 
0972             if (sc->result == MPI_SCSI_STATUS_TASK_SET_FULL)
0973                 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
0974 
0975             /* Add handling of:
0976              * Reservation Conflict, Busy,
0977              * Command Terminated, CHECK
0978              */
0979             break;
0980 
0981         case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR:     /* 0x0047 */
0982             sc->result = DID_SOFT_ERROR << 16;
0983             break;
0984 
0985         case MPI_IOCSTATUS_INVALID_FUNCTION:        /* 0x0001 */
0986         case MPI_IOCSTATUS_INVALID_SGL:         /* 0x0003 */
0987         case MPI_IOCSTATUS_INTERNAL_ERROR:      /* 0x0004 */
0988         case MPI_IOCSTATUS_RESERVED:            /* 0x0005 */
0989         case MPI_IOCSTATUS_INVALID_FIELD:       /* 0x0007 */
0990         case MPI_IOCSTATUS_INVALID_STATE:       /* 0x0008 */
0991         case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR:      /* 0x0046 */
0992         case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED:   /* 0x004A */
0993         default:
0994             /*
0995              * What to do?
0996              */
0997             sc->result = DID_SOFT_ERROR << 16;
0998             break;
0999 
1000         }   /* switch(status) */
1001 
1002 #ifdef CONFIG_FUSION_LOGGING
1003         if (sc->result && (ioc->debug_level & MPT_DEBUG_REPLY))
1004             mptscsih_info_scsiio(ioc, sc, pScsiReply);
1005 #endif
1006 
1007     } /* end of address reply case */
1008 out:
1009     /* Unmap the DMA buffers, if any. */
1010     scsi_dma_unmap(sc);
1011 
1012     scsi_done(sc);          /* Issue the command callback */
1013 
1014     /* Free Chain buffers */
1015     mptscsih_freeChainBuffers(ioc, req_idx);
1016     return 1;
1017 }
1018 
1019 /*
1020  *  mptscsih_flush_running_cmds - For each command found, search
1021  *      Scsi_Host instance taskQ and reply to OS.
1022  *      Called only if recovering from a FW reload.
1023  *  @hd: Pointer to a SCSI HOST structure
1024  *
1025  *  Returns: None.
1026  *
1027  *  Must be called while new I/Os are being queued.
1028  */
1029 void
1030 mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
1031 {
1032     MPT_ADAPTER *ioc = hd->ioc;
1033     struct scsi_cmnd *sc;
1034     SCSIIORequest_t *mf = NULL;
1035     int      ii;
1036     int      channel, id;
1037 
1038     for (ii= 0; ii < ioc->req_depth; ii++) {
1039         sc = mptscsih_getclear_scsi_lookup(ioc, ii);
1040         if (!sc)
1041             continue;
1042         mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(ioc, ii);
1043         if (!mf)
1044             continue;
1045         channel = mf->Bus;
1046         id = mf->TargetID;
1047         mptscsih_freeChainBuffers(ioc, ii);
1048         mpt_free_msg_frame(ioc, (MPT_FRAME_HDR *)mf);
1049         if ((unsigned char *)mf != sc->host_scribble)
1050             continue;
1051         scsi_dma_unmap(sc);
1052         sc->result = DID_RESET << 16;
1053         sc->host_scribble = NULL;
1054         dtmprintk(ioc, sdev_printk(KERN_INFO, sc->device, MYIOC_s_FMT
1055             "completing cmds: fw_channel %d, fw_id %d, sc=%p, mf = %p, "
1056             "idx=%x\n", ioc->name, channel, id, sc, mf, ii));
1057         scsi_done(sc);
1058     }
1059 }
1060 EXPORT_SYMBOL(mptscsih_flush_running_cmds);
1061 
1062 /*
1063  *  mptscsih_search_running_cmds - Delete any commands associated
1064  *      with the specified target and lun. Function called only
1065  *      when a lun is disable by mid-layer.
1066  *      Do NOT access the referenced scsi_cmnd structure or
1067  *      members. Will cause either a paging or NULL ptr error.
1068  *      (BUT, BUT, BUT, the code does reference it! - mdr)
1069  *      @hd: Pointer to a SCSI HOST structure
1070  *  @vdevice: per device private data
1071  *
1072  *  Returns: None.
1073  *
1074  *  Called from slave_destroy.
1075  */
1076 static void
1077 mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
1078 {
1079     SCSIIORequest_t *mf = NULL;
1080     int      ii;
1081     struct scsi_cmnd *sc;
1082     struct scsi_lun  lun;
1083     MPT_ADAPTER *ioc = hd->ioc;
1084     unsigned long   flags;
1085 
1086     spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
1087     for (ii = 0; ii < ioc->req_depth; ii++) {
1088         if ((sc = ioc->ScsiLookup[ii]) != NULL) {
1089 
1090             mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(ioc, ii);
1091             if (mf == NULL)
1092                 continue;
1093             /* If the device is a hidden raid component, then its
1094              * expected that the mf->function will be RAID_SCSI_IO
1095              */
1096             if (vdevice->vtarget->tflags &
1097                 MPT_TARGET_FLAGS_RAID_COMPONENT && mf->Function !=
1098                 MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)
1099                 continue;
1100 
1101             int_to_scsilun(vdevice->lun, &lun);
1102             if ((mf->Bus != vdevice->vtarget->channel) ||
1103                 (mf->TargetID != vdevice->vtarget->id) ||
1104                 memcmp(lun.scsi_lun, mf->LUN, 8))
1105                 continue;
1106 
1107             if ((unsigned char *)mf != sc->host_scribble)
1108                 continue;
1109             ioc->ScsiLookup[ii] = NULL;
1110             spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
1111             mptscsih_freeChainBuffers(ioc, ii);
1112             mpt_free_msg_frame(ioc, (MPT_FRAME_HDR *)mf);
1113             scsi_dma_unmap(sc);
1114             sc->host_scribble = NULL;
1115             sc->result = DID_NO_CONNECT << 16;
1116             dtmprintk(ioc, sdev_printk(KERN_INFO, sc->device,
1117                MYIOC_s_FMT "completing cmds: fw_channel %d, "
1118                "fw_id %d, sc=%p, mf = %p, idx=%x\n", ioc->name,
1119                vdevice->vtarget->channel, vdevice->vtarget->id,
1120                sc, mf, ii));
1121             scsi_done(sc);
1122             spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
1123         }
1124     }
1125     spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
1126     return;
1127 }
1128 
1129 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1130 
1131 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1132 /*
1133  *  mptscsih_report_queue_full - Report QUEUE_FULL status returned
1134  *  from a SCSI target device.
1135  *  @sc: Pointer to scsi_cmnd structure
1136  *  @pScsiReply: Pointer to SCSIIOReply_t
1137  *  @pScsiReq: Pointer to original SCSI request
1138  *
1139  *  This routine periodically reports QUEUE_FULL status returned from a
1140  *  SCSI target device.  It reports this to the console via kernel
1141  *  printk() API call, not more than once every 10 seconds.
1142  */
1143 static void
1144 mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq)
1145 {
1146     long time = jiffies;
1147     MPT_SCSI_HOST       *hd;
1148     MPT_ADAPTER *ioc;
1149 
1150     if (sc->device == NULL)
1151         return;
1152     if (sc->device->host == NULL)
1153         return;
1154     if ((hd = shost_priv(sc->device->host)) == NULL)
1155         return;
1156     ioc = hd->ioc;
1157     if (time - hd->last_queue_full > 10 * HZ) {
1158         dprintk(ioc, printk(MYIOC_s_WARN_FMT "Device (%d:%d:%llu) reported QUEUE_FULL!\n",
1159                 ioc->name, 0, sc->device->id, sc->device->lun));
1160         hd->last_queue_full = time;
1161     }
1162 }
1163 
1164 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1165 /*
1166  *  mptscsih_remove - Removed scsi devices
1167  *  @pdev: Pointer to pci_dev structure
1168  *
1169  *
1170  */
1171 void
1172 mptscsih_remove(struct pci_dev *pdev)
1173 {
1174     MPT_ADAPTER         *ioc = pci_get_drvdata(pdev);
1175     struct Scsi_Host    *host = ioc->sh;
1176     MPT_SCSI_HOST       *hd;
1177     int sz1;
1178 
1179     if (host == NULL)
1180         hd = NULL;
1181     else
1182         hd = shost_priv(host);
1183 
1184     mptscsih_shutdown(pdev);
1185 
1186     sz1=0;
1187 
1188     if (ioc->ScsiLookup != NULL) {
1189         sz1 = ioc->req_depth * sizeof(void *);
1190         kfree(ioc->ScsiLookup);
1191         ioc->ScsiLookup = NULL;
1192     }
1193 
1194     dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1195         "Free'd ScsiLookup (%d) memory\n",
1196         ioc->name, sz1));
1197 
1198     if (hd)
1199         kfree(hd->info_kbuf);
1200 
1201     /* NULL the Scsi_Host pointer
1202      */
1203     ioc->sh = NULL;
1204 
1205     if (host)
1206         scsi_host_put(host);
1207     mpt_detach(pdev);
1208 
1209 }
1210 
1211 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1212 /*
1213  *  mptscsih_shutdown - reboot notifier
1214  *
1215  */
1216 void
1217 mptscsih_shutdown(struct pci_dev *pdev)
1218 {
1219 }
1220 
1221 #ifdef CONFIG_PM
1222 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1223 /*
1224  *  mptscsih_suspend - Fusion MPT scsi driver suspend routine.
1225  *
1226  *
1227  */
1228 int
1229 mptscsih_suspend(struct pci_dev *pdev, pm_message_t state)
1230 {
1231     MPT_ADAPTER         *ioc = pci_get_drvdata(pdev);
1232 
1233     scsi_block_requests(ioc->sh);
1234     flush_scheduled_work();
1235     mptscsih_shutdown(pdev);
1236     return mpt_suspend(pdev,state);
1237 }
1238 
1239 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1240 /*
1241  *  mptscsih_resume - Fusion MPT scsi driver resume routine.
1242  *
1243  *
1244  */
1245 int
1246 mptscsih_resume(struct pci_dev *pdev)
1247 {
1248     MPT_ADAPTER         *ioc = pci_get_drvdata(pdev);
1249     int rc;
1250 
1251     rc = mpt_resume(pdev);
1252     scsi_unblock_requests(ioc->sh);
1253     return rc;
1254 }
1255 
1256 #endif
1257 
1258 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1259 /**
1260  *  mptscsih_info - Return information about MPT adapter
1261  *  @SChost: Pointer to Scsi_Host structure
1262  *
1263  *  (linux scsi_host_template.info routine)
1264  *
1265  *  Returns pointer to buffer where information was written.
1266  */
1267 const char *
1268 mptscsih_info(struct Scsi_Host *SChost)
1269 {
1270     MPT_SCSI_HOST *h;
1271     int size = 0;
1272 
1273     h = shost_priv(SChost);
1274 
1275     if (h->info_kbuf == NULL)
1276         if ((h->info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)
1277             return h->info_kbuf;
1278     h->info_kbuf[0] = '\0';
1279 
1280     mpt_print_ioc_summary(h->ioc, h->info_kbuf, &size, 0, 0);
1281     h->info_kbuf[size-1] = '\0';
1282 
1283     return h->info_kbuf;
1284 }
1285 
1286 int mptscsih_show_info(struct seq_file *m, struct Scsi_Host *host)
1287 {
1288     MPT_SCSI_HOST   *hd = shost_priv(host);
1289     MPT_ADAPTER *ioc = hd->ioc;
1290 
1291     seq_printf(m, "%s: %s, ", ioc->name, ioc->prod_name);
1292     seq_printf(m, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING, ioc->facts.FWVersion.Word);
1293     seq_printf(m, "Ports=%d, ", ioc->facts.NumberOfPorts);
1294     seq_printf(m, "MaxQ=%d\n", ioc->req_depth);
1295 
1296     return 0;
1297 }
1298 
1299 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1300 #define ADD_INDEX_LOG(req_ent)  do { } while(0)
1301 
1302 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1303 /**
1304  *  mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine.
1305  *  @SCpnt: Pointer to scsi_cmnd structure
1306  *
1307  *  (linux scsi_host_template.queuecommand routine)
1308  *  This is the primary SCSI IO start routine.  Create a MPI SCSIIORequest
1309  *  from a linux scsi_cmnd request and send it to the IOC.
1310  *
1311  *  Returns 0. (rtn value discarded by linux scsi mid-layer)
1312  */
1313 int
1314 mptscsih_qcmd(struct scsi_cmnd *SCpnt)
1315 {
1316     MPT_SCSI_HOST       *hd;
1317     MPT_FRAME_HDR       *mf;
1318     SCSIIORequest_t     *pScsiReq;
1319     VirtDevice      *vdevice = SCpnt->device->hostdata;
1320     u32  datalen;
1321     u32  scsictl;
1322     u32  scsidir;
1323     u32  cmd_len;
1324     int  my_idx;
1325     int  ii;
1326     MPT_ADAPTER *ioc;
1327 
1328     hd = shost_priv(SCpnt->device->host);
1329     ioc = hd->ioc;
1330 
1331     dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "qcmd: SCpnt=%p\n",
1332         ioc->name, SCpnt));
1333 
1334     if (ioc->taskmgmt_quiesce_io)
1335         return SCSI_MLQUEUE_HOST_BUSY;
1336 
1337     /*
1338      *  Put together a MPT SCSI request...
1339      */
1340     if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
1341         dprintk(ioc, printk(MYIOC_s_WARN_FMT "QueueCmd, no msg frames!!\n",
1342                 ioc->name));
1343         return SCSI_MLQUEUE_HOST_BUSY;
1344     }
1345 
1346     pScsiReq = (SCSIIORequest_t *) mf;
1347 
1348     my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
1349 
1350     ADD_INDEX_LOG(my_idx);
1351 
1352     /*    TUR's being issued with scsictl=0x02000000 (DATA_IN)!
1353      *    Seems we may receive a buffer (datalen>0) even when there
1354      *    will be no data transfer!  GRRRRR...
1355      */
1356     if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
1357         datalen = scsi_bufflen(SCpnt);
1358         scsidir = MPI_SCSIIO_CONTROL_READ;  /* DATA IN  (host<--ioc<--dev) */
1359     } else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
1360         datalen = scsi_bufflen(SCpnt);
1361         scsidir = MPI_SCSIIO_CONTROL_WRITE; /* DATA OUT (host-->ioc-->dev) */
1362     } else {
1363         datalen = 0;
1364         scsidir = MPI_SCSIIO_CONTROL_NODATATRANSFER;
1365     }
1366 
1367     /* Default to untagged. Once a target structure has been allocated,
1368      * use the Inquiry data to determine if device supports tagged.
1369      */
1370     if ((vdevice->vtarget->tflags & MPT_TARGET_FLAGS_Q_YES) &&
1371         SCpnt->device->tagged_supported)
1372         scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
1373     else
1374         scsictl = scsidir | MPI_SCSIIO_CONTROL_UNTAGGED;
1375 
1376 
1377     /* Use the above information to set up the message frame
1378      */
1379     pScsiReq->TargetID = (u8) vdevice->vtarget->id;
1380     pScsiReq->Bus = vdevice->vtarget->channel;
1381     pScsiReq->ChainOffset = 0;
1382     if (vdevice->vtarget->tflags &  MPT_TARGET_FLAGS_RAID_COMPONENT)
1383         pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
1384     else
1385         pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
1386     pScsiReq->CDBLength = SCpnt->cmd_len;
1387     pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
1388     pScsiReq->Reserved = 0;
1389     pScsiReq->MsgFlags = mpt_msg_flags(ioc);
1390     int_to_scsilun(SCpnt->device->lun, (struct scsi_lun *)pScsiReq->LUN);
1391     pScsiReq->Control = cpu_to_le32(scsictl);
1392 
1393     /*
1394      *  Write SCSI CDB into the message
1395      */
1396     cmd_len = SCpnt->cmd_len;
1397     for (ii=0; ii < cmd_len; ii++)
1398         pScsiReq->CDB[ii] = SCpnt->cmnd[ii];
1399 
1400     for (ii=cmd_len; ii < 16; ii++)
1401         pScsiReq->CDB[ii] = 0;
1402 
1403     /* DataLength */
1404     pScsiReq->DataLength = cpu_to_le32(datalen);
1405 
1406     /* SenseBuffer low address */
1407     pScsiReq->SenseBufferLowAddr = cpu_to_le32(ioc->sense_buf_low_dma
1408                        + (my_idx * MPT_SENSE_BUFFER_ALLOC));
1409 
1410     /* Now add the SG list
1411      * Always have a SGE even if null length.
1412      */
1413     if (datalen == 0) {
1414         /* Add a NULL SGE */
1415         ioc->add_sge((char *)&pScsiReq->SGL,
1416             MPT_SGE_FLAGS_SSIMPLE_READ | 0,
1417             (dma_addr_t) -1);
1418     } else {
1419         /* Add a 32 or 64 bit SGE */
1420         if (mptscsih_AddSGE(ioc, SCpnt, pScsiReq, my_idx) != SUCCESS)
1421             goto fail;
1422     }
1423 
1424     SCpnt->host_scribble = (unsigned char *)mf;
1425     mptscsih_set_scsi_lookup(ioc, my_idx, SCpnt);
1426 
1427     mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
1428     dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n",
1429             ioc->name, SCpnt, mf, my_idx));
1430     DBG_DUMP_REQUEST_FRAME(ioc, (u32 *)mf);
1431     return 0;
1432 
1433  fail:
1434     mptscsih_freeChainBuffers(ioc, my_idx);
1435     mpt_free_msg_frame(ioc, mf);
1436     return SCSI_MLQUEUE_HOST_BUSY;
1437 }
1438 
1439 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1440 /*
1441  *  mptscsih_freeChainBuffers - Function to free chain buffers associated
1442  *  with a SCSI IO request
1443  *  @hd: Pointer to the MPT_SCSI_HOST instance
1444  *  @req_idx: Index of the SCSI IO request frame.
1445  *
1446  *  Called if SG chain buffer allocation fails and mptscsih callbacks.
1447  *  No return.
1448  */
1449 static void
1450 mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
1451 {
1452     MPT_FRAME_HDR *chain;
1453     unsigned long flags;
1454     int chain_idx;
1455     int next;
1456 
1457     /* Get the first chain index and reset
1458      * tracker state.
1459      */
1460     chain_idx = ioc->ReqToChain[req_idx];
1461     ioc->ReqToChain[req_idx] = MPT_HOST_NO_CHAIN;
1462 
1463     while (chain_idx != MPT_HOST_NO_CHAIN) {
1464 
1465         /* Save the next chain buffer index */
1466         next = ioc->ChainToChain[chain_idx];
1467 
1468         /* Free this chain buffer and reset
1469          * tracker
1470          */
1471         ioc->ChainToChain[chain_idx] = MPT_HOST_NO_CHAIN;
1472 
1473         chain = (MPT_FRAME_HDR *) (ioc->ChainBuffer
1474                     + (chain_idx * ioc->req_sz));
1475 
1476         spin_lock_irqsave(&ioc->FreeQlock, flags);
1477         list_add_tail(&chain->u.frame.linkage.list, &ioc->FreeChainQ);
1478         spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1479 
1480         dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FreeChainBuffers (index %d)\n",
1481                 ioc->name, chain_idx));
1482 
1483         /* handle next */
1484         chain_idx = next;
1485     }
1486     return;
1487 }
1488 
1489 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1490 /*
1491  *  Reset Handling
1492  */
1493 
1494 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1495 /**
1496  *  mptscsih_IssueTaskMgmt - Generic send Task Management function.
1497  *  @hd: Pointer to MPT_SCSI_HOST structure
1498  *  @type: Task Management type
1499  *  @channel: channel number for task management
1500  *  @id: Logical Target ID for reset (if appropriate)
1501  *  @lun: Logical Unit for reset (if appropriate)
1502  *  @ctx2abort: Context for the task to be aborted (if appropriate)
1503  *  @timeout: timeout for task management control
1504  *
1505  *  Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
1506  *  or a non-interrupt thread.  In the former, must not call schedule().
1507  *
1508  *  Not all fields are meaningfull for all task types.
1509  *
1510  *  Returns 0 for SUCCESS, or FAILED.
1511  *
1512  **/
1513 int
1514 mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, u64 lun,
1515     int ctx2abort, ulong timeout)
1516 {
1517     MPT_FRAME_HDR   *mf;
1518     SCSITaskMgmt_t  *pScsiTm;
1519     int      ii;
1520     int      retval;
1521     MPT_ADAPTER     *ioc = hd->ioc;
1522     u8       issue_hard_reset;
1523     u32      ioc_raw_state;
1524     unsigned long    time_count;
1525 
1526     issue_hard_reset = 0;
1527     ioc_raw_state = mpt_GetIocState(ioc, 0);
1528 
1529     if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) {
1530         printk(MYIOC_s_WARN_FMT
1531             "TaskMgmt type=%x: IOC Not operational (0x%x)!\n",
1532             ioc->name, type, ioc_raw_state);
1533         printk(MYIOC_s_WARN_FMT "Issuing HardReset from %s!!\n",
1534             ioc->name, __func__);
1535         if (mpt_HardResetHandler(ioc, CAN_SLEEP) < 0)
1536             printk(MYIOC_s_WARN_FMT "TaskMgmt HardReset "
1537                 "FAILED!!\n", ioc->name);
1538         return 0;
1539     }
1540 
1541     /* DOORBELL ACTIVE check is not required if
1542     *  MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q is supported.
1543     */
1544 
1545     if (!((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q)
1546          && (ioc->facts.MsgVersion >= MPI_VERSION_01_05)) &&
1547         (ioc_raw_state & MPI_DOORBELL_ACTIVE)) {
1548         printk(MYIOC_s_WARN_FMT
1549             "TaskMgmt type=%x: ioc_state: "
1550             "DOORBELL_ACTIVE (0x%x)!\n",
1551             ioc->name, type, ioc_raw_state);
1552         return FAILED;
1553     }
1554 
1555     mutex_lock(&ioc->taskmgmt_cmds.mutex);
1556     if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0) {
1557         mf = NULL;
1558         retval = FAILED;
1559         goto out;
1560     }
1561 
1562     /* Return Fail to calling function if no message frames available.
1563      */
1564     if ((mf = mpt_get_msg_frame(ioc->TaskCtx, ioc)) == NULL) {
1565         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1566             "TaskMgmt no msg frames!!\n", ioc->name));
1567         retval = FAILED;
1568         mpt_clear_taskmgmt_in_progress_flag(ioc);
1569         goto out;
1570     }
1571     dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt request (mf=%p)\n",
1572             ioc->name, mf));
1573 
1574     /* Format the Request
1575      */
1576     pScsiTm = (SCSITaskMgmt_t *) mf;
1577     pScsiTm->TargetID = id;
1578     pScsiTm->Bus = channel;
1579     pScsiTm->ChainOffset = 0;
1580     pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
1581 
1582     pScsiTm->Reserved = 0;
1583     pScsiTm->TaskType = type;
1584     pScsiTm->Reserved1 = 0;
1585     pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)
1586                     ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0;
1587 
1588     int_to_scsilun(lun, (struct scsi_lun *)pScsiTm->LUN);
1589 
1590     for (ii=0; ii < 7; ii++)
1591         pScsiTm->Reserved2[ii] = 0;
1592 
1593     pScsiTm->TaskMsgContext = ctx2abort;
1594 
1595     dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt: ctx2abort (0x%08x) "
1596         "task_type = 0x%02X, timeout = %ld\n", ioc->name, ctx2abort,
1597         type, timeout));
1598 
1599     DBG_DUMP_TM_REQUEST_FRAME(ioc, (u32 *)pScsiTm);
1600 
1601     INITIALIZE_MGMT_STATUS(ioc->taskmgmt_cmds.status)
1602     time_count = jiffies;
1603     if ((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q) &&
1604         (ioc->facts.MsgVersion >= MPI_VERSION_01_05))
1605         mpt_put_msg_frame_hi_pri(ioc->TaskCtx, ioc, mf);
1606     else {
1607         retval = mpt_send_handshake_request(ioc->TaskCtx, ioc,
1608             sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, CAN_SLEEP);
1609         if (retval) {
1610             dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1611                 "TaskMgmt handshake FAILED!(mf=%p, rc=%d) \n",
1612                 ioc->name, mf, retval));
1613             mpt_free_msg_frame(ioc, mf);
1614             mpt_clear_taskmgmt_in_progress_flag(ioc);
1615             goto out;
1616         }
1617     }
1618 
1619     wait_for_completion_timeout(&ioc->taskmgmt_cmds.done,
1620         timeout*HZ);
1621     if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
1622         retval = FAILED;
1623         dtmprintk(ioc, printk(MYIOC_s_ERR_FMT
1624             "TaskMgmt TIMED OUT!(mf=%p)\n", ioc->name, mf));
1625         mpt_clear_taskmgmt_in_progress_flag(ioc);
1626         if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
1627             goto out;
1628         issue_hard_reset = 1;
1629         goto out;
1630     }
1631 
1632     retval = mptscsih_taskmgmt_reply(ioc, type,
1633         (SCSITaskMgmtReply_t *) ioc->taskmgmt_cmds.reply);
1634 
1635     dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1636         "TaskMgmt completed (%d seconds)\n",
1637         ioc->name, jiffies_to_msecs(jiffies - time_count)/1000));
1638 
1639  out:
1640 
1641     CLEAR_MGMT_STATUS(ioc->taskmgmt_cmds.status)
1642     if (issue_hard_reset) {
1643         printk(MYIOC_s_WARN_FMT
1644                "Issuing Reset from %s!! doorbell=0x%08x\n",
1645                ioc->name, __func__, mpt_GetIocState(ioc, 0));
1646         retval = (ioc->bus_type == SAS) ?
1647             mpt_HardResetHandler(ioc, CAN_SLEEP) :
1648             mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
1649         mpt_free_msg_frame(ioc, mf);
1650     }
1651 
1652     retval = (retval == 0) ? 0 : FAILED;
1653     mutex_unlock(&ioc->taskmgmt_cmds.mutex);
1654     return retval;
1655 }
1656 EXPORT_SYMBOL(mptscsih_IssueTaskMgmt);
1657 
1658 static int
1659 mptscsih_get_tm_timeout(MPT_ADAPTER *ioc)
1660 {
1661     switch (ioc->bus_type) {
1662     case FC:
1663         return 40;
1664     case SAS:
1665         return 30;
1666     case SPI:
1667     default:
1668         return 10;
1669     }
1670 }
1671 
1672 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1673 /**
1674  *  mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant
1675  *  @SCpnt: Pointer to scsi_cmnd structure, IO to be aborted
1676  *
1677  *  (linux scsi_host_template.eh_abort_handler routine)
1678  *
1679  *  Returns SUCCESS or FAILED.
1680  **/
1681 int
1682 mptscsih_abort(struct scsi_cmnd * SCpnt)
1683 {
1684     MPT_SCSI_HOST   *hd;
1685     MPT_FRAME_HDR   *mf;
1686     u32      ctx2abort;
1687     int      scpnt_idx;
1688     int      retval;
1689     VirtDevice   *vdevice;
1690     MPT_ADAPTER *ioc;
1691 
1692     /* If we can't locate our host adapter structure, return FAILED status.
1693      */
1694     if ((hd = shost_priv(SCpnt->device->host)) == NULL) {
1695         SCpnt->result = DID_RESET << 16;
1696         scsi_done(SCpnt);
1697         printk(KERN_ERR MYNAM ": task abort: "
1698             "can't locate host! (sc=%p)\n", SCpnt);
1699         return FAILED;
1700     }
1701 
1702     ioc = hd->ioc;
1703     printk(MYIOC_s_INFO_FMT "attempting task abort! (sc=%p)\n",
1704            ioc->name, SCpnt);
1705     scsi_print_command(SCpnt);
1706 
1707     vdevice = SCpnt->device->hostdata;
1708     if (!vdevice || !vdevice->vtarget) {
1709         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1710             "task abort: device has been deleted (sc=%p)\n",
1711             ioc->name, SCpnt));
1712         SCpnt->result = DID_NO_CONNECT << 16;
1713         scsi_done(SCpnt);
1714         retval = SUCCESS;
1715         goto out;
1716     }
1717 
1718     /* Task aborts are not supported for hidden raid components.
1719      */
1720     if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
1721         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1722             "task abort: hidden raid component (sc=%p)\n",
1723             ioc->name, SCpnt));
1724         SCpnt->result = DID_RESET << 16;
1725         retval = FAILED;
1726         goto out;
1727     }
1728 
1729     /* Task aborts are not supported for volumes.
1730      */
1731     if (vdevice->vtarget->raidVolume) {
1732         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1733             "task abort: raid volume (sc=%p)\n",
1734             ioc->name, SCpnt));
1735         SCpnt->result = DID_RESET << 16;
1736         retval = FAILED;
1737         goto out;
1738     }
1739 
1740     /* Find this command
1741      */
1742     if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(ioc, SCpnt)) < 0) {
1743         /* Cmd not found in ScsiLookup.
1744          * Do OS callback.
1745          */
1746         SCpnt->result = DID_RESET << 16;
1747         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "task abort: "
1748            "Command not in the active list! (sc=%p)\n", ioc->name,
1749            SCpnt));
1750         retval = SUCCESS;
1751         goto out;
1752     }
1753 
1754     if (ioc->timeouts < -1)
1755         ioc->timeouts++;
1756 
1757     if (mpt_fwfault_debug)
1758         mpt_halt_firmware(ioc);
1759 
1760     /* Most important!  Set TaskMsgContext to SCpnt's MsgContext!
1761      * (the IO to be ABORT'd)
1762      *
1763      * NOTE: Since we do not byteswap MsgContext, we do not
1764      *   swap it here either.  It is an opaque cookie to
1765      *   the controller, so it does not matter. -DaveM
1766      */
1767     mf = MPT_INDEX_2_MFPTR(ioc, scpnt_idx);
1768     ctx2abort = mf->u.frame.hwhdr.msgctxu.MsgContext;
1769     retval = mptscsih_IssueTaskMgmt(hd,
1770              MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
1771              vdevice->vtarget->channel,
1772              vdevice->vtarget->id, vdevice->lun,
1773              ctx2abort, mptscsih_get_tm_timeout(ioc));
1774 
1775     if (SCPNT_TO_LOOKUP_IDX(ioc, SCpnt) == scpnt_idx) {
1776         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1777             "task abort: command still in active list! (sc=%p)\n",
1778             ioc->name, SCpnt));
1779         retval = FAILED;
1780     } else {
1781         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1782             "task abort: command cleared from active list! (sc=%p)\n",
1783             ioc->name, SCpnt));
1784         retval = SUCCESS;
1785     }
1786 
1787  out:
1788     printk(MYIOC_s_INFO_FMT "task abort: %s (rv=%04x) (sc=%p)\n",
1789         ioc->name, ((retval == SUCCESS) ? "SUCCESS" : "FAILED"), retval,
1790         SCpnt);
1791 
1792     return retval;
1793 }
1794 
1795 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1796 /**
1797  *  mptscsih_dev_reset - Perform a SCSI TARGET_RESET!  new_eh variant
1798  *  @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1799  *
1800  *  (linux scsi_host_template.eh_dev_reset_handler routine)
1801  *
1802  *  Returns SUCCESS or FAILED.
1803  **/
1804 int
1805 mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
1806 {
1807     MPT_SCSI_HOST   *hd;
1808     int      retval;
1809     VirtDevice   *vdevice;
1810     MPT_ADAPTER *ioc;
1811 
1812     /* If we can't locate our host adapter structure, return FAILED status.
1813      */
1814     if ((hd = shost_priv(SCpnt->device->host)) == NULL){
1815         printk(KERN_ERR MYNAM ": target reset: "
1816            "Can't locate host! (sc=%p)\n", SCpnt);
1817         return FAILED;
1818     }
1819 
1820     ioc = hd->ioc;
1821     printk(MYIOC_s_INFO_FMT "attempting target reset! (sc=%p)\n",
1822            ioc->name, SCpnt);
1823     scsi_print_command(SCpnt);
1824 
1825     vdevice = SCpnt->device->hostdata;
1826     if (!vdevice || !vdevice->vtarget) {
1827         retval = 0;
1828         goto out;
1829     }
1830 
1831     /* Target reset to hidden raid component is not supported
1832      */
1833     if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
1834         retval = FAILED;
1835         goto out;
1836     }
1837 
1838     retval = mptscsih_IssueTaskMgmt(hd,
1839                 MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
1840                 vdevice->vtarget->channel,
1841                 vdevice->vtarget->id, 0, 0,
1842                 mptscsih_get_tm_timeout(ioc));
1843 
1844  out:
1845     printk (MYIOC_s_INFO_FMT "target reset: %s (sc=%p)\n",
1846         ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1847 
1848     if (retval == 0)
1849         return SUCCESS;
1850     else
1851         return FAILED;
1852 }
1853 
1854 
1855 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1856 /**
1857  *  mptscsih_bus_reset - Perform a SCSI BUS_RESET!  new_eh variant
1858  *  @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1859  *
1860  *  (linux scsi_host_template.eh_bus_reset_handler routine)
1861  *
1862  *  Returns SUCCESS or FAILED.
1863  **/
1864 int
1865 mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
1866 {
1867     MPT_SCSI_HOST   *hd;
1868     int      retval;
1869     VirtDevice   *vdevice;
1870     MPT_ADAPTER *ioc;
1871 
1872     /* If we can't locate our host adapter structure, return FAILED status.
1873      */
1874     if ((hd = shost_priv(SCpnt->device->host)) == NULL){
1875         printk(KERN_ERR MYNAM ": bus reset: "
1876            "Can't locate host! (sc=%p)\n", SCpnt);
1877         return FAILED;
1878     }
1879 
1880     ioc = hd->ioc;
1881     printk(MYIOC_s_INFO_FMT "attempting bus reset! (sc=%p)\n",
1882            ioc->name, SCpnt);
1883     scsi_print_command(SCpnt);
1884 
1885     if (ioc->timeouts < -1)
1886         ioc->timeouts++;
1887 
1888     vdevice = SCpnt->device->hostdata;
1889     if (!vdevice || !vdevice->vtarget)
1890         return SUCCESS;
1891     retval = mptscsih_IssueTaskMgmt(hd,
1892                     MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
1893                     vdevice->vtarget->channel, 0, 0, 0,
1894                     mptscsih_get_tm_timeout(ioc));
1895 
1896     printk(MYIOC_s_INFO_FMT "bus reset: %s (sc=%p)\n",
1897         ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1898 
1899     if (retval == 0)
1900         return SUCCESS;
1901     else
1902         return FAILED;
1903 }
1904 
1905 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1906 /**
1907  *  mptscsih_host_reset - Perform a SCSI host adapter RESET (new_eh variant)
1908  *  @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1909  *
1910  *  (linux scsi_host_template.eh_host_reset_handler routine)
1911  *
1912  *  Returns SUCCESS or FAILED.
1913  */
1914 int
1915 mptscsih_host_reset(struct scsi_cmnd *SCpnt)
1916 {
1917     MPT_SCSI_HOST *  hd;
1918     int              status = SUCCESS;
1919     MPT_ADAPTER *ioc;
1920     int     retval;
1921 
1922     /*  If we can't locate the host to reset, then we failed. */
1923     if ((hd = shost_priv(SCpnt->device->host)) == NULL){
1924         printk(KERN_ERR MYNAM ": host reset: "
1925             "Can't locate host! (sc=%p)\n", SCpnt);
1926         return FAILED;
1927     }
1928 
1929     /* make sure we have no outstanding commands at this stage */
1930     mptscsih_flush_running_cmds(hd);
1931 
1932     ioc = hd->ioc;
1933     printk(MYIOC_s_INFO_FMT "attempting host reset! (sc=%p)\n",
1934         ioc->name, SCpnt);
1935 
1936     /*  If our attempts to reset the host failed, then return a failed
1937      *  status.  The host will be taken off line by the SCSI mid-layer.
1938      */
1939     retval = mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
1940     if (retval < 0)
1941         status = FAILED;
1942     else
1943         status = SUCCESS;
1944 
1945     printk(MYIOC_s_INFO_FMT "host reset: %s (sc=%p)\n",
1946         ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1947 
1948     return status;
1949 }
1950 
1951 static int
1952 mptscsih_taskmgmt_reply(MPT_ADAPTER *ioc, u8 type,
1953     SCSITaskMgmtReply_t *pScsiTmReply)
1954 {
1955     u16          iocstatus;
1956     u32          termination_count;
1957     int          retval;
1958 
1959     if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
1960         retval = FAILED;
1961         goto out;
1962     }
1963 
1964     DBG_DUMP_TM_REPLY_FRAME(ioc, (u32 *)pScsiTmReply);
1965 
1966     iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
1967     termination_count = le32_to_cpu(pScsiTmReply->TerminationCount);
1968 
1969     dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1970         "TaskMgmt fw_channel = %d, fw_id = %d, task_type = 0x%02X,\n"
1971         "\tiocstatus = 0x%04X, loginfo = 0x%08X, response_code = 0x%02X,\n"
1972         "\tterm_cmnds = %d\n", ioc->name, pScsiTmReply->Bus,
1973         pScsiTmReply->TargetID, type, le16_to_cpu(pScsiTmReply->IOCStatus),
1974         le32_to_cpu(pScsiTmReply->IOCLogInfo), pScsiTmReply->ResponseCode,
1975         termination_count));
1976 
1977     if (ioc->facts.MsgVersion >= MPI_VERSION_01_05 &&
1978         pScsiTmReply->ResponseCode)
1979         mptscsih_taskmgmt_response_code(ioc,
1980             pScsiTmReply->ResponseCode);
1981 
1982     if (iocstatus == MPI_IOCSTATUS_SUCCESS) {
1983         retval = 0;
1984         goto out;
1985     }
1986 
1987     retval = FAILED;
1988     if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
1989         if (termination_count == 1)
1990             retval = 0;
1991         goto out;
1992     }
1993 
1994     if (iocstatus == MPI_IOCSTATUS_SCSI_TASK_TERMINATED ||
1995        iocstatus == MPI_IOCSTATUS_SCSI_IOC_TERMINATED)
1996         retval = 0;
1997 
1998  out:
1999     return retval;
2000 }
2001 
2002 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2003 void
2004 mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code)
2005 {
2006     char *desc;
2007 
2008     switch (response_code) {
2009     case MPI_SCSITASKMGMT_RSP_TM_COMPLETE:
2010         desc = "The task completed.";
2011         break;
2012     case MPI_SCSITASKMGMT_RSP_INVALID_FRAME:
2013         desc = "The IOC received an invalid frame status.";
2014         break;
2015     case MPI_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED:
2016         desc = "The task type is not supported.";
2017         break;
2018     case MPI_SCSITASKMGMT_RSP_TM_FAILED:
2019         desc = "The requested task failed.";
2020         break;
2021     case MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED:
2022         desc = "The task completed successfully.";
2023         break;
2024     case MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN:
2025         desc = "The LUN request is invalid.";
2026         break;
2027     case MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC:
2028         desc = "The task is in the IOC queue and has not been sent to target.";
2029         break;
2030     default:
2031         desc = "unknown";
2032         break;
2033     }
2034     printk(MYIOC_s_INFO_FMT "Response Code(0x%08x): F/W: %s\n",
2035         ioc->name, response_code, desc);
2036 }
2037 EXPORT_SYMBOL(mptscsih_taskmgmt_response_code);
2038 
2039 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2040 /**
2041  *  mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
2042  *  @ioc: Pointer to MPT_ADAPTER structure
2043  *  @mf: Pointer to SCSI task mgmt request frame
2044  *  @mr: Pointer to SCSI task mgmt reply frame
2045  *
2046  *  This routine is called from mptbase.c::mpt_interrupt() at the completion
2047  *  of any SCSI task management request.
2048  *  This routine is registered with the MPT (base) driver at driver
2049  *  load/init time via the mpt_register() API call.
2050  *
2051  *  Returns 1 indicating alloc'd request frame ptr should be freed.
2052  **/
2053 int
2054 mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf,
2055     MPT_FRAME_HDR *mr)
2056 {
2057     dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2058         "TaskMgmt completed (mf=%p, mr=%p)\n", ioc->name, mf, mr));
2059 
2060     ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
2061 
2062     if (!mr)
2063         goto out;
2064 
2065     ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
2066     memcpy(ioc->taskmgmt_cmds.reply, mr,
2067         min(MPT_DEFAULT_FRAME_SIZE, 4 * mr->u.reply.MsgLength));
2068  out:
2069     if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_PENDING) {
2070         mpt_clear_taskmgmt_in_progress_flag(ioc);
2071         ioc->taskmgmt_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
2072         complete(&ioc->taskmgmt_cmds.done);
2073         if (ioc->bus_type == SAS)
2074             ioc->schedule_target_reset(ioc);
2075         return 1;
2076     }
2077     return 0;
2078 }
2079 
2080 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2081 /*
2082  *  This is anyones guess quite frankly.
2083  */
2084 int
2085 mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
2086         sector_t capacity, int geom[])
2087 {
2088     int     heads;
2089     int     sectors;
2090     sector_t    cylinders;
2091     ulong       dummy;
2092 
2093     heads = 64;
2094     sectors = 32;
2095 
2096     dummy = heads * sectors;
2097     cylinders = capacity;
2098     sector_div(cylinders,dummy);
2099 
2100     /*
2101      * Handle extended translation size for logical drives
2102      * > 1Gb
2103      */
2104     if ((ulong)capacity >= 0x200000) {
2105         heads = 255;
2106         sectors = 63;
2107         dummy = heads * sectors;
2108         cylinders = capacity;
2109         sector_div(cylinders,dummy);
2110     }
2111 
2112     /* return result */
2113     geom[0] = heads;
2114     geom[1] = sectors;
2115     geom[2] = cylinders;
2116 
2117     return 0;
2118 }
2119 
2120 /* Search IOC page 3 to determine if this is hidden physical disk
2121  *
2122  */
2123 int
2124 mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id)
2125 {
2126     struct inactive_raid_component_info *component_info;
2127     int i, j;
2128     RaidPhysDiskPage1_t *phys_disk;
2129     int rc = 0;
2130     int num_paths;
2131 
2132     if (!ioc->raid_data.pIocPg3)
2133         goto out;
2134     for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2135         if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) &&
2136             (channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) {
2137             rc = 1;
2138             goto out;
2139         }
2140     }
2141 
2142     if (ioc->bus_type != SAS)
2143         goto out;
2144 
2145     /*
2146      * Check if dual path
2147      */
2148     for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2149         num_paths = mpt_raid_phys_disk_get_num_paths(ioc,
2150             ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum);
2151         if (num_paths < 2)
2152             continue;
2153         phys_disk = kzalloc(offsetof(RaidPhysDiskPage1_t, Path) +
2154            (num_paths * sizeof(RAID_PHYS_DISK1_PATH)), GFP_KERNEL);
2155         if (!phys_disk)
2156             continue;
2157         if ((mpt_raid_phys_disk_pg1(ioc,
2158             ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum,
2159             phys_disk))) {
2160             kfree(phys_disk);
2161             continue;
2162         }
2163         for (j = 0; j < num_paths; j++) {
2164             if ((phys_disk->Path[j].Flags &
2165                 MPI_RAID_PHYSDISK1_FLAG_INVALID))
2166                 continue;
2167             if ((phys_disk->Path[j].Flags &
2168                 MPI_RAID_PHYSDISK1_FLAG_BROKEN))
2169                 continue;
2170             if ((id == phys_disk->Path[j].PhysDiskID) &&
2171                 (channel == phys_disk->Path[j].PhysDiskBus)) {
2172                 rc = 1;
2173                 kfree(phys_disk);
2174                 goto out;
2175             }
2176         }
2177         kfree(phys_disk);
2178     }
2179 
2180 
2181     /*
2182      * Check inactive list for matching phys disks
2183      */
2184     if (list_empty(&ioc->raid_data.inactive_list))
2185         goto out;
2186 
2187     mutex_lock(&ioc->raid_data.inactive_list_mutex);
2188     list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
2189         list) {
2190         if ((component_info->d.PhysDiskID == id) &&
2191             (component_info->d.PhysDiskBus == channel))
2192             rc = 1;
2193     }
2194     mutex_unlock(&ioc->raid_data.inactive_list_mutex);
2195 
2196  out:
2197     return rc;
2198 }
2199 EXPORT_SYMBOL(mptscsih_is_phys_disk);
2200 
2201 u8
2202 mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id)
2203 {
2204     struct inactive_raid_component_info *component_info;
2205     int i, j;
2206     RaidPhysDiskPage1_t *phys_disk;
2207     int rc = -ENXIO;
2208     int num_paths;
2209 
2210     if (!ioc->raid_data.pIocPg3)
2211         goto out;
2212     for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2213         if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) &&
2214             (channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) {
2215             rc = ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum;
2216             goto out;
2217         }
2218     }
2219 
2220     if (ioc->bus_type != SAS)
2221         goto out;
2222 
2223     /*
2224      * Check if dual path
2225      */
2226     for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2227         num_paths = mpt_raid_phys_disk_get_num_paths(ioc,
2228             ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum);
2229         if (num_paths < 2)
2230             continue;
2231         phys_disk = kzalloc(offsetof(RaidPhysDiskPage1_t, Path) +
2232            (num_paths * sizeof(RAID_PHYS_DISK1_PATH)), GFP_KERNEL);
2233         if (!phys_disk)
2234             continue;
2235         if ((mpt_raid_phys_disk_pg1(ioc,
2236             ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum,
2237             phys_disk))) {
2238             kfree(phys_disk);
2239             continue;
2240         }
2241         for (j = 0; j < num_paths; j++) {
2242             if ((phys_disk->Path[j].Flags &
2243                 MPI_RAID_PHYSDISK1_FLAG_INVALID))
2244                 continue;
2245             if ((phys_disk->Path[j].Flags &
2246                 MPI_RAID_PHYSDISK1_FLAG_BROKEN))
2247                 continue;
2248             if ((id == phys_disk->Path[j].PhysDiskID) &&
2249                 (channel == phys_disk->Path[j].PhysDiskBus)) {
2250                 rc = phys_disk->PhysDiskNum;
2251                 kfree(phys_disk);
2252                 goto out;
2253             }
2254         }
2255         kfree(phys_disk);
2256     }
2257 
2258     /*
2259      * Check inactive list for matching phys disks
2260      */
2261     if (list_empty(&ioc->raid_data.inactive_list))
2262         goto out;
2263 
2264     mutex_lock(&ioc->raid_data.inactive_list_mutex);
2265     list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
2266         list) {
2267         if ((component_info->d.PhysDiskID == id) &&
2268             (component_info->d.PhysDiskBus == channel))
2269             rc = component_info->d.PhysDiskNum;
2270     }
2271     mutex_unlock(&ioc->raid_data.inactive_list_mutex);
2272 
2273  out:
2274     return rc;
2275 }
2276 EXPORT_SYMBOL(mptscsih_raid_id_to_num);
2277 
2278 /*
2279  *  OS entry point to allow for host driver to free allocated memory
2280  *  Called if no device present or device being unloaded
2281  */
2282 void
2283 mptscsih_slave_destroy(struct scsi_device *sdev)
2284 {
2285     struct Scsi_Host    *host = sdev->host;
2286     MPT_SCSI_HOST       *hd = shost_priv(host);
2287     VirtTarget      *vtarget;
2288     VirtDevice      *vdevice;
2289     struct scsi_target  *starget;
2290 
2291     starget = scsi_target(sdev);
2292     vtarget = starget->hostdata;
2293     vdevice = sdev->hostdata;
2294     if (!vdevice)
2295         return;
2296 
2297     mptscsih_search_running_cmds(hd, vdevice);
2298     vtarget->num_luns--;
2299     mptscsih_synchronize_cache(hd, vdevice);
2300     kfree(vdevice);
2301     sdev->hostdata = NULL;
2302 }
2303 
2304 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2305 /*
2306  *  mptscsih_change_queue_depth - This function will set a devices queue depth
2307  *  @sdev: per scsi_device pointer
2308  *  @qdepth: requested queue depth
2309  *
2310  *  Adding support for new 'change_queue_depth' api.
2311 */
2312 int
2313 mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
2314 {
2315     MPT_SCSI_HOST       *hd = shost_priv(sdev->host);
2316     VirtTarget      *vtarget;
2317     struct scsi_target  *starget;
2318     int         max_depth;
2319     MPT_ADAPTER     *ioc = hd->ioc;
2320 
2321     starget = scsi_target(sdev);
2322     vtarget = starget->hostdata;
2323 
2324     if (ioc->bus_type == SPI) {
2325         if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
2326             max_depth = 1;
2327         else if (sdev->type == TYPE_DISK &&
2328              vtarget->minSyncFactor <= MPT_ULTRA160)
2329             max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2330         else
2331             max_depth = MPT_SCSI_CMD_PER_DEV_LOW;
2332     } else
2333          max_depth = ioc->sh->can_queue;
2334 
2335     if (!sdev->tagged_supported)
2336         max_depth = 1;
2337 
2338     if (qdepth > max_depth)
2339         qdepth = max_depth;
2340 
2341     return scsi_change_queue_depth(sdev, qdepth);
2342 }
2343 
2344 /*
2345  *  OS entry point to adjust the queue_depths on a per-device basis.
2346  *  Called once per device the bus scan. Use it to force the queue_depth
2347  *  member to 1 if a device does not support Q tags.
2348  *  Return non-zero if fails.
2349  */
2350 int
2351 mptscsih_slave_configure(struct scsi_device *sdev)
2352 {
2353     struct Scsi_Host    *sh = sdev->host;
2354     VirtTarget      *vtarget;
2355     VirtDevice      *vdevice;
2356     struct scsi_target  *starget;
2357     MPT_SCSI_HOST       *hd = shost_priv(sh);
2358     MPT_ADAPTER     *ioc = hd->ioc;
2359 
2360     starget = scsi_target(sdev);
2361     vtarget = starget->hostdata;
2362     vdevice = sdev->hostdata;
2363 
2364     dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2365         "device @ %p, channel=%d, id=%d, lun=%llu\n",
2366         ioc->name, sdev, sdev->channel, sdev->id, sdev->lun));
2367     if (ioc->bus_type == SPI)
2368         dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2369             "sdtr %d wdtr %d ppr %d inq length=%d\n",
2370             ioc->name, sdev->sdtr, sdev->wdtr,
2371             sdev->ppr, sdev->inquiry_len));
2372 
2373     vdevice->configured_lun = 1;
2374 
2375     dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2376         "Queue depth=%d, tflags=%x\n",
2377         ioc->name, sdev->queue_depth, vtarget->tflags));
2378 
2379     if (ioc->bus_type == SPI)
2380         dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2381             "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
2382             ioc->name, vtarget->negoFlags, vtarget->maxOffset,
2383             vtarget->minSyncFactor));
2384 
2385     mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH);
2386     dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2387         "tagged %d, simple %d\n",
2388         ioc->name,sdev->tagged_supported, sdev->simple_tags));
2389 
2390     blk_queue_dma_alignment (sdev->request_queue, 512 - 1);
2391 
2392     return 0;
2393 }
2394 
2395 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2396 /*
2397  *  Private routines...
2398  */
2399 
2400 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2401 /* Utility function to copy sense data from the scsi_cmnd buffer
2402  * to the FC and SCSI target structures.
2403  *
2404  */
2405 static void
2406 mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
2407 {
2408     VirtDevice  *vdevice;
2409     SCSIIORequest_t *pReq;
2410     u32      sense_count = le32_to_cpu(pScsiReply->SenseCount);
2411     MPT_ADAPTER     *ioc = hd->ioc;
2412 
2413     /* Get target structure
2414      */
2415     pReq = (SCSIIORequest_t *) mf;
2416     vdevice = sc->device->hostdata;
2417 
2418     if (sense_count) {
2419         u8 *sense_data;
2420         int req_index;
2421 
2422         /* Copy the sense received into the scsi command block. */
2423         req_index = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2424         sense_data = ((u8 *)ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC));
2425         memcpy(sc->sense_buffer, sense_data, MPT_SENSE_BUFFER_ALLOC);
2426 
2427         /* Log SMART data (asc = 0x5D, non-IM case only) if required.
2428          */
2429         if ((ioc->events) && (ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) {
2430             if ((sense_data[12] == 0x5D) && (vdevice->vtarget->raidVolume == 0)) {
2431                 int idx;
2432 
2433                 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
2434                 ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
2435                 ioc->events[idx].eventContext = ioc->eventContext;
2436 
2437                 ioc->events[idx].data[0] = (pReq->LUN[1] << 24) |
2438                     (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) |
2439                     (sc->device->channel << 8) | sc->device->id;
2440 
2441                 ioc->events[idx].data[1] = (sense_data[13] << 8) | sense_data[12];
2442 
2443                 ioc->eventContext++;
2444                 if (ioc->pcidev->vendor ==
2445                     PCI_VENDOR_ID_IBM) {
2446                     mptscsih_issue_sep_command(ioc,
2447                         vdevice->vtarget, MPI_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT);
2448                     vdevice->vtarget->tflags |=
2449                         MPT_TARGET_FLAGS_LED_ON;
2450                 }
2451             }
2452         }
2453     } else {
2454         dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Hmmm... SenseData len=0! (?)\n",
2455                 ioc->name));
2456     }
2457 }
2458 
2459 /**
2460  * mptscsih_get_scsi_lookup - retrieves scmd entry
2461  * @ioc: Pointer to MPT_ADAPTER structure
2462  * @i: index into the array
2463  *
2464  * Returns the scsi_cmd pointer
2465  */
2466 struct scsi_cmnd *
2467 mptscsih_get_scsi_lookup(MPT_ADAPTER *ioc, int i)
2468 {
2469     unsigned long   flags;
2470     struct scsi_cmnd *scmd;
2471 
2472     spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
2473     scmd = ioc->ScsiLookup[i];
2474     spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
2475 
2476     return scmd;
2477 }
2478 EXPORT_SYMBOL(mptscsih_get_scsi_lookup);
2479 
2480 /**
2481  * mptscsih_getclear_scsi_lookup -  retrieves and clears scmd entry from ScsiLookup[] array list
2482  * @ioc: Pointer to MPT_ADAPTER structure
2483  * @i: index into the array
2484  *
2485  * Returns the scsi_cmd pointer
2486  *
2487  **/
2488 static struct scsi_cmnd *
2489 mptscsih_getclear_scsi_lookup(MPT_ADAPTER *ioc, int i)
2490 {
2491     unsigned long   flags;
2492     struct scsi_cmnd *scmd;
2493 
2494     spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
2495     scmd = ioc->ScsiLookup[i];
2496     ioc->ScsiLookup[i] = NULL;
2497     spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
2498 
2499     return scmd;
2500 }
2501 
2502 /**
2503  * mptscsih_set_scsi_lookup - write a scmd entry into the ScsiLookup[] array list
2504  *
2505  * @ioc: Pointer to MPT_ADAPTER structure
2506  * @i: index into the array
2507  * @scmd: scsi_cmnd pointer
2508  *
2509  **/
2510 static void
2511 mptscsih_set_scsi_lookup(MPT_ADAPTER *ioc, int i, struct scsi_cmnd *scmd)
2512 {
2513     unsigned long   flags;
2514 
2515     spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
2516     ioc->ScsiLookup[i] = scmd;
2517     spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
2518 }
2519 
2520 /**
2521  * SCPNT_TO_LOOKUP_IDX - searches for a given scmd in the ScsiLookup[] array list
2522  * @ioc: Pointer to MPT_ADAPTER structure
2523  * @sc: scsi_cmnd pointer
2524  */
2525 static int
2526 SCPNT_TO_LOOKUP_IDX(MPT_ADAPTER *ioc, struct scsi_cmnd *sc)
2527 {
2528     unsigned long   flags;
2529     int i, index=-1;
2530 
2531     spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
2532     for (i = 0; i < ioc->req_depth; i++) {
2533         if (ioc->ScsiLookup[i] == sc) {
2534             index = i;
2535             goto out;
2536         }
2537     }
2538 
2539  out:
2540     spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
2541     return index;
2542 }
2543 
2544 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2545 int
2546 mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2547 {
2548     MPT_SCSI_HOST   *hd;
2549 
2550     if (ioc->sh == NULL || shost_priv(ioc->sh) == NULL)
2551         return 0;
2552 
2553     hd = shost_priv(ioc->sh);
2554     switch (reset_phase) {
2555     case MPT_IOC_SETUP_RESET:
2556         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2557             "%s: MPT_IOC_SETUP_RESET\n", ioc->name, __func__));
2558         break;
2559     case MPT_IOC_PRE_RESET:
2560         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2561             "%s: MPT_IOC_PRE_RESET\n", ioc->name, __func__));
2562         mptscsih_flush_running_cmds(hd);
2563         break;
2564     case MPT_IOC_POST_RESET:
2565         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2566             "%s: MPT_IOC_POST_RESET\n", ioc->name, __func__));
2567         if (ioc->internal_cmds.status & MPT_MGMT_STATUS_PENDING) {
2568             ioc->internal_cmds.status |=
2569                 MPT_MGMT_STATUS_DID_IOCRESET;
2570             complete(&ioc->internal_cmds.done);
2571         }
2572         break;
2573     default:
2574         break;
2575     }
2576     return 1;       /* currently means nothing really */
2577 }
2578 
2579 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2580 int
2581 mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2582 {
2583     u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
2584 
2585     devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2586         "MPT event (=%02Xh) routed to SCSI host driver!\n",
2587         ioc->name, event));
2588 
2589     if ((event == MPI_EVENT_IOC_BUS_RESET ||
2590         event == MPI_EVENT_EXT_BUS_RESET) &&
2591         (ioc->bus_type == SPI) && (ioc->soft_resets < -1))
2592             ioc->soft_resets++;
2593 
2594     return 1;       /* currently means nothing really */
2595 }
2596 
2597 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2598 /*
2599  *  Bus Scan and Domain Validation functionality ...
2600  */
2601 
2602 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2603 /*
2604  *  mptscsih_scandv_complete - Scan and DV callback routine registered
2605  *  to Fustion MPT (base) driver.
2606  *
2607  *  @ioc: Pointer to MPT_ADAPTER structure
2608  *  @mf: Pointer to original MPT request frame
2609  *  @mr: Pointer to MPT reply frame (NULL if TurboReply)
2610  *
2611  *  This routine is called from mpt.c::mpt_interrupt() at the completion
2612  *  of any SCSI IO request.
2613  *  This routine is registered with the Fusion MPT (base) driver at driver
2614  *  load/init time via the mpt_register() API call.
2615  *
2616  *  Returns 1 indicating alloc'd request frame ptr should be freed.
2617  *
2618  *  Remark: Sets a completion code and (possibly) saves sense data
2619  *  in the IOC member localReply structure.
2620  *  Used ONLY for DV and other internal commands.
2621  */
2622 int
2623 mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
2624                 MPT_FRAME_HDR *reply)
2625 {
2626     SCSIIORequest_t *pReq;
2627     SCSIIOReply_t   *pReply;
2628     u8       cmd;
2629     u16      req_idx;
2630     u8  *sense_data;
2631     int      sz;
2632 
2633     ioc->internal_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
2634     ioc->internal_cmds.completion_code = MPT_SCANDV_GOOD;
2635     if (!reply)
2636         goto out;
2637 
2638     pReply = (SCSIIOReply_t *) reply;
2639     pReq = (SCSIIORequest_t *) req;
2640     ioc->internal_cmds.completion_code =
2641         mptscsih_get_completion_code(ioc, req, reply);
2642     ioc->internal_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
2643     memcpy(ioc->internal_cmds.reply, reply,
2644         min(MPT_DEFAULT_FRAME_SIZE, 4 * reply->u.reply.MsgLength));
2645     cmd = reply->u.hdr.Function;
2646     if (((cmd == MPI_FUNCTION_SCSI_IO_REQUEST) ||
2647         (cmd == MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) &&
2648         (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID)) {
2649         req_idx = le16_to_cpu(req->u.frame.hwhdr.msgctxu.fld.req_idx);
2650         sense_data = ((u8 *)ioc->sense_buf_pool +
2651             (req_idx * MPT_SENSE_BUFFER_ALLOC));
2652         sz = min_t(int, pReq->SenseBufferLength,
2653             MPT_SENSE_BUFFER_ALLOC);
2654         memcpy(ioc->internal_cmds.sense, sense_data, sz);
2655     }
2656  out:
2657     if (!(ioc->internal_cmds.status & MPT_MGMT_STATUS_PENDING))
2658         return 0;
2659     ioc->internal_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
2660     complete(&ioc->internal_cmds.done);
2661     return 1;
2662 }
2663 
2664 
2665 /**
2666  *  mptscsih_get_completion_code - get completion code from MPT request
2667  *  @ioc: Pointer to MPT_ADAPTER structure
2668  *  @req: Pointer to original MPT request frame
2669  *  @reply: Pointer to MPT reply frame (NULL if TurboReply)
2670  *
2671  **/
2672 static int
2673 mptscsih_get_completion_code(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
2674                 MPT_FRAME_HDR *reply)
2675 {
2676     SCSIIOReply_t   *pReply;
2677     MpiRaidActionReply_t *pr;
2678     u8       scsi_status;
2679     u16      status;
2680     int      completion_code;
2681 
2682     pReply = (SCSIIOReply_t *)reply;
2683     status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2684     scsi_status = pReply->SCSIStatus;
2685 
2686     devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2687         "IOCStatus=%04xh, SCSIState=%02xh, SCSIStatus=%02xh,"
2688         "IOCLogInfo=%08xh\n", ioc->name, status, pReply->SCSIState,
2689         scsi_status, le32_to_cpu(pReply->IOCLogInfo)));
2690 
2691     switch (status) {
2692 
2693     case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE:   /* 0x0043 */
2694         completion_code = MPT_SCANDV_SELECTION_TIMEOUT;
2695         break;
2696 
2697     case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR:      /* 0x0046 */
2698     case MPI_IOCSTATUS_SCSI_TASK_TERMINATED:    /* 0x0048 */
2699     case MPI_IOCSTATUS_SCSI_IOC_TERMINATED:     /* 0x004B */
2700     case MPI_IOCSTATUS_SCSI_EXT_TERMINATED:     /* 0x004C */
2701         completion_code = MPT_SCANDV_DID_RESET;
2702         break;
2703 
2704     case MPI_IOCSTATUS_BUSY:
2705     case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES:
2706         completion_code = MPT_SCANDV_BUSY;
2707         break;
2708 
2709     case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN:      /* 0x0045 */
2710     case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR:    /* 0x0040 */
2711     case MPI_IOCSTATUS_SUCCESS:         /* 0x0000 */
2712         if (pReply->Function == MPI_FUNCTION_CONFIG) {
2713             completion_code = MPT_SCANDV_GOOD;
2714         } else if (pReply->Function == MPI_FUNCTION_RAID_ACTION) {
2715             pr = (MpiRaidActionReply_t *)reply;
2716             if (le16_to_cpu(pr->ActionStatus) ==
2717                 MPI_RAID_ACTION_ASTATUS_SUCCESS)
2718                 completion_code = MPT_SCANDV_GOOD;
2719             else
2720                 completion_code = MPT_SCANDV_SOME_ERROR;
2721         } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID)
2722             completion_code = MPT_SCANDV_SENSE;
2723         else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_FAILED) {
2724             if (req->u.scsireq.CDB[0] == INQUIRY)
2725                 completion_code = MPT_SCANDV_ISSUE_SENSE;
2726             else
2727                 completion_code = MPT_SCANDV_DID_RESET;
2728         } else if (pReply->SCSIState & MPI_SCSI_STATE_NO_SCSI_STATUS)
2729             completion_code = MPT_SCANDV_DID_RESET;
2730         else if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
2731             completion_code = MPT_SCANDV_DID_RESET;
2732         else if (scsi_status == MPI_SCSI_STATUS_BUSY)
2733             completion_code = MPT_SCANDV_BUSY;
2734         else
2735             completion_code = MPT_SCANDV_GOOD;
2736         break;
2737 
2738     case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR:     /* 0x0047 */
2739         if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
2740             completion_code = MPT_SCANDV_DID_RESET;
2741         else
2742             completion_code = MPT_SCANDV_SOME_ERROR;
2743         break;
2744     default:
2745         completion_code = MPT_SCANDV_SOME_ERROR;
2746         break;
2747 
2748     }   /* switch(status) */
2749 
2750     devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2751         "  completionCode set to %08xh\n", ioc->name, completion_code));
2752     return completion_code;
2753 }
2754 
2755 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2756 /**
2757  *  mptscsih_do_cmd - Do internal command.
2758  *  @hd: MPT_SCSI_HOST pointer
2759  *  @io: INTERNAL_CMD pointer.
2760  *
2761  *  Issue the specified internally generated command and do command
2762  *  specific cleanup. For bus scan / DV only.
2763  *  NOTES: If command is Inquiry and status is good,
2764  *  initialize a target structure, save the data
2765  *
2766  *  Remark: Single threaded access only.
2767  *
2768  *  Return:
2769  *      < 0 if an illegal command or no resources
2770  *
2771  *         0 if good
2772  *
2773  *       > 0 if command complete but some type of completion error.
2774  */
2775 static int
2776 mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
2777 {
2778     MPT_FRAME_HDR   *mf;
2779     SCSIIORequest_t *pScsiReq;
2780     int      my_idx, ii, dir;
2781     int      timeout;
2782     char         cmdLen;
2783     char         CDB[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
2784     u8       cmd = io->cmd;
2785     MPT_ADAPTER *ioc = hd->ioc;
2786     int      ret = 0;
2787     unsigned long    timeleft;
2788     unsigned long    flags;
2789 
2790     /* don't send internal command during diag reset */
2791     spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
2792     if (ioc->ioc_reset_in_progress) {
2793         spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2794         dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2795             "%s: busy with host reset\n", ioc->name, __func__));
2796         return MPT_SCANDV_BUSY;
2797     }
2798     spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2799 
2800     mutex_lock(&ioc->internal_cmds.mutex);
2801 
2802     /* Set command specific information
2803      */
2804     switch (cmd) {
2805     case INQUIRY:
2806         cmdLen = 6;
2807         dir = MPI_SCSIIO_CONTROL_READ;
2808         CDB[0] = cmd;
2809         CDB[4] = io->size;
2810         timeout = 10;
2811         break;
2812 
2813     case TEST_UNIT_READY:
2814         cmdLen = 6;
2815         dir = MPI_SCSIIO_CONTROL_READ;
2816         timeout = 10;
2817         break;
2818 
2819     case START_STOP:
2820         cmdLen = 6;
2821         dir = MPI_SCSIIO_CONTROL_READ;
2822         CDB[0] = cmd;
2823         CDB[4] = 1; /*Spin up the disk */
2824         timeout = 15;
2825         break;
2826 
2827     case REQUEST_SENSE:
2828         cmdLen = 6;
2829         CDB[0] = cmd;
2830         CDB[4] = io->size;
2831         dir = MPI_SCSIIO_CONTROL_READ;
2832         timeout = 10;
2833         break;
2834 
2835     case READ_BUFFER:
2836         cmdLen = 10;
2837         dir = MPI_SCSIIO_CONTROL_READ;
2838         CDB[0] = cmd;
2839         if (io->flags & MPT_ICFLAG_ECHO) {
2840             CDB[1] = 0x0A;
2841         } else {
2842             CDB[1] = 0x02;
2843         }
2844 
2845         if (io->flags & MPT_ICFLAG_BUF_CAP) {
2846             CDB[1] |= 0x01;
2847         }
2848         CDB[6] = (io->size >> 16) & 0xFF;
2849         CDB[7] = (io->size >>  8) & 0xFF;
2850         CDB[8] = io->size & 0xFF;
2851         timeout = 10;
2852         break;
2853 
2854     case WRITE_BUFFER:
2855         cmdLen = 10;
2856         dir = MPI_SCSIIO_CONTROL_WRITE;
2857         CDB[0] = cmd;
2858         if (io->flags & MPT_ICFLAG_ECHO) {
2859             CDB[1] = 0x0A;
2860         } else {
2861             CDB[1] = 0x02;
2862         }
2863         CDB[6] = (io->size >> 16) & 0xFF;
2864         CDB[7] = (io->size >>  8) & 0xFF;
2865         CDB[8] = io->size & 0xFF;
2866         timeout = 10;
2867         break;
2868 
2869     case RESERVE:
2870         cmdLen = 6;
2871         dir = MPI_SCSIIO_CONTROL_READ;
2872         CDB[0] = cmd;
2873         timeout = 10;
2874         break;
2875 
2876     case RELEASE:
2877         cmdLen = 6;
2878         dir = MPI_SCSIIO_CONTROL_READ;
2879         CDB[0] = cmd;
2880         timeout = 10;
2881         break;
2882 
2883     case SYNCHRONIZE_CACHE:
2884         cmdLen = 10;
2885         dir = MPI_SCSIIO_CONTROL_READ;
2886         CDB[0] = cmd;
2887 //      CDB[1] = 0x02;  /* set immediate bit */
2888         timeout = 10;
2889         break;
2890 
2891     default:
2892         /* Error Case */
2893         ret = -EFAULT;
2894         goto out;
2895     }
2896 
2897     /* Get and Populate a free Frame
2898      * MsgContext set in mpt_get_msg_frame call
2899      */
2900     if ((mf = mpt_get_msg_frame(ioc->InternalCtx, ioc)) == NULL) {
2901         dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: No msg frames!\n",
2902             ioc->name, __func__));
2903         ret = MPT_SCANDV_BUSY;
2904         goto out;
2905     }
2906 
2907     pScsiReq = (SCSIIORequest_t *) mf;
2908 
2909     /* Get the request index */
2910     my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2911     ADD_INDEX_LOG(my_idx); /* for debug */
2912 
2913     if (io->flags & MPT_ICFLAG_PHYS_DISK) {
2914         pScsiReq->TargetID = io->physDiskNum;
2915         pScsiReq->Bus = 0;
2916         pScsiReq->ChainOffset = 0;
2917         pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
2918     } else {
2919         pScsiReq->TargetID = io->id;
2920         pScsiReq->Bus = io->channel;
2921         pScsiReq->ChainOffset = 0;
2922         pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
2923     }
2924 
2925     pScsiReq->CDBLength = cmdLen;
2926     pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
2927 
2928     pScsiReq->Reserved = 0;
2929 
2930     pScsiReq->MsgFlags = mpt_msg_flags(ioc);
2931     /* MsgContext set in mpt_get_msg_fram call  */
2932 
2933     int_to_scsilun(io->lun, (struct scsi_lun *)pScsiReq->LUN);
2934 
2935     if (io->flags & MPT_ICFLAG_TAGGED_CMD)
2936         pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ);
2937     else
2938         pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
2939 
2940     if (cmd == REQUEST_SENSE) {
2941         pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
2942         devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2943             "%s: Untagged! 0x%02x\n", ioc->name, __func__, cmd));
2944     }
2945 
2946     for (ii = 0; ii < 16; ii++)
2947         pScsiReq->CDB[ii] = CDB[ii];
2948 
2949     pScsiReq->DataLength = cpu_to_le32(io->size);
2950     pScsiReq->SenseBufferLowAddr = cpu_to_le32(ioc->sense_buf_low_dma
2951                        + (my_idx * MPT_SENSE_BUFFER_ALLOC));
2952 
2953     devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2954         "%s: Sending Command 0x%02x for fw_channel=%d fw_id=%d lun=%llu\n",
2955         ioc->name, __func__, cmd, io->channel, io->id, io->lun));
2956 
2957     if (dir == MPI_SCSIIO_CONTROL_READ)
2958         ioc->add_sge((char *) &pScsiReq->SGL,
2959             MPT_SGE_FLAGS_SSIMPLE_READ | io->size, io->data_dma);
2960     else
2961         ioc->add_sge((char *) &pScsiReq->SGL,
2962             MPT_SGE_FLAGS_SSIMPLE_WRITE | io->size, io->data_dma);
2963 
2964     INITIALIZE_MGMT_STATUS(ioc->internal_cmds.status)
2965     mpt_put_msg_frame(ioc->InternalCtx, ioc, mf);
2966     timeleft = wait_for_completion_timeout(&ioc->internal_cmds.done,
2967         timeout*HZ);
2968     if (!(ioc->internal_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
2969         ret = MPT_SCANDV_DID_RESET;
2970         dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2971             "%s: TIMED OUT for cmd=0x%02x\n", ioc->name, __func__,
2972             cmd));
2973         if (ioc->internal_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET) {
2974             mpt_free_msg_frame(ioc, mf);
2975             goto out;
2976         }
2977         if (!timeleft) {
2978             printk(MYIOC_s_WARN_FMT
2979                    "Issuing Reset from %s!! doorbell=0x%08xh"
2980                    " cmd=0x%02x\n",
2981                    ioc->name, __func__, mpt_GetIocState(ioc, 0),
2982                    cmd);
2983             mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
2984             mpt_free_msg_frame(ioc, mf);
2985         }
2986         goto out;
2987     }
2988 
2989     ret = ioc->internal_cmds.completion_code;
2990     devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: success, rc=0x%02x\n",
2991             ioc->name, __func__, ret));
2992 
2993  out:
2994     CLEAR_MGMT_STATUS(ioc->internal_cmds.status)
2995     mutex_unlock(&ioc->internal_cmds.mutex);
2996     return ret;
2997 }
2998 
2999 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3000 /**
3001  *  mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
3002  *  @hd: Pointer to a SCSI HOST structure
3003  *  @vdevice: virtual target device
3004  *
3005  *  Uses the ISR, but with special processing.
3006  *  MUST be single-threaded.
3007  *
3008  */
3009 static void
3010 mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
3011 {
3012     INTERNAL_CMD         iocmd;
3013 
3014     /* Ignore hidden raid components, this is handled when the command
3015      * is sent to the volume
3016      */
3017     if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
3018         return;
3019 
3020     if (vdevice->vtarget->type != TYPE_DISK || vdevice->vtarget->deleted ||
3021         !vdevice->configured_lun)
3022         return;
3023 
3024     /* Following parameters will not change
3025      * in this routine.
3026      */
3027     iocmd.cmd = SYNCHRONIZE_CACHE;
3028     iocmd.flags = 0;
3029     iocmd.physDiskNum = -1;
3030     iocmd.data = NULL;
3031     iocmd.data_dma = -1;
3032     iocmd.size = 0;
3033     iocmd.rsvd = iocmd.rsvd2 = 0;
3034     iocmd.channel = vdevice->vtarget->channel;
3035     iocmd.id = vdevice->vtarget->id;
3036     iocmd.lun = vdevice->lun;
3037 
3038     mptscsih_do_cmd(hd, &iocmd);
3039 }
3040 
3041 static ssize_t
3042 mptscsih_version_fw_show(struct device *dev, struct device_attribute *attr,
3043              char *buf)
3044 {
3045     struct Scsi_Host *host = class_to_shost(dev);
3046     MPT_SCSI_HOST   *hd = shost_priv(host);
3047     MPT_ADAPTER *ioc = hd->ioc;
3048 
3049     return snprintf(buf, PAGE_SIZE, "%02d.%02d.%02d.%02d\n",
3050         (ioc->facts.FWVersion.Word & 0xFF000000) >> 24,
3051         (ioc->facts.FWVersion.Word & 0x00FF0000) >> 16,
3052         (ioc->facts.FWVersion.Word & 0x0000FF00) >> 8,
3053         ioc->facts.FWVersion.Word & 0x000000FF);
3054 }
3055 static DEVICE_ATTR(version_fw, S_IRUGO, mptscsih_version_fw_show, NULL);
3056 
3057 static ssize_t
3058 mptscsih_version_bios_show(struct device *dev, struct device_attribute *attr,
3059                char *buf)
3060 {
3061     struct Scsi_Host *host = class_to_shost(dev);
3062     MPT_SCSI_HOST   *hd = shost_priv(host);
3063     MPT_ADAPTER *ioc = hd->ioc;
3064 
3065     return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x.%02x\n",
3066         (ioc->biosVersion & 0xFF000000) >> 24,
3067         (ioc->biosVersion & 0x00FF0000) >> 16,
3068         (ioc->biosVersion & 0x0000FF00) >> 8,
3069         ioc->biosVersion & 0x000000FF);
3070 }
3071 static DEVICE_ATTR(version_bios, S_IRUGO, mptscsih_version_bios_show, NULL);
3072 
3073 static ssize_t
3074 mptscsih_version_mpi_show(struct device *dev, struct device_attribute *attr,
3075               char *buf)
3076 {
3077     struct Scsi_Host *host = class_to_shost(dev);
3078     MPT_SCSI_HOST   *hd = shost_priv(host);
3079     MPT_ADAPTER *ioc = hd->ioc;
3080 
3081     return snprintf(buf, PAGE_SIZE, "%03x\n", ioc->facts.MsgVersion);
3082 }
3083 static DEVICE_ATTR(version_mpi, S_IRUGO, mptscsih_version_mpi_show, NULL);
3084 
3085 static ssize_t
3086 mptscsih_version_product_show(struct device *dev,
3087                   struct device_attribute *attr,
3088 char *buf)
3089 {
3090     struct Scsi_Host *host = class_to_shost(dev);
3091     MPT_SCSI_HOST   *hd = shost_priv(host);
3092     MPT_ADAPTER *ioc = hd->ioc;
3093 
3094     return snprintf(buf, PAGE_SIZE, "%s\n", ioc->prod_name);
3095 }
3096 static DEVICE_ATTR(version_product, S_IRUGO,
3097     mptscsih_version_product_show, NULL);
3098 
3099 static ssize_t
3100 mptscsih_version_nvdata_persistent_show(struct device *dev,
3101                     struct device_attribute *attr,
3102                     char *buf)
3103 {
3104     struct Scsi_Host *host = class_to_shost(dev);
3105     MPT_SCSI_HOST   *hd = shost_priv(host);
3106     MPT_ADAPTER *ioc = hd->ioc;
3107 
3108     return snprintf(buf, PAGE_SIZE, "%02xh\n",
3109         ioc->nvdata_version_persistent);
3110 }
3111 static DEVICE_ATTR(version_nvdata_persistent, S_IRUGO,
3112     mptscsih_version_nvdata_persistent_show, NULL);
3113 
3114 static ssize_t
3115 mptscsih_version_nvdata_default_show(struct device *dev,
3116                      struct device_attribute *attr, char *buf)
3117 {
3118     struct Scsi_Host *host = class_to_shost(dev);
3119     MPT_SCSI_HOST   *hd = shost_priv(host);
3120     MPT_ADAPTER *ioc = hd->ioc;
3121 
3122     return snprintf(buf, PAGE_SIZE, "%02xh\n",ioc->nvdata_version_default);
3123 }
3124 static DEVICE_ATTR(version_nvdata_default, S_IRUGO,
3125     mptscsih_version_nvdata_default_show, NULL);
3126 
3127 static ssize_t
3128 mptscsih_board_name_show(struct device *dev, struct device_attribute *attr,
3129              char *buf)
3130 {
3131     struct Scsi_Host *host = class_to_shost(dev);
3132     MPT_SCSI_HOST   *hd = shost_priv(host);
3133     MPT_ADAPTER *ioc = hd->ioc;
3134 
3135     return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_name);
3136 }
3137 static DEVICE_ATTR(board_name, S_IRUGO, mptscsih_board_name_show, NULL);
3138 
3139 static ssize_t
3140 mptscsih_board_assembly_show(struct device *dev,
3141                  struct device_attribute *attr, char *buf)
3142 {
3143     struct Scsi_Host *host = class_to_shost(dev);
3144     MPT_SCSI_HOST   *hd = shost_priv(host);
3145     MPT_ADAPTER *ioc = hd->ioc;
3146 
3147     return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_assembly);
3148 }
3149 static DEVICE_ATTR(board_assembly, S_IRUGO,
3150     mptscsih_board_assembly_show, NULL);
3151 
3152 static ssize_t
3153 mptscsih_board_tracer_show(struct device *dev, struct device_attribute *attr,
3154                char *buf)
3155 {
3156     struct Scsi_Host *host = class_to_shost(dev);
3157     MPT_SCSI_HOST   *hd = shost_priv(host);
3158     MPT_ADAPTER *ioc = hd->ioc;
3159 
3160     return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_tracer);
3161 }
3162 static DEVICE_ATTR(board_tracer, S_IRUGO,
3163     mptscsih_board_tracer_show, NULL);
3164 
3165 static ssize_t
3166 mptscsih_io_delay_show(struct device *dev, struct device_attribute *attr,
3167                char *buf)
3168 {
3169     struct Scsi_Host *host = class_to_shost(dev);
3170     MPT_SCSI_HOST   *hd = shost_priv(host);
3171     MPT_ADAPTER *ioc = hd->ioc;
3172 
3173     return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->io_missing_delay);
3174 }
3175 static DEVICE_ATTR(io_delay, S_IRUGO,
3176     mptscsih_io_delay_show, NULL);
3177 
3178 static ssize_t
3179 mptscsih_device_delay_show(struct device *dev, struct device_attribute *attr,
3180                char *buf)
3181 {
3182     struct Scsi_Host *host = class_to_shost(dev);
3183     MPT_SCSI_HOST   *hd = shost_priv(host);
3184     MPT_ADAPTER *ioc = hd->ioc;
3185 
3186     return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->device_missing_delay);
3187 }
3188 static DEVICE_ATTR(device_delay, S_IRUGO,
3189     mptscsih_device_delay_show, NULL);
3190 
3191 static ssize_t
3192 mptscsih_debug_level_show(struct device *dev, struct device_attribute *attr,
3193               char *buf)
3194 {
3195     struct Scsi_Host *host = class_to_shost(dev);
3196     MPT_SCSI_HOST   *hd = shost_priv(host);
3197     MPT_ADAPTER *ioc = hd->ioc;
3198 
3199     return snprintf(buf, PAGE_SIZE, "%08xh\n", ioc->debug_level);
3200 }
3201 static ssize_t
3202 mptscsih_debug_level_store(struct device *dev, struct device_attribute *attr,
3203                const char *buf, size_t count)
3204 {
3205     struct Scsi_Host *host = class_to_shost(dev);
3206     MPT_SCSI_HOST   *hd = shost_priv(host);
3207     MPT_ADAPTER *ioc = hd->ioc;
3208     int val = 0;
3209 
3210     if (sscanf(buf, "%x", &val) != 1)
3211         return -EINVAL;
3212 
3213     ioc->debug_level = val;
3214     printk(MYIOC_s_INFO_FMT "debug_level=%08xh\n",
3215                 ioc->name, ioc->debug_level);
3216     return strlen(buf);
3217 }
3218 static DEVICE_ATTR(debug_level, S_IRUGO | S_IWUSR,
3219     mptscsih_debug_level_show, mptscsih_debug_level_store);
3220 
3221 static struct attribute *mptscsih_host_attrs[] = {
3222     &dev_attr_version_fw.attr,
3223     &dev_attr_version_bios.attr,
3224     &dev_attr_version_mpi.attr,
3225     &dev_attr_version_product.attr,
3226     &dev_attr_version_nvdata_persistent.attr,
3227     &dev_attr_version_nvdata_default.attr,
3228     &dev_attr_board_name.attr,
3229     &dev_attr_board_assembly.attr,
3230     &dev_attr_board_tracer.attr,
3231     &dev_attr_io_delay.attr,
3232     &dev_attr_device_delay.attr,
3233     &dev_attr_debug_level.attr,
3234     NULL,
3235 };
3236 
3237 static const struct attribute_group mptscsih_host_attr_group = {
3238     .attrs = mptscsih_host_attrs
3239 };
3240 
3241 const struct attribute_group *mptscsih_host_attr_groups[] = {
3242     &mptscsih_host_attr_group,
3243     NULL
3244 };
3245 EXPORT_SYMBOL(mptscsih_host_attr_groups);
3246 
3247 EXPORT_SYMBOL(mptscsih_remove);
3248 EXPORT_SYMBOL(mptscsih_shutdown);
3249 #ifdef CONFIG_PM
3250 EXPORT_SYMBOL(mptscsih_suspend);
3251 EXPORT_SYMBOL(mptscsih_resume);
3252 #endif
3253 EXPORT_SYMBOL(mptscsih_show_info);
3254 EXPORT_SYMBOL(mptscsih_info);
3255 EXPORT_SYMBOL(mptscsih_qcmd);
3256 EXPORT_SYMBOL(mptscsih_slave_destroy);
3257 EXPORT_SYMBOL(mptscsih_slave_configure);
3258 EXPORT_SYMBOL(mptscsih_abort);
3259 EXPORT_SYMBOL(mptscsih_dev_reset);
3260 EXPORT_SYMBOL(mptscsih_bus_reset);
3261 EXPORT_SYMBOL(mptscsih_host_reset);
3262 EXPORT_SYMBOL(mptscsih_bios_param);
3263 EXPORT_SYMBOL(mptscsih_io_done);
3264 EXPORT_SYMBOL(mptscsih_taskmgmt_complete);
3265 EXPORT_SYMBOL(mptscsih_scandv_complete);
3266 EXPORT_SYMBOL(mptscsih_event_process);
3267 EXPORT_SYMBOL(mptscsih_ioc_reset);
3268 EXPORT_SYMBOL(mptscsih_change_queue_depth);
3269 
3270 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/