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 == FC)
453 if ((mf = mpt_get_msg_frame(ioc->InternalCtx, ioc)) == NULL) {
454 dfailprintk((MYIOC_s_WARN_FMT "%s: no msg frames!!\n",
455 ioc->name,__FUNCTION__));
459 SEPMsg = (SEPRequest_t *)mf;
460 SEPMsg->Function = MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR;
461 SEPMsg->Bus = vtarget->channel;
462 SEPMsg->TargetID = vtarget->id;
463 SEPMsg->Action = MPI_SEP_REQ_ACTION_WRITE_STATUS;
464 SEPMsg->SlotStatus = SlotStatus;
465 devtverboseprintk((MYIOC_s_WARN_FMT
466 "Sending SEP cmd=%x channel=%d id=%d\n",
467 ioc->name, SlotStatus, SEPMsg->Bus, SEPMsg->TargetID));
468 mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
471 #ifdef MPT_DEBUG_REPLY
473 * mptscsih_iocstatus_info_scsiio - IOCSTATUS information for SCSIIO
474 * @ioc: Pointer to MPT_ADAPTER structure
475 * @ioc_status: U32 IOCStatus word from IOC
476 * @scsi_status: U8 sam status from target
477 * @scsi_state: U8 scsi state
478 * @sc: original scsi cmnd pointer
479 * @mf: Pointer to MPT request frame
481 * Refer to lsi/mpi.h.
484 mptscsih_iocstatus_info_scsiio(MPT_ADAPTER *ioc, u32 ioc_status,
485 u8 scsi_status, u8 scsi_state, struct scsi_cmnd *sc)
487 char extend_desc[EVENT_DESCR_STR_SZ];
490 switch (ioc_status) {
492 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
493 desc = "SCSI Invalid Bus";
496 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
497 desc = "SCSI Invalid TargetID";
500 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
502 * Inquiry is issued for device scanning
504 if (sc->cmnd[0] != 0x12)
505 desc = "SCSI Device Not There";
508 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
509 desc = "SCSI Data Overrun";
512 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
513 desc = "SCSI I/O Data Error";
516 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
517 desc = "SCSI Protocol Error";
520 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
521 desc = "SCSI Task Terminated";
524 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
525 desc = "SCSI Residual Mismatch";
528 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
529 desc = "SCSI Task Management Failed";
532 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
533 desc = "SCSI IOC Terminated";
536 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
537 desc = "SCSI Ext Terminated";
544 snprintf(extend_desc, EVENT_DESCR_STR_SZ,
545 "[%d:%d:%d:%d] cmd=%02Xh, sam_status=%02Xh state=%02Xh",
546 sc->device->host->host_no,
547 sc->device->channel, sc->device->id, sc->device->lun,
548 sc->cmnd[0], scsi_status, scsi_state);
550 printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04X): %s: %s\n",
551 ioc->name, ioc_status, desc, extend_desc);
555 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
557 * mptscsih_io_done - Main SCSI IO callback routine registered to
558 * Fusion MPT (base) driver
559 * @ioc: Pointer to MPT_ADAPTER structure
560 * @mf: Pointer to original MPT request frame
561 * @r: Pointer to MPT reply frame (NULL if TurboReply)
563 * This routine is called from mpt.c::mpt_interrupt() at the completion
564 * of any SCSI IO request.
565 * This routine is registered with the Fusion MPT (base) driver at driver
566 * load/init time via the mpt_register() API call.
568 * Returns 1 indicating alloc'd request frame ptr should be freed.
571 mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
573 struct scsi_cmnd *sc;
575 SCSIIORequest_t *pScsiReq;
576 SCSIIOReply_t *pScsiReply;
577 u16 req_idx, req_idx_MR;
581 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
583 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
584 req_idx_MR = (mr != NULL) ?
585 le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx) : req_idx;
586 if ((req_idx != req_idx_MR) ||
587 (mf->u.frame.linkage.arg1 == 0xdeadbeaf)) {
588 printk(MYIOC_s_ERR_FMT "Received a mf that was already freed\n",
590 printk (MYIOC_s_ERR_FMT
591 "req_idx=%x req_idx_MR=%x mf=%p mr=%p sc=%p\n",
592 ioc->name, req_idx, req_idx_MR, mf, mr,
593 hd->ScsiLookup[req_idx_MR]);
597 sc = hd->ScsiLookup[req_idx];
598 hd->ScsiLookup[req_idx] = NULL;
600 MPIHeader_t *hdr = (MPIHeader_t *)mf;
602 /* Remark: writeSDP1 will use the ScsiDoneCtx
603 * If a SCSI I/O cmd, device disabled by OS and
604 * completion done. Cannot touch sc struct. Just free mem.
606 if (hdr->Function == MPI_FUNCTION_SCSI_IO_REQUEST)
607 printk(MYIOC_s_ERR_FMT "NULL ScsiCmd ptr!\n",
610 mptscsih_freeChainBuffers(ioc, req_idx);
614 if ((unsigned char *)mf != sc->host_scribble) {
615 mptscsih_freeChainBuffers(ioc, req_idx);
619 sc->host_scribble = NULL;
620 sc->result = DID_OK << 16; /* Set default reply as OK */
621 pScsiReq = (SCSIIORequest_t *) mf;
622 pScsiReply = (SCSIIOReply_t *) mr;
624 if((ioc->facts.MsgVersion >= MPI_VERSION_01_05) && pScsiReply){
625 dmfprintk((MYIOC_s_INFO_FMT
626 "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d,task-tag=%d)\n",
627 ioc->name, mf, mr, sc, req_idx, pScsiReply->TaskTag));
629 dmfprintk((MYIOC_s_INFO_FMT
630 "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n",
631 ioc->name, mf, mr, sc, req_idx));
634 if (pScsiReply == NULL) {
635 /* special context reply handling */
640 u8 scsi_state, scsi_status;
643 status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK;
644 scsi_state = pScsiReply->SCSIState;
645 scsi_status = pScsiReply->SCSIStatus;
646 xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
647 scsi_set_resid(sc, scsi_bufflen(sc) - xfer_cnt);
648 log_info = le32_to_cpu(pScsiReply->IOCLogInfo);
651 * if we get a data underrun indication, yet no data was
652 * transferred and the SCSI status indicates that the
653 * command was never started, change the data underrun
656 if (status == MPI_IOCSTATUS_SCSI_DATA_UNDERRUN && xfer_cnt == 0 &&
657 (scsi_status == MPI_SCSI_STATUS_BUSY ||
658 scsi_status == MPI_SCSI_STATUS_RESERVATION_CONFLICT ||
659 scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)) {
660 status = MPI_IOCSTATUS_SUCCESS;
663 if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)
664 mptscsih_copy_sense_data(sc, hd, mf, pScsiReply);
667 * Look for + dump FCP ResponseInfo[]!
669 if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID &&
670 pScsiReply->ResponseInfo) {
671 printk(KERN_NOTICE "[%d:%d:%d:%d] "
672 "FCP_ResponseInfo=%08xh\n",
673 sc->device->host->host_no, sc->device->channel,
674 sc->device->id, sc->device->lun,
675 le32_to_cpu(pScsiReply->ResponseInfo));
679 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
681 * Maybe: DRIVER_BUSY | SUGGEST_RETRY | DID_SOFT_ERROR (retry)
682 * But not: DID_BUS_BUSY lest one risk
683 * killing interrupt handler:-(
685 sc->result = SAM_STAT_BUSY;
688 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
689 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
690 sc->result = DID_BAD_TARGET << 16;
693 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
694 /* Spoof to SCSI Selection Timeout! */
695 if (ioc->bus_type != FC)
696 sc->result = DID_NO_CONNECT << 16;
697 /* else fibre, just stall until rescan event */
699 sc->result = DID_REQUEUE << 16;
701 if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF)
702 hd->sel_timeout[pScsiReq->TargetID]++;
704 vdev = sc->device->hostdata;
707 vtarget = vdev->vtarget;
708 if (vtarget->tflags & MPT_TARGET_FLAGS_LED_ON) {
709 mptscsih_issue_sep_command(ioc, vtarget,
710 MPI_SEP_REQ_SLOTSTATUS_UNCONFIGURED);
711 vtarget->tflags &= ~MPT_TARGET_FLAGS_LED_ON;
715 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
716 if ( ioc->bus_type == SAS ) {
717 u16 ioc_status = le16_to_cpu(pScsiReply->IOCStatus);
718 if (ioc_status & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
719 if ((log_info & SAS_LOGINFO_MASK)
720 == SAS_LOGINFO_NEXUS_LOSS) {
721 sc->result = (DID_BUS_BUSY << 16);
725 } else if (ioc->bus_type == FC) {
727 * The FC IOC may kill a request for variety of
728 * reasons, some of which may be recovered by a
729 * retry, some which are unlikely to be
730 * recovered. Return DID_ERROR instead of
731 * DID_RESET to permit retry of the command,
732 * just not an infinite number of them
734 sc->result = DID_ERROR << 16;
739 * Allow non-SAS & non-NEXUS_LOSS to drop into below code
742 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
743 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
744 /* Linux handles an unsolicited DID_RESET better
745 * than an unsolicited DID_ABORT.
747 sc->result = DID_RESET << 16;
751 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
752 scsi_set_resid(sc, scsi_bufflen(sc) - xfer_cnt);
753 if((xfer_cnt==0)||(sc->underflow > xfer_cnt))
754 sc->result=DID_SOFT_ERROR << 16;
755 else /* Sufficient data transfer occurred */
756 sc->result = (DID_OK << 16) | scsi_status;
757 dreplyprintk((KERN_NOTICE
758 "RESIDUAL_MISMATCH: result=%x on channel=%d id=%d\n",
759 sc->result, sc->device->channel, sc->device->id));
762 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
764 * Do upfront check for valid SenseData and give it
767 sc->result = (DID_OK << 16) | scsi_status;
768 if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
769 /* Have already saved the status and sense data
773 if (xfer_cnt < sc->underflow) {
774 if (scsi_status == SAM_STAT_BUSY)
775 sc->result = SAM_STAT_BUSY;
777 sc->result = DID_SOFT_ERROR << 16;
779 if (scsi_state & (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)) {
782 sc->result = DID_SOFT_ERROR << 16;
784 else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
785 /* Not real sure here either... */
786 sc->result = DID_RESET << 16;
790 dreplyprintk((KERN_NOTICE " sc->underflow={report ERR if < %02xh bytes xfer'd}\n",
792 dreplyprintk((KERN_NOTICE " ActBytesXferd=%02xh\n", xfer_cnt));
795 if (scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)
796 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
800 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
801 scsi_set_resid(sc, 0);
802 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
803 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
804 sc->result = (DID_OK << 16) | scsi_status;
805 if (scsi_state == 0) {
807 } else if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
809 * If running against circa 200003dd 909 MPT f/w,
810 * may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL
811 * (QUEUE_FULL) returned from device! --> get 0x0000?128
812 * and with SenseBytes set to 0.
814 if (pScsiReply->SCSIStatus == MPI_SCSI_STATUS_TASK_SET_FULL)
815 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
818 else if (scsi_state &
819 (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)
824 sc->result = DID_SOFT_ERROR << 16;
826 else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
827 /* Not real sure here either... */
828 sc->result = DID_RESET << 16;
830 else if (scsi_state & MPI_SCSI_STATE_QUEUE_TAG_REJECTED) {
831 /* Device Inq. data indicates that it supports
832 * QTags, but rejects QTag messages.
833 * This command completed OK.
835 * Not real sure here either so do nothing... */
838 if (sc->result == MPI_SCSI_STATUS_TASK_SET_FULL)
839 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
842 * Reservation Conflict, Busy,
843 * Command Terminated, CHECK
847 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
848 sc->result = DID_SOFT_ERROR << 16;
851 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
852 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
853 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
854 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
855 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
856 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
857 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
858 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
859 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
864 sc->result = DID_SOFT_ERROR << 16;
867 } /* switch(status) */
869 #ifdef MPT_DEBUG_REPLY
872 mptscsih_iocstatus_info_scsiio(ioc, status,
873 scsi_status, scsi_state, sc);
875 dreplyprintk(("%s: [%d:%d:%d:%d] cmd=0x%02x "
876 "result=0x%08x\n\tiocstatus=0x%04X "
877 "scsi_state=0x%02X scsi_status=0x%02X "
878 "loginfo=0x%08X\n", __FUNCTION__,
879 sc->device->host->host_no, sc->device->channel, sc->device->id,
880 sc->device->lun, sc->cmnd[0], sc->result, status,
881 scsi_state, scsi_status, log_info));
883 dreplyprintk(("%s: [%d:%d:%d:%d] resid=%d "
884 "bufflen=%d xfer_cnt=%d\n", __FUNCTION__,
885 sc->device->host->host_no,
886 sc->device->channel, sc->device->id,
887 sc->device->lun, scsi_get_resid(sc),
888 scsi_bufflen(sc), xfer_cnt));
892 } /* end of address reply case */
894 /* Unmap the DMA buffers, if any. */
897 sc->scsi_done(sc); /* Issue the command callback */
899 /* Free Chain buffers */
900 mptscsih_freeChainBuffers(ioc, req_idx);
905 * mptscsih_flush_running_cmds - For each command found, search
906 * Scsi_Host instance taskQ and reply to OS.
907 * Called only if recovering from a FW reload.
908 * @hd: Pointer to a SCSI HOST structure
912 * Must be called while new I/Os are being queued.
915 mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
917 MPT_ADAPTER *ioc = hd->ioc;
918 struct scsi_cmnd *SCpnt;
921 int max = ioc->req_depth;
923 dprintk((KERN_INFO MYNAM ": flush_ScsiLookup called\n"));
924 for (ii= 0; ii < max; ii++) {
925 if ((SCpnt = hd->ScsiLookup[ii]) != NULL) {
930 /* Null ScsiLookup index
932 hd->ScsiLookup[ii] = NULL;
934 mf = MPT_INDEX_2_MFPTR(ioc, ii);
935 dmfprintk(( "flush: ScsiDone (mf=%p,sc=%p)\n",
938 /* Free Chain buffers */
939 mptscsih_freeChainBuffers(ioc, ii);
941 /* Free Message frames */
942 mpt_free_msg_frame(ioc, mf);
944 if ((unsigned char *)mf != SCpnt->host_scribble)
947 /* Set status, free OS resources (SG DMA buffers)
950 scsi_dma_unmap(SCpnt);
952 SCpnt->result = DID_RESET << 16;
953 SCpnt->host_scribble = NULL;
955 SCpnt->scsi_done(SCpnt); /* Issue the command callback */
963 * mptscsih_search_running_cmds - Delete any commands associated
964 * with the specified target and lun. Function called only
965 * when a lun is disable by mid-layer.
966 * Do NOT access the referenced scsi_cmnd structure or
967 * members. Will cause either a paging or NULL ptr error.
968 * (BUT, BUT, BUT, the code does reference it! - mdr)
969 * @hd: Pointer to a SCSI HOST structure
970 * @vdevice: per device private data
974 * Called from slave_destroy.
977 mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
979 SCSIIORequest_t *mf = NULL;
981 int max = hd->ioc->req_depth;
982 struct scsi_cmnd *sc;
985 dsprintk((KERN_INFO MYNAM ": search_running channel %d id %d lun %d max %d\n",
986 vdevice->vtarget->channel, vdevice->vtarget->id, vdevice->lun, max));
988 for (ii=0; ii < max; ii++) {
989 if ((sc = hd->ScsiLookup[ii]) != NULL) {
991 mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii);
994 int_to_scsilun(vdevice->lun, &lun);
995 if ((mf->Bus != vdevice->vtarget->channel) ||
996 (mf->TargetID != vdevice->vtarget->id) ||
997 memcmp(lun.scsi_lun, mf->LUN, 8))
999 dsprintk(( "search_running: found (sc=%p, mf = %p) "
1000 "channel %d id %d, lun %d \n", hd->ScsiLookup[ii],
1001 mf, mf->Bus, mf->TargetID, vdevice->lun));
1005 hd->ScsiLookup[ii] = NULL;
1006 mptscsih_freeChainBuffers(hd->ioc, ii);
1007 mpt_free_msg_frame(hd->ioc, (MPT_FRAME_HDR *)mf);
1008 if ((unsigned char *)mf != sc->host_scribble)
1012 sc->host_scribble = NULL;
1013 sc->result = DID_NO_CONNECT << 16;
1020 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1022 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1024 * mptscsih_report_queue_full - Report QUEUE_FULL status returned
1025 * from a SCSI target device.
1026 * @sc: Pointer to scsi_cmnd structure
1027 * @pScsiReply: Pointer to SCSIIOReply_t
1028 * @pScsiReq: Pointer to original SCSI request
1030 * This routine periodically reports QUEUE_FULL status returned from a
1031 * SCSI target device. It reports this to the console via kernel
1032 * printk() API call, not more than once every 10 seconds.
1035 mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq)
1037 long time = jiffies;
1040 if (sc->device == NULL)
1042 if (sc->device->host == NULL)
1044 if ((hd = (MPT_SCSI_HOST *)sc->device->host->hostdata) == NULL)
1047 if (time - hd->last_queue_full > 10 * HZ) {
1048 dprintk((MYIOC_s_WARN_FMT "Device (%d:%d:%d) reported QUEUE_FULL!\n",
1049 hd->ioc->name, 0, sc->device->id, sc->device->lun));
1050 hd->last_queue_full = time;
1054 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1056 * mptscsih_remove - Removed scsi devices
1057 * @pdev: Pointer to pci_dev structure
1062 mptscsih_remove(struct pci_dev *pdev)
1064 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1065 struct Scsi_Host *host = ioc->sh;
1074 scsi_remove_host(host);
1076 if((hd = (MPT_SCSI_HOST *)host->hostdata) == NULL)
1079 mptscsih_shutdown(pdev);
1083 if (hd->ScsiLookup != NULL) {
1084 sz1 = hd->ioc->req_depth * sizeof(void *);
1085 kfree(hd->ScsiLookup);
1086 hd->ScsiLookup = NULL;
1089 dprintk((MYIOC_s_INFO_FMT
1090 "Free'd ScsiLookup (%d) memory\n",
1091 hd->ioc->name, sz1));
1093 kfree(hd->info_kbuf);
1095 /* NULL the Scsi_Host pointer
1099 scsi_host_put(host);
1105 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1107 * mptscsih_shutdown - reboot notifier
1111 mptscsih_shutdown(struct pci_dev *pdev)
1113 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1114 struct Scsi_Host *host = ioc->sh;
1120 hd = (MPT_SCSI_HOST *)host->hostdata;
1125 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1127 * mptscsih_suspend - Fusion MPT scsi driver suspend routine.
1132 mptscsih_suspend(struct pci_dev *pdev, pm_message_t state)
1134 mptscsih_shutdown(pdev);
1135 return mpt_suspend(pdev,state);
1138 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1140 * mptscsih_resume - Fusion MPT scsi driver resume routine.
1145 mptscsih_resume(struct pci_dev *pdev)
1147 return mpt_resume(pdev);
1152 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1154 * mptscsih_info - Return information about MPT adapter
1155 * @SChost: Pointer to Scsi_Host structure
1157 * (linux scsi_host_template.info routine)
1159 * Returns pointer to buffer where information was written.
1162 mptscsih_info(struct Scsi_Host *SChost)
1167 h = (MPT_SCSI_HOST *)SChost->hostdata;
1170 if (h->info_kbuf == NULL)
1171 if ((h->info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)
1172 return h->info_kbuf;
1173 h->info_kbuf[0] = '\0';
1175 mpt_print_ioc_summary(h->ioc, h->info_kbuf, &size, 0, 0);
1176 h->info_kbuf[size-1] = '\0';
1179 return h->info_kbuf;
1190 mptscsih_copy_mem_info(struct info_str *info, char *data, int len)
1192 if (info->pos + len > info->length)
1193 len = info->length - info->pos;
1195 if (info->pos + len < info->offset) {
1200 if (info->pos < info->offset) {
1201 data += (info->offset - info->pos);
1202 len -= (info->offset - info->pos);
1206 memcpy(info->buffer + info->pos, data, len);
1212 mptscsih_copy_info(struct info_str *info, char *fmt, ...)
1218 va_start(args, fmt);
1219 len = vsprintf(buf, fmt, args);
1222 mptscsih_copy_mem_info(info, buf, len);
1227 mptscsih_host_info(MPT_ADAPTER *ioc, char *pbuf, off_t offset, int len)
1229 struct info_str info;
1233 info.offset = offset;
1236 mptscsih_copy_info(&info, "%s: %s, ", ioc->name, ioc->prod_name);
1237 mptscsih_copy_info(&info, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING, ioc->facts.FWVersion.Word);
1238 mptscsih_copy_info(&info, "Ports=%d, ", ioc->facts.NumberOfPorts);
1239 mptscsih_copy_info(&info, "MaxQ=%d\n", ioc->req_depth);
1241 return ((info.pos > info.offset) ? info.pos - info.offset : 0);
1244 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1246 * mptscsih_proc_info - Return information about MPT adapter
1247 * @host: scsi host struct
1248 * @buffer: if write, user data; if read, buffer for user
1249 * @start: returns the buffer address
1250 * @offset: if write, 0; if read, the current offset into the buffer from
1251 * the previous read.
1252 * @length: if write, return length;
1253 * @func: write = 1; read = 0
1255 * (linux scsi_host_template.info routine)
1258 mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
1259 int length, int func)
1261 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
1262 MPT_ADAPTER *ioc = hd->ioc;
1267 * write is not supported
1273 size = mptscsih_host_info(ioc, buffer, offset, length);
1279 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1280 #define ADD_INDEX_LOG(req_ent) do { } while(0)
1282 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1284 * mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine.
1285 * @SCpnt: Pointer to scsi_cmnd structure
1286 * @done: Pointer SCSI mid-layer IO completion function
1288 * (linux scsi_host_template.queuecommand routine)
1289 * This is the primary SCSI IO start routine. Create a MPI SCSIIORequest
1290 * from a linux scsi_cmnd request and send it to the IOC.
1292 * Returns 0. (rtn value discarded by linux scsi mid-layer)
1295 mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1299 SCSIIORequest_t *pScsiReq;
1300 VirtDevice *vdev = SCpnt->device->hostdata;
1309 hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata;
1310 lun = SCpnt->device->lun;
1311 SCpnt->scsi_done = done;
1313 dmfprintk((MYIOC_s_INFO_FMT "qcmd: SCpnt=%p, done()=%p\n",
1314 (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt, done));
1316 if (hd->resetPending) {
1317 dtmprintk((MYIOC_s_WARN_FMT "qcmd: SCpnt=%p timeout + 60HZ\n",
1318 (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt));
1319 return SCSI_MLQUEUE_HOST_BUSY;
1323 * Put together a MPT SCSI request...
1325 if ((mf = mpt_get_msg_frame(hd->ioc->DoneCtx, hd->ioc)) == NULL) {
1326 dprintk((MYIOC_s_WARN_FMT "QueueCmd, no msg frames!!\n",
1328 return SCSI_MLQUEUE_HOST_BUSY;
1331 pScsiReq = (SCSIIORequest_t *) mf;
1333 my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
1335 ADD_INDEX_LOG(my_idx);
1337 /* TUR's being issued with scsictl=0x02000000 (DATA_IN)!
1338 * Seems we may receive a buffer (datalen>0) even when there
1339 * will be no data transfer! GRRRRR...
1341 if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
1342 datalen = scsi_bufflen(SCpnt);
1343 scsidir = MPI_SCSIIO_CONTROL_READ; /* DATA IN (host<--ioc<--dev) */
1344 } else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
1345 datalen = scsi_bufflen(SCpnt);
1346 scsidir = MPI_SCSIIO_CONTROL_WRITE; /* DATA OUT (host-->ioc-->dev) */
1349 scsidir = MPI_SCSIIO_CONTROL_NODATATRANSFER;
1352 /* Default to untagged. Once a target structure has been allocated,
1353 * use the Inquiry data to determine if device supports tagged.
1356 && (vdev->vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)
1357 && (SCpnt->device->tagged_supported)) {
1358 scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
1360 scsictl = scsidir | MPI_SCSIIO_CONTROL_UNTAGGED;
1363 /* Use the above information to set up the message frame
1365 pScsiReq->TargetID = (u8) vdev->vtarget->id;
1366 pScsiReq->Bus = vdev->vtarget->channel;
1367 pScsiReq->ChainOffset = 0;
1368 if (vdev->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
1369 pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
1371 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
1372 pScsiReq->CDBLength = SCpnt->cmd_len;
1373 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
1374 pScsiReq->Reserved = 0;
1375 pScsiReq->MsgFlags = mpt_msg_flags();
1376 int_to_scsilun(SCpnt->device->lun, (struct scsi_lun *)pScsiReq->LUN);
1377 pScsiReq->Control = cpu_to_le32(scsictl);
1380 * Write SCSI CDB into the message
1382 cmd_len = SCpnt->cmd_len;
1383 for (ii=0; ii < cmd_len; ii++)
1384 pScsiReq->CDB[ii] = SCpnt->cmnd[ii];
1386 for (ii=cmd_len; ii < 16; ii++)
1387 pScsiReq->CDB[ii] = 0;
1390 pScsiReq->DataLength = cpu_to_le32(datalen);
1392 /* SenseBuffer low address */
1393 pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
1394 + (my_idx * MPT_SENSE_BUFFER_ALLOC));
1396 /* Now add the SG list
1397 * Always have a SGE even if null length.
1400 /* Add a NULL SGE */
1401 mptscsih_add_sge((char *)&pScsiReq->SGL, MPT_SGE_FLAGS_SSIMPLE_READ | 0,
1404 /* Add a 32 or 64 bit SGE */
1405 if (mptscsih_AddSGE(hd->ioc, SCpnt, pScsiReq, my_idx) != SUCCESS)
1409 SCpnt->host_scribble = (unsigned char *)mf;
1410 hd->ScsiLookup[my_idx] = SCpnt;
1412 mpt_put_msg_frame(hd->ioc->DoneCtx, hd->ioc, mf);
1413 dmfprintk((MYIOC_s_INFO_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n",
1414 hd->ioc->name, SCpnt, mf, my_idx));
1415 DBG_DUMP_REQUEST_FRAME(mf)
1419 hd->ScsiLookup[my_idx] = NULL;
1420 mptscsih_freeChainBuffers(hd->ioc, my_idx);
1421 mpt_free_msg_frame(hd->ioc, mf);
1422 return SCSI_MLQUEUE_HOST_BUSY;
1425 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1427 * mptscsih_freeChainBuffers - Function to free chain buffers associated
1428 * with a SCSI IO request
1429 * @hd: Pointer to the MPT_SCSI_HOST instance
1430 * @req_idx: Index of the SCSI IO request frame.
1432 * Called if SG chain buffer allocation fails and mptscsih callbacks.
1436 mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
1438 MPT_FRAME_HDR *chain;
1439 unsigned long flags;
1443 /* Get the first chain index and reset
1446 chain_idx = ioc->ReqToChain[req_idx];
1447 ioc->ReqToChain[req_idx] = MPT_HOST_NO_CHAIN;
1449 while (chain_idx != MPT_HOST_NO_CHAIN) {
1451 /* Save the next chain buffer index */
1452 next = ioc->ChainToChain[chain_idx];
1454 /* Free this chain buffer and reset
1457 ioc->ChainToChain[chain_idx] = MPT_HOST_NO_CHAIN;
1459 chain = (MPT_FRAME_HDR *) (ioc->ChainBuffer
1460 + (chain_idx * ioc->req_sz));
1462 spin_lock_irqsave(&ioc->FreeQlock, flags);
1463 list_add_tail(&chain->u.frame.linkage.list, &ioc->FreeChainQ);
1464 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1466 dmfprintk((MYIOC_s_INFO_FMT "FreeChainBuffers (index %d)\n",
1467 ioc->name, chain_idx));
1475 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1480 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1482 * mptscsih_TMHandler - Generic handler for SCSI Task Management.
1483 * @hd: Pointer to MPT SCSI HOST structure
1484 * @type: Task Management type
1485 * @channel: channel number for task management
1486 * @id: Logical Target ID for reset (if appropriate)
1487 * @lun: Logical Unit for reset (if appropriate)
1488 * @ctx2abort: Context for the task to be aborted (if appropriate)
1489 * @timeout: timeout for task management control
1491 * Fall through to mpt_HardResetHandler if: not operational, too many
1492 * failed TM requests or handshake failure.
1494 * Remark: Currently invoked from a non-interrupt thread (_bh).
1496 * Remark: With old EH code, at most 1 SCSI TaskMgmt function per IOC
1499 * Returns 0 for SUCCESS, or %FAILED.
1502 mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout)
1507 unsigned long flags;
1510 dtmprintk((MYIOC_s_INFO_FMT "TMHandler Entered!\n", ioc->name));
1512 // SJR - CHECKME - Can we avoid this here?
1513 // (mpt_HardResetHandler has this check...)
1514 spin_lock_irqsave(&ioc->diagLock, flags);
1515 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)) {
1516 spin_unlock_irqrestore(&ioc->diagLock, flags);
1519 spin_unlock_irqrestore(&ioc->diagLock, flags);
1521 /* Wait a fixed amount of time for the TM pending flag to be cleared.
1522 * If we time out and not bus reset, then we return a FAILED status
1524 * The call to mptscsih_tm_pending_wait() will set the pending flag
1526 * successful. Otherwise, reload the FW.
1528 if (mptscsih_tm_pending_wait(hd) == FAILED) {
1529 if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
1530 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler abort: "
1531 "Timed out waiting for last TM (%d) to complete! \n",
1532 hd->ioc->name, hd->tmPending));
1534 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) {
1535 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler target "
1536 "reset: Timed out waiting for last TM (%d) "
1537 "to complete! \n", hd->ioc->name,
1540 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
1541 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler bus reset: "
1542 "Timed out waiting for last TM (%d) to complete! \n",
1543 hd->ioc->name, hd->tmPending));
1547 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
1548 hd->tmPending |= (1 << type);
1549 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1552 ioc_raw_state = mpt_GetIocState(hd->ioc, 0);
1554 if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) {
1555 printk(MYIOC_s_WARN_FMT
1556 "TM Handler for type=%x: IOC Not operational (0x%x)!\n",
1557 ioc->name, type, ioc_raw_state);
1558 printk(KERN_WARNING " Issuing HardReset!!\n");
1559 if (mpt_HardResetHandler(ioc, CAN_SLEEP) < 0)
1560 printk((KERN_WARNING "TMHandler: HardReset "
1565 if (ioc_raw_state & MPI_DOORBELL_ACTIVE) {
1566 printk(MYIOC_s_WARN_FMT
1567 "TM Handler for type=%x: ioc_state: "
1568 "DOORBELL_ACTIVE (0x%x)!\n",
1569 ioc->name, type, ioc_raw_state);
1573 /* Isse the Task Mgmt request.
1575 if (hd->hard_resets < -1)
1578 rc = mptscsih_IssueTaskMgmt(hd, type, channel, id, lun,
1579 ctx2abort, timeout);
1581 printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n",
1584 dtmprintk((MYIOC_s_INFO_FMT "Issue of TaskMgmt Successful!\n",
1587 dtmprintk((MYIOC_s_INFO_FMT "TMHandler rc = %d!\n", hd->ioc->name, rc));
1593 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1595 * mptscsih_IssueTaskMgmt - Generic send Task Management function.
1596 * @hd: Pointer to MPT_SCSI_HOST structure
1597 * @type: Task Management type
1598 * @channel: channel number for task management
1599 * @id: Logical Target ID for reset (if appropriate)
1600 * @lun: Logical Unit for reset (if appropriate)
1601 * @ctx2abort: Context for the task to be aborted (if appropriate)
1602 * @timeout: timeout for task management control
1604 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
1605 * or a non-interrupt thread. In the former, must not call schedule().
1607 * Not all fields are meaningfull for all task types.
1609 * Returns 0 for SUCCESS, or FAILED.
1613 mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout)
1616 SCSITaskMgmt_t *pScsiTm;
1620 /* Return Fail to calling function if no message frames available.
1622 if ((mf = mpt_get_msg_frame(hd->ioc->TaskCtx, hd->ioc)) == NULL) {
1623 dfailprintk((MYIOC_s_ERR_FMT "IssueTaskMgmt, no msg frames!!\n",
1627 dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt request @ %p\n",
1628 hd->ioc->name, mf));
1630 /* Format the Request
1632 pScsiTm = (SCSITaskMgmt_t *) mf;
1633 pScsiTm->TargetID = id;
1634 pScsiTm->Bus = channel;
1635 pScsiTm->ChainOffset = 0;
1636 pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
1638 pScsiTm->Reserved = 0;
1639 pScsiTm->TaskType = type;
1640 pScsiTm->Reserved1 = 0;
1641 pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)
1642 ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0;
1644 int_to_scsilun(lun, (struct scsi_lun *)pScsiTm->LUN);
1646 for (ii=0; ii < 7; ii++)
1647 pScsiTm->Reserved2[ii] = 0;
1649 pScsiTm->TaskMsgContext = ctx2abort;
1651 dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt: ctx2abort (0x%08x) "
1652 "type=%d\n", hd->ioc->name, ctx2abort, type));
1654 DBG_DUMP_TM_REQUEST_FRAME((u32 *)pScsiTm);
1656 if ((retval = mpt_send_handshake_request(hd->ioc->TaskCtx, hd->ioc,
1657 sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, CAN_SLEEP)) != 0) {
1658 dfailprintk((MYIOC_s_ERR_FMT "send_handshake FAILED!"
1659 " (hd %p, ioc %p, mf %p, rc=%d) \n", hd->ioc->name, hd,
1660 hd->ioc, mf, retval));
1664 if(mptscsih_tm_wait_for_completion(hd, timeout) == FAILED) {
1665 dfailprintk((MYIOC_s_ERR_FMT "task management request TIMED OUT!"
1666 " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
1668 dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
1670 retval = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
1671 dtmprintk((MYIOC_s_INFO_FMT "rc=%d \n",
1672 hd->ioc->name, retval));
1677 * Handle success case, see if theres a non-zero ioc_status.
1679 if (hd->tm_iocstatus == MPI_IOCSTATUS_SUCCESS ||
1680 hd->tm_iocstatus == MPI_IOCSTATUS_SCSI_TASK_TERMINATED ||
1681 hd->tm_iocstatus == MPI_IOCSTATUS_SCSI_IOC_TERMINATED)
1691 * Free task managment mf, and corresponding tm flags
1693 mpt_free_msg_frame(hd->ioc, mf);
1695 hd->tmState = TM_STATE_NONE;
1700 mptscsih_get_tm_timeout(MPT_ADAPTER *ioc)
1702 switch (ioc->bus_type) {
1713 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1715 * mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant
1716 * @SCpnt: Pointer to scsi_cmnd structure, IO to be aborted
1718 * (linux scsi_host_template.eh_abort_handler routine)
1720 * Returns SUCCESS or FAILED.
1723 mptscsih_abort(struct scsi_cmnd * SCpnt)
1731 ulong sn = SCpnt->serial_number;
1733 /* If we can't locate our host adapter structure, return FAILED status.
1735 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL) {
1736 SCpnt->result = DID_RESET << 16;
1737 SCpnt->scsi_done(SCpnt);
1738 dfailprintk((KERN_INFO MYNAM ": mptscsih_abort: "
1739 "Can't locate host! (sc=%p)\n",
1744 /* Find this command
1746 if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) {
1747 /* Cmd not found in ScsiLookup.
1750 SCpnt->result = DID_RESET << 16;
1751 dtmprintk((KERN_INFO MYNAM ": %s: mptscsih_abort: "
1752 "Command not in the active list! (sc=%p)\n",
1753 hd->ioc->name, SCpnt));
1757 if (hd->resetPending)
1760 if (hd->timeouts < -1)
1763 printk(KERN_WARNING MYNAM ": %s: attempting task abort! (sc=%p)\n",
1764 hd->ioc->name, SCpnt);
1765 scsi_print_command(SCpnt);
1767 /* Most important! Set TaskMsgContext to SCpnt's MsgContext!
1768 * (the IO to be ABORT'd)
1770 * NOTE: Since we do not byteswap MsgContext, we do not
1771 * swap it here either. It is an opaque cookie to
1772 * the controller, so it does not matter. -DaveM
1774 mf = MPT_INDEX_2_MFPTR(hd->ioc, scpnt_idx);
1775 ctx2abort = mf->u.frame.hwhdr.msgctxu.MsgContext;
1777 hd->abortSCpnt = SCpnt;
1779 vdev = SCpnt->device->hostdata;
1780 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
1781 vdev->vtarget->channel, vdev->vtarget->id, vdev->lun,
1782 ctx2abort, mptscsih_get_tm_timeout(hd->ioc));
1784 if (SCPNT_TO_LOOKUP_IDX(SCpnt) == scpnt_idx &&
1785 SCpnt->serial_number == sn)
1788 printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n",
1790 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1798 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1800 * mptscsih_dev_reset - Perform a SCSI TARGET_RESET! new_eh variant
1801 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1803 * (linux scsi_host_template.eh_dev_reset_handler routine)
1805 * Returns SUCCESS or FAILED.
1808 mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
1814 /* If we can't locate our host adapter structure, return FAILED status.
1816 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1817 dtmprintk((KERN_INFO MYNAM ": mptscsih_dev_reset: "
1818 "Can't locate host! (sc=%p)\n",
1823 if (hd->resetPending)
1826 printk(KERN_WARNING MYNAM ": %s: attempting target reset! (sc=%p)\n",
1827 hd->ioc->name, SCpnt);
1828 scsi_print_command(SCpnt);
1830 vdev = SCpnt->device->hostdata;
1831 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
1832 vdev->vtarget->channel, vdev->vtarget->id,
1833 0, 0, mptscsih_get_tm_timeout(hd->ioc));
1835 printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n",
1837 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1846 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1848 * mptscsih_bus_reset - Perform a SCSI BUS_RESET! new_eh variant
1849 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1851 * (linux scsi_host_template.eh_bus_reset_handler routine)
1853 * Returns SUCCESS or FAILED.
1856 mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
1862 /* If we can't locate our host adapter structure, return FAILED status.
1864 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1865 dtmprintk((KERN_INFO MYNAM ": mptscsih_bus_reset: "
1866 "Can't locate host! (sc=%p)\n",
1871 printk(KERN_WARNING MYNAM ": %s: attempting bus reset! (sc=%p)\n",
1872 hd->ioc->name, SCpnt);
1873 scsi_print_command(SCpnt);
1875 if (hd->timeouts < -1)
1878 vdev = SCpnt->device->hostdata;
1879 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
1880 vdev->vtarget->channel, 0, 0, 0, mptscsih_get_tm_timeout(hd->ioc));
1882 printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n",
1884 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1892 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1894 * mptscsih_host_reset - Perform a SCSI host adapter RESET (new_eh variant)
1895 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1897 * (linux scsi_host_template.eh_host_reset_handler routine)
1899 * Returns SUCCESS or FAILED.
1902 mptscsih_host_reset(struct scsi_cmnd *SCpnt)
1905 int status = SUCCESS;
1907 /* If we can't locate the host to reset, then we failed. */
1908 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1909 dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
1910 "Can't locate host! (sc=%p)\n",
1915 printk(KERN_WARNING MYNAM ": %s: Attempting host reset! (sc=%p)\n",
1916 hd->ioc->name, SCpnt);
1918 /* If our attempts to reset the host failed, then return a failed
1919 * status. The host will be taken off line by the SCSI mid-layer.
1921 if (mpt_HardResetHandler(hd->ioc, CAN_SLEEP) < 0){
1924 /* Make sure TM pending is cleared and TM state is set to
1928 hd->tmState = TM_STATE_NONE;
1931 dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
1933 (status == SUCCESS) ? "SUCCESS" : "FAILED" ) );
1938 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1940 * mptscsih_tm_pending_wait - wait for pending task management request to complete
1941 * @hd: Pointer to MPT host structure.
1943 * Returns {SUCCESS,FAILED}.
1946 mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd)
1948 unsigned long flags;
1949 int loop_count = 4 * 10; /* Wait 10 seconds */
1950 int status = FAILED;
1953 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
1954 if (hd->tmState == TM_STATE_NONE) {
1955 hd->tmState = TM_STATE_IN_PROGRESS;
1957 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1961 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1963 } while (--loop_count);
1968 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1970 * mptscsih_tm_wait_for_completion - wait for completion of TM task
1971 * @hd: Pointer to MPT host structure.
1972 * @timeout: timeout value
1974 * Returns {SUCCESS,FAILED}.
1977 mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout )
1979 unsigned long flags;
1980 int loop_count = 4 * timeout;
1981 int status = FAILED;
1984 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
1985 if(hd->tmPending == 0) {
1987 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1990 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1992 } while (--loop_count);
1997 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1999 mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code)
2003 switch (response_code) {
2004 case MPI_SCSITASKMGMT_RSP_TM_COMPLETE:
2005 desc = "The task completed.";
2007 case MPI_SCSITASKMGMT_RSP_INVALID_FRAME:
2008 desc = "The IOC received an invalid frame status.";
2010 case MPI_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED:
2011 desc = "The task type is not supported.";
2013 case MPI_SCSITASKMGMT_RSP_TM_FAILED:
2014 desc = "The requested task failed.";
2016 case MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED:
2017 desc = "The task completed successfully.";
2019 case MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN:
2020 desc = "The LUN request is invalid.";
2022 case MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC:
2023 desc = "The task is in the IOC queue and has not been sent to target.";
2029 printk(MYIOC_s_INFO_FMT "Response Code(0x%08x): F/W: %s\n",
2030 ioc->name, response_code, desc);
2033 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2035 * mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
2036 * @ioc: Pointer to MPT_ADAPTER structure
2037 * @mf: Pointer to SCSI task mgmt request frame
2038 * @mr: Pointer to SCSI task mgmt reply frame
2040 * This routine is called from mptbase.c::mpt_interrupt() at the completion
2041 * of any SCSI task management request.
2042 * This routine is registered with the MPT (base) driver at driver
2043 * load/init time via the mpt_register() API call.
2045 * Returns 1 indicating alloc'd request frame ptr should be freed.
2048 mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
2050 SCSITaskMgmtReply_t *pScsiTmReply;
2051 SCSITaskMgmt_t *pScsiTmReq;
2053 unsigned long flags;
2056 u32 termination_count;
2058 dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt completed (mf=%p,mr=%p)\n",
2059 ioc->name, mf, mr));
2061 dtmprintk((MYIOC_s_WARN_FMT
2062 "TaskMgmt Complete: NULL Scsi Host Ptr\n", ioc->name));
2067 dtmprintk((MYIOC_s_WARN_FMT
2068 "ERROR! TaskMgmt Reply: NULL Request %p\n", ioc->name, mf));
2072 hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
2073 pScsiTmReply = (SCSITaskMgmtReply_t*)mr;
2074 pScsiTmReq = (SCSITaskMgmt_t*)mf;
2075 tmType = pScsiTmReq->TaskType;
2076 iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2077 termination_count = le32_to_cpu(pScsiTmReply->TerminationCount);
2079 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05 &&
2080 pScsiTmReply->ResponseCode)
2081 mptscsih_taskmgmt_response_code(ioc,
2082 pScsiTmReply->ResponseCode);
2083 DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply);
2085 #if defined(MPT_DEBUG_REPLY) || defined(MPT_DEBUG_TM)
2086 printk("%s: ha=%d [%d:%d:0] task_type=0x%02X "
2087 "iocstatus=0x%04X\n\tloginfo=0x%08X response_code=0x%02X "
2088 "term_cmnds=%d\n", __FUNCTION__, ioc->id, pScsiTmReply->Bus,
2089 pScsiTmReply->TargetID, pScsiTmReq->TaskType,
2090 le16_to_cpu(pScsiTmReply->IOCStatus),
2091 le32_to_cpu(pScsiTmReply->IOCLogInfo),pScsiTmReply->ResponseCode,
2092 le32_to_cpu(pScsiTmReply->TerminationCount));
2095 dtmprintk((MYIOC_s_WARN_FMT " TaskMgmt SUCCESS\n", ioc->name));
2096 hd->abortSCpnt = NULL;
2100 /* Error? (anything non-zero?) */
2102 /* clear flags and continue.
2106 case MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK:
2107 if (termination_count == 1)
2108 iocstatus = MPI_IOCSTATUS_SCSI_TASK_TERMINATED;
2109 hd->abortSCpnt = NULL;
2112 case MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS:
2114 /* If an internal command is present
2115 * or the TM failed - reload the FW.
2116 * FC FW may respond FAILED to an ABORT
2118 if (iocstatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED ||
2120 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
2121 printk((KERN_WARNING " Firmware Reload FAILED!!\n"));
2124 case MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET:
2130 spin_lock_irqsave(&ioc->FreeQlock, flags);
2132 hd->tmState = TM_STATE_NONE;
2133 hd->tm_iocstatus = iocstatus;
2134 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2139 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2141 * This is anyones guess quite frankly.
2144 mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
2145 sector_t capacity, int geom[])
2155 dummy = heads * sectors;
2156 cylinders = capacity;
2157 sector_div(cylinders,dummy);
2160 * Handle extended translation size for logical drives
2163 if ((ulong)capacity >= 0x200000) {
2166 dummy = heads * sectors;
2167 cylinders = capacity;
2168 sector_div(cylinders,dummy);
2174 geom[2] = cylinders;
2176 dprintk((KERN_NOTICE
2177 ": bios_param: Id=%i Lun=%i Channel=%i CHS=%i/%i/%i\n",
2178 sdev->id, sdev->lun, sdev->channel, (int)cylinders, heads, sectors));
2183 /* Search IOC page 3 to determine if this is hidden physical disk
2187 mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id)
2189 struct inactive_raid_component_info *component_info;
2193 if (!ioc->raid_data.pIocPg3)
2195 for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2196 if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) &&
2197 (channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) {
2204 * Check inactive list for matching phys disks
2206 if (list_empty(&ioc->raid_data.inactive_list))
2209 down(&ioc->raid_data.inactive_list_mutex);
2210 list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
2212 if ((component_info->d.PhysDiskID == id) &&
2213 (component_info->d.PhysDiskBus == channel))
2216 up(&ioc->raid_data.inactive_list_mutex);
2221 EXPORT_SYMBOL(mptscsih_is_phys_disk);
2224 mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id)
2226 struct inactive_raid_component_info *component_info;
2230 if (!ioc->raid_data.pIocPg3)
2232 for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2233 if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) &&
2234 (channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) {
2235 rc = ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum;
2241 * Check inactive list for matching phys disks
2243 if (list_empty(&ioc->raid_data.inactive_list))
2246 down(&ioc->raid_data.inactive_list_mutex);
2247 list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
2249 if ((component_info->d.PhysDiskID == id) &&
2250 (component_info->d.PhysDiskBus == channel))
2251 rc = component_info->d.PhysDiskNum;
2253 up(&ioc->raid_data.inactive_list_mutex);
2258 EXPORT_SYMBOL(mptscsih_raid_id_to_num);
2261 * OS entry point to allow for host driver to free allocated memory
2262 * Called if no device present or device being unloaded
2265 mptscsih_slave_destroy(struct scsi_device *sdev)
2267 struct Scsi_Host *host = sdev->host;
2268 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
2269 VirtTarget *vtarget;
2270 VirtDevice *vdevice;
2271 struct scsi_target *starget;
2273 starget = scsi_target(sdev);
2274 vtarget = starget->hostdata;
2275 vdevice = sdev->hostdata;
2277 mptscsih_search_running_cmds(hd, vdevice);
2278 vtarget->num_luns--;
2279 mptscsih_synchronize_cache(hd, vdevice);
2281 sdev->hostdata = NULL;
2284 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2286 * mptscsih_change_queue_depth - This function will set a devices queue depth
2287 * @sdev: per scsi_device pointer
2288 * @qdepth: requested queue depth
2290 * Adding support for new 'change_queue_depth' api.
2293 mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
2295 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sdev->host->hostdata;
2296 VirtTarget *vtarget;
2297 struct scsi_target *starget;
2301 starget = scsi_target(sdev);
2302 vtarget = starget->hostdata;
2304 if (hd->ioc->bus_type == SPI) {
2305 if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
2307 else if (sdev->type == TYPE_DISK &&
2308 vtarget->minSyncFactor <= MPT_ULTRA160)
2309 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2311 max_depth = MPT_SCSI_CMD_PER_DEV_LOW;
2313 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2315 if (qdepth > max_depth)
2320 tagged = MSG_SIMPLE_TAG;
2322 scsi_adjust_queue_depth(sdev, tagged, qdepth);
2323 return sdev->queue_depth;
2327 * OS entry point to adjust the queue_depths on a per-device basis.
2328 * Called once per device the bus scan. Use it to force the queue_depth
2329 * member to 1 if a device does not support Q tags.
2330 * Return non-zero if fails.
2333 mptscsih_slave_configure(struct scsi_device *sdev)
2335 struct Scsi_Host *sh = sdev->host;
2336 VirtTarget *vtarget;
2337 VirtDevice *vdevice;
2338 struct scsi_target *starget;
2339 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sh->hostdata;
2341 starget = scsi_target(sdev);
2342 vtarget = starget->hostdata;
2343 vdevice = sdev->hostdata;
2345 dsprintk((MYIOC_s_INFO_FMT
2346 "device @ %p, channel=%d, id=%d, lun=%d\n",
2347 hd->ioc->name, sdev, sdev->channel, sdev->id, sdev->lun));
2348 if (hd->ioc->bus_type == SPI)
2349 dsprintk((MYIOC_s_INFO_FMT
2350 "sdtr %d wdtr %d ppr %d inq length=%d\n",
2351 hd->ioc->name, sdev->sdtr, sdev->wdtr,
2352 sdev->ppr, sdev->inquiry_len));
2354 if (sdev->id > sh->max_id) {
2355 /* error case, should never happen */
2356 scsi_adjust_queue_depth(sdev, 0, 1);
2357 goto slave_configure_exit;
2360 vdevice->configured_lun = 1;
2361 mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH);
2363 dsprintk((MYIOC_s_INFO_FMT
2364 "Queue depth=%d, tflags=%x\n",
2365 hd->ioc->name, sdev->queue_depth, vtarget->tflags));
2367 if (hd->ioc->bus_type == SPI)
2368 dsprintk((MYIOC_s_INFO_FMT
2369 "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
2370 hd->ioc->name, vtarget->negoFlags, vtarget->maxOffset,
2371 vtarget->minSyncFactor));
2373 slave_configure_exit:
2375 dsprintk((MYIOC_s_INFO_FMT
2376 "tagged %d, simple %d, ordered %d\n",
2377 hd->ioc->name,sdev->tagged_supported, sdev->simple_tags,
2378 sdev->ordered_tags));
2383 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2385 * Private routines...
2388 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2389 /* Utility function to copy sense data from the scsi_cmnd buffer
2390 * to the FC and SCSI target structures.
2394 mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
2397 SCSIIORequest_t *pReq;
2398 u32 sense_count = le32_to_cpu(pScsiReply->SenseCount);
2400 /* Get target structure
2402 pReq = (SCSIIORequest_t *) mf;
2403 vdev = sc->device->hostdata;
2409 /* Copy the sense received into the scsi command block. */
2410 req_index = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2411 sense_data = ((u8 *)hd->ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC));
2412 memcpy(sc->sense_buffer, sense_data, SNS_LEN(sc));
2414 /* Log SMART data (asc = 0x5D, non-IM case only) if required.
2416 if ((hd->ioc->events) && (hd->ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) {
2417 if ((sense_data[12] == 0x5D) && (vdev->vtarget->raidVolume == 0)) {
2419 MPT_ADAPTER *ioc = hd->ioc;
2421 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
2422 ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
2423 ioc->events[idx].eventContext = ioc->eventContext;
2425 ioc->events[idx].data[0] = (pReq->LUN[1] << 24) |
2426 (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) |
2427 (sc->device->channel << 8) | sc->device->id;
2429 ioc->events[idx].data[1] = (sense_data[13] << 8) | sense_data[12];
2431 ioc->eventContext++;
2432 if (hd->ioc->pcidev->vendor ==
2433 PCI_VENDOR_ID_IBM) {
2434 mptscsih_issue_sep_command(hd->ioc,
2435 vdev->vtarget, MPI_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT);
2436 vdev->vtarget->tflags |=
2437 MPT_TARGET_FLAGS_LED_ON;
2442 dprintk((MYIOC_s_INFO_FMT "Hmmm... SenseData len=0! (?)\n",
2448 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc)
2453 hd = (MPT_SCSI_HOST *) sc->device->host->hostdata;
2455 for (i = 0; i < hd->ioc->req_depth; i++) {
2456 if (hd->ScsiLookup[i] == sc) {
2464 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2466 mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2469 unsigned long flags;
2472 dtmprintk((KERN_WARNING MYNAM
2473 ": IOC %s_reset routed to SCSI host driver!\n",
2474 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
2475 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
2477 /* If a FW reload request arrives after base installed but
2478 * before all scsi hosts have been attached, then an alt_ioc
2479 * may have a NULL sh pointer.
2481 if ((ioc->sh == NULL) || (ioc->sh->hostdata == NULL))
2484 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2486 if (reset_phase == MPT_IOC_SETUP_RESET) {
2487 dtmprintk((MYIOC_s_WARN_FMT "Setup-Diag Reset\n", ioc->name));
2490 * 1. Set Hard Reset Pending Flag
2491 * All new commands go to doneQ
2493 hd->resetPending = 1;
2495 } else if (reset_phase == MPT_IOC_PRE_RESET) {
2496 dtmprintk((MYIOC_s_WARN_FMT "Pre-Diag Reset\n", ioc->name));
2498 /* 2. Flush running commands
2499 * Clean ScsiLookup (and associated memory)
2503 /* 2b. Reply to OS all known outstanding I/O commands.
2505 mptscsih_flush_running_cmds(hd);
2507 /* 2c. If there was an internal command that
2508 * has not completed, configuration or io request,
2509 * free these resources.
2512 del_timer(&hd->timer);
2513 mpt_free_msg_frame(ioc, hd->cmdPtr);
2516 dtmprintk((MYIOC_s_WARN_FMT "Pre-Reset complete.\n", ioc->name));
2519 dtmprintk((MYIOC_s_WARN_FMT "Post-Diag Reset\n", ioc->name));
2521 /* Once a FW reload begins, all new OS commands are
2522 * redirected to the doneQ w/ a reset status.
2523 * Init all control structures.
2526 /* ScsiLookup initialization
2528 for (ii=0; ii < hd->ioc->req_depth; ii++)
2529 hd->ScsiLookup[ii] = NULL;
2531 /* 2. Chain Buffer initialization
2534 /* 4. Renegotiate to all devices, if SPI
2537 /* 5. Enable new commands to be posted
2539 spin_lock_irqsave(&ioc->FreeQlock, flags);
2541 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2542 hd->resetPending = 0;
2543 hd->tmState = TM_STATE_NONE;
2545 /* 6. If there was an internal command,
2546 * wake this process up.
2550 * Wake up the original calling thread
2552 hd->pLocal = &hd->localReply;
2553 hd->pLocal->completion = MPT_SCANDV_DID_RESET;
2554 hd->scandv_wait_done = 1;
2555 wake_up(&hd->scandv_waitq);
2559 dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name));
2563 return 1; /* currently means nothing really */
2566 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2568 mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2571 u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
2573 devtverboseprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
2576 if (ioc->sh == NULL ||
2577 ((hd = (MPT_SCSI_HOST *)ioc->sh->hostdata) == NULL))
2581 case MPI_EVENT_UNIT_ATTENTION: /* 03 */
2584 case MPI_EVENT_IOC_BUS_RESET: /* 04 */
2585 case MPI_EVENT_EXT_BUS_RESET: /* 05 */
2586 if (hd && (ioc->bus_type == SPI) && (hd->soft_resets < -1))
2589 case MPI_EVENT_LOGOUT: /* 09 */
2593 case MPI_EVENT_RESCAN: /* 06 */
2597 * CHECKME! Don't think we need to do
2598 * anything for these, but...
2600 case MPI_EVENT_LINK_STATUS_CHANGE: /* 07 */
2601 case MPI_EVENT_LOOP_STATE_CHANGE: /* 08 */
2603 * CHECKME! Falling thru...
2607 case MPI_EVENT_INTEGRATED_RAID: /* 0B */
2610 case MPI_EVENT_NONE: /* 00 */
2611 case MPI_EVENT_LOG_DATA: /* 01 */
2612 case MPI_EVENT_STATE_CHANGE: /* 02 */
2613 case MPI_EVENT_EVENT_CHANGE: /* 0A */
2615 dprintk((KERN_INFO " Ignoring event (=%02Xh)\n", event));
2619 return 1; /* currently means nothing really */
2622 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2624 * Bus Scan and Domain Validation functionality ...
2627 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2629 * mptscsih_scandv_complete - Scan and DV callback routine registered
2630 * to Fustion MPT (base) driver.
2632 * @ioc: Pointer to MPT_ADAPTER structure
2633 * @mf: Pointer to original MPT request frame
2634 * @mr: Pointer to MPT reply frame (NULL if TurboReply)
2636 * This routine is called from mpt.c::mpt_interrupt() at the completion
2637 * of any SCSI IO request.
2638 * This routine is registered with the Fusion MPT (base) driver at driver
2639 * load/init time via the mpt_register() API call.
2641 * Returns 1 indicating alloc'd request frame ptr should be freed.
2643 * Remark: Sets a completion code and (possibly) saves sense data
2644 * in the IOC member localReply structure.
2645 * Used ONLY for DV and other internal commands.
2648 mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
2651 SCSIIORequest_t *pReq;
2655 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2658 (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) {
2659 printk(MYIOC_s_ERR_FMT
2660 "ScanDvComplete, %s req frame ptr! (=%p)\n",
2661 ioc->name, mf?"BAD":"NULL", (void *) mf);
2665 del_timer(&hd->timer);
2666 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2667 hd->ScsiLookup[req_idx] = NULL;
2668 pReq = (SCSIIORequest_t *) mf;
2670 if (mf != hd->cmdPtr) {
2671 printk(MYIOC_s_WARN_FMT "ScanDvComplete (mf=%p, cmdPtr=%p, idx=%d)\n",
2672 hd->ioc->name, (void *)mf, (void *) hd->cmdPtr, req_idx);
2676 ddvprintk((MYIOC_s_INFO_FMT "ScanDvComplete (mf=%p,mr=%p,idx=%d)\n",
2677 hd->ioc->name, mf, mr, req_idx));
2679 hd->pLocal = &hd->localReply;
2680 hd->pLocal->scsiStatus = 0;
2682 /* If target struct exists, clear sense valid flag.
2685 completionCode = MPT_SCANDV_GOOD;
2687 SCSIIOReply_t *pReply;
2691 pReply = (SCSIIOReply_t *) mr;
2693 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2694 scsi_status = pReply->SCSIStatus;
2696 ddvtprintk((KERN_NOTICE " IOCStatus=%04xh, SCSIState=%02xh, SCSIStatus=%02xh, IOCLogInfo=%08xh\n",
2697 status, pReply->SCSIState, scsi_status,
2698 le32_to_cpu(pReply->IOCLogInfo)));
2702 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
2703 completionCode = MPT_SCANDV_SELECTION_TIMEOUT;
2706 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
2707 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
2708 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
2709 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
2710 completionCode = MPT_SCANDV_DID_RESET;
2713 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
2714 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
2715 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
2716 if (pReply->Function == MPI_FUNCTION_CONFIG) {
2717 ConfigReply_t *pr = (ConfigReply_t *)mr;
2718 completionCode = MPT_SCANDV_GOOD;
2719 hd->pLocal->header.PageVersion = pr->Header.PageVersion;
2720 hd->pLocal->header.PageLength = pr->Header.PageLength;
2721 hd->pLocal->header.PageNumber = pr->Header.PageNumber;
2722 hd->pLocal->header.PageType = pr->Header.PageType;
2724 } else if (pReply->Function == MPI_FUNCTION_RAID_ACTION) {
2725 /* If the RAID Volume request is successful,
2726 * return GOOD, else indicate that
2727 * some type of error occurred.
2729 MpiRaidActionReply_t *pr = (MpiRaidActionReply_t *)mr;
2730 if (le16_to_cpu(pr->ActionStatus) == MPI_RAID_ACTION_ASTATUS_SUCCESS)
2731 completionCode = MPT_SCANDV_GOOD;
2733 completionCode = MPT_SCANDV_SOME_ERROR;
2734 memcpy(hd->pLocal->sense, pr, sizeof(hd->pLocal->sense));
2736 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID) {
2740 /* save sense data in global structure
2742 completionCode = MPT_SCANDV_SENSE;
2743 hd->pLocal->scsiStatus = scsi_status;
2744 sense_data = ((u8 *)hd->ioc->sense_buf_pool +
2745 (req_idx * MPT_SENSE_BUFFER_ALLOC));
2747 sz = min_t(int, pReq->SenseBufferLength,
2748 SCSI_STD_SENSE_BYTES);
2749 memcpy(hd->pLocal->sense, sense_data, sz);
2751 ddvprintk((KERN_NOTICE " Check Condition, sense ptr %p\n",
2753 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_FAILED) {
2754 if (pReq->CDB[0] == INQUIRY)
2755 completionCode = MPT_SCANDV_ISSUE_SENSE;
2757 completionCode = MPT_SCANDV_DID_RESET;
2759 else if (pReply->SCSIState & MPI_SCSI_STATE_NO_SCSI_STATUS)
2760 completionCode = MPT_SCANDV_DID_RESET;
2761 else if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
2762 completionCode = MPT_SCANDV_DID_RESET;
2764 completionCode = MPT_SCANDV_GOOD;
2765 hd->pLocal->scsiStatus = scsi_status;
2769 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
2770 if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
2771 completionCode = MPT_SCANDV_DID_RESET;
2773 completionCode = MPT_SCANDV_SOME_ERROR;
2777 completionCode = MPT_SCANDV_SOME_ERROR;
2780 } /* switch(status) */
2782 ddvtprintk((KERN_NOTICE " completionCode set to %08xh\n",
2784 } /* end of address reply case */
2786 hd->pLocal->completion = completionCode;
2788 /* MF and RF are freed in mpt_interrupt
2791 /* Free Chain buffers (will never chain) in scan or dv */
2792 //mptscsih_freeChainBuffers(ioc, req_idx);
2795 * Wake up the original calling thread
2797 hd->scandv_wait_done = 1;
2798 wake_up(&hd->scandv_waitq);
2803 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2804 /* mptscsih_timer_expired - Call back for timer process.
2805 * Used only for dv functionality.
2806 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
2810 mptscsih_timer_expired(unsigned long data)
2812 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) data;
2814 ddvprintk((MYIOC_s_WARN_FMT "Timer Expired! Cmd %p\n", hd->ioc->name, hd->cmdPtr));
2817 MPIHeader_t *cmd = (MPIHeader_t *)hd->cmdPtr;
2819 if (cmd->Function == MPI_FUNCTION_SCSI_IO_REQUEST) {
2820 /* Desire to issue a task management request here.
2821 * TM requests MUST be single threaded.
2822 * If old eh code and no TM current, issue request.
2823 * If new eh code, do nothing. Wait for OS cmd timeout
2826 ddvtprintk((MYIOC_s_NOTE_FMT "DV Cmd Timeout: NoOp\n", hd->ioc->name));
2828 /* Perform a FW reload */
2829 if (mpt_HardResetHandler(hd->ioc, NO_SLEEP) < 0) {
2830 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", hd->ioc->name);
2834 /* This should NEVER happen */
2835 printk(MYIOC_s_WARN_FMT "Null cmdPtr!!!!\n", hd->ioc->name);
2838 /* No more processing.
2839 * TM call will generate an interrupt for SCSI TM Management.
2840 * The FW will reply to all outstanding commands, callback will finish cleanup.
2841 * Hard reset clean-up will free all resources.
2843 ddvprintk((MYIOC_s_WARN_FMT "Timer Expired Complete!\n", hd->ioc->name));
2849 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2851 * mptscsih_do_cmd - Do internal command.
2852 * @hd: MPT_SCSI_HOST pointer
2853 * @io: INTERNAL_CMD pointer.
2855 * Issue the specified internally generated command and do command
2856 * specific cleanup. For bus scan / DV only.
2857 * NOTES: If command is Inquiry and status is good,
2858 * initialize a target structure, save the data
2860 * Remark: Single threaded access only.
2863 * < 0 if an illegal command or no resources
2867 * > 0 if command complete but some type of completion error.
2870 mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
2873 SCSIIORequest_t *pScsiReq;
2874 SCSIIORequest_t ReqCopy;
2875 int my_idx, ii, dir;
2879 char CDB[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
2882 in_isr = in_interrupt();
2884 dprintk((MYIOC_s_WARN_FMT "Internal SCSI IO request not allowed in ISR context!\n",
2890 /* Set command specific information
2895 dir = MPI_SCSIIO_CONTROL_READ;
2901 case TEST_UNIT_READY:
2903 dir = MPI_SCSIIO_CONTROL_READ;
2909 dir = MPI_SCSIIO_CONTROL_READ;
2911 CDB[4] = 1; /*Spin up the disk */
2919 dir = MPI_SCSIIO_CONTROL_READ;
2925 dir = MPI_SCSIIO_CONTROL_READ;
2927 if (io->flags & MPT_ICFLAG_ECHO) {
2933 if (io->flags & MPT_ICFLAG_BUF_CAP) {
2936 CDB[6] = (io->size >> 16) & 0xFF;
2937 CDB[7] = (io->size >> 8) & 0xFF;
2938 CDB[8] = io->size & 0xFF;
2944 dir = MPI_SCSIIO_CONTROL_WRITE;
2946 if (io->flags & MPT_ICFLAG_ECHO) {
2951 CDB[6] = (io->size >> 16) & 0xFF;
2952 CDB[7] = (io->size >> 8) & 0xFF;
2953 CDB[8] = io->size & 0xFF;
2959 dir = MPI_SCSIIO_CONTROL_READ;
2966 dir = MPI_SCSIIO_CONTROL_READ;
2971 case SYNCHRONIZE_CACHE:
2973 dir = MPI_SCSIIO_CONTROL_READ;
2975 // CDB[1] = 0x02; /* set immediate bit */
2984 /* Get and Populate a free Frame
2986 if ((mf = mpt_get_msg_frame(hd->ioc->InternalCtx, hd->ioc)) == NULL) {
2987 ddvprintk((MYIOC_s_WARN_FMT "No msg frames!\n",
2992 pScsiReq = (SCSIIORequest_t *) mf;
2994 /* Get the request index */
2995 my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2996 ADD_INDEX_LOG(my_idx); /* for debug */
2998 if (io->flags & MPT_ICFLAG_PHYS_DISK) {
2999 pScsiReq->TargetID = io->physDiskNum;
3001 pScsiReq->ChainOffset = 0;
3002 pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
3004 pScsiReq->TargetID = io->id;
3005 pScsiReq->Bus = io->channel;
3006 pScsiReq->ChainOffset = 0;
3007 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
3010 pScsiReq->CDBLength = cmdLen;
3011 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
3013 pScsiReq->Reserved = 0;
3015 pScsiReq->MsgFlags = mpt_msg_flags();
3016 /* MsgContext set in mpt_get_msg_fram call */
3018 int_to_scsilun(io->lun, (struct scsi_lun *)pScsiReq->LUN);
3020 if (io->flags & MPT_ICFLAG_TAGGED_CMD)
3021 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ);
3023 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3025 if (cmd == REQUEST_SENSE) {
3026 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3027 ddvprintk((MYIOC_s_INFO_FMT "Untagged! 0x%2x\n",
3028 hd->ioc->name, cmd));
3031 for (ii=0; ii < 16; ii++)
3032 pScsiReq->CDB[ii] = CDB[ii];
3034 pScsiReq->DataLength = cpu_to_le32(io->size);
3035 pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
3036 + (my_idx * MPT_SENSE_BUFFER_ALLOC));
3038 ddvprintk((MYIOC_s_INFO_FMT "Sending Command 0x%x for (%d:%d:%d)\n",
3039 hd->ioc->name, cmd, io->channel, io->id, io->lun));
3041 if (dir == MPI_SCSIIO_CONTROL_READ) {
3042 mpt_add_sge((char *) &pScsiReq->SGL,
3043 MPT_SGE_FLAGS_SSIMPLE_READ | io->size,
3046 mpt_add_sge((char *) &pScsiReq->SGL,
3047 MPT_SGE_FLAGS_SSIMPLE_WRITE | io->size,
3051 /* The ISR will free the request frame, but we need
3052 * the information to initialize the target. Duplicate.
3054 memcpy(&ReqCopy, pScsiReq, sizeof(SCSIIORequest_t));
3056 /* Issue this command after:
3059 * Wait until the reply has been received
3060 * ScsiScanDvCtx callback function will
3062 * set scandv_wait_done and call wake_up
3065 hd->timer.expires = jiffies + HZ*cmdTimeout;
3066 hd->scandv_wait_done = 0;
3068 /* Save cmd pointer, for resource free if timeout or
3073 add_timer(&hd->timer);
3074 mpt_put_msg_frame(hd->ioc->InternalCtx, hd->ioc, mf);
3075 wait_event(hd->scandv_waitq, hd->scandv_wait_done);
3078 rc = hd->pLocal->completion;
3079 hd->pLocal->skip = 0;
3081 /* Always set fatal error codes in some cases.
3083 if (rc == MPT_SCANDV_SELECTION_TIMEOUT)
3085 else if (rc == MPT_SCANDV_SOME_ERROR)
3089 /* This should never happen. */
3090 ddvprintk((MYIOC_s_INFO_FMT "_do_cmd: Null pLocal!!!\n",
3097 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3099 * mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
3100 * @hd: Pointer to a SCSI HOST structure
3101 * @vdevice: virtual target device
3103 * Uses the ISR, but with special processing.
3104 * MUST be single-threaded.
3108 mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
3112 /* Following parameters will not change
3115 iocmd.cmd = SYNCHRONIZE_CACHE;
3117 iocmd.physDiskNum = -1;
3119 iocmd.data_dma = -1;
3121 iocmd.rsvd = iocmd.rsvd2 = 0;
3122 iocmd.channel = vdevice->vtarget->channel;
3123 iocmd.id = vdevice->vtarget->id;
3124 iocmd.lun = vdevice->lun;
3126 if ((vdevice->vtarget->type == TYPE_DISK) &&
3127 (vdevice->configured_lun))
3128 mptscsih_do_cmd(hd, &iocmd);
3131 EXPORT_SYMBOL(mptscsih_remove);
3132 EXPORT_SYMBOL(mptscsih_shutdown);
3134 EXPORT_SYMBOL(mptscsih_suspend);
3135 EXPORT_SYMBOL(mptscsih_resume);
3137 EXPORT_SYMBOL(mptscsih_proc_info);
3138 EXPORT_SYMBOL(mptscsih_info);
3139 EXPORT_SYMBOL(mptscsih_qcmd);
3140 EXPORT_SYMBOL(mptscsih_slave_destroy);
3141 EXPORT_SYMBOL(mptscsih_slave_configure);
3142 EXPORT_SYMBOL(mptscsih_abort);
3143 EXPORT_SYMBOL(mptscsih_dev_reset);
3144 EXPORT_SYMBOL(mptscsih_bus_reset);
3145 EXPORT_SYMBOL(mptscsih_host_reset);
3146 EXPORT_SYMBOL(mptscsih_bios_param);
3147 EXPORT_SYMBOL(mptscsih_io_done);
3148 EXPORT_SYMBOL(mptscsih_taskmgmt_complete);
3149 EXPORT_SYMBOL(mptscsih_scandv_complete);
3150 EXPORT_SYMBOL(mptscsih_event_process);
3151 EXPORT_SYMBOL(mptscsih_ioc_reset);
3152 EXPORT_SYMBOL(mptscsih_change_queue_depth);
3153 EXPORT_SYMBOL(mptscsih_timer_expired);
3154 EXPORT_SYMBOL(mptscsih_TMHandler);
3156 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/