2 * linux/drivers/message/fusion/mptscsih.c
3 * For use with LSI Logic PCI chip/adapter(s)
4 * running LSI Logic Fusion MPT (Message Passing Technology) firmware.
6 * Copyright (c) 1999-2007 LSI Logic Corporation
7 * (mailto:DL-MPTFusionLinux@lsi.com)
10 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; version 2 of the License.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
22 THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
23 CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
24 LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
25 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
26 solely responsible for determining the appropriateness of using and
27 distributing the Program and assumes all risks associated with its
28 exercise of rights under this Agreement, including but not limited to
29 the risks and costs of program errors, damage to or loss of data,
30 programs or equipment, and unavailability or interruption of operations.
32 DISCLAIMER OF LIABILITY
33 NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
34 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
35 DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
36 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
37 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
38 USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
39 HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
41 You should have received a copy of the GNU General Public License
42 along with this program; if not, write to the Free Software
43 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
45 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
47 #include <linux/module.h>
48 #include <linux/kernel.h>
49 #include <linux/init.h>
50 #include <linux/errno.h>
51 #include <linux/kdev_t.h>
52 #include <linux/blkdev.h>
53 #include <linux/delay.h> /* for mdelay */
54 #include <linux/interrupt.h> /* needed for in_interrupt() proto */
55 #include <linux/reboot.h> /* notifier code */
56 #include <linux/workqueue.h>
58 #include <scsi/scsi.h>
59 #include <scsi/scsi_cmnd.h>
60 #include <scsi/scsi_device.h>
61 #include <scsi/scsi_host.h>
62 #include <scsi/scsi_tcq.h>
63 #include <scsi/scsi_dbg.h>
67 #include "lsi/mpi_log_sas.h"
69 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
70 #define my_NAME "Fusion MPT SCSI Host driver"
71 #define my_VERSION MPT_LINUX_VERSION_COMMON
72 #define MYNAM "mptscsih"
74 MODULE_AUTHOR(MODULEAUTHOR);
75 MODULE_DESCRIPTION(my_NAME);
76 MODULE_LICENSE("GPL");
77 MODULE_VERSION(my_VERSION);
79 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
81 * Other private/forward protos...
83 int mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
84 static void mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq);
85 int mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
87 static int mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
88 SCSIIORequest_t *pReq, int req_idx);
89 static void mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx);
90 static void mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply);
91 static int mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd);
92 static int mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout );
93 static int SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc);
95 static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout);
97 int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
98 int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
100 int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
101 static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
102 static void mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice);
104 void mptscsih_remove(struct pci_dev *);
105 void mptscsih_shutdown(struct pci_dev *);
107 int mptscsih_suspend(struct pci_dev *pdev, pm_message_t state);
108 int mptscsih_resume(struct pci_dev *pdev);
111 #define SNS_LEN(scp) sizeof((scp)->sense_buffer)
113 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
115 * mptscsih_add_sge - Place a simple SGE at address pAddr.
116 * @pAddr: virtual address for SGE
117 * @flagslength: SGE flags and data transfer length
118 * @dma_addr: Physical address
120 * This routine places a MPT request frame back on the MPT adapter's
124 mptscsih_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
126 if (sizeof(dma_addr_t) == sizeof(u64)) {
127 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
128 u32 tmp = dma_addr & 0xFFFFFFFF;
130 pSge->FlagsLength = cpu_to_le32(flagslength);
131 pSge->Address.Low = cpu_to_le32(tmp);
132 tmp = (u32) ((u64)dma_addr >> 32);
133 pSge->Address.High = cpu_to_le32(tmp);
136 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
137 pSge->FlagsLength = cpu_to_le32(flagslength);
138 pSge->Address = cpu_to_le32(dma_addr);
140 } /* mptscsih_add_sge() */
142 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
144 * mptscsih_add_chain - Place a chain SGE at address pAddr.
145 * @pAddr: virtual address for SGE
146 * @next: nextChainOffset value (u32's)
147 * @length: length of next SGL segment
148 * @dma_addr: Physical address
150 * This routine places a MPT request frame back on the MPT adapter's
154 mptscsih_add_chain(char *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
156 if (sizeof(dma_addr_t) == sizeof(u64)) {
157 SGEChain64_t *pChain = (SGEChain64_t *) pAddr;
158 u32 tmp = dma_addr & 0xFFFFFFFF;
160 pChain->Length = cpu_to_le16(length);
161 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size();
163 pChain->NextChainOffset = next;
165 pChain->Address.Low = cpu_to_le32(tmp);
166 tmp = (u32) ((u64)dma_addr >> 32);
167 pChain->Address.High = cpu_to_le32(tmp);
169 SGEChain32_t *pChain = (SGEChain32_t *) pAddr;
170 pChain->Length = cpu_to_le16(length);
171 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size();
172 pChain->NextChainOffset = next;
173 pChain->Address = cpu_to_le32(dma_addr);
175 } /* mptscsih_add_chain() */
177 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
179 * mptscsih_getFreeChainBuffer - Function to get a free chain
180 * from the MPT_SCSI_HOST FreeChainQ.
181 * @ioc: Pointer to MPT_ADAPTER structure
182 * @req_idx: Index of the SCSI IO request frame. (output)
184 * return SUCCESS or FAILED
187 mptscsih_getFreeChainBuffer(MPT_ADAPTER *ioc, int *retIndex)
189 MPT_FRAME_HDR *chainBuf;
194 dsgprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer called\n",
196 spin_lock_irqsave(&ioc->FreeQlock, flags);
197 if (!list_empty(&ioc->FreeChainQ)) {
200 chainBuf = list_entry(ioc->FreeChainQ.next, MPT_FRAME_HDR,
201 u.frame.linkage.list);
202 list_del(&chainBuf->u.frame.linkage.list);
203 offset = (u8 *)chainBuf - (u8 *)ioc->ChainBuffer;
204 chain_idx = offset / ioc->req_sz;
206 dsgprintk((MYIOC_s_ERR_FMT "getFreeChainBuffer chainBuf=%p ChainBuffer=%p offset=%d chain_idx=%d\n",
207 ioc->name, chainBuf, ioc->ChainBuffer, offset, chain_idx));
210 chain_idx = MPT_HOST_NO_CHAIN;
211 dfailprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer failed\n",
214 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
216 *retIndex = chain_idx;
218 } /* mptscsih_getFreeChainBuffer() */
220 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
222 * mptscsih_AddSGE - Add a SGE (plus chain buffers) to the
223 * SCSIIORequest_t Message Frame.
224 * @ioc: Pointer to MPT_ADAPTER structure
225 * @SCpnt: Pointer to scsi_cmnd structure
226 * @pReq: Pointer to SCSIIORequest_t structure
231 mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
232 SCSIIORequest_t *pReq, int req_idx)
236 struct scatterlist *sg;
238 int sges_left, sg_done;
239 int chain_idx = MPT_HOST_NO_CHAIN;
241 int numSgeSlots, numSgeThisFrame;
242 u32 sgflags, sgdir, thisxfer = 0;
243 int chain_dma_off = 0;
249 sgdir = le32_to_cpu(pReq->Control) & MPI_SCSIIO_CONTROL_DATADIRECTION_MASK;
250 if (sgdir == MPI_SCSIIO_CONTROL_WRITE) {
251 sgdir = MPT_TRANSFER_HOST_TO_IOC;
253 sgdir = MPT_TRANSFER_IOC_TO_HOST;
256 psge = (char *) &pReq->SGL;
257 frm_sz = ioc->req_sz;
259 /* Map the data portion, if any.
260 * sges_left = 0 if no data transfer.
262 sges_left = scsi_dma_map(SCpnt);
266 /* Handle the SG case.
268 sg = scsi_sglist(SCpnt);
270 sgeOffset = sizeof(SCSIIORequest_t) - sizeof(SGE_IO_UNION);
273 /* Prior to entering this loop - the following must be set
274 * current MF: sgeOffset (bytes)
275 * chainSge (Null if original MF is not a chain buffer)
276 * sg_done (num SGE done for this MF)
280 numSgeSlots = ((frm_sz - sgeOffset) / (sizeof(u32) + sizeof(dma_addr_t)) );
281 numSgeThisFrame = (sges_left < numSgeSlots) ? sges_left : numSgeSlots;
283 sgflags = MPT_SGE_FLAGS_SIMPLE_ELEMENT | MPT_SGE_FLAGS_ADDRESSING | sgdir;
285 /* Get first (num - 1) SG elements
286 * Skip any SG entries with a length of 0
287 * NOTE: at finish, sg and psge pointed to NEXT data/location positions
289 for (ii=0; ii < (numSgeThisFrame-1); ii++) {
290 thisxfer = sg_dma_len(sg);
292 sg ++; /* Get next SG element from the OS */
297 v2 = sg_dma_address(sg);
298 mptscsih_add_sge(psge, sgflags | thisxfer, v2);
300 sg++; /* Get next SG element from the OS */
301 psge += (sizeof(u32) + sizeof(dma_addr_t));
302 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
306 if (numSgeThisFrame == sges_left) {
307 /* Add last element, end of buffer and end of list flags.
309 sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT |
310 MPT_SGE_FLAGS_END_OF_BUFFER |
311 MPT_SGE_FLAGS_END_OF_LIST;
313 /* Add last SGE and set termination flags.
314 * Note: Last SGE may have a length of 0 - which should be ok.
316 thisxfer = sg_dma_len(sg);
318 v2 = sg_dma_address(sg);
319 mptscsih_add_sge(psge, sgflags | thisxfer, v2);
322 psge += (sizeof(u32) + sizeof(dma_addr_t));
324 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
328 /* The current buffer is a chain buffer,
329 * but there is not another one.
330 * Update the chain element
331 * Offset and Length fields.
333 mptscsih_add_chain((char *)chainSge, 0, sgeOffset, ioc->ChainBufferDMA + chain_dma_off);
335 /* The current buffer is the original MF
336 * and there is no Chain buffer.
338 pReq->ChainOffset = 0;
339 RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor) + 1) & 0x03;
340 dsgprintk((MYIOC_s_INFO_FMT
341 "Single Buffer RequestNB=%x, sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
342 ioc->RequestNB[req_idx] = RequestNB;
345 /* At least one chain buffer is needed.
346 * Complete the first MF
347 * - last SGE element, set the LastElement bit
348 * - set ChainOffset (words) for orig MF
349 * (OR finish previous MF chain buffer)
350 * - update MFStructPtr ChainIndex
351 * - Populate chain element
356 dsgprintk((MYIOC_s_INFO_FMT "SG: Chain Required! sg done %d\n",
357 ioc->name, sg_done));
359 /* Set LAST_ELEMENT flag for last non-chain element
360 * in the buffer. Since psge points at the NEXT
361 * SGE element, go back one SGE element, update the flags
362 * and reset the pointer. (Note: sgflags & thisxfer are already
366 u32 *ptmp = (u32 *) (psge - (sizeof(u32) + sizeof(dma_addr_t)));
367 sgflags = le32_to_cpu(*ptmp);
368 sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT;
369 *ptmp = cpu_to_le32(sgflags);
373 /* The current buffer is a chain buffer.
374 * chainSge points to the previous Chain Element.
375 * Update its chain element Offset and Length (must
376 * include chain element size) fields.
377 * Old chain element is now complete.
379 u8 nextChain = (u8) (sgeOffset >> 2);
380 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
381 mptscsih_add_chain((char *)chainSge, nextChain, sgeOffset, ioc->ChainBufferDMA + chain_dma_off);
383 /* The original MF buffer requires a chain buffer -
385 * Last element in this MF is a chain element.
387 pReq->ChainOffset = (u8) (sgeOffset >> 2);
388 RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor) + 1) & 0x03;
389 dsgprintk((MYIOC_s_ERR_FMT "Chain Buffer Needed, RequestNB=%x sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
390 ioc->RequestNB[req_idx] = RequestNB;
393 sges_left -= sg_done;
396 /* NOTE: psge points to the beginning of the chain element
397 * in current buffer. Get a chain buffer.
399 if ((mptscsih_getFreeChainBuffer(ioc, &newIndex)) == FAILED) {
400 dfailprintk((MYIOC_s_INFO_FMT
401 "getFreeChainBuffer FAILED SCSI cmd=%02x (%p)\n",
402 ioc->name, pReq->CDB[0], SCpnt));
406 /* Update the tracking arrays.
407 * If chainSge == NULL, update ReqToChain, else ChainToChain
410 ioc->ChainToChain[chain_idx] = newIndex;
412 ioc->ReqToChain[req_idx] = newIndex;
414 chain_idx = newIndex;
415 chain_dma_off = ioc->req_sz * chain_idx;
417 /* Populate the chainSGE for the current buffer.
418 * - Set chain buffer pointer to psge and fill
419 * out the Address and Flags fields.
421 chainSge = (char *) psge;
422 dsgprintk((KERN_INFO " Current buff @ %p (index 0x%x)",
425 /* Start the SGE for the next buffer
427 psge = (char *) (ioc->ChainBuffer + chain_dma_off);
431 dsgprintk((KERN_INFO " Chain buff @ %p (index 0x%x)\n",
434 /* Start the SGE for the next buffer
441 } /* mptscsih_AddSGE() */
444 mptscsih_issue_sep_command(MPT_ADAPTER *ioc, VirtTarget *vtarget,
448 SEPRequest_t *SEPMsg;
450 if (ioc->bus_type != SAS)
453 /* Not supported for hidden raid components
455 if (vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
458 if ((mf = mpt_get_msg_frame(ioc->InternalCtx, ioc)) == NULL) {
459 dfailprintk((MYIOC_s_WARN_FMT "%s: no msg frames!!\n",
460 ioc->name,__FUNCTION__));
464 SEPMsg = (SEPRequest_t *)mf;
465 SEPMsg->Function = MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR;
466 SEPMsg->Bus = vtarget->channel;
467 SEPMsg->TargetID = vtarget->id;
468 SEPMsg->Action = MPI_SEP_REQ_ACTION_WRITE_STATUS;
469 SEPMsg->SlotStatus = SlotStatus;
470 devtverboseprintk((MYIOC_s_WARN_FMT
471 "Sending SEP cmd=%x channel=%d id=%d\n",
472 ioc->name, SlotStatus, SEPMsg->Bus, SEPMsg->TargetID));
473 mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
476 #ifdef MPT_DEBUG_REPLY
478 * mptscsih_iocstatus_info_scsiio - IOCSTATUS information for SCSIIO
479 * @ioc: Pointer to MPT_ADAPTER structure
480 * @ioc_status: U32 IOCStatus word from IOC
481 * @scsi_status: U8 sam status from target
482 * @scsi_state: U8 scsi state
483 * @sc: original scsi cmnd pointer
484 * @mf: Pointer to MPT request frame
486 * Refer to lsi/mpi.h.
489 mptscsih_iocstatus_info_scsiio(MPT_ADAPTER *ioc, u32 ioc_status,
490 u8 scsi_status, u8 scsi_state, struct scsi_cmnd *sc)
492 char extend_desc[EVENT_DESCR_STR_SZ];
495 switch (ioc_status) {
497 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
498 desc = "SCSI Invalid Bus";
501 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
502 desc = "SCSI Invalid TargetID";
505 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
507 * Inquiry is issued for device scanning
509 if (sc->cmnd[0] != 0x12)
510 desc = "SCSI Device Not There";
513 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
514 desc = "SCSI Data Overrun";
517 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
518 desc = "SCSI I/O Data Error";
521 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
522 desc = "SCSI Protocol Error";
525 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
526 desc = "SCSI Task Terminated";
529 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
530 desc = "SCSI Residual Mismatch";
533 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
534 desc = "SCSI Task Management Failed";
537 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
538 desc = "SCSI IOC Terminated";
541 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
542 desc = "SCSI Ext Terminated";
549 snprintf(extend_desc, EVENT_DESCR_STR_SZ,
550 "[%d:%d:%d:%d] cmd=%02Xh, sam_status=%02Xh state=%02Xh",
551 sc->device->host->host_no,
552 sc->device->channel, sc->device->id, sc->device->lun,
553 sc->cmnd[0], scsi_status, scsi_state);
555 printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04X): %s: %s\n",
556 ioc->name, ioc_status, desc, extend_desc);
560 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
562 * mptscsih_io_done - Main SCSI IO callback routine registered to
563 * Fusion MPT (base) driver
564 * @ioc: Pointer to MPT_ADAPTER structure
565 * @mf: Pointer to original MPT request frame
566 * @r: Pointer to MPT reply frame (NULL if TurboReply)
568 * This routine is called from mpt.c::mpt_interrupt() at the completion
569 * of any SCSI IO request.
570 * This routine is registered with the Fusion MPT (base) driver at driver
571 * load/init time via the mpt_register() API call.
573 * Returns 1 indicating alloc'd request frame ptr should be freed.
576 mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
578 struct scsi_cmnd *sc;
580 SCSIIORequest_t *pScsiReq;
581 SCSIIOReply_t *pScsiReply;
582 u16 req_idx, req_idx_MR;
586 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
588 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
589 req_idx_MR = (mr != NULL) ?
590 le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx) : req_idx;
591 if ((req_idx != req_idx_MR) ||
592 (mf->u.frame.linkage.arg1 == 0xdeadbeaf)) {
593 printk(MYIOC_s_ERR_FMT "Received a mf that was already freed\n",
595 printk (MYIOC_s_ERR_FMT
596 "req_idx=%x req_idx_MR=%x mf=%p mr=%p sc=%p\n",
597 ioc->name, req_idx, req_idx_MR, mf, mr,
598 hd->ScsiLookup[req_idx_MR]);
602 sc = hd->ScsiLookup[req_idx];
603 hd->ScsiLookup[req_idx] = NULL;
605 MPIHeader_t *hdr = (MPIHeader_t *)mf;
607 /* Remark: writeSDP1 will use the ScsiDoneCtx
608 * If a SCSI I/O cmd, device disabled by OS and
609 * completion done. Cannot touch sc struct. Just free mem.
611 if (hdr->Function == MPI_FUNCTION_SCSI_IO_REQUEST)
612 printk(MYIOC_s_ERR_FMT "NULL ScsiCmd ptr!\n",
615 mptscsih_freeChainBuffers(ioc, req_idx);
619 if ((unsigned char *)mf != sc->host_scribble) {
620 mptscsih_freeChainBuffers(ioc, req_idx);
624 sc->host_scribble = NULL;
625 sc->result = DID_OK << 16; /* Set default reply as OK */
626 pScsiReq = (SCSIIORequest_t *) mf;
627 pScsiReply = (SCSIIOReply_t *) mr;
629 if((ioc->facts.MsgVersion >= MPI_VERSION_01_05) && pScsiReply){
630 dmfprintk((MYIOC_s_INFO_FMT
631 "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d,task-tag=%d)\n",
632 ioc->name, mf, mr, sc, req_idx, pScsiReply->TaskTag));
634 dmfprintk((MYIOC_s_INFO_FMT
635 "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n",
636 ioc->name, mf, mr, sc, req_idx));
639 if (pScsiReply == NULL) {
640 /* special context reply handling */
645 u8 scsi_state, scsi_status;
648 status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK;
649 scsi_state = pScsiReply->SCSIState;
650 scsi_status = pScsiReply->SCSIStatus;
651 xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
652 scsi_set_resid(sc, scsi_bufflen(sc) - xfer_cnt);
653 log_info = le32_to_cpu(pScsiReply->IOCLogInfo);
656 * if we get a data underrun indication, yet no data was
657 * transferred and the SCSI status indicates that the
658 * command was never started, change the data underrun
661 if (status == MPI_IOCSTATUS_SCSI_DATA_UNDERRUN && xfer_cnt == 0 &&
662 (scsi_status == MPI_SCSI_STATUS_BUSY ||
663 scsi_status == MPI_SCSI_STATUS_RESERVATION_CONFLICT ||
664 scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)) {
665 status = MPI_IOCSTATUS_SUCCESS;
668 if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)
669 mptscsih_copy_sense_data(sc, hd, mf, pScsiReply);
672 * Look for + dump FCP ResponseInfo[]!
674 if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID &&
675 pScsiReply->ResponseInfo) {
676 printk(KERN_NOTICE "[%d:%d:%d:%d] "
677 "FCP_ResponseInfo=%08xh\n",
678 sc->device->host->host_no, sc->device->channel,
679 sc->device->id, sc->device->lun,
680 le32_to_cpu(pScsiReply->ResponseInfo));
684 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
686 * Maybe: DRIVER_BUSY | SUGGEST_RETRY | DID_SOFT_ERROR (retry)
687 * But not: DID_BUS_BUSY lest one risk
688 * killing interrupt handler:-(
690 sc->result = SAM_STAT_BUSY;
693 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
694 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
695 sc->result = DID_BAD_TARGET << 16;
698 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
699 /* Spoof to SCSI Selection Timeout! */
700 if (ioc->bus_type != FC)
701 sc->result = DID_NO_CONNECT << 16;
702 /* else fibre, just stall until rescan event */
704 sc->result = DID_REQUEUE << 16;
706 if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF)
707 hd->sel_timeout[pScsiReq->TargetID]++;
709 vdev = sc->device->hostdata;
712 vtarget = vdev->vtarget;
713 if (vtarget->tflags & MPT_TARGET_FLAGS_LED_ON) {
714 mptscsih_issue_sep_command(ioc, vtarget,
715 MPI_SEP_REQ_SLOTSTATUS_UNCONFIGURED);
716 vtarget->tflags &= ~MPT_TARGET_FLAGS_LED_ON;
720 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
721 if ( ioc->bus_type == SAS ) {
722 u16 ioc_status = le16_to_cpu(pScsiReply->IOCStatus);
723 if (ioc_status & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
724 if ((log_info & SAS_LOGINFO_MASK)
725 == SAS_LOGINFO_NEXUS_LOSS) {
726 sc->result = (DID_BUS_BUSY << 16);
730 } else if (ioc->bus_type == FC) {
732 * The FC IOC may kill a request for variety of
733 * reasons, some of which may be recovered by a
734 * retry, some which are unlikely to be
735 * recovered. Return DID_ERROR instead of
736 * DID_RESET to permit retry of the command,
737 * just not an infinite number of them
739 sc->result = DID_ERROR << 16;
744 * Allow non-SAS & non-NEXUS_LOSS to drop into below code
747 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
748 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
749 /* Linux handles an unsolicited DID_RESET better
750 * than an unsolicited DID_ABORT.
752 sc->result = DID_RESET << 16;
756 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
757 scsi_set_resid(sc, scsi_bufflen(sc) - xfer_cnt);
758 if((xfer_cnt==0)||(sc->underflow > xfer_cnt))
759 sc->result=DID_SOFT_ERROR << 16;
760 else /* Sufficient data transfer occurred */
761 sc->result = (DID_OK << 16) | scsi_status;
762 dreplyprintk((KERN_NOTICE
763 "RESIDUAL_MISMATCH: result=%x on channel=%d id=%d\n",
764 sc->result, sc->device->channel, sc->device->id));
767 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
769 * Do upfront check for valid SenseData and give it
772 sc->result = (DID_OK << 16) | scsi_status;
773 if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
774 /* Have already saved the status and sense data
778 if (xfer_cnt < sc->underflow) {
779 if (scsi_status == SAM_STAT_BUSY)
780 sc->result = SAM_STAT_BUSY;
782 sc->result = DID_SOFT_ERROR << 16;
784 if (scsi_state & (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)) {
787 sc->result = DID_SOFT_ERROR << 16;
789 else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
790 /* Not real sure here either... */
791 sc->result = DID_RESET << 16;
795 dreplyprintk((KERN_NOTICE " sc->underflow={report ERR if < %02xh bytes xfer'd}\n",
797 dreplyprintk((KERN_NOTICE " ActBytesXferd=%02xh\n", xfer_cnt));
800 if (scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)
801 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
805 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
806 scsi_set_resid(sc, 0);
807 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
808 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
809 sc->result = (DID_OK << 16) | scsi_status;
810 if (scsi_state == 0) {
812 } else if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
814 * If running against circa 200003dd 909 MPT f/w,
815 * may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL
816 * (QUEUE_FULL) returned from device! --> get 0x0000?128
817 * and with SenseBytes set to 0.
819 if (pScsiReply->SCSIStatus == MPI_SCSI_STATUS_TASK_SET_FULL)
820 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
823 else if (scsi_state &
824 (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)
829 sc->result = DID_SOFT_ERROR << 16;
831 else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
832 /* Not real sure here either... */
833 sc->result = DID_RESET << 16;
835 else if (scsi_state & MPI_SCSI_STATE_QUEUE_TAG_REJECTED) {
836 /* Device Inq. data indicates that it supports
837 * QTags, but rejects QTag messages.
838 * This command completed OK.
840 * Not real sure here either so do nothing... */
843 if (sc->result == MPI_SCSI_STATUS_TASK_SET_FULL)
844 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
847 * Reservation Conflict, Busy,
848 * Command Terminated, CHECK
852 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
853 sc->result = DID_SOFT_ERROR << 16;
856 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
857 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
858 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
859 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
860 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
861 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
862 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
863 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
864 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
869 sc->result = DID_SOFT_ERROR << 16;
872 } /* switch(status) */
874 #ifdef MPT_DEBUG_REPLY
877 mptscsih_iocstatus_info_scsiio(ioc, status,
878 scsi_status, scsi_state, sc);
880 dreplyprintk(("%s: [%d:%d:%d:%d] cmd=0x%02x "
881 "result=0x%08x\n\tiocstatus=0x%04X "
882 "scsi_state=0x%02X scsi_status=0x%02X "
883 "loginfo=0x%08X\n", __FUNCTION__,
884 sc->device->host->host_no, sc->device->channel, sc->device->id,
885 sc->device->lun, sc->cmnd[0], sc->result, status,
886 scsi_state, scsi_status, log_info));
888 dreplyprintk(("%s: [%d:%d:%d:%d] resid=%d "
889 "bufflen=%d xfer_cnt=%d\n", __FUNCTION__,
890 sc->device->host->host_no,
891 sc->device->channel, sc->device->id,
892 sc->device->lun, scsi_get_resid(sc),
893 scsi_bufflen(sc), xfer_cnt));
897 } /* end of address reply case */
899 /* Unmap the DMA buffers, if any. */
902 sc->scsi_done(sc); /* Issue the command callback */
904 /* Free Chain buffers */
905 mptscsih_freeChainBuffers(ioc, req_idx);
910 * mptscsih_flush_running_cmds - For each command found, search
911 * Scsi_Host instance taskQ and reply to OS.
912 * Called only if recovering from a FW reload.
913 * @hd: Pointer to a SCSI HOST structure
917 * Must be called while new I/Os are being queued.
920 mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
922 MPT_ADAPTER *ioc = hd->ioc;
923 struct scsi_cmnd *SCpnt;
926 int max = ioc->req_depth;
928 dprintk((KERN_INFO MYNAM ": flush_ScsiLookup called\n"));
929 for (ii= 0; ii < max; ii++) {
930 if ((SCpnt = hd->ScsiLookup[ii]) != NULL) {
935 /* Null ScsiLookup index
937 hd->ScsiLookup[ii] = NULL;
939 mf = MPT_INDEX_2_MFPTR(ioc, ii);
940 dmfprintk(( "flush: ScsiDone (mf=%p,sc=%p)\n",
943 /* Free Chain buffers */
944 mptscsih_freeChainBuffers(ioc, ii);
946 /* Free Message frames */
947 mpt_free_msg_frame(ioc, mf);
949 if ((unsigned char *)mf != SCpnt->host_scribble)
952 /* Set status, free OS resources (SG DMA buffers)
955 scsi_dma_unmap(SCpnt);
957 SCpnt->result = DID_RESET << 16;
958 SCpnt->host_scribble = NULL;
960 SCpnt->scsi_done(SCpnt); /* Issue the command callback */
968 * mptscsih_search_running_cmds - Delete any commands associated
969 * with the specified target and lun. Function called only
970 * when a lun is disable by mid-layer.
971 * Do NOT access the referenced scsi_cmnd structure or
972 * members. Will cause either a paging or NULL ptr error.
973 * (BUT, BUT, BUT, the code does reference it! - mdr)
974 * @hd: Pointer to a SCSI HOST structure
975 * @vdevice: per device private data
979 * Called from slave_destroy.
982 mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
984 SCSIIORequest_t *mf = NULL;
986 int max = hd->ioc->req_depth;
987 struct scsi_cmnd *sc;
990 dsprintk((KERN_INFO MYNAM ": search_running channel %d id %d lun %d max %d\n",
991 vdevice->vtarget->channel, vdevice->vtarget->id, vdevice->lun, max));
993 for (ii=0; ii < max; ii++) {
994 if ((sc = hd->ScsiLookup[ii]) != NULL) {
996 mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii);
999 /* If the device is a hidden raid component, then its
1000 * expected that the mf->function will be RAID_SCSI_IO
1002 if (vdevice->vtarget->tflags &
1003 MPT_TARGET_FLAGS_RAID_COMPONENT && mf->Function !=
1004 MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)
1007 int_to_scsilun(vdevice->lun, &lun);
1008 if ((mf->Bus != vdevice->vtarget->channel) ||
1009 (mf->TargetID != vdevice->vtarget->id) ||
1010 memcmp(lun.scsi_lun, mf->LUN, 8))
1015 hd->ScsiLookup[ii] = NULL;
1016 mptscsih_freeChainBuffers(hd->ioc, ii);
1017 mpt_free_msg_frame(hd->ioc, (MPT_FRAME_HDR *)mf);
1018 if ((unsigned char *)mf != sc->host_scribble)
1021 sc->host_scribble = NULL;
1022 sc->result = DID_NO_CONNECT << 16;
1023 dsprintk(( "search_running: found (sc=%p, mf = %p) "
1024 "channel %d id %d, lun %d \n", sc, mf,
1025 vdevice->vtarget->channel, vdevice->vtarget->id, vdevice->lun));
1032 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1034 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1036 * mptscsih_report_queue_full - Report QUEUE_FULL status returned
1037 * from a SCSI target device.
1038 * @sc: Pointer to scsi_cmnd structure
1039 * @pScsiReply: Pointer to SCSIIOReply_t
1040 * @pScsiReq: Pointer to original SCSI request
1042 * This routine periodically reports QUEUE_FULL status returned from a
1043 * SCSI target device. It reports this to the console via kernel
1044 * printk() API call, not more than once every 10 seconds.
1047 mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq)
1049 long time = jiffies;
1052 if (sc->device == NULL)
1054 if (sc->device->host == NULL)
1056 if ((hd = (MPT_SCSI_HOST *)sc->device->host->hostdata) == NULL)
1059 if (time - hd->last_queue_full > 10 * HZ) {
1060 dprintk((MYIOC_s_WARN_FMT "Device (%d:%d:%d) reported QUEUE_FULL!\n",
1061 hd->ioc->name, 0, sc->device->id, sc->device->lun));
1062 hd->last_queue_full = time;
1066 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1068 * mptscsih_remove - Removed scsi devices
1069 * @pdev: Pointer to pci_dev structure
1074 mptscsih_remove(struct pci_dev *pdev)
1076 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1077 struct Scsi_Host *host = ioc->sh;
1086 scsi_remove_host(host);
1088 if((hd = (MPT_SCSI_HOST *)host->hostdata) == NULL)
1091 mptscsih_shutdown(pdev);
1095 if (hd->ScsiLookup != NULL) {
1096 sz1 = hd->ioc->req_depth * sizeof(void *);
1097 kfree(hd->ScsiLookup);
1098 hd->ScsiLookup = NULL;
1101 dprintk((MYIOC_s_INFO_FMT
1102 "Free'd ScsiLookup (%d) memory\n",
1103 hd->ioc->name, sz1));
1105 kfree(hd->info_kbuf);
1107 /* NULL the Scsi_Host pointer
1111 scsi_host_put(host);
1117 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1119 * mptscsih_shutdown - reboot notifier
1123 mptscsih_shutdown(struct pci_dev *pdev)
1125 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1126 struct Scsi_Host *host = ioc->sh;
1132 hd = (MPT_SCSI_HOST *)host->hostdata;
1137 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1139 * mptscsih_suspend - Fusion MPT scsi driver suspend routine.
1144 mptscsih_suspend(struct pci_dev *pdev, pm_message_t state)
1146 mptscsih_shutdown(pdev);
1147 return mpt_suspend(pdev,state);
1150 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1152 * mptscsih_resume - Fusion MPT scsi driver resume routine.
1157 mptscsih_resume(struct pci_dev *pdev)
1159 return mpt_resume(pdev);
1164 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1166 * mptscsih_info - Return information about MPT adapter
1167 * @SChost: Pointer to Scsi_Host structure
1169 * (linux scsi_host_template.info routine)
1171 * Returns pointer to buffer where information was written.
1174 mptscsih_info(struct Scsi_Host *SChost)
1179 h = (MPT_SCSI_HOST *)SChost->hostdata;
1182 if (h->info_kbuf == NULL)
1183 if ((h->info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)
1184 return h->info_kbuf;
1185 h->info_kbuf[0] = '\0';
1187 mpt_print_ioc_summary(h->ioc, h->info_kbuf, &size, 0, 0);
1188 h->info_kbuf[size-1] = '\0';
1191 return h->info_kbuf;
1202 mptscsih_copy_mem_info(struct info_str *info, char *data, int len)
1204 if (info->pos + len > info->length)
1205 len = info->length - info->pos;
1207 if (info->pos + len < info->offset) {
1212 if (info->pos < info->offset) {
1213 data += (info->offset - info->pos);
1214 len -= (info->offset - info->pos);
1218 memcpy(info->buffer + info->pos, data, len);
1224 mptscsih_copy_info(struct info_str *info, char *fmt, ...)
1230 va_start(args, fmt);
1231 len = vsprintf(buf, fmt, args);
1234 mptscsih_copy_mem_info(info, buf, len);
1239 mptscsih_host_info(MPT_ADAPTER *ioc, char *pbuf, off_t offset, int len)
1241 struct info_str info;
1245 info.offset = offset;
1248 mptscsih_copy_info(&info, "%s: %s, ", ioc->name, ioc->prod_name);
1249 mptscsih_copy_info(&info, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING, ioc->facts.FWVersion.Word);
1250 mptscsih_copy_info(&info, "Ports=%d, ", ioc->facts.NumberOfPorts);
1251 mptscsih_copy_info(&info, "MaxQ=%d\n", ioc->req_depth);
1253 return ((info.pos > info.offset) ? info.pos - info.offset : 0);
1256 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1258 * mptscsih_proc_info - Return information about MPT adapter
1259 * @host: scsi host struct
1260 * @buffer: if write, user data; if read, buffer for user
1261 * @start: returns the buffer address
1262 * @offset: if write, 0; if read, the current offset into the buffer from
1263 * the previous read.
1264 * @length: if write, return length;
1265 * @func: write = 1; read = 0
1267 * (linux scsi_host_template.info routine)
1270 mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
1271 int length, int func)
1273 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
1274 MPT_ADAPTER *ioc = hd->ioc;
1279 * write is not supported
1285 size = mptscsih_host_info(ioc, buffer, offset, length);
1291 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1292 #define ADD_INDEX_LOG(req_ent) do { } while(0)
1294 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1296 * mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine.
1297 * @SCpnt: Pointer to scsi_cmnd structure
1298 * @done: Pointer SCSI mid-layer IO completion function
1300 * (linux scsi_host_template.queuecommand routine)
1301 * This is the primary SCSI IO start routine. Create a MPI SCSIIORequest
1302 * from a linux scsi_cmnd request and send it to the IOC.
1304 * Returns 0. (rtn value discarded by linux scsi mid-layer)
1307 mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1311 SCSIIORequest_t *pScsiReq;
1312 VirtDevice *vdev = SCpnt->device->hostdata;
1321 hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata;
1322 lun = SCpnt->device->lun;
1323 SCpnt->scsi_done = done;
1325 dmfprintk((MYIOC_s_INFO_FMT "qcmd: SCpnt=%p, done()=%p\n",
1326 (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt, done));
1328 if (hd->resetPending) {
1329 dtmprintk((MYIOC_s_WARN_FMT "qcmd: SCpnt=%p timeout + 60HZ\n",
1330 (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt));
1331 return SCSI_MLQUEUE_HOST_BUSY;
1335 * Put together a MPT SCSI request...
1337 if ((mf = mpt_get_msg_frame(hd->ioc->DoneCtx, hd->ioc)) == NULL) {
1338 dprintk((MYIOC_s_WARN_FMT "QueueCmd, no msg frames!!\n",
1340 return SCSI_MLQUEUE_HOST_BUSY;
1343 pScsiReq = (SCSIIORequest_t *) mf;
1345 my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
1347 ADD_INDEX_LOG(my_idx);
1349 /* TUR's being issued with scsictl=0x02000000 (DATA_IN)!
1350 * Seems we may receive a buffer (datalen>0) even when there
1351 * will be no data transfer! GRRRRR...
1353 if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
1354 datalen = scsi_bufflen(SCpnt);
1355 scsidir = MPI_SCSIIO_CONTROL_READ; /* DATA IN (host<--ioc<--dev) */
1356 } else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
1357 datalen = scsi_bufflen(SCpnt);
1358 scsidir = MPI_SCSIIO_CONTROL_WRITE; /* DATA OUT (host-->ioc-->dev) */
1361 scsidir = MPI_SCSIIO_CONTROL_NODATATRANSFER;
1364 /* Default to untagged. Once a target structure has been allocated,
1365 * use the Inquiry data to determine if device supports tagged.
1368 && (vdev->vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)
1369 && (SCpnt->device->tagged_supported)) {
1370 scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
1372 scsictl = scsidir | MPI_SCSIIO_CONTROL_UNTAGGED;
1375 /* Use the above information to set up the message frame
1377 pScsiReq->TargetID = (u8) vdev->vtarget->id;
1378 pScsiReq->Bus = vdev->vtarget->channel;
1379 pScsiReq->ChainOffset = 0;
1380 if (vdev->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
1381 pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
1383 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
1384 pScsiReq->CDBLength = SCpnt->cmd_len;
1385 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
1386 pScsiReq->Reserved = 0;
1387 pScsiReq->MsgFlags = mpt_msg_flags();
1388 int_to_scsilun(SCpnt->device->lun, (struct scsi_lun *)pScsiReq->LUN);
1389 pScsiReq->Control = cpu_to_le32(scsictl);
1392 * Write SCSI CDB into the message
1394 cmd_len = SCpnt->cmd_len;
1395 for (ii=0; ii < cmd_len; ii++)
1396 pScsiReq->CDB[ii] = SCpnt->cmnd[ii];
1398 for (ii=cmd_len; ii < 16; ii++)
1399 pScsiReq->CDB[ii] = 0;
1402 pScsiReq->DataLength = cpu_to_le32(datalen);
1404 /* SenseBuffer low address */
1405 pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
1406 + (my_idx * MPT_SENSE_BUFFER_ALLOC));
1408 /* Now add the SG list
1409 * Always have a SGE even if null length.
1412 /* Add a NULL SGE */
1413 mptscsih_add_sge((char *)&pScsiReq->SGL, MPT_SGE_FLAGS_SSIMPLE_READ | 0,
1416 /* Add a 32 or 64 bit SGE */
1417 if (mptscsih_AddSGE(hd->ioc, SCpnt, pScsiReq, my_idx) != SUCCESS)
1421 SCpnt->host_scribble = (unsigned char *)mf;
1422 hd->ScsiLookup[my_idx] = SCpnt;
1424 mpt_put_msg_frame(hd->ioc->DoneCtx, hd->ioc, mf);
1425 dmfprintk((MYIOC_s_INFO_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n",
1426 hd->ioc->name, SCpnt, mf, my_idx));
1427 DBG_DUMP_REQUEST_FRAME(mf)
1431 hd->ScsiLookup[my_idx] = NULL;
1432 mptscsih_freeChainBuffers(hd->ioc, my_idx);
1433 mpt_free_msg_frame(hd->ioc, mf);
1434 return SCSI_MLQUEUE_HOST_BUSY;
1437 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1439 * mptscsih_freeChainBuffers - Function to free chain buffers associated
1440 * with a SCSI IO request
1441 * @hd: Pointer to the MPT_SCSI_HOST instance
1442 * @req_idx: Index of the SCSI IO request frame.
1444 * Called if SG chain buffer allocation fails and mptscsih callbacks.
1448 mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
1450 MPT_FRAME_HDR *chain;
1451 unsigned long flags;
1455 /* Get the first chain index and reset
1458 chain_idx = ioc->ReqToChain[req_idx];
1459 ioc->ReqToChain[req_idx] = MPT_HOST_NO_CHAIN;
1461 while (chain_idx != MPT_HOST_NO_CHAIN) {
1463 /* Save the next chain buffer index */
1464 next = ioc->ChainToChain[chain_idx];
1466 /* Free this chain buffer and reset
1469 ioc->ChainToChain[chain_idx] = MPT_HOST_NO_CHAIN;
1471 chain = (MPT_FRAME_HDR *) (ioc->ChainBuffer
1472 + (chain_idx * ioc->req_sz));
1474 spin_lock_irqsave(&ioc->FreeQlock, flags);
1475 list_add_tail(&chain->u.frame.linkage.list, &ioc->FreeChainQ);
1476 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1478 dmfprintk((MYIOC_s_INFO_FMT "FreeChainBuffers (index %d)\n",
1479 ioc->name, chain_idx));
1487 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1492 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1494 * mptscsih_TMHandler - Generic handler for SCSI Task Management.
1495 * @hd: Pointer to MPT SCSI HOST structure
1496 * @type: Task Management type
1497 * @channel: channel number for task management
1498 * @id: Logical Target ID for reset (if appropriate)
1499 * @lun: Logical Unit for reset (if appropriate)
1500 * @ctx2abort: Context for the task to be aborted (if appropriate)
1501 * @timeout: timeout for task management control
1503 * Fall through to mpt_HardResetHandler if: not operational, too many
1504 * failed TM requests or handshake failure.
1506 * Remark: Currently invoked from a non-interrupt thread (_bh).
1508 * Remark: With old EH code, at most 1 SCSI TaskMgmt function per IOC
1511 * Returns 0 for SUCCESS, or %FAILED.
1514 mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout)
1519 unsigned long flags;
1522 dtmprintk((MYIOC_s_INFO_FMT "TMHandler Entered!\n", ioc->name));
1524 // SJR - CHECKME - Can we avoid this here?
1525 // (mpt_HardResetHandler has this check...)
1526 spin_lock_irqsave(&ioc->diagLock, flags);
1527 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)) {
1528 spin_unlock_irqrestore(&ioc->diagLock, flags);
1531 spin_unlock_irqrestore(&ioc->diagLock, flags);
1533 /* Wait a fixed amount of time for the TM pending flag to be cleared.
1534 * If we time out and not bus reset, then we return a FAILED status
1536 * The call to mptscsih_tm_pending_wait() will set the pending flag
1538 * successful. Otherwise, reload the FW.
1540 if (mptscsih_tm_pending_wait(hd) == FAILED) {
1541 if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
1542 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler abort: "
1543 "Timed out waiting for last TM (%d) to complete! \n",
1544 hd->ioc->name, hd->tmPending));
1546 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) {
1547 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler target "
1548 "reset: Timed out waiting for last TM (%d) "
1549 "to complete! \n", hd->ioc->name,
1552 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
1553 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler bus reset: "
1554 "Timed out waiting for last TM (%d) to complete! \n",
1555 hd->ioc->name, hd->tmPending));
1559 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
1560 hd->tmPending |= (1 << type);
1561 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1564 ioc_raw_state = mpt_GetIocState(hd->ioc, 0);
1566 if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) {
1567 printk(MYIOC_s_WARN_FMT
1568 "TM Handler for type=%x: IOC Not operational (0x%x)!\n",
1569 ioc->name, type, ioc_raw_state);
1570 printk(KERN_WARNING " Issuing HardReset!!\n");
1571 if (mpt_HardResetHandler(ioc, CAN_SLEEP) < 0)
1572 printk((KERN_WARNING "TMHandler: HardReset "
1577 if (ioc_raw_state & MPI_DOORBELL_ACTIVE) {
1578 printk(MYIOC_s_WARN_FMT
1579 "TM Handler for type=%x: ioc_state: "
1580 "DOORBELL_ACTIVE (0x%x)!\n",
1581 ioc->name, type, ioc_raw_state);
1585 /* Isse the Task Mgmt request.
1587 if (hd->hard_resets < -1)
1590 rc = mptscsih_IssueTaskMgmt(hd, type, channel, id, lun,
1591 ctx2abort, timeout);
1593 printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n",
1596 dtmprintk((MYIOC_s_INFO_FMT "Issue of TaskMgmt Successful!\n",
1599 dtmprintk((MYIOC_s_INFO_FMT "TMHandler rc = %d!\n", hd->ioc->name, rc));
1605 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1607 * mptscsih_IssueTaskMgmt - Generic send Task Management function.
1608 * @hd: Pointer to MPT_SCSI_HOST structure
1609 * @type: Task Management type
1610 * @channel: channel number for task management
1611 * @id: Logical Target ID for reset (if appropriate)
1612 * @lun: Logical Unit for reset (if appropriate)
1613 * @ctx2abort: Context for the task to be aborted (if appropriate)
1614 * @timeout: timeout for task management control
1616 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
1617 * or a non-interrupt thread. In the former, must not call schedule().
1619 * Not all fields are meaningfull for all task types.
1621 * Returns 0 for SUCCESS, or FAILED.
1625 mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout)
1628 SCSITaskMgmt_t *pScsiTm;
1632 /* Return Fail to calling function if no message frames available.
1634 if ((mf = mpt_get_msg_frame(hd->ioc->TaskCtx, hd->ioc)) == NULL) {
1635 dfailprintk((MYIOC_s_ERR_FMT "IssueTaskMgmt, no msg frames!!\n",
1639 dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt request @ %p\n",
1640 hd->ioc->name, mf));
1642 /* Format the Request
1644 pScsiTm = (SCSITaskMgmt_t *) mf;
1645 pScsiTm->TargetID = id;
1646 pScsiTm->Bus = channel;
1647 pScsiTm->ChainOffset = 0;
1648 pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
1650 pScsiTm->Reserved = 0;
1651 pScsiTm->TaskType = type;
1652 pScsiTm->Reserved1 = 0;
1653 pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)
1654 ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0;
1656 int_to_scsilun(lun, (struct scsi_lun *)pScsiTm->LUN);
1658 for (ii=0; ii < 7; ii++)
1659 pScsiTm->Reserved2[ii] = 0;
1661 pScsiTm->TaskMsgContext = ctx2abort;
1663 dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt: ctx2abort (0x%08x) "
1664 "type=%d\n", hd->ioc->name, ctx2abort, type));
1666 DBG_DUMP_TM_REQUEST_FRAME((u32 *)pScsiTm);
1668 if ((retval = mpt_send_handshake_request(hd->ioc->TaskCtx, hd->ioc,
1669 sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, CAN_SLEEP)) != 0) {
1670 dfailprintk((MYIOC_s_ERR_FMT "send_handshake FAILED!"
1671 " (hd %p, ioc %p, mf %p, rc=%d) \n", hd->ioc->name, hd,
1672 hd->ioc, mf, retval));
1676 if(mptscsih_tm_wait_for_completion(hd, timeout) == FAILED) {
1677 dfailprintk((MYIOC_s_ERR_FMT "task management request TIMED OUT!"
1678 " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
1680 dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
1682 retval = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
1683 dtmprintk((MYIOC_s_INFO_FMT "rc=%d \n",
1684 hd->ioc->name, retval));
1689 * Handle success case, see if theres a non-zero ioc_status.
1691 if (hd->tm_iocstatus == MPI_IOCSTATUS_SUCCESS ||
1692 hd->tm_iocstatus == MPI_IOCSTATUS_SCSI_TASK_TERMINATED ||
1693 hd->tm_iocstatus == MPI_IOCSTATUS_SCSI_IOC_TERMINATED)
1703 * Free task managment mf, and corresponding tm flags
1705 mpt_free_msg_frame(hd->ioc, mf);
1707 hd->tmState = TM_STATE_NONE;
1712 mptscsih_get_tm_timeout(MPT_ADAPTER *ioc)
1714 switch (ioc->bus_type) {
1725 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1727 * mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant
1728 * @SCpnt: Pointer to scsi_cmnd structure, IO to be aborted
1730 * (linux scsi_host_template.eh_abort_handler routine)
1732 * Returns SUCCESS or FAILED.
1735 mptscsih_abort(struct scsi_cmnd * SCpnt)
1742 VirtDevice *vdevice;
1743 ulong sn = SCpnt->serial_number;
1746 /* If we can't locate our host adapter structure, return FAILED status.
1748 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL) {
1749 SCpnt->result = DID_RESET << 16;
1750 SCpnt->scsi_done(SCpnt);
1751 dfailprintk((KERN_INFO MYNAM ": mptscsih_abort: Can't locate "
1752 "host! (sc=%p)\n", SCpnt));
1757 printk(MYIOC_s_INFO_FMT "attempting task abort! (sc=%p)\n",
1759 scsi_print_command(SCpnt);
1761 vdevice = SCpnt->device->hostdata;
1762 if (!vdevice || !vdevice->vtarget) {
1763 dtmprintk((MYIOC_s_DEBUG_FMT "task abort: device has been "
1764 "deleted (sc=%p)\n", ioc->name, SCpnt));
1765 SCpnt->result = DID_NO_CONNECT << 16;
1766 SCpnt->scsi_done(SCpnt);
1771 /* Task aborts are not supported for hidden raid components.
1773 if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
1774 dtmprintk((MYIOC_s_DEBUG_FMT "task abort: hidden raid "
1775 "component (sc=%p)\n", ioc->name, SCpnt));
1776 SCpnt->result = DID_RESET << 16;
1781 /* Find this command
1783 if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) {
1784 /* Cmd not found in ScsiLookup.
1787 SCpnt->result = DID_RESET << 16;
1788 dtmprintk((KERN_INFO MYNAM ": %s: mptscsih_abort: "
1789 "Command not in the active list! (sc=%p)\n", ioc->name,
1795 if (hd->resetPending) {
1800 if (hd->timeouts < -1)
1803 /* Most important! Set TaskMsgContext to SCpnt's MsgContext!
1804 * (the IO to be ABORT'd)
1806 * NOTE: Since we do not byteswap MsgContext, we do not
1807 * swap it here either. It is an opaque cookie to
1808 * the controller, so it does not matter. -DaveM
1810 mf = MPT_INDEX_2_MFPTR(hd->ioc, scpnt_idx);
1811 ctx2abort = mf->u.frame.hwhdr.msgctxu.MsgContext;
1813 hd->abortSCpnt = SCpnt;
1815 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
1816 vdevice->vtarget->channel, vdevice->vtarget->id, vdevice->lun,
1817 ctx2abort, mptscsih_get_tm_timeout(ioc));
1819 if (SCPNT_TO_LOOKUP_IDX(SCpnt) == scpnt_idx &&
1820 SCpnt->serial_number == sn)
1824 printk(MYIOC_s_INFO_FMT "task abort: %s (sc=%p)\n",
1825 ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1833 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1835 * mptscsih_dev_reset - Perform a SCSI TARGET_RESET! new_eh variant
1836 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1838 * (linux scsi_host_template.eh_dev_reset_handler routine)
1840 * Returns SUCCESS or FAILED.
1843 mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
1847 VirtDevice *vdevice;
1850 /* If we can't locate our host adapter structure, return FAILED status.
1852 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1853 dtmprintk((KERN_INFO MYNAM ": mptscsih_dev_reset: Can't "
1854 "locate host! (sc=%p)\n", SCpnt));
1859 printk(MYIOC_s_INFO_FMT "attempting target reset! (sc=%p)\n",
1861 scsi_print_command(SCpnt);
1863 if (hd->resetPending) {
1868 vdevice = SCpnt->device->hostdata;
1869 if (!vdevice || !vdevice->vtarget) {
1874 /* Target reset to hidden raid component is not supported
1876 if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
1881 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
1882 vdevice->vtarget->channel, vdevice->vtarget->id, 0, 0,
1883 mptscsih_get_tm_timeout(ioc));
1886 printk (MYIOC_s_INFO_FMT "target reset: %s (sc=%p)\n",
1887 ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1896 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1898 * mptscsih_bus_reset - Perform a SCSI BUS_RESET! new_eh variant
1899 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1901 * (linux scsi_host_template.eh_bus_reset_handler routine)
1903 * Returns SUCCESS or FAILED.
1906 mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
1913 /* If we can't locate our host adapter structure, return FAILED status.
1915 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1916 dtmprintk((KERN_INFO MYNAM ": mptscsih_bus_reset: Can't "
1917 "locate host! (sc=%p)\n", SCpnt ));
1922 printk(MYIOC_s_INFO_FMT "attempting bus reset! (sc=%p)\n",
1924 scsi_print_command(SCpnt);
1926 if (hd->timeouts < -1)
1929 vdev = SCpnt->device->hostdata;
1930 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
1931 vdev->vtarget->channel, 0, 0, 0, mptscsih_get_tm_timeout(ioc));
1933 printk(MYIOC_s_INFO_FMT "bus reset: %s (sc=%p)\n",
1934 ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1942 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1944 * mptscsih_host_reset - Perform a SCSI host adapter RESET (new_eh variant)
1945 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1947 * (linux scsi_host_template.eh_host_reset_handler routine)
1949 * Returns SUCCESS or FAILED.
1952 mptscsih_host_reset(struct scsi_cmnd *SCpnt)
1958 /* If we can't locate the host to reset, then we failed. */
1959 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1960 dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: Can't "
1961 "locate host! (sc=%p)\n", SCpnt));
1966 printk(MYIOC_s_INFO_FMT "attempting host reset! (sc=%p)\n",
1969 /* If our attempts to reset the host failed, then return a failed
1970 * status. The host will be taken off line by the SCSI mid-layer.
1972 if (mpt_HardResetHandler(hd->ioc, CAN_SLEEP) < 0) {
1975 /* Make sure TM pending is cleared and TM state is set to
1980 hd->tmState = TM_STATE_NONE;
1983 printk(MYIOC_s_INFO_FMT "host reset: %s (sc=%p)\n",
1984 ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1989 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1991 * mptscsih_tm_pending_wait - wait for pending task management request to complete
1992 * @hd: Pointer to MPT host structure.
1994 * Returns {SUCCESS,FAILED}.
1997 mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd)
1999 unsigned long flags;
2000 int loop_count = 4 * 10; /* Wait 10 seconds */
2001 int status = FAILED;
2004 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
2005 if (hd->tmState == TM_STATE_NONE) {
2006 hd->tmState = TM_STATE_IN_PROGRESS;
2008 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2012 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2014 } while (--loop_count);
2019 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2021 * mptscsih_tm_wait_for_completion - wait for completion of TM task
2022 * @hd: Pointer to MPT host structure.
2023 * @timeout: timeout value
2025 * Returns {SUCCESS,FAILED}.
2028 mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout )
2030 unsigned long flags;
2031 int loop_count = 4 * timeout;
2032 int status = FAILED;
2035 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
2036 if(hd->tmPending == 0) {
2038 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2041 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2043 } while (--loop_count);
2048 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2050 mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code)
2054 switch (response_code) {
2055 case MPI_SCSITASKMGMT_RSP_TM_COMPLETE:
2056 desc = "The task completed.";
2058 case MPI_SCSITASKMGMT_RSP_INVALID_FRAME:
2059 desc = "The IOC received an invalid frame status.";
2061 case MPI_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED:
2062 desc = "The task type is not supported.";
2064 case MPI_SCSITASKMGMT_RSP_TM_FAILED:
2065 desc = "The requested task failed.";
2067 case MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED:
2068 desc = "The task completed successfully.";
2070 case MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN:
2071 desc = "The LUN request is invalid.";
2073 case MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC:
2074 desc = "The task is in the IOC queue and has not been sent to target.";
2080 printk(MYIOC_s_INFO_FMT "Response Code(0x%08x): F/W: %s\n",
2081 ioc->name, response_code, desc);
2084 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2086 * mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
2087 * @ioc: Pointer to MPT_ADAPTER structure
2088 * @mf: Pointer to SCSI task mgmt request frame
2089 * @mr: Pointer to SCSI task mgmt reply frame
2091 * This routine is called from mptbase.c::mpt_interrupt() at the completion
2092 * of any SCSI task management request.
2093 * This routine is registered with the MPT (base) driver at driver
2094 * load/init time via the mpt_register() API call.
2096 * Returns 1 indicating alloc'd request frame ptr should be freed.
2099 mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
2101 SCSITaskMgmtReply_t *pScsiTmReply;
2102 SCSITaskMgmt_t *pScsiTmReq;
2104 unsigned long flags;
2107 u32 termination_count;
2109 dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt completed (mf=%p,mr=%p)\n",
2110 ioc->name, mf, mr));
2112 dtmprintk((MYIOC_s_WARN_FMT
2113 "TaskMgmt Complete: NULL Scsi Host Ptr\n", ioc->name));
2118 dtmprintk((MYIOC_s_WARN_FMT
2119 "ERROR! TaskMgmt Reply: NULL Request %p\n", ioc->name, mf));
2123 hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
2124 pScsiTmReply = (SCSITaskMgmtReply_t*)mr;
2125 pScsiTmReq = (SCSITaskMgmt_t*)mf;
2126 tmType = pScsiTmReq->TaskType;
2127 iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2128 termination_count = le32_to_cpu(pScsiTmReply->TerminationCount);
2130 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05 &&
2131 pScsiTmReply->ResponseCode)
2132 mptscsih_taskmgmt_response_code(ioc,
2133 pScsiTmReply->ResponseCode);
2134 DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply);
2136 #if defined(MPT_DEBUG_REPLY) || defined(MPT_DEBUG_TM)
2137 printk("%s: ha=%d [%d:%d:0] task_type=0x%02X "
2138 "iocstatus=0x%04X\n\tloginfo=0x%08X response_code=0x%02X "
2139 "term_cmnds=%d\n", __FUNCTION__, ioc->id, pScsiTmReply->Bus,
2140 pScsiTmReply->TargetID, pScsiTmReq->TaskType,
2141 le16_to_cpu(pScsiTmReply->IOCStatus),
2142 le32_to_cpu(pScsiTmReply->IOCLogInfo),pScsiTmReply->ResponseCode,
2143 le32_to_cpu(pScsiTmReply->TerminationCount));
2146 dtmprintk((MYIOC_s_WARN_FMT " TaskMgmt SUCCESS\n", ioc->name));
2147 hd->abortSCpnt = NULL;
2151 /* Error? (anything non-zero?) */
2153 /* clear flags and continue.
2157 case MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK:
2158 if (termination_count == 1)
2159 iocstatus = MPI_IOCSTATUS_SCSI_TASK_TERMINATED;
2160 hd->abortSCpnt = NULL;
2163 case MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS:
2165 /* If an internal command is present
2166 * or the TM failed - reload the FW.
2167 * FC FW may respond FAILED to an ABORT
2169 if (iocstatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED ||
2171 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
2172 printk((KERN_WARNING " Firmware Reload FAILED!!\n"));
2175 case MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET:
2181 spin_lock_irqsave(&ioc->FreeQlock, flags);
2183 hd->tmState = TM_STATE_NONE;
2184 hd->tm_iocstatus = iocstatus;
2185 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2190 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2192 * This is anyones guess quite frankly.
2195 mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
2196 sector_t capacity, int geom[])
2206 dummy = heads * sectors;
2207 cylinders = capacity;
2208 sector_div(cylinders,dummy);
2211 * Handle extended translation size for logical drives
2214 if ((ulong)capacity >= 0x200000) {
2217 dummy = heads * sectors;
2218 cylinders = capacity;
2219 sector_div(cylinders,dummy);
2225 geom[2] = cylinders;
2227 dprintk((KERN_NOTICE
2228 ": bios_param: Id=%i Lun=%i Channel=%i CHS=%i/%i/%i\n",
2229 sdev->id, sdev->lun, sdev->channel, (int)cylinders, heads, sectors));
2234 /* Search IOC page 3 to determine if this is hidden physical disk
2238 mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id)
2240 struct inactive_raid_component_info *component_info;
2244 if (!ioc->raid_data.pIocPg3)
2246 for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2247 if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) &&
2248 (channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) {
2255 * Check inactive list for matching phys disks
2257 if (list_empty(&ioc->raid_data.inactive_list))
2260 down(&ioc->raid_data.inactive_list_mutex);
2261 list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
2263 if ((component_info->d.PhysDiskID == id) &&
2264 (component_info->d.PhysDiskBus == channel))
2267 up(&ioc->raid_data.inactive_list_mutex);
2272 EXPORT_SYMBOL(mptscsih_is_phys_disk);
2275 mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id)
2277 struct inactive_raid_component_info *component_info;
2281 if (!ioc->raid_data.pIocPg3)
2283 for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2284 if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) &&
2285 (channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) {
2286 rc = ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum;
2292 * Check inactive list for matching phys disks
2294 if (list_empty(&ioc->raid_data.inactive_list))
2297 down(&ioc->raid_data.inactive_list_mutex);
2298 list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
2300 if ((component_info->d.PhysDiskID == id) &&
2301 (component_info->d.PhysDiskBus == channel))
2302 rc = component_info->d.PhysDiskNum;
2304 up(&ioc->raid_data.inactive_list_mutex);
2309 EXPORT_SYMBOL(mptscsih_raid_id_to_num);
2312 * OS entry point to allow for host driver to free allocated memory
2313 * Called if no device present or device being unloaded
2316 mptscsih_slave_destroy(struct scsi_device *sdev)
2318 struct Scsi_Host *host = sdev->host;
2319 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
2320 VirtTarget *vtarget;
2321 VirtDevice *vdevice;
2322 struct scsi_target *starget;
2324 starget = scsi_target(sdev);
2325 vtarget = starget->hostdata;
2326 vdevice = sdev->hostdata;
2328 mptscsih_search_running_cmds(hd, vdevice);
2329 vtarget->num_luns--;
2330 mptscsih_synchronize_cache(hd, vdevice);
2332 sdev->hostdata = NULL;
2335 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2337 * mptscsih_change_queue_depth - This function will set a devices queue depth
2338 * @sdev: per scsi_device pointer
2339 * @qdepth: requested queue depth
2341 * Adding support for new 'change_queue_depth' api.
2344 mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
2346 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sdev->host->hostdata;
2347 VirtTarget *vtarget;
2348 struct scsi_target *starget;
2352 starget = scsi_target(sdev);
2353 vtarget = starget->hostdata;
2355 if (hd->ioc->bus_type == SPI) {
2356 if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
2358 else if (sdev->type == TYPE_DISK &&
2359 vtarget->minSyncFactor <= MPT_ULTRA160)
2360 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2362 max_depth = MPT_SCSI_CMD_PER_DEV_LOW;
2364 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2366 if (qdepth > max_depth)
2371 tagged = MSG_SIMPLE_TAG;
2373 scsi_adjust_queue_depth(sdev, tagged, qdepth);
2374 return sdev->queue_depth;
2378 * OS entry point to adjust the queue_depths on a per-device basis.
2379 * Called once per device the bus scan. Use it to force the queue_depth
2380 * member to 1 if a device does not support Q tags.
2381 * Return non-zero if fails.
2384 mptscsih_slave_configure(struct scsi_device *sdev)
2386 struct Scsi_Host *sh = sdev->host;
2387 VirtTarget *vtarget;
2388 VirtDevice *vdevice;
2389 struct scsi_target *starget;
2390 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sh->hostdata;
2392 starget = scsi_target(sdev);
2393 vtarget = starget->hostdata;
2394 vdevice = sdev->hostdata;
2396 dsprintk((MYIOC_s_INFO_FMT
2397 "device @ %p, channel=%d, id=%d, lun=%d\n",
2398 hd->ioc->name, sdev, sdev->channel, sdev->id, sdev->lun));
2399 if (hd->ioc->bus_type == SPI)
2400 dsprintk((MYIOC_s_INFO_FMT
2401 "sdtr %d wdtr %d ppr %d inq length=%d\n",
2402 hd->ioc->name, sdev->sdtr, sdev->wdtr,
2403 sdev->ppr, sdev->inquiry_len));
2405 if (sdev->id > sh->max_id) {
2406 /* error case, should never happen */
2407 scsi_adjust_queue_depth(sdev, 0, 1);
2408 goto slave_configure_exit;
2411 vdevice->configured_lun = 1;
2412 mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH);
2414 dsprintk((MYIOC_s_INFO_FMT
2415 "Queue depth=%d, tflags=%x\n",
2416 hd->ioc->name, sdev->queue_depth, vtarget->tflags));
2418 if (hd->ioc->bus_type == SPI)
2419 dsprintk((MYIOC_s_INFO_FMT
2420 "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
2421 hd->ioc->name, vtarget->negoFlags, vtarget->maxOffset,
2422 vtarget->minSyncFactor));
2424 slave_configure_exit:
2426 dsprintk((MYIOC_s_INFO_FMT
2427 "tagged %d, simple %d, ordered %d\n",
2428 hd->ioc->name,sdev->tagged_supported, sdev->simple_tags,
2429 sdev->ordered_tags));
2434 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2436 * Private routines...
2439 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2440 /* Utility function to copy sense data from the scsi_cmnd buffer
2441 * to the FC and SCSI target structures.
2445 mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
2448 SCSIIORequest_t *pReq;
2449 u32 sense_count = le32_to_cpu(pScsiReply->SenseCount);
2451 /* Get target structure
2453 pReq = (SCSIIORequest_t *) mf;
2454 vdev = sc->device->hostdata;
2460 /* Copy the sense received into the scsi command block. */
2461 req_index = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2462 sense_data = ((u8 *)hd->ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC));
2463 memcpy(sc->sense_buffer, sense_data, SNS_LEN(sc));
2465 /* Log SMART data (asc = 0x5D, non-IM case only) if required.
2467 if ((hd->ioc->events) && (hd->ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) {
2468 if ((sense_data[12] == 0x5D) && (vdev->vtarget->raidVolume == 0)) {
2470 MPT_ADAPTER *ioc = hd->ioc;
2472 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
2473 ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
2474 ioc->events[idx].eventContext = ioc->eventContext;
2476 ioc->events[idx].data[0] = (pReq->LUN[1] << 24) |
2477 (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) |
2478 (sc->device->channel << 8) | sc->device->id;
2480 ioc->events[idx].data[1] = (sense_data[13] << 8) | sense_data[12];
2482 ioc->eventContext++;
2483 if (hd->ioc->pcidev->vendor ==
2484 PCI_VENDOR_ID_IBM) {
2485 mptscsih_issue_sep_command(hd->ioc,
2486 vdev->vtarget, MPI_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT);
2487 vdev->vtarget->tflags |=
2488 MPT_TARGET_FLAGS_LED_ON;
2493 dprintk((MYIOC_s_INFO_FMT "Hmmm... SenseData len=0! (?)\n",
2499 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc)
2504 hd = (MPT_SCSI_HOST *) sc->device->host->hostdata;
2506 for (i = 0; i < hd->ioc->req_depth; i++) {
2507 if (hd->ScsiLookup[i] == sc) {
2515 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2517 mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2520 unsigned long flags;
2523 dtmprintk((KERN_WARNING MYNAM
2524 ": IOC %s_reset routed to SCSI host driver!\n",
2525 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
2526 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
2528 /* If a FW reload request arrives after base installed but
2529 * before all scsi hosts have been attached, then an alt_ioc
2530 * may have a NULL sh pointer.
2532 if ((ioc->sh == NULL) || (ioc->sh->hostdata == NULL))
2535 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2537 if (reset_phase == MPT_IOC_SETUP_RESET) {
2538 dtmprintk((MYIOC_s_WARN_FMT "Setup-Diag Reset\n", ioc->name));
2541 * 1. Set Hard Reset Pending Flag
2542 * All new commands go to doneQ
2544 hd->resetPending = 1;
2546 } else if (reset_phase == MPT_IOC_PRE_RESET) {
2547 dtmprintk((MYIOC_s_WARN_FMT "Pre-Diag Reset\n", ioc->name));
2549 /* 2. Flush running commands
2550 * Clean ScsiLookup (and associated memory)
2554 /* 2b. Reply to OS all known outstanding I/O commands.
2556 mptscsih_flush_running_cmds(hd);
2558 /* 2c. If there was an internal command that
2559 * has not completed, configuration or io request,
2560 * free these resources.
2563 del_timer(&hd->timer);
2564 mpt_free_msg_frame(ioc, hd->cmdPtr);
2567 dtmprintk((MYIOC_s_WARN_FMT "Pre-Reset complete.\n", ioc->name));
2570 dtmprintk((MYIOC_s_WARN_FMT "Post-Diag Reset\n", ioc->name));
2572 /* Once a FW reload begins, all new OS commands are
2573 * redirected to the doneQ w/ a reset status.
2574 * Init all control structures.
2577 /* ScsiLookup initialization
2579 for (ii=0; ii < hd->ioc->req_depth; ii++)
2580 hd->ScsiLookup[ii] = NULL;
2582 /* 2. Chain Buffer initialization
2585 /* 4. Renegotiate to all devices, if SPI
2588 /* 5. Enable new commands to be posted
2590 spin_lock_irqsave(&ioc->FreeQlock, flags);
2592 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2593 hd->resetPending = 0;
2594 hd->tmState = TM_STATE_NONE;
2596 /* 6. If there was an internal command,
2597 * wake this process up.
2601 * Wake up the original calling thread
2603 hd->pLocal = &hd->localReply;
2604 hd->pLocal->completion = MPT_SCANDV_DID_RESET;
2605 hd->scandv_wait_done = 1;
2606 wake_up(&hd->scandv_waitq);
2610 dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name));
2614 return 1; /* currently means nothing really */
2617 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2619 mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2622 u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
2624 devtverboseprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
2627 if (ioc->sh == NULL ||
2628 ((hd = (MPT_SCSI_HOST *)ioc->sh->hostdata) == NULL))
2632 case MPI_EVENT_UNIT_ATTENTION: /* 03 */
2635 case MPI_EVENT_IOC_BUS_RESET: /* 04 */
2636 case MPI_EVENT_EXT_BUS_RESET: /* 05 */
2637 if (hd && (ioc->bus_type == SPI) && (hd->soft_resets < -1))
2640 case MPI_EVENT_LOGOUT: /* 09 */
2644 case MPI_EVENT_RESCAN: /* 06 */
2648 * CHECKME! Don't think we need to do
2649 * anything for these, but...
2651 case MPI_EVENT_LINK_STATUS_CHANGE: /* 07 */
2652 case MPI_EVENT_LOOP_STATE_CHANGE: /* 08 */
2654 * CHECKME! Falling thru...
2658 case MPI_EVENT_INTEGRATED_RAID: /* 0B */
2661 case MPI_EVENT_NONE: /* 00 */
2662 case MPI_EVENT_LOG_DATA: /* 01 */
2663 case MPI_EVENT_STATE_CHANGE: /* 02 */
2664 case MPI_EVENT_EVENT_CHANGE: /* 0A */
2666 dprintk((KERN_INFO " Ignoring event (=%02Xh)\n", event));
2670 return 1; /* currently means nothing really */
2673 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2675 * Bus Scan and Domain Validation functionality ...
2678 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2680 * mptscsih_scandv_complete - Scan and DV callback routine registered
2681 * to Fustion MPT (base) driver.
2683 * @ioc: Pointer to MPT_ADAPTER structure
2684 * @mf: Pointer to original MPT request frame
2685 * @mr: Pointer to MPT reply frame (NULL if TurboReply)
2687 * This routine is called from mpt.c::mpt_interrupt() at the completion
2688 * of any SCSI IO request.
2689 * This routine is registered with the Fusion MPT (base) driver at driver
2690 * load/init time via the mpt_register() API call.
2692 * Returns 1 indicating alloc'd request frame ptr should be freed.
2694 * Remark: Sets a completion code and (possibly) saves sense data
2695 * in the IOC member localReply structure.
2696 * Used ONLY for DV and other internal commands.
2699 mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
2702 SCSIIORequest_t *pReq;
2706 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2709 (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) {
2710 printk(MYIOC_s_ERR_FMT
2711 "ScanDvComplete, %s req frame ptr! (=%p)\n",
2712 ioc->name, mf?"BAD":"NULL", (void *) mf);
2716 del_timer(&hd->timer);
2717 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2718 hd->ScsiLookup[req_idx] = NULL;
2719 pReq = (SCSIIORequest_t *) mf;
2721 if (mf != hd->cmdPtr) {
2722 printk(MYIOC_s_WARN_FMT "ScanDvComplete (mf=%p, cmdPtr=%p, idx=%d)\n",
2723 hd->ioc->name, (void *)mf, (void *) hd->cmdPtr, req_idx);
2727 ddvprintk((MYIOC_s_INFO_FMT "ScanDvComplete (mf=%p,mr=%p,idx=%d)\n",
2728 hd->ioc->name, mf, mr, req_idx));
2730 hd->pLocal = &hd->localReply;
2731 hd->pLocal->scsiStatus = 0;
2733 /* If target struct exists, clear sense valid flag.
2736 completionCode = MPT_SCANDV_GOOD;
2738 SCSIIOReply_t *pReply;
2742 pReply = (SCSIIOReply_t *) mr;
2744 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2745 scsi_status = pReply->SCSIStatus;
2747 ddvtprintk((KERN_NOTICE " IOCStatus=%04xh, SCSIState=%02xh, SCSIStatus=%02xh, IOCLogInfo=%08xh\n",
2748 status, pReply->SCSIState, scsi_status,
2749 le32_to_cpu(pReply->IOCLogInfo)));
2753 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
2754 completionCode = MPT_SCANDV_SELECTION_TIMEOUT;
2757 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
2758 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
2759 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
2760 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
2761 completionCode = MPT_SCANDV_DID_RESET;
2764 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
2765 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
2766 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
2767 if (pReply->Function == MPI_FUNCTION_CONFIG) {
2768 ConfigReply_t *pr = (ConfigReply_t *)mr;
2769 completionCode = MPT_SCANDV_GOOD;
2770 hd->pLocal->header.PageVersion = pr->Header.PageVersion;
2771 hd->pLocal->header.PageLength = pr->Header.PageLength;
2772 hd->pLocal->header.PageNumber = pr->Header.PageNumber;
2773 hd->pLocal->header.PageType = pr->Header.PageType;
2775 } else if (pReply->Function == MPI_FUNCTION_RAID_ACTION) {
2776 /* If the RAID Volume request is successful,
2777 * return GOOD, else indicate that
2778 * some type of error occurred.
2780 MpiRaidActionReply_t *pr = (MpiRaidActionReply_t *)mr;
2781 if (le16_to_cpu(pr->ActionStatus) == MPI_RAID_ACTION_ASTATUS_SUCCESS)
2782 completionCode = MPT_SCANDV_GOOD;
2784 completionCode = MPT_SCANDV_SOME_ERROR;
2785 memcpy(hd->pLocal->sense, pr, sizeof(hd->pLocal->sense));
2787 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID) {
2791 /* save sense data in global structure
2793 completionCode = MPT_SCANDV_SENSE;
2794 hd->pLocal->scsiStatus = scsi_status;
2795 sense_data = ((u8 *)hd->ioc->sense_buf_pool +
2796 (req_idx * MPT_SENSE_BUFFER_ALLOC));
2798 sz = min_t(int, pReq->SenseBufferLength,
2799 SCSI_STD_SENSE_BYTES);
2800 memcpy(hd->pLocal->sense, sense_data, sz);
2802 ddvprintk((KERN_NOTICE " Check Condition, sense ptr %p\n",
2804 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_FAILED) {
2805 if (pReq->CDB[0] == INQUIRY)
2806 completionCode = MPT_SCANDV_ISSUE_SENSE;
2808 completionCode = MPT_SCANDV_DID_RESET;
2810 else if (pReply->SCSIState & MPI_SCSI_STATE_NO_SCSI_STATUS)
2811 completionCode = MPT_SCANDV_DID_RESET;
2812 else if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
2813 completionCode = MPT_SCANDV_DID_RESET;
2815 completionCode = MPT_SCANDV_GOOD;
2816 hd->pLocal->scsiStatus = scsi_status;
2820 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
2821 if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
2822 completionCode = MPT_SCANDV_DID_RESET;
2824 completionCode = MPT_SCANDV_SOME_ERROR;
2828 completionCode = MPT_SCANDV_SOME_ERROR;
2831 } /* switch(status) */
2833 ddvtprintk((KERN_NOTICE " completionCode set to %08xh\n",
2835 } /* end of address reply case */
2837 hd->pLocal->completion = completionCode;
2839 /* MF and RF are freed in mpt_interrupt
2842 /* Free Chain buffers (will never chain) in scan or dv */
2843 //mptscsih_freeChainBuffers(ioc, req_idx);
2846 * Wake up the original calling thread
2848 hd->scandv_wait_done = 1;
2849 wake_up(&hd->scandv_waitq);
2854 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2855 /* mptscsih_timer_expired - Call back for timer process.
2856 * Used only for dv functionality.
2857 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
2861 mptscsih_timer_expired(unsigned long data)
2863 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) data;
2865 ddvprintk((MYIOC_s_WARN_FMT "Timer Expired! Cmd %p\n", hd->ioc->name, hd->cmdPtr));
2868 MPIHeader_t *cmd = (MPIHeader_t *)hd->cmdPtr;
2870 if (cmd->Function == MPI_FUNCTION_SCSI_IO_REQUEST) {
2871 /* Desire to issue a task management request here.
2872 * TM requests MUST be single threaded.
2873 * If old eh code and no TM current, issue request.
2874 * If new eh code, do nothing. Wait for OS cmd timeout
2877 ddvtprintk((MYIOC_s_NOTE_FMT "DV Cmd Timeout: NoOp\n", hd->ioc->name));
2879 /* Perform a FW reload */
2880 if (mpt_HardResetHandler(hd->ioc, NO_SLEEP) < 0) {
2881 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", hd->ioc->name);
2885 /* This should NEVER happen */
2886 printk(MYIOC_s_WARN_FMT "Null cmdPtr!!!!\n", hd->ioc->name);
2889 /* No more processing.
2890 * TM call will generate an interrupt for SCSI TM Management.
2891 * The FW will reply to all outstanding commands, callback will finish cleanup.
2892 * Hard reset clean-up will free all resources.
2894 ddvprintk((MYIOC_s_WARN_FMT "Timer Expired Complete!\n", hd->ioc->name));
2900 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2902 * mptscsih_do_cmd - Do internal command.
2903 * @hd: MPT_SCSI_HOST pointer
2904 * @io: INTERNAL_CMD pointer.
2906 * Issue the specified internally generated command and do command
2907 * specific cleanup. For bus scan / DV only.
2908 * NOTES: If command is Inquiry and status is good,
2909 * initialize a target structure, save the data
2911 * Remark: Single threaded access only.
2914 * < 0 if an illegal command or no resources
2918 * > 0 if command complete but some type of completion error.
2921 mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
2924 SCSIIORequest_t *pScsiReq;
2925 SCSIIORequest_t ReqCopy;
2926 int my_idx, ii, dir;
2930 char CDB[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
2933 in_isr = in_interrupt();
2935 dprintk((MYIOC_s_WARN_FMT "Internal SCSI IO request not allowed in ISR context!\n",
2941 /* Set command specific information
2946 dir = MPI_SCSIIO_CONTROL_READ;
2952 case TEST_UNIT_READY:
2954 dir = MPI_SCSIIO_CONTROL_READ;
2960 dir = MPI_SCSIIO_CONTROL_READ;
2962 CDB[4] = 1; /*Spin up the disk */
2970 dir = MPI_SCSIIO_CONTROL_READ;
2976 dir = MPI_SCSIIO_CONTROL_READ;
2978 if (io->flags & MPT_ICFLAG_ECHO) {
2984 if (io->flags & MPT_ICFLAG_BUF_CAP) {
2987 CDB[6] = (io->size >> 16) & 0xFF;
2988 CDB[7] = (io->size >> 8) & 0xFF;
2989 CDB[8] = io->size & 0xFF;
2995 dir = MPI_SCSIIO_CONTROL_WRITE;
2997 if (io->flags & MPT_ICFLAG_ECHO) {
3002 CDB[6] = (io->size >> 16) & 0xFF;
3003 CDB[7] = (io->size >> 8) & 0xFF;
3004 CDB[8] = io->size & 0xFF;
3010 dir = MPI_SCSIIO_CONTROL_READ;
3017 dir = MPI_SCSIIO_CONTROL_READ;
3022 case SYNCHRONIZE_CACHE:
3024 dir = MPI_SCSIIO_CONTROL_READ;
3026 // CDB[1] = 0x02; /* set immediate bit */
3035 /* Get and Populate a free Frame
3037 if ((mf = mpt_get_msg_frame(hd->ioc->InternalCtx, hd->ioc)) == NULL) {
3038 ddvprintk((MYIOC_s_WARN_FMT "No msg frames!\n",
3043 pScsiReq = (SCSIIORequest_t *) mf;
3045 /* Get the request index */
3046 my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3047 ADD_INDEX_LOG(my_idx); /* for debug */
3049 if (io->flags & MPT_ICFLAG_PHYS_DISK) {
3050 pScsiReq->TargetID = io->physDiskNum;
3052 pScsiReq->ChainOffset = 0;
3053 pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
3055 pScsiReq->TargetID = io->id;
3056 pScsiReq->Bus = io->channel;
3057 pScsiReq->ChainOffset = 0;
3058 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
3061 pScsiReq->CDBLength = cmdLen;
3062 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
3064 pScsiReq->Reserved = 0;
3066 pScsiReq->MsgFlags = mpt_msg_flags();
3067 /* MsgContext set in mpt_get_msg_fram call */
3069 int_to_scsilun(io->lun, (struct scsi_lun *)pScsiReq->LUN);
3071 if (io->flags & MPT_ICFLAG_TAGGED_CMD)
3072 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ);
3074 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3076 if (cmd == REQUEST_SENSE) {
3077 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3078 ddvprintk((MYIOC_s_INFO_FMT "Untagged! 0x%2x\n",
3079 hd->ioc->name, cmd));
3082 for (ii=0; ii < 16; ii++)
3083 pScsiReq->CDB[ii] = CDB[ii];
3085 pScsiReq->DataLength = cpu_to_le32(io->size);
3086 pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
3087 + (my_idx * MPT_SENSE_BUFFER_ALLOC));
3089 ddvprintk((MYIOC_s_INFO_FMT "Sending Command 0x%x for (%d:%d:%d)\n",
3090 hd->ioc->name, cmd, io->channel, io->id, io->lun));
3092 if (dir == MPI_SCSIIO_CONTROL_READ) {
3093 mpt_add_sge((char *) &pScsiReq->SGL,
3094 MPT_SGE_FLAGS_SSIMPLE_READ | io->size,
3097 mpt_add_sge((char *) &pScsiReq->SGL,
3098 MPT_SGE_FLAGS_SSIMPLE_WRITE | io->size,
3102 /* The ISR will free the request frame, but we need
3103 * the information to initialize the target. Duplicate.
3105 memcpy(&ReqCopy, pScsiReq, sizeof(SCSIIORequest_t));
3107 /* Issue this command after:
3110 * Wait until the reply has been received
3111 * ScsiScanDvCtx callback function will
3113 * set scandv_wait_done and call wake_up
3116 hd->timer.expires = jiffies + HZ*cmdTimeout;
3117 hd->scandv_wait_done = 0;
3119 /* Save cmd pointer, for resource free if timeout or
3124 add_timer(&hd->timer);
3125 mpt_put_msg_frame(hd->ioc->InternalCtx, hd->ioc, mf);
3126 wait_event(hd->scandv_waitq, hd->scandv_wait_done);
3129 rc = hd->pLocal->completion;
3130 hd->pLocal->skip = 0;
3132 /* Always set fatal error codes in some cases.
3134 if (rc == MPT_SCANDV_SELECTION_TIMEOUT)
3136 else if (rc == MPT_SCANDV_SOME_ERROR)
3140 /* This should never happen. */
3141 ddvprintk((MYIOC_s_INFO_FMT "_do_cmd: Null pLocal!!!\n",
3148 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3150 * mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
3151 * @hd: Pointer to a SCSI HOST structure
3152 * @vdevice: virtual target device
3154 * Uses the ISR, but with special processing.
3155 * MUST be single-threaded.
3159 mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
3163 /* Ignore hidden raid components, this is handled when the command
3164 * is sent to the volume
3166 if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
3169 if (vdevice->vtarget->type != TYPE_DISK || vdevice->vtarget->deleted ||
3170 !vdevice->configured_lun)
3173 /* Following parameters will not change
3176 iocmd.cmd = SYNCHRONIZE_CACHE;
3178 iocmd.physDiskNum = -1;
3180 iocmd.data_dma = -1;
3182 iocmd.rsvd = iocmd.rsvd2 = 0;
3183 iocmd.channel = vdevice->vtarget->channel;
3184 iocmd.id = vdevice->vtarget->id;
3185 iocmd.lun = vdevice->lun;
3187 mptscsih_do_cmd(hd, &iocmd);
3190 EXPORT_SYMBOL(mptscsih_remove);
3191 EXPORT_SYMBOL(mptscsih_shutdown);
3193 EXPORT_SYMBOL(mptscsih_suspend);
3194 EXPORT_SYMBOL(mptscsih_resume);
3196 EXPORT_SYMBOL(mptscsih_proc_info);
3197 EXPORT_SYMBOL(mptscsih_info);
3198 EXPORT_SYMBOL(mptscsih_qcmd);
3199 EXPORT_SYMBOL(mptscsih_slave_destroy);
3200 EXPORT_SYMBOL(mptscsih_slave_configure);
3201 EXPORT_SYMBOL(mptscsih_abort);
3202 EXPORT_SYMBOL(mptscsih_dev_reset);
3203 EXPORT_SYMBOL(mptscsih_bus_reset);
3204 EXPORT_SYMBOL(mptscsih_host_reset);
3205 EXPORT_SYMBOL(mptscsih_bios_param);
3206 EXPORT_SYMBOL(mptscsih_io_done);
3207 EXPORT_SYMBOL(mptscsih_taskmgmt_complete);
3208 EXPORT_SYMBOL(mptscsih_scandv_complete);
3209 EXPORT_SYMBOL(mptscsih_event_process);
3210 EXPORT_SYMBOL(mptscsih_ioc_reset);
3211 EXPORT_SYMBOL(mptscsih_change_queue_depth);
3212 EXPORT_SYMBOL(mptscsih_timer_expired);
3213 EXPORT_SYMBOL(mptscsih_TMHandler);
3215 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/