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:mpt_linux_developer@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_compat.h" /* linux-2.6 tweaks */
48 #include <linux/module.h>
49 #include <linux/kernel.h>
50 #include <linux/init.h>
51 #include <linux/errno.h>
52 #include <linux/kdev_t.h>
53 #include <linux/blkdev.h>
54 #include <linux/delay.h> /* for mdelay */
55 #include <linux/interrupt.h> /* needed for in_interrupt() proto */
56 #include <linux/reboot.h> /* notifier code */
57 #include <linux/workqueue.h>
59 #include <scsi/scsi.h>
60 #include <scsi/scsi_cmnd.h>
61 #include <scsi/scsi_device.h>
62 #include <scsi/scsi_host.h>
63 #include <scsi/scsi_tcq.h>
64 #include <scsi/scsi_dbg.h>
68 #include "lsi/mpi_log_sas.h"
70 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
71 #define my_NAME "Fusion MPT SCSI Host driver"
72 #define my_VERSION MPT_LINUX_VERSION_COMMON
73 #define MYNAM "mptscsih"
75 MODULE_AUTHOR(MODULEAUTHOR);
76 MODULE_DESCRIPTION(my_NAME);
77 MODULE_LICENSE("GPL");
78 MODULE_VERSION(my_VERSION);
80 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
82 * Other private/forward protos...
84 int mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
85 static void mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq);
86 int mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
88 static int mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
89 SCSIIORequest_t *pReq, int req_idx);
90 static void mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx);
91 static void mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply);
92 static int mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd);
93 static int mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout );
94 static int SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc);
96 static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout);
98 int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
99 int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
101 int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
102 static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
103 static void mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice);
105 void mptscsih_remove(struct pci_dev *);
106 void mptscsih_shutdown(struct pci_dev *);
108 int mptscsih_suspend(struct pci_dev *pdev, pm_message_t state);
109 int mptscsih_resume(struct pci_dev *pdev);
112 #define SNS_LEN(scp) sizeof((scp)->sense_buffer)
114 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
116 * mptscsih_add_sge - Place a simple SGE at address pAddr.
117 * @pAddr: virtual address for SGE
118 * @flagslength: SGE flags and data transfer length
119 * @dma_addr: Physical address
121 * This routine places a MPT request frame back on the MPT adapter's
125 mptscsih_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
127 if (sizeof(dma_addr_t) == sizeof(u64)) {
128 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
129 u32 tmp = dma_addr & 0xFFFFFFFF;
131 pSge->FlagsLength = cpu_to_le32(flagslength);
132 pSge->Address.Low = cpu_to_le32(tmp);
133 tmp = (u32) ((u64)dma_addr >> 32);
134 pSge->Address.High = cpu_to_le32(tmp);
137 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
138 pSge->FlagsLength = cpu_to_le32(flagslength);
139 pSge->Address = cpu_to_le32(dma_addr);
141 } /* mptscsih_add_sge() */
143 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
145 * mptscsih_add_chain - Place a chain SGE at address pAddr.
146 * @pAddr: virtual address for SGE
147 * @next: nextChainOffset value (u32's)
148 * @length: length of next SGL segment
149 * @dma_addr: Physical address
151 * This routine places a MPT request frame back on the MPT adapter's
155 mptscsih_add_chain(char *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
157 if (sizeof(dma_addr_t) == sizeof(u64)) {
158 SGEChain64_t *pChain = (SGEChain64_t *) pAddr;
159 u32 tmp = dma_addr & 0xFFFFFFFF;
161 pChain->Length = cpu_to_le16(length);
162 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size();
164 pChain->NextChainOffset = next;
166 pChain->Address.Low = cpu_to_le32(tmp);
167 tmp = (u32) ((u64)dma_addr >> 32);
168 pChain->Address.High = cpu_to_le32(tmp);
170 SGEChain32_t *pChain = (SGEChain32_t *) pAddr;
171 pChain->Length = cpu_to_le16(length);
172 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size();
173 pChain->NextChainOffset = next;
174 pChain->Address = cpu_to_le32(dma_addr);
176 } /* mptscsih_add_chain() */
178 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
180 * mptscsih_getFreeChainBuffer - Function to get a free chain
181 * from the MPT_SCSI_HOST FreeChainQ.
182 * @ioc: Pointer to MPT_ADAPTER structure
183 * @req_idx: Index of the SCSI IO request frame. (output)
185 * return SUCCESS or FAILED
188 mptscsih_getFreeChainBuffer(MPT_ADAPTER *ioc, int *retIndex)
190 MPT_FRAME_HDR *chainBuf;
195 dsgprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer called\n",
197 spin_lock_irqsave(&ioc->FreeQlock, flags);
198 if (!list_empty(&ioc->FreeChainQ)) {
201 chainBuf = list_entry(ioc->FreeChainQ.next, MPT_FRAME_HDR,
202 u.frame.linkage.list);
203 list_del(&chainBuf->u.frame.linkage.list);
204 offset = (u8 *)chainBuf - (u8 *)ioc->ChainBuffer;
205 chain_idx = offset / ioc->req_sz;
207 dsgprintk((MYIOC_s_ERR_FMT "getFreeChainBuffer chainBuf=%p ChainBuffer=%p offset=%d chain_idx=%d\n",
208 ioc->name, chainBuf, ioc->ChainBuffer, offset, chain_idx));
211 chain_idx = MPT_HOST_NO_CHAIN;
212 dfailprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer failed\n",
215 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
217 *retIndex = chain_idx;
219 } /* mptscsih_getFreeChainBuffer() */
221 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
223 * mptscsih_AddSGE - Add a SGE (plus chain buffers) to the
224 * SCSIIORequest_t Message Frame.
225 * @ioc: Pointer to MPT_ADAPTER structure
226 * @SCpnt: Pointer to scsi_cmnd structure
227 * @pReq: Pointer to SCSIIORequest_t structure
232 mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
233 SCSIIORequest_t *pReq, int req_idx)
237 struct scatterlist *sg;
239 int sges_left, sg_done;
240 int chain_idx = MPT_HOST_NO_CHAIN;
242 int numSgeSlots, numSgeThisFrame;
243 u32 sgflags, sgdir, thisxfer = 0;
244 int chain_dma_off = 0;
250 sgdir = le32_to_cpu(pReq->Control) & MPI_SCSIIO_CONTROL_DATADIRECTION_MASK;
251 if (sgdir == MPI_SCSIIO_CONTROL_WRITE) {
252 sgdir = MPT_TRANSFER_HOST_TO_IOC;
254 sgdir = MPT_TRANSFER_IOC_TO_HOST;
257 psge = (char *) &pReq->SGL;
258 frm_sz = ioc->req_sz;
260 /* Map the data portion, if any.
261 * sges_left = 0 if no data transfer.
263 if ( (sges_left = SCpnt->use_sg) ) {
264 sges_left = pci_map_sg(ioc->pcidev,
265 (struct scatterlist *) SCpnt->request_buffer,
267 SCpnt->sc_data_direction);
270 } else if (SCpnt->request_bufflen) {
271 SCpnt->SCp.dma_handle = pci_map_single(ioc->pcidev,
272 SCpnt->request_buffer,
273 SCpnt->request_bufflen,
274 SCpnt->sc_data_direction);
275 dsgprintk((MYIOC_s_INFO_FMT "SG: non-SG for %p, len=%d\n",
276 ioc->name, SCpnt, SCpnt->request_bufflen));
277 mptscsih_add_sge((char *) &pReq->SGL,
278 0xD1000000|MPT_SGE_FLAGS_ADDRESSING|sgdir|SCpnt->request_bufflen,
279 SCpnt->SCp.dma_handle);
284 /* Handle the SG case.
286 sg = (struct scatterlist *) SCpnt->request_buffer;
288 sgeOffset = sizeof(SCSIIORequest_t) - sizeof(SGE_IO_UNION);
291 /* Prior to entering this loop - the following must be set
292 * current MF: sgeOffset (bytes)
293 * chainSge (Null if original MF is not a chain buffer)
294 * sg_done (num SGE done for this MF)
298 numSgeSlots = ((frm_sz - sgeOffset) / (sizeof(u32) + sizeof(dma_addr_t)) );
299 numSgeThisFrame = (sges_left < numSgeSlots) ? sges_left : numSgeSlots;
301 sgflags = MPT_SGE_FLAGS_SIMPLE_ELEMENT | MPT_SGE_FLAGS_ADDRESSING | sgdir;
303 /* Get first (num - 1) SG elements
304 * Skip any SG entries with a length of 0
305 * NOTE: at finish, sg and psge pointed to NEXT data/location positions
307 for (ii=0; ii < (numSgeThisFrame-1); ii++) {
308 thisxfer = sg_dma_len(sg);
310 sg ++; /* Get next SG element from the OS */
315 v2 = sg_dma_address(sg);
316 mptscsih_add_sge(psge, sgflags | thisxfer, v2);
318 sg++; /* Get next SG element from the OS */
319 psge += (sizeof(u32) + sizeof(dma_addr_t));
320 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
324 if (numSgeThisFrame == sges_left) {
325 /* Add last element, end of buffer and end of list flags.
327 sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT |
328 MPT_SGE_FLAGS_END_OF_BUFFER |
329 MPT_SGE_FLAGS_END_OF_LIST;
331 /* Add last SGE and set termination flags.
332 * Note: Last SGE may have a length of 0 - which should be ok.
334 thisxfer = sg_dma_len(sg);
336 v2 = sg_dma_address(sg);
337 mptscsih_add_sge(psge, sgflags | thisxfer, v2);
340 psge += (sizeof(u32) + sizeof(dma_addr_t));
342 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
346 /* The current buffer is a chain buffer,
347 * but there is not another one.
348 * Update the chain element
349 * Offset and Length fields.
351 mptscsih_add_chain((char *)chainSge, 0, sgeOffset, ioc->ChainBufferDMA + chain_dma_off);
353 /* The current buffer is the original MF
354 * and there is no Chain buffer.
356 pReq->ChainOffset = 0;
357 RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor) + 1) & 0x03;
358 dsgprintk((MYIOC_s_INFO_FMT
359 "Single Buffer RequestNB=%x, sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
360 ioc->RequestNB[req_idx] = RequestNB;
363 /* At least one chain buffer is needed.
364 * Complete the first MF
365 * - last SGE element, set the LastElement bit
366 * - set ChainOffset (words) for orig MF
367 * (OR finish previous MF chain buffer)
368 * - update MFStructPtr ChainIndex
369 * - Populate chain element
374 dsgprintk((MYIOC_s_INFO_FMT "SG: Chain Required! sg done %d\n",
375 ioc->name, sg_done));
377 /* Set LAST_ELEMENT flag for last non-chain element
378 * in the buffer. Since psge points at the NEXT
379 * SGE element, go back one SGE element, update the flags
380 * and reset the pointer. (Note: sgflags & thisxfer are already
384 u32 *ptmp = (u32 *) (psge - (sizeof(u32) + sizeof(dma_addr_t)));
385 sgflags = le32_to_cpu(*ptmp);
386 sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT;
387 *ptmp = cpu_to_le32(sgflags);
391 /* The current buffer is a chain buffer.
392 * chainSge points to the previous Chain Element.
393 * Update its chain element Offset and Length (must
394 * include chain element size) fields.
395 * Old chain element is now complete.
397 u8 nextChain = (u8) (sgeOffset >> 2);
398 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
399 mptscsih_add_chain((char *)chainSge, nextChain, sgeOffset, ioc->ChainBufferDMA + chain_dma_off);
401 /* The original MF buffer requires a chain buffer -
403 * Last element in this MF is a chain element.
405 pReq->ChainOffset = (u8) (sgeOffset >> 2);
406 RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor) + 1) & 0x03;
407 dsgprintk((MYIOC_s_ERR_FMT "Chain Buffer Needed, RequestNB=%x sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
408 ioc->RequestNB[req_idx] = RequestNB;
411 sges_left -= sg_done;
414 /* NOTE: psge points to the beginning of the chain element
415 * in current buffer. Get a chain buffer.
417 if ((mptscsih_getFreeChainBuffer(ioc, &newIndex)) == FAILED) {
418 dfailprintk((MYIOC_s_INFO_FMT
419 "getFreeChainBuffer FAILED SCSI cmd=%02x (%p)\n",
420 ioc->name, pReq->CDB[0], SCpnt));
424 /* Update the tracking arrays.
425 * If chainSge == NULL, update ReqToChain, else ChainToChain
428 ioc->ChainToChain[chain_idx] = newIndex;
430 ioc->ReqToChain[req_idx] = newIndex;
432 chain_idx = newIndex;
433 chain_dma_off = ioc->req_sz * chain_idx;
435 /* Populate the chainSGE for the current buffer.
436 * - Set chain buffer pointer to psge and fill
437 * out the Address and Flags fields.
439 chainSge = (char *) psge;
440 dsgprintk((KERN_INFO " Current buff @ %p (index 0x%x)",
443 /* Start the SGE for the next buffer
445 psge = (char *) (ioc->ChainBuffer + chain_dma_off);
449 dsgprintk((KERN_INFO " Chain buff @ %p (index 0x%x)\n",
452 /* Start the SGE for the next buffer
459 } /* mptscsih_AddSGE() */
462 mptscsih_issue_sep_command(MPT_ADAPTER *ioc, VirtTarget *vtarget,
466 SEPRequest_t *SEPMsg;
468 if (ioc->bus_type == FC)
471 if ((mf = mpt_get_msg_frame(ioc->InternalCtx, ioc)) == NULL) {
472 dfailprintk((MYIOC_s_WARN_FMT "%s: no msg frames!!\n",
473 ioc->name,__FUNCTION__));
477 SEPMsg = (SEPRequest_t *)mf;
478 SEPMsg->Function = MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR;
479 SEPMsg->Bus = vtarget->channel;
480 SEPMsg->TargetID = vtarget->id;
481 SEPMsg->Action = MPI_SEP_REQ_ACTION_WRITE_STATUS;
482 SEPMsg->SlotStatus = SlotStatus;
483 devtverboseprintk((MYIOC_s_WARN_FMT
484 "Sending SEP cmd=%x channel=%d id=%d\n",
485 ioc->name, SlotStatus, SEPMsg->Bus, SEPMsg->TargetID));
486 mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
489 #ifdef MPT_DEBUG_REPLY
491 * mptscsih_iocstatus_info_scsiio - IOCSTATUS information for SCSIIO
492 * @ioc: Pointer to MPT_ADAPTER structure
493 * @ioc_status: U32 IOCStatus word from IOC
494 * @scsi_status: U8 sam status from target
495 * @scsi_state: U8 scsi state
496 * @sc: original scsi cmnd pointer
497 * @mf: Pointer to MPT request frame
499 * Refer to lsi/mpi.h.
502 mptscsih_iocstatus_info_scsiio(MPT_ADAPTER *ioc, u32 ioc_status,
503 u8 scsi_status, u8 scsi_state, struct scsi_cmnd *sc)
505 char extend_desc[EVENT_DESCR_STR_SZ];
508 switch (ioc_status) {
510 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
511 desc = "SCSI Invalid Bus";
514 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
515 desc = "SCSI Invalid TargetID";
518 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
520 * Inquiry is issued for device scanning
522 if (sc->cmnd[0] != 0x12)
523 desc = "SCSI Device Not There";
526 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
527 desc = "SCSI Data Overrun";
530 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
531 desc = "SCSI I/O Data Error";
534 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
535 desc = "SCSI Protocol Error";
538 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
539 desc = "SCSI Task Terminated";
542 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
543 desc = "SCSI Residual Mismatch";
546 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
547 desc = "SCSI Task Management Failed";
550 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
551 desc = "SCSI IOC Terminated";
554 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
555 desc = "SCSI Ext Terminated";
562 snprintf(extend_desc, EVENT_DESCR_STR_SZ,
563 "[%d:%d:%d:%d] cmd=%02Xh, sam_status=%02Xh state=%02Xh",
564 sc->device->host->host_no,
565 sc->device->channel, sc->device->id, sc->device->lun,
566 sc->cmnd[0], scsi_status, scsi_state);
568 printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04X): %s: %s\n",
569 ioc->name, ioc_status, desc, extend_desc);
573 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
575 * mptscsih_io_done - Main SCSI IO callback routine registered to
576 * Fusion MPT (base) driver
577 * @ioc: Pointer to MPT_ADAPTER structure
578 * @mf: Pointer to original MPT request frame
579 * @r: Pointer to MPT reply frame (NULL if TurboReply)
581 * This routine is called from mpt.c::mpt_interrupt() at the completion
582 * of any SCSI IO request.
583 * This routine is registered with the Fusion MPT (base) driver at driver
584 * load/init time via the mpt_register() API call.
586 * Returns 1 indicating alloc'd request frame ptr should be freed.
589 mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
591 struct scsi_cmnd *sc;
593 SCSIIORequest_t *pScsiReq;
594 SCSIIOReply_t *pScsiReply;
595 u16 req_idx, req_idx_MR;
599 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
601 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
602 req_idx_MR = (mr != NULL) ?
603 le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx) : req_idx;
604 if ((req_idx != req_idx_MR) ||
605 (mf->u.frame.linkage.arg1 == 0xdeadbeaf)) {
606 printk(MYIOC_s_ERR_FMT "Received a mf that was already freed\n",
608 printk (MYIOC_s_ERR_FMT
609 "req_idx=%x req_idx_MR=%x mf=%p mr=%p sc=%p\n",
610 ioc->name, req_idx, req_idx_MR, mf, mr,
611 hd->ScsiLookup[req_idx_MR]);
615 sc = hd->ScsiLookup[req_idx];
616 hd->ScsiLookup[req_idx] = NULL;
618 MPIHeader_t *hdr = (MPIHeader_t *)mf;
620 /* Remark: writeSDP1 will use the ScsiDoneCtx
621 * If a SCSI I/O cmd, device disabled by OS and
622 * completion done. Cannot touch sc struct. Just free mem.
624 if (hdr->Function == MPI_FUNCTION_SCSI_IO_REQUEST)
625 printk(MYIOC_s_ERR_FMT "NULL ScsiCmd ptr!\n",
628 mptscsih_freeChainBuffers(ioc, req_idx);
632 if ((unsigned char *)mf != sc->host_scribble) {
633 mptscsih_freeChainBuffers(ioc, req_idx);
637 sc->host_scribble = NULL;
638 sc->result = DID_OK << 16; /* Set default reply as OK */
639 pScsiReq = (SCSIIORequest_t *) mf;
640 pScsiReply = (SCSIIOReply_t *) mr;
642 if((ioc->facts.MsgVersion >= MPI_VERSION_01_05) && pScsiReply){
643 dmfprintk((MYIOC_s_INFO_FMT
644 "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d,task-tag=%d)\n",
645 ioc->name, mf, mr, sc, req_idx, pScsiReply->TaskTag));
647 dmfprintk((MYIOC_s_INFO_FMT
648 "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n",
649 ioc->name, mf, mr, sc, req_idx));
652 if (pScsiReply == NULL) {
653 /* special context reply handling */
658 u8 scsi_state, scsi_status;
661 status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK;
662 scsi_state = pScsiReply->SCSIState;
663 scsi_status = pScsiReply->SCSIStatus;
664 xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
665 sc->resid = sc->request_bufflen - xfer_cnt;
666 log_info = le32_to_cpu(pScsiReply->IOCLogInfo);
669 * if we get a data underrun indication, yet no data was
670 * transferred and the SCSI status indicates that the
671 * command was never started, change the data underrun
674 if (status == MPI_IOCSTATUS_SCSI_DATA_UNDERRUN && xfer_cnt == 0 &&
675 (scsi_status == MPI_SCSI_STATUS_BUSY ||
676 scsi_status == MPI_SCSI_STATUS_RESERVATION_CONFLICT ||
677 scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)) {
678 status = MPI_IOCSTATUS_SUCCESS;
681 if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)
682 mptscsih_copy_sense_data(sc, hd, mf, pScsiReply);
685 * Look for + dump FCP ResponseInfo[]!
687 if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID &&
688 pScsiReply->ResponseInfo) {
689 printk(KERN_NOTICE "[%d:%d:%d:%d] "
690 "FCP_ResponseInfo=%08xh\n",
691 sc->device->host->host_no, sc->device->channel,
692 sc->device->id, sc->device->lun,
693 le32_to_cpu(pScsiReply->ResponseInfo));
697 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
699 * Maybe: DRIVER_BUSY | SUGGEST_RETRY | DID_SOFT_ERROR (retry)
700 * But not: DID_BUS_BUSY lest one risk
701 * killing interrupt handler:-(
703 sc->result = SAM_STAT_BUSY;
706 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
707 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
708 sc->result = DID_BAD_TARGET << 16;
711 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
712 /* Spoof to SCSI Selection Timeout! */
713 if (ioc->bus_type != FC)
714 sc->result = DID_NO_CONNECT << 16;
715 /* else fibre, just stall until rescan event */
717 sc->result = DID_REQUEUE << 16;
719 if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF)
720 hd->sel_timeout[pScsiReq->TargetID]++;
722 vdev = sc->device->hostdata;
725 vtarget = vdev->vtarget;
726 if (vtarget->tflags & MPT_TARGET_FLAGS_LED_ON) {
727 mptscsih_issue_sep_command(ioc, vtarget,
728 MPI_SEP_REQ_SLOTSTATUS_UNCONFIGURED);
729 vtarget->tflags &= ~MPT_TARGET_FLAGS_LED_ON;
733 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
734 if ( ioc->bus_type == SAS ) {
735 u16 ioc_status = le16_to_cpu(pScsiReply->IOCStatus);
736 if (ioc_status & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
737 if ((log_info & SAS_LOGINFO_MASK)
738 == SAS_LOGINFO_NEXUS_LOSS) {
739 sc->result = (DID_BUS_BUSY << 16);
743 } else if (ioc->bus_type == FC) {
745 * The FC IOC may kill a request for variety of
746 * reasons, some of which may be recovered by a
747 * retry, some which are unlikely to be
748 * recovered. Return DID_ERROR instead of
749 * DID_RESET to permit retry of the command,
750 * just not an infinite number of them
752 sc->result = DID_ERROR << 16;
757 * Allow non-SAS & non-NEXUS_LOSS to drop into below code
760 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
761 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
762 /* Linux handles an unsolicited DID_RESET better
763 * than an unsolicited DID_ABORT.
765 sc->result = DID_RESET << 16;
769 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
770 sc->resid = sc->request_bufflen - xfer_cnt;
771 if((xfer_cnt==0)||(sc->underflow > xfer_cnt))
772 sc->result=DID_SOFT_ERROR << 16;
773 else /* Sufficient data transfer occurred */
774 sc->result = (DID_OK << 16) | scsi_status;
775 dreplyprintk((KERN_NOTICE
776 "RESIDUAL_MISMATCH: result=%x on channel=%d id=%d\n",
777 sc->result, sc->device->channel, sc->device->id));
780 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
782 * Do upfront check for valid SenseData and give it
785 sc->result = (DID_OK << 16) | scsi_status;
786 if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
787 /* Have already saved the status and sense data
791 if (xfer_cnt < sc->underflow) {
792 if (scsi_status == SAM_STAT_BUSY)
793 sc->result = SAM_STAT_BUSY;
795 sc->result = DID_SOFT_ERROR << 16;
797 if (scsi_state & (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)) {
800 sc->result = DID_SOFT_ERROR << 16;
802 else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
803 /* Not real sure here either... */
804 sc->result = DID_RESET << 16;
808 dreplyprintk((KERN_NOTICE " sc->underflow={report ERR if < %02xh bytes xfer'd}\n",
810 dreplyprintk((KERN_NOTICE " ActBytesXferd=%02xh\n", xfer_cnt));
813 if (scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)
814 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
818 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
820 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
821 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
822 if (scsi_status == MPI_SCSI_STATUS_BUSY)
823 sc->result = (DID_BUS_BUSY << 16) | scsi_status;
825 sc->result = (DID_OK << 16) | scsi_status;
826 if (scsi_state == 0) {
828 } else if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
830 * If running against circa 200003dd 909 MPT f/w,
831 * may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL
832 * (QUEUE_FULL) returned from device! --> get 0x0000?128
833 * and with SenseBytes set to 0.
835 if (pScsiReply->SCSIStatus == MPI_SCSI_STATUS_TASK_SET_FULL)
836 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
839 else if (scsi_state &
840 (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)
845 sc->result = DID_SOFT_ERROR << 16;
847 else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
848 /* Not real sure here either... */
849 sc->result = DID_RESET << 16;
851 else if (scsi_state & MPI_SCSI_STATE_QUEUE_TAG_REJECTED) {
852 /* Device Inq. data indicates that it supports
853 * QTags, but rejects QTag messages.
854 * This command completed OK.
856 * Not real sure here either so do nothing... */
859 if (sc->result == MPI_SCSI_STATUS_TASK_SET_FULL)
860 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
863 * Reservation Conflict, Busy,
864 * Command Terminated, CHECK
868 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
869 sc->result = DID_SOFT_ERROR << 16;
872 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
873 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
874 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
875 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
876 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
877 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
878 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
879 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
880 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
885 sc->result = DID_SOFT_ERROR << 16;
888 } /* switch(status) */
890 #ifdef MPT_DEBUG_REPLY
893 mptscsih_iocstatus_info_scsiio(ioc, status,
894 scsi_status, scsi_state, sc);
896 dreplyprintk(("%s: [%d:%d:%d:%d] cmd=0x%02x "
897 "result=0x%08x\n\tiocstatus=0x%04X "
898 "scsi_state=0x%02X scsi_status=0x%02X "
899 "loginfo=0x%08X\n", __FUNCTION__,
900 sc->device->host->host_no, sc->device->channel, sc->device->id,
901 sc->device->lun, sc->cmnd[0], sc->result, status,
902 scsi_state, scsi_status, log_info));
904 dreplyprintk(("%s: [%d:%d:%d:%d] resid=%d "
905 "bufflen=%d xfer_cnt=%d\n", __FUNCTION__,
906 sc->device->host->host_no, sc->device->channel, sc->device->id,
907 sc->device->lun, sc->resid, sc->request_bufflen,
912 } /* end of address reply case */
914 /* Unmap the DMA buffers, if any. */
916 pci_unmap_sg(ioc->pcidev, (struct scatterlist *) sc->request_buffer,
917 sc->use_sg, sc->sc_data_direction);
918 } else if (sc->request_bufflen) {
919 pci_unmap_single(ioc->pcidev, sc->SCp.dma_handle,
920 sc->request_bufflen, sc->sc_data_direction);
923 sc->scsi_done(sc); /* Issue the command callback */
925 /* Free Chain buffers */
926 mptscsih_freeChainBuffers(ioc, req_idx);
931 * mptscsih_flush_running_cmds - For each command found, search
932 * Scsi_Host instance taskQ and reply to OS.
933 * Called only if recovering from a FW reload.
934 * @hd: Pointer to a SCSI HOST structure
938 * Must be called while new I/Os are being queued.
941 mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
943 MPT_ADAPTER *ioc = hd->ioc;
944 struct scsi_cmnd *SCpnt;
947 int max = ioc->req_depth;
949 dprintk((KERN_INFO MYNAM ": flush_ScsiLookup called\n"));
950 for (ii= 0; ii < max; ii++) {
951 if ((SCpnt = hd->ScsiLookup[ii]) != NULL) {
956 /* Null ScsiLookup index
958 hd->ScsiLookup[ii] = NULL;
960 mf = MPT_INDEX_2_MFPTR(ioc, ii);
961 dmfprintk(( "flush: ScsiDone (mf=%p,sc=%p)\n",
964 /* Free Chain buffers */
965 mptscsih_freeChainBuffers(ioc, ii);
967 /* Free Message frames */
968 mpt_free_msg_frame(ioc, mf);
970 if ((unsigned char *)mf != SCpnt->host_scribble)
973 /* Set status, free OS resources (SG DMA buffers)
977 pci_unmap_sg(ioc->pcidev,
978 (struct scatterlist *) SCpnt->request_buffer,
980 SCpnt->sc_data_direction);
981 } else if (SCpnt->request_bufflen) {
982 pci_unmap_single(ioc->pcidev,
983 SCpnt->SCp.dma_handle,
984 SCpnt->request_bufflen,
985 SCpnt->sc_data_direction);
987 SCpnt->result = DID_RESET << 16;
988 SCpnt->host_scribble = NULL;
990 SCpnt->scsi_done(SCpnt); /* Issue the command callback */
998 * mptscsih_search_running_cmds - Delete any commands associated
999 * with the specified target and lun. Function called only
1000 * when a lun is disable by mid-layer.
1001 * Do NOT access the referenced scsi_cmnd structure or
1002 * members. Will cause either a paging or NULL ptr error.
1003 * (BUT, BUT, BUT, the code does reference it! - mdr)
1004 * @hd: Pointer to a SCSI HOST structure
1005 * @vdevice: per device private data
1009 * Called from slave_destroy.
1012 mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
1014 SCSIIORequest_t *mf = NULL;
1016 int max = hd->ioc->req_depth;
1017 struct scsi_cmnd *sc;
1018 struct scsi_lun lun;
1020 dsprintk((KERN_INFO MYNAM ": search_running channel %d id %d lun %d max %d\n",
1021 vdevice->vtarget->channel, vdevice->vtarget->id, vdevice->lun, max));
1023 for (ii=0; ii < max; ii++) {
1024 if ((sc = hd->ScsiLookup[ii]) != NULL) {
1026 mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii);
1029 int_to_scsilun(vdevice->lun, &lun);
1030 if ((mf->Bus != vdevice->vtarget->channel) ||
1031 (mf->TargetID != vdevice->vtarget->id) ||
1032 memcmp(lun.scsi_lun, mf->LUN, 8))
1034 dsprintk(( "search_running: found (sc=%p, mf = %p) "
1035 "channel %d id %d, lun %d \n", hd->ScsiLookup[ii],
1036 mf, mf->Bus, mf->TargetID, vdevice->lun));
1040 hd->ScsiLookup[ii] = NULL;
1041 mptscsih_freeChainBuffers(hd->ioc, ii);
1042 mpt_free_msg_frame(hd->ioc, (MPT_FRAME_HDR *)mf);
1043 if ((unsigned char *)mf != sc->host_scribble)
1046 pci_unmap_sg(hd->ioc->pcidev,
1047 (struct scatterlist *) sc->request_buffer,
1049 sc->sc_data_direction);
1050 } else if (sc->request_bufflen) {
1051 pci_unmap_single(hd->ioc->pcidev,
1053 sc->request_bufflen,
1054 sc->sc_data_direction);
1056 sc->host_scribble = NULL;
1057 sc->result = DID_NO_CONNECT << 16;
1064 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1066 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1068 * mptscsih_report_queue_full - Report QUEUE_FULL status returned
1069 * from a SCSI target device.
1070 * @sc: Pointer to scsi_cmnd structure
1071 * @pScsiReply: Pointer to SCSIIOReply_t
1072 * @pScsiReq: Pointer to original SCSI request
1074 * This routine periodically reports QUEUE_FULL status returned from a
1075 * SCSI target device. It reports this to the console via kernel
1076 * printk() API call, not more than once every 10 seconds.
1079 mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq)
1081 long time = jiffies;
1084 if (sc->device == NULL)
1086 if (sc->device->host == NULL)
1088 if ((hd = (MPT_SCSI_HOST *)sc->device->host->hostdata) == NULL)
1091 if (time - hd->last_queue_full > 10 * HZ) {
1092 dprintk((MYIOC_s_WARN_FMT "Device (%d:%d:%d) reported QUEUE_FULL!\n",
1093 hd->ioc->name, 0, sc->device->id, sc->device->lun));
1094 hd->last_queue_full = time;
1098 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1100 * mptscsih_remove - Removed scsi devices
1101 * @pdev: Pointer to pci_dev structure
1106 mptscsih_remove(struct pci_dev *pdev)
1108 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1109 struct Scsi_Host *host = ioc->sh;
1118 scsi_remove_host(host);
1120 if((hd = (MPT_SCSI_HOST *)host->hostdata) == NULL)
1123 mptscsih_shutdown(pdev);
1127 if (hd->ScsiLookup != NULL) {
1128 sz1 = hd->ioc->req_depth * sizeof(void *);
1129 kfree(hd->ScsiLookup);
1130 hd->ScsiLookup = NULL;
1133 dprintk((MYIOC_s_INFO_FMT
1134 "Free'd ScsiLookup (%d) memory\n",
1135 hd->ioc->name, sz1));
1137 kfree(hd->info_kbuf);
1139 /* NULL the Scsi_Host pointer
1143 scsi_host_put(host);
1149 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1151 * mptscsih_shutdown - reboot notifier
1155 mptscsih_shutdown(struct pci_dev *pdev)
1157 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1158 struct Scsi_Host *host = ioc->sh;
1164 hd = (MPT_SCSI_HOST *)host->hostdata;
1169 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1171 * mptscsih_suspend - Fusion MPT scsi driver suspend routine.
1176 mptscsih_suspend(struct pci_dev *pdev, pm_message_t state)
1178 mptscsih_shutdown(pdev);
1179 return mpt_suspend(pdev,state);
1182 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1184 * mptscsih_resume - Fusion MPT scsi driver resume routine.
1189 mptscsih_resume(struct pci_dev *pdev)
1197 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1199 * mptscsih_info - Return information about MPT adapter
1200 * @SChost: Pointer to Scsi_Host structure
1202 * (linux scsi_host_template.info routine)
1204 * Returns pointer to buffer where information was written.
1207 mptscsih_info(struct Scsi_Host *SChost)
1212 h = (MPT_SCSI_HOST *)SChost->hostdata;
1215 if (h->info_kbuf == NULL)
1216 if ((h->info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)
1217 return h->info_kbuf;
1218 h->info_kbuf[0] = '\0';
1220 mpt_print_ioc_summary(h->ioc, h->info_kbuf, &size, 0, 0);
1221 h->info_kbuf[size-1] = '\0';
1224 return h->info_kbuf;
1235 mptscsih_copy_mem_info(struct info_str *info, char *data, int len)
1237 if (info->pos + len > info->length)
1238 len = info->length - info->pos;
1240 if (info->pos + len < info->offset) {
1245 if (info->pos < info->offset) {
1246 data += (info->offset - info->pos);
1247 len -= (info->offset - info->pos);
1251 memcpy(info->buffer + info->pos, data, len);
1257 mptscsih_copy_info(struct info_str *info, char *fmt, ...)
1263 va_start(args, fmt);
1264 len = vsprintf(buf, fmt, args);
1267 mptscsih_copy_mem_info(info, buf, len);
1272 mptscsih_host_info(MPT_ADAPTER *ioc, char *pbuf, off_t offset, int len)
1274 struct info_str info;
1278 info.offset = offset;
1281 mptscsih_copy_info(&info, "%s: %s, ", ioc->name, ioc->prod_name);
1282 mptscsih_copy_info(&info, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING, ioc->facts.FWVersion.Word);
1283 mptscsih_copy_info(&info, "Ports=%d, ", ioc->facts.NumberOfPorts);
1284 mptscsih_copy_info(&info, "MaxQ=%d\n", ioc->req_depth);
1286 return ((info.pos > info.offset) ? info.pos - info.offset : 0);
1289 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1291 * mptscsih_proc_info - Return information about MPT adapter
1292 * @host: scsi host struct
1293 * @buffer: if write, user data; if read, buffer for user
1294 * @start: returns the buffer address
1295 * @offset: if write, 0; if read, the current offset into the buffer from
1296 * the previous read.
1297 * @length: if write, return length;
1298 * @func: write = 1; read = 0
1300 * (linux scsi_host_template.info routine)
1303 mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
1304 int length, int func)
1306 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
1307 MPT_ADAPTER *ioc = hd->ioc;
1312 * write is not supported
1318 size = mptscsih_host_info(ioc, buffer, offset, length);
1324 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1325 #define ADD_INDEX_LOG(req_ent) do { } while(0)
1327 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1329 * mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine.
1330 * @SCpnt: Pointer to scsi_cmnd structure
1331 * @done: Pointer SCSI mid-layer IO completion function
1333 * (linux scsi_host_template.queuecommand routine)
1334 * This is the primary SCSI IO start routine. Create a MPI SCSIIORequest
1335 * from a linux scsi_cmnd request and send it to the IOC.
1337 * Returns 0. (rtn value discarded by linux scsi mid-layer)
1340 mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1344 SCSIIORequest_t *pScsiReq;
1345 VirtDevice *vdev = SCpnt->device->hostdata;
1354 hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata;
1355 lun = SCpnt->device->lun;
1356 SCpnt->scsi_done = done;
1358 dmfprintk((MYIOC_s_INFO_FMT "qcmd: SCpnt=%p, done()=%p\n",
1359 (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt, done));
1361 if (hd->resetPending) {
1362 dtmprintk((MYIOC_s_WARN_FMT "qcmd: SCpnt=%p timeout + 60HZ\n",
1363 (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt));
1364 return SCSI_MLQUEUE_HOST_BUSY;
1368 * Put together a MPT SCSI request...
1370 if ((mf = mpt_get_msg_frame(hd->ioc->DoneCtx, hd->ioc)) == NULL) {
1371 dprintk((MYIOC_s_WARN_FMT "QueueCmd, no msg frames!!\n",
1373 return SCSI_MLQUEUE_HOST_BUSY;
1376 pScsiReq = (SCSIIORequest_t *) mf;
1378 my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
1380 ADD_INDEX_LOG(my_idx);
1382 /* TUR's being issued with scsictl=0x02000000 (DATA_IN)!
1383 * Seems we may receive a buffer (datalen>0) even when there
1384 * will be no data transfer! GRRRRR...
1386 if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
1387 datalen = SCpnt->request_bufflen;
1388 scsidir = MPI_SCSIIO_CONTROL_READ; /* DATA IN (host<--ioc<--dev) */
1389 } else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
1390 datalen = SCpnt->request_bufflen;
1391 scsidir = MPI_SCSIIO_CONTROL_WRITE; /* DATA OUT (host-->ioc-->dev) */
1394 scsidir = MPI_SCSIIO_CONTROL_NODATATRANSFER;
1397 /* Default to untagged. Once a target structure has been allocated,
1398 * use the Inquiry data to determine if device supports tagged.
1401 && (vdev->vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)
1402 && (SCpnt->device->tagged_supported)) {
1403 scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
1405 scsictl = scsidir | MPI_SCSIIO_CONTROL_UNTAGGED;
1408 /* Use the above information to set up the message frame
1410 pScsiReq->TargetID = (u8) vdev->vtarget->id;
1411 pScsiReq->Bus = vdev->vtarget->channel;
1412 pScsiReq->ChainOffset = 0;
1413 if (vdev->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
1414 pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
1416 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
1417 pScsiReq->CDBLength = SCpnt->cmd_len;
1418 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
1419 pScsiReq->Reserved = 0;
1420 pScsiReq->MsgFlags = mpt_msg_flags();
1421 int_to_scsilun(SCpnt->device->lun, (struct scsi_lun *)pScsiReq->LUN);
1422 pScsiReq->Control = cpu_to_le32(scsictl);
1425 * Write SCSI CDB into the message
1427 cmd_len = SCpnt->cmd_len;
1428 for (ii=0; ii < cmd_len; ii++)
1429 pScsiReq->CDB[ii] = SCpnt->cmnd[ii];
1431 for (ii=cmd_len; ii < 16; ii++)
1432 pScsiReq->CDB[ii] = 0;
1435 pScsiReq->DataLength = cpu_to_le32(datalen);
1437 /* SenseBuffer low address */
1438 pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
1439 + (my_idx * MPT_SENSE_BUFFER_ALLOC));
1441 /* Now add the SG list
1442 * Always have a SGE even if null length.
1445 /* Add a NULL SGE */
1446 mptscsih_add_sge((char *)&pScsiReq->SGL, MPT_SGE_FLAGS_SSIMPLE_READ | 0,
1449 /* Add a 32 or 64 bit SGE */
1450 if (mptscsih_AddSGE(hd->ioc, SCpnt, pScsiReq, my_idx) != SUCCESS)
1454 SCpnt->host_scribble = (unsigned char *)mf;
1455 hd->ScsiLookup[my_idx] = SCpnt;
1457 mpt_put_msg_frame(hd->ioc->DoneCtx, hd->ioc, mf);
1458 dmfprintk((MYIOC_s_INFO_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n",
1459 hd->ioc->name, SCpnt, mf, my_idx));
1460 DBG_DUMP_REQUEST_FRAME(mf)
1464 hd->ScsiLookup[my_idx] = NULL;
1465 mptscsih_freeChainBuffers(hd->ioc, my_idx);
1466 mpt_free_msg_frame(hd->ioc, mf);
1467 return SCSI_MLQUEUE_HOST_BUSY;
1470 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1472 * mptscsih_freeChainBuffers - Function to free chain buffers associated
1473 * with a SCSI IO request
1474 * @hd: Pointer to the MPT_SCSI_HOST instance
1475 * @req_idx: Index of the SCSI IO request frame.
1477 * Called if SG chain buffer allocation fails and mptscsih callbacks.
1481 mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
1483 MPT_FRAME_HDR *chain;
1484 unsigned long flags;
1488 /* Get the first chain index and reset
1491 chain_idx = ioc->ReqToChain[req_idx];
1492 ioc->ReqToChain[req_idx] = MPT_HOST_NO_CHAIN;
1494 while (chain_idx != MPT_HOST_NO_CHAIN) {
1496 /* Save the next chain buffer index */
1497 next = ioc->ChainToChain[chain_idx];
1499 /* Free this chain buffer and reset
1502 ioc->ChainToChain[chain_idx] = MPT_HOST_NO_CHAIN;
1504 chain = (MPT_FRAME_HDR *) (ioc->ChainBuffer
1505 + (chain_idx * ioc->req_sz));
1507 spin_lock_irqsave(&ioc->FreeQlock, flags);
1508 list_add_tail(&chain->u.frame.linkage.list, &ioc->FreeChainQ);
1509 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1511 dmfprintk((MYIOC_s_INFO_FMT "FreeChainBuffers (index %d)\n",
1512 ioc->name, chain_idx));
1520 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1525 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1527 * mptscsih_TMHandler - Generic handler for SCSI Task Management.
1528 * @hd: Pointer to MPT SCSI HOST structure
1529 * @type: Task Management type
1530 * @channel: channel number for task management
1531 * @id: Logical Target ID for reset (if appropriate)
1532 * @lun: Logical Unit for reset (if appropriate)
1533 * @ctx2abort: Context for the task to be aborted (if appropriate)
1534 * @timeout: timeout for task management control
1536 * Fall through to mpt_HardResetHandler if: not operational, too many
1537 * failed TM requests or handshake failure.
1539 * Remark: Currently invoked from a non-interrupt thread (_bh).
1541 * Remark: With old EH code, at most 1 SCSI TaskMgmt function per IOC
1544 * Returns 0 for SUCCESS, or %FAILED.
1547 mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout)
1552 unsigned long flags;
1555 dtmprintk((MYIOC_s_INFO_FMT "TMHandler Entered!\n", ioc->name));
1557 // SJR - CHECKME - Can we avoid this here?
1558 // (mpt_HardResetHandler has this check...)
1559 spin_lock_irqsave(&ioc->diagLock, flags);
1560 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)) {
1561 spin_unlock_irqrestore(&ioc->diagLock, flags);
1564 spin_unlock_irqrestore(&ioc->diagLock, flags);
1566 /* Wait a fixed amount of time for the TM pending flag to be cleared.
1567 * If we time out and not bus reset, then we return a FAILED status
1569 * The call to mptscsih_tm_pending_wait() will set the pending flag
1571 * successful. Otherwise, reload the FW.
1573 if (mptscsih_tm_pending_wait(hd) == FAILED) {
1574 if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
1575 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler abort: "
1576 "Timed out waiting for last TM (%d) to complete! \n",
1577 hd->ioc->name, hd->tmPending));
1579 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) {
1580 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler target "
1581 "reset: Timed out waiting for last TM (%d) "
1582 "to complete! \n", hd->ioc->name,
1585 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
1586 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler bus reset: "
1587 "Timed out waiting for last TM (%d) to complete! \n",
1588 hd->ioc->name, hd->tmPending));
1592 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
1593 hd->tmPending |= (1 << type);
1594 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1597 ioc_raw_state = mpt_GetIocState(hd->ioc, 0);
1599 if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) {
1600 printk(MYIOC_s_WARN_FMT
1601 "TM Handler for type=%x: IOC Not operational (0x%x)!\n",
1602 ioc->name, type, ioc_raw_state);
1603 printk(KERN_WARNING " Issuing HardReset!!\n");
1604 if (mpt_HardResetHandler(ioc, CAN_SLEEP) < 0)
1605 printk((KERN_WARNING "TMHandler: HardReset "
1610 if (ioc_raw_state & MPI_DOORBELL_ACTIVE) {
1611 printk(MYIOC_s_WARN_FMT
1612 "TM Handler for type=%x: ioc_state: "
1613 "DOORBELL_ACTIVE (0x%x)!\n",
1614 ioc->name, type, ioc_raw_state);
1618 /* Isse the Task Mgmt request.
1620 if (hd->hard_resets < -1)
1623 rc = mptscsih_IssueTaskMgmt(hd, type, channel, id, lun,
1624 ctx2abort, timeout);
1626 printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n",
1629 dtmprintk((MYIOC_s_INFO_FMT "Issue of TaskMgmt Successful!\n",
1632 dtmprintk((MYIOC_s_INFO_FMT "TMHandler rc = %d!\n", hd->ioc->name, rc));
1638 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1640 * mptscsih_IssueTaskMgmt - Generic send Task Management function.
1641 * @hd: Pointer to MPT_SCSI_HOST structure
1642 * @type: Task Management type
1643 * @channel: channel number for task management
1644 * @id: Logical Target ID for reset (if appropriate)
1645 * @lun: Logical Unit for reset (if appropriate)
1646 * @ctx2abort: Context for the task to be aborted (if appropriate)
1647 * @timeout: timeout for task management control
1649 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
1650 * or a non-interrupt thread. In the former, must not call schedule().
1652 * Not all fields are meaningfull for all task types.
1654 * Returns 0 for SUCCESS, or FAILED.
1658 mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout)
1661 SCSITaskMgmt_t *pScsiTm;
1665 /* Return Fail to calling function if no message frames available.
1667 if ((mf = mpt_get_msg_frame(hd->ioc->TaskCtx, hd->ioc)) == NULL) {
1668 dfailprintk((MYIOC_s_ERR_FMT "IssueTaskMgmt, no msg frames!!\n",
1672 dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt request @ %p\n",
1673 hd->ioc->name, mf));
1675 /* Format the Request
1677 pScsiTm = (SCSITaskMgmt_t *) mf;
1678 pScsiTm->TargetID = id;
1679 pScsiTm->Bus = channel;
1680 pScsiTm->ChainOffset = 0;
1681 pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
1683 pScsiTm->Reserved = 0;
1684 pScsiTm->TaskType = type;
1685 pScsiTm->Reserved1 = 0;
1686 pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)
1687 ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0;
1689 int_to_scsilun(lun, (struct scsi_lun *)pScsiTm->LUN);
1691 for (ii=0; ii < 7; ii++)
1692 pScsiTm->Reserved2[ii] = 0;
1694 pScsiTm->TaskMsgContext = ctx2abort;
1696 dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt: ctx2abort (0x%08x) "
1697 "type=%d\n", hd->ioc->name, ctx2abort, type));
1699 DBG_DUMP_TM_REQUEST_FRAME((u32 *)pScsiTm);
1701 if ((retval = mpt_send_handshake_request(hd->ioc->TaskCtx, hd->ioc,
1702 sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, CAN_SLEEP)) != 0) {
1703 dfailprintk((MYIOC_s_ERR_FMT "send_handshake FAILED!"
1704 " (hd %p, ioc %p, mf %p, rc=%d) \n", hd->ioc->name, hd,
1705 hd->ioc, mf, retval));
1709 if(mptscsih_tm_wait_for_completion(hd, timeout) == FAILED) {
1710 dfailprintk((MYIOC_s_ERR_FMT "task management request TIMED OUT!"
1711 " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
1713 dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
1715 retval = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
1716 dtmprintk((MYIOC_s_INFO_FMT "rc=%d \n",
1717 hd->ioc->name, retval));
1722 * Handle success case, see if theres a non-zero ioc_status.
1724 if (hd->tm_iocstatus == MPI_IOCSTATUS_SUCCESS ||
1725 hd->tm_iocstatus == MPI_IOCSTATUS_SCSI_TASK_TERMINATED ||
1726 hd->tm_iocstatus == MPI_IOCSTATUS_SCSI_IOC_TERMINATED)
1736 * Free task managment mf, and corresponding tm flags
1738 mpt_free_msg_frame(hd->ioc, mf);
1740 hd->tmState = TM_STATE_NONE;
1745 mptscsih_get_tm_timeout(MPT_ADAPTER *ioc)
1747 switch (ioc->bus_type) {
1758 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1760 * mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant
1761 * @SCpnt: Pointer to scsi_cmnd structure, IO to be aborted
1763 * (linux scsi_host_template.eh_abort_handler routine)
1765 * Returns SUCCESS or FAILED.
1768 mptscsih_abort(struct scsi_cmnd * SCpnt)
1776 ulong sn = SCpnt->serial_number;
1778 /* If we can't locate our host adapter structure, return FAILED status.
1780 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL) {
1781 SCpnt->result = DID_RESET << 16;
1782 SCpnt->scsi_done(SCpnt);
1783 dfailprintk((KERN_INFO MYNAM ": mptscsih_abort: "
1784 "Can't locate host! (sc=%p)\n",
1789 /* Find this command
1791 if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) {
1792 /* Cmd not found in ScsiLookup.
1795 SCpnt->result = DID_RESET << 16;
1796 dtmprintk((KERN_INFO MYNAM ": %s: mptscsih_abort: "
1797 "Command not in the active list! (sc=%p)\n",
1798 hd->ioc->name, SCpnt));
1802 if (hd->resetPending)
1805 if (hd->timeouts < -1)
1808 printk(KERN_WARNING MYNAM ": %s: attempting task abort! (sc=%p)\n",
1809 hd->ioc->name, SCpnt);
1810 scsi_print_command(SCpnt);
1812 /* Most important! Set TaskMsgContext to SCpnt's MsgContext!
1813 * (the IO to be ABORT'd)
1815 * NOTE: Since we do not byteswap MsgContext, we do not
1816 * swap it here either. It is an opaque cookie to
1817 * the controller, so it does not matter. -DaveM
1819 mf = MPT_INDEX_2_MFPTR(hd->ioc, scpnt_idx);
1820 ctx2abort = mf->u.frame.hwhdr.msgctxu.MsgContext;
1822 hd->abortSCpnt = SCpnt;
1824 vdev = SCpnt->device->hostdata;
1825 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
1826 vdev->vtarget->channel, vdev->vtarget->id, vdev->lun,
1827 ctx2abort, mptscsih_get_tm_timeout(hd->ioc));
1829 if (SCPNT_TO_LOOKUP_IDX(SCpnt) == scpnt_idx &&
1830 SCpnt->serial_number == sn)
1833 printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n",
1835 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1843 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1845 * mptscsih_dev_reset - Perform a SCSI TARGET_RESET! new_eh variant
1846 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1848 * (linux scsi_host_template.eh_dev_reset_handler routine)
1850 * Returns SUCCESS or FAILED.
1853 mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
1859 /* If we can't locate our host adapter structure, return FAILED status.
1861 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1862 dtmprintk((KERN_INFO MYNAM ": mptscsih_dev_reset: "
1863 "Can't locate host! (sc=%p)\n",
1868 if (hd->resetPending)
1871 printk(KERN_WARNING MYNAM ": %s: attempting target reset! (sc=%p)\n",
1872 hd->ioc->name, SCpnt);
1873 scsi_print_command(SCpnt);
1875 vdev = SCpnt->device->hostdata;
1876 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
1877 vdev->vtarget->channel, vdev->vtarget->id,
1878 0, 0, mptscsih_get_tm_timeout(hd->ioc));
1880 printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n",
1882 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1891 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1893 * mptscsih_bus_reset - Perform a SCSI BUS_RESET! new_eh variant
1894 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1896 * (linux scsi_host_template.eh_bus_reset_handler routine)
1898 * Returns SUCCESS or FAILED.
1901 mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
1907 /* If we can't locate our host adapter structure, return FAILED status.
1909 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1910 dtmprintk((KERN_INFO MYNAM ": mptscsih_bus_reset: "
1911 "Can't locate host! (sc=%p)\n",
1916 printk(KERN_WARNING MYNAM ": %s: attempting bus reset! (sc=%p)\n",
1917 hd->ioc->name, SCpnt);
1918 scsi_print_command(SCpnt);
1920 if (hd->timeouts < -1)
1923 vdev = SCpnt->device->hostdata;
1924 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
1925 vdev->vtarget->channel, 0, 0, 0, mptscsih_get_tm_timeout(hd->ioc));
1927 printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n",
1929 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1937 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1939 * mptscsih_host_reset - Perform a SCSI host adapter RESET (new_eh variant)
1940 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1942 * (linux scsi_host_template.eh_host_reset_handler routine)
1944 * Returns SUCCESS or FAILED.
1947 mptscsih_host_reset(struct scsi_cmnd *SCpnt)
1950 int status = SUCCESS;
1952 /* If we can't locate the host to reset, then we failed. */
1953 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1954 dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
1955 "Can't locate host! (sc=%p)\n",
1960 printk(KERN_WARNING MYNAM ": %s: Attempting host reset! (sc=%p)\n",
1961 hd->ioc->name, SCpnt);
1963 /* If our attempts to reset the host failed, then return a failed
1964 * status. The host will be taken off line by the SCSI mid-layer.
1966 if (mpt_HardResetHandler(hd->ioc, CAN_SLEEP) < 0){
1969 /* Make sure TM pending is cleared and TM state is set to
1973 hd->tmState = TM_STATE_NONE;
1976 dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
1978 (status == SUCCESS) ? "SUCCESS" : "FAILED" ) );
1983 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1985 * mptscsih_tm_pending_wait - wait for pending task management request to complete
1986 * @hd: Pointer to MPT host structure.
1988 * Returns {SUCCESS,FAILED}.
1991 mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd)
1993 unsigned long flags;
1994 int loop_count = 4 * 10; /* Wait 10 seconds */
1995 int status = FAILED;
1998 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
1999 if (hd->tmState == TM_STATE_NONE) {
2000 hd->tmState = TM_STATE_IN_PROGRESS;
2002 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2006 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2008 } while (--loop_count);
2013 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2015 * mptscsih_tm_wait_for_completion - wait for completion of TM task
2016 * @hd: Pointer to MPT host structure.
2017 * @timeout: timeout value
2019 * Returns {SUCCESS,FAILED}.
2022 mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout )
2024 unsigned long flags;
2025 int loop_count = 4 * timeout;
2026 int status = FAILED;
2029 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
2030 if(hd->tmPending == 0) {
2032 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2035 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2037 } while (--loop_count);
2042 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2044 mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code)
2048 switch (response_code) {
2049 case MPI_SCSITASKMGMT_RSP_TM_COMPLETE:
2050 desc = "The task completed.";
2052 case MPI_SCSITASKMGMT_RSP_INVALID_FRAME:
2053 desc = "The IOC received an invalid frame status.";
2055 case MPI_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED:
2056 desc = "The task type is not supported.";
2058 case MPI_SCSITASKMGMT_RSP_TM_FAILED:
2059 desc = "The requested task failed.";
2061 case MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED:
2062 desc = "The task completed successfully.";
2064 case MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN:
2065 desc = "The LUN request is invalid.";
2067 case MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC:
2068 desc = "The task is in the IOC queue and has not been sent to target.";
2074 printk(MYIOC_s_INFO_FMT "Response Code(0x%08x): F/W: %s\n",
2075 ioc->name, response_code, desc);
2078 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2080 * mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
2081 * @ioc: Pointer to MPT_ADAPTER structure
2082 * @mf: Pointer to SCSI task mgmt request frame
2083 * @mr: Pointer to SCSI task mgmt reply frame
2085 * This routine is called from mptbase.c::mpt_interrupt() at the completion
2086 * of any SCSI task management request.
2087 * This routine is registered with the MPT (base) driver at driver
2088 * load/init time via the mpt_register() API call.
2090 * Returns 1 indicating alloc'd request frame ptr should be freed.
2093 mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
2095 SCSITaskMgmtReply_t *pScsiTmReply;
2096 SCSITaskMgmt_t *pScsiTmReq;
2098 unsigned long flags;
2101 u32 termination_count;
2103 dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt completed (mf=%p,mr=%p)\n",
2104 ioc->name, mf, mr));
2106 dtmprintk((MYIOC_s_WARN_FMT
2107 "TaskMgmt Complete: NULL Scsi Host Ptr\n", ioc->name));
2112 dtmprintk((MYIOC_s_WARN_FMT
2113 "ERROR! TaskMgmt Reply: NULL Request %p\n", ioc->name, mf));
2117 hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
2118 pScsiTmReply = (SCSITaskMgmtReply_t*)mr;
2119 pScsiTmReq = (SCSITaskMgmt_t*)mf;
2120 tmType = pScsiTmReq->TaskType;
2121 iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2122 termination_count = le32_to_cpu(pScsiTmReply->TerminationCount);
2124 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05 &&
2125 pScsiTmReply->ResponseCode)
2126 mptscsih_taskmgmt_response_code(ioc,
2127 pScsiTmReply->ResponseCode);
2128 DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply);
2130 #if defined(MPT_DEBUG_REPLY) || defined(MPT_DEBUG_TM)
2131 printk("%s: ha=%d [%d:%d:0] task_type=0x%02X "
2132 "iocstatus=0x%04X\n\tloginfo=0x%08X response_code=0x%02X "
2133 "term_cmnds=%d\n", __FUNCTION__, ioc->id, pScsiTmReply->Bus,
2134 pScsiTmReply->TargetID, pScsiTmReq->TaskType,
2135 le16_to_cpu(pScsiTmReply->IOCStatus),
2136 le32_to_cpu(pScsiTmReply->IOCLogInfo),pScsiTmReply->ResponseCode,
2137 le32_to_cpu(pScsiTmReply->TerminationCount));
2140 dtmprintk((MYIOC_s_WARN_FMT " TaskMgmt SUCCESS\n", ioc->name));
2141 hd->abortSCpnt = NULL;
2145 /* Error? (anything non-zero?) */
2147 /* clear flags and continue.
2151 case MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK:
2152 if (termination_count == 1)
2153 iocstatus = MPI_IOCSTATUS_SCSI_TASK_TERMINATED;
2154 hd->abortSCpnt = NULL;
2157 case MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS:
2159 /* If an internal command is present
2160 * or the TM failed - reload the FW.
2161 * FC FW may respond FAILED to an ABORT
2163 if (iocstatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED ||
2165 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
2166 printk((KERN_WARNING " Firmware Reload FAILED!!\n"));
2169 case MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET:
2175 spin_lock_irqsave(&ioc->FreeQlock, flags);
2177 hd->tmState = TM_STATE_NONE;
2178 hd->tm_iocstatus = iocstatus;
2179 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2184 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2186 * This is anyones guess quite frankly.
2189 mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
2190 sector_t capacity, int geom[])
2200 dummy = heads * sectors;
2201 cylinders = capacity;
2202 sector_div(cylinders,dummy);
2205 * Handle extended translation size for logical drives
2208 if ((ulong)capacity >= 0x200000) {
2211 dummy = heads * sectors;
2212 cylinders = capacity;
2213 sector_div(cylinders,dummy);
2219 geom[2] = cylinders;
2221 dprintk((KERN_NOTICE
2222 ": bios_param: Id=%i Lun=%i Channel=%i CHS=%i/%i/%i\n",
2223 sdev->id, sdev->lun, sdev->channel, (int)cylinders, heads, sectors));
2228 /* Search IOC page 3 to determine if this is hidden physical disk
2232 mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id)
2234 struct inactive_raid_component_info *component_info;
2238 if (!ioc->raid_data.pIocPg3)
2240 for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2241 if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) &&
2242 (channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) {
2249 * Check inactive list for matching phys disks
2251 if (list_empty(&ioc->raid_data.inactive_list))
2254 down(&ioc->raid_data.inactive_list_mutex);
2255 list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
2257 if ((component_info->d.PhysDiskID == id) &&
2258 (component_info->d.PhysDiskBus == channel))
2261 up(&ioc->raid_data.inactive_list_mutex);
2266 EXPORT_SYMBOL(mptscsih_is_phys_disk);
2269 mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id)
2271 struct inactive_raid_component_info *component_info;
2275 if (!ioc->raid_data.pIocPg3)
2277 for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2278 if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) &&
2279 (channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) {
2280 rc = ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum;
2286 * Check inactive list for matching phys disks
2288 if (list_empty(&ioc->raid_data.inactive_list))
2291 down(&ioc->raid_data.inactive_list_mutex);
2292 list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
2294 if ((component_info->d.PhysDiskID == id) &&
2295 (component_info->d.PhysDiskBus == channel))
2296 rc = component_info->d.PhysDiskNum;
2298 up(&ioc->raid_data.inactive_list_mutex);
2303 EXPORT_SYMBOL(mptscsih_raid_id_to_num);
2306 * OS entry point to allow for host driver to free allocated memory
2307 * Called if no device present or device being unloaded
2310 mptscsih_slave_destroy(struct scsi_device *sdev)
2312 struct Scsi_Host *host = sdev->host;
2313 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
2314 VirtTarget *vtarget;
2315 VirtDevice *vdevice;
2316 struct scsi_target *starget;
2318 starget = scsi_target(sdev);
2319 vtarget = starget->hostdata;
2320 vdevice = sdev->hostdata;
2322 mptscsih_search_running_cmds(hd, vdevice);
2323 vtarget->num_luns--;
2324 mptscsih_synchronize_cache(hd, vdevice);
2326 sdev->hostdata = NULL;
2329 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2331 * mptscsih_change_queue_depth - This function will set a devices queue depth
2332 * @sdev: per scsi_device pointer
2333 * @qdepth: requested queue depth
2335 * Adding support for new 'change_queue_depth' api.
2338 mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
2340 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sdev->host->hostdata;
2341 VirtTarget *vtarget;
2342 struct scsi_target *starget;
2346 starget = scsi_target(sdev);
2347 vtarget = starget->hostdata;
2349 if (hd->ioc->bus_type == SPI) {
2350 if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
2352 else if (sdev->type == TYPE_DISK &&
2353 vtarget->minSyncFactor <= MPT_ULTRA160)
2354 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2356 max_depth = MPT_SCSI_CMD_PER_DEV_LOW;
2358 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2360 if (qdepth > max_depth)
2365 tagged = MSG_SIMPLE_TAG;
2367 scsi_adjust_queue_depth(sdev, tagged, qdepth);
2368 return sdev->queue_depth;
2372 * OS entry point to adjust the queue_depths on a per-device basis.
2373 * Called once per device the bus scan. Use it to force the queue_depth
2374 * member to 1 if a device does not support Q tags.
2375 * Return non-zero if fails.
2378 mptscsih_slave_configure(struct scsi_device *sdev)
2380 struct Scsi_Host *sh = sdev->host;
2381 VirtTarget *vtarget;
2382 VirtDevice *vdevice;
2383 struct scsi_target *starget;
2384 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sh->hostdata;
2386 starget = scsi_target(sdev);
2387 vtarget = starget->hostdata;
2388 vdevice = sdev->hostdata;
2390 dsprintk((MYIOC_s_INFO_FMT
2391 "device @ %p, channel=%d, id=%d, lun=%d\n",
2392 hd->ioc->name, sdev, sdev->channel, sdev->id, sdev->lun));
2393 if (hd->ioc->bus_type == SPI)
2394 dsprintk((MYIOC_s_INFO_FMT
2395 "sdtr %d wdtr %d ppr %d inq length=%d\n",
2396 hd->ioc->name, sdev->sdtr, sdev->wdtr,
2397 sdev->ppr, sdev->inquiry_len));
2399 if (sdev->id > sh->max_id) {
2400 /* error case, should never happen */
2401 scsi_adjust_queue_depth(sdev, 0, 1);
2402 goto slave_configure_exit;
2405 vdevice->configured_lun = 1;
2406 mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH);
2408 dsprintk((MYIOC_s_INFO_FMT
2409 "Queue depth=%d, tflags=%x\n",
2410 hd->ioc->name, sdev->queue_depth, vtarget->tflags));
2412 if (hd->ioc->bus_type == SPI)
2413 dsprintk((MYIOC_s_INFO_FMT
2414 "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
2415 hd->ioc->name, vtarget->negoFlags, vtarget->maxOffset,
2416 vtarget->minSyncFactor));
2418 slave_configure_exit:
2420 dsprintk((MYIOC_s_INFO_FMT
2421 "tagged %d, simple %d, ordered %d\n",
2422 hd->ioc->name,sdev->tagged_supported, sdev->simple_tags,
2423 sdev->ordered_tags));
2428 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2430 * Private routines...
2433 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2434 /* Utility function to copy sense data from the scsi_cmnd buffer
2435 * to the FC and SCSI target structures.
2439 mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
2442 SCSIIORequest_t *pReq;
2443 u32 sense_count = le32_to_cpu(pScsiReply->SenseCount);
2445 /* Get target structure
2447 pReq = (SCSIIORequest_t *) mf;
2448 vdev = sc->device->hostdata;
2454 /* Copy the sense received into the scsi command block. */
2455 req_index = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2456 sense_data = ((u8 *)hd->ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC));
2457 memcpy(sc->sense_buffer, sense_data, SNS_LEN(sc));
2459 /* Log SMART data (asc = 0x5D, non-IM case only) if required.
2461 if ((hd->ioc->events) && (hd->ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) {
2462 if ((sense_data[12] == 0x5D) && (vdev->vtarget->raidVolume == 0)) {
2464 MPT_ADAPTER *ioc = hd->ioc;
2466 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
2467 ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
2468 ioc->events[idx].eventContext = ioc->eventContext;
2470 ioc->events[idx].data[0] = (pReq->LUN[1] << 24) ||
2471 (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) ||
2472 (sc->device->channel << 8) || sc->device->id;
2474 ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12];
2476 ioc->eventContext++;
2477 if (hd->ioc->pcidev->vendor ==
2478 PCI_VENDOR_ID_IBM) {
2479 mptscsih_issue_sep_command(hd->ioc,
2480 vdev->vtarget, MPI_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT);
2481 vdev->vtarget->tflags |=
2482 MPT_TARGET_FLAGS_LED_ON;
2487 dprintk((MYIOC_s_INFO_FMT "Hmmm... SenseData len=0! (?)\n",
2493 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc)
2498 hd = (MPT_SCSI_HOST *) sc->device->host->hostdata;
2500 for (i = 0; i < hd->ioc->req_depth; i++) {
2501 if (hd->ScsiLookup[i] == sc) {
2509 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2511 mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2514 unsigned long flags;
2517 dtmprintk((KERN_WARNING MYNAM
2518 ": IOC %s_reset routed to SCSI host driver!\n",
2519 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
2520 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
2522 /* If a FW reload request arrives after base installed but
2523 * before all scsi hosts have been attached, then an alt_ioc
2524 * may have a NULL sh pointer.
2526 if ((ioc->sh == NULL) || (ioc->sh->hostdata == NULL))
2529 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2531 if (reset_phase == MPT_IOC_SETUP_RESET) {
2532 dtmprintk((MYIOC_s_WARN_FMT "Setup-Diag Reset\n", ioc->name));
2535 * 1. Set Hard Reset Pending Flag
2536 * All new commands go to doneQ
2538 hd->resetPending = 1;
2540 } else if (reset_phase == MPT_IOC_PRE_RESET) {
2541 dtmprintk((MYIOC_s_WARN_FMT "Pre-Diag Reset\n", ioc->name));
2543 /* 2. Flush running commands
2544 * Clean ScsiLookup (and associated memory)
2548 /* 2b. Reply to OS all known outstanding I/O commands.
2550 mptscsih_flush_running_cmds(hd);
2552 /* 2c. If there was an internal command that
2553 * has not completed, configuration or io request,
2554 * free these resources.
2557 del_timer(&hd->timer);
2558 mpt_free_msg_frame(ioc, hd->cmdPtr);
2561 dtmprintk((MYIOC_s_WARN_FMT "Pre-Reset complete.\n", ioc->name));
2564 dtmprintk((MYIOC_s_WARN_FMT "Post-Diag Reset\n", ioc->name));
2566 /* Once a FW reload begins, all new OS commands are
2567 * redirected to the doneQ w/ a reset status.
2568 * Init all control structures.
2571 /* ScsiLookup initialization
2573 for (ii=0; ii < hd->ioc->req_depth; ii++)
2574 hd->ScsiLookup[ii] = NULL;
2576 /* 2. Chain Buffer initialization
2579 /* 4. Renegotiate to all devices, if SPI
2582 /* 5. Enable new commands to be posted
2584 spin_lock_irqsave(&ioc->FreeQlock, flags);
2586 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2587 hd->resetPending = 0;
2588 hd->tmState = TM_STATE_NONE;
2590 /* 6. If there was an internal command,
2591 * wake this process up.
2595 * Wake up the original calling thread
2597 hd->pLocal = &hd->localReply;
2598 hd->pLocal->completion = MPT_SCANDV_DID_RESET;
2599 hd->scandv_wait_done = 1;
2600 wake_up(&hd->scandv_waitq);
2604 dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name));
2608 return 1; /* currently means nothing really */
2611 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2613 mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2616 u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
2618 devtverboseprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
2621 if (ioc->sh == NULL ||
2622 ((hd = (MPT_SCSI_HOST *)ioc->sh->hostdata) == NULL))
2626 case MPI_EVENT_UNIT_ATTENTION: /* 03 */
2629 case MPI_EVENT_IOC_BUS_RESET: /* 04 */
2630 case MPI_EVENT_EXT_BUS_RESET: /* 05 */
2631 if (hd && (ioc->bus_type == SPI) && (hd->soft_resets < -1))
2634 case MPI_EVENT_LOGOUT: /* 09 */
2638 case MPI_EVENT_RESCAN: /* 06 */
2642 * CHECKME! Don't think we need to do
2643 * anything for these, but...
2645 case MPI_EVENT_LINK_STATUS_CHANGE: /* 07 */
2646 case MPI_EVENT_LOOP_STATE_CHANGE: /* 08 */
2648 * CHECKME! Falling thru...
2652 case MPI_EVENT_INTEGRATED_RAID: /* 0B */
2655 case MPI_EVENT_NONE: /* 00 */
2656 case MPI_EVENT_LOG_DATA: /* 01 */
2657 case MPI_EVENT_STATE_CHANGE: /* 02 */
2658 case MPI_EVENT_EVENT_CHANGE: /* 0A */
2660 dprintk((KERN_INFO " Ignoring event (=%02Xh)\n", event));
2664 return 1; /* currently means nothing really */
2667 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2669 * Bus Scan and Domain Validation functionality ...
2672 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2674 * mptscsih_scandv_complete - Scan and DV callback routine registered
2675 * to Fustion MPT (base) driver.
2677 * @ioc: Pointer to MPT_ADAPTER structure
2678 * @mf: Pointer to original MPT request frame
2679 * @mr: Pointer to MPT reply frame (NULL if TurboReply)
2681 * This routine is called from mpt.c::mpt_interrupt() at the completion
2682 * of any SCSI IO request.
2683 * This routine is registered with the Fusion MPT (base) driver at driver
2684 * load/init time via the mpt_register() API call.
2686 * Returns 1 indicating alloc'd request frame ptr should be freed.
2688 * Remark: Sets a completion code and (possibly) saves sense data
2689 * in the IOC member localReply structure.
2690 * Used ONLY for DV and other internal commands.
2693 mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
2696 SCSIIORequest_t *pReq;
2700 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2703 (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) {
2704 printk(MYIOC_s_ERR_FMT
2705 "ScanDvComplete, %s req frame ptr! (=%p)\n",
2706 ioc->name, mf?"BAD":"NULL", (void *) mf);
2710 del_timer(&hd->timer);
2711 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2712 hd->ScsiLookup[req_idx] = NULL;
2713 pReq = (SCSIIORequest_t *) mf;
2715 if (mf != hd->cmdPtr) {
2716 printk(MYIOC_s_WARN_FMT "ScanDvComplete (mf=%p, cmdPtr=%p, idx=%d)\n",
2717 hd->ioc->name, (void *)mf, (void *) hd->cmdPtr, req_idx);
2721 ddvprintk((MYIOC_s_INFO_FMT "ScanDvComplete (mf=%p,mr=%p,idx=%d)\n",
2722 hd->ioc->name, mf, mr, req_idx));
2724 hd->pLocal = &hd->localReply;
2725 hd->pLocal->scsiStatus = 0;
2727 /* If target struct exists, clear sense valid flag.
2730 completionCode = MPT_SCANDV_GOOD;
2732 SCSIIOReply_t *pReply;
2736 pReply = (SCSIIOReply_t *) mr;
2738 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2739 scsi_status = pReply->SCSIStatus;
2741 ddvtprintk((KERN_NOTICE " IOCStatus=%04xh, SCSIState=%02xh, SCSIStatus=%02xh, IOCLogInfo=%08xh\n",
2742 status, pReply->SCSIState, scsi_status,
2743 le32_to_cpu(pReply->IOCLogInfo)));
2747 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
2748 completionCode = MPT_SCANDV_SELECTION_TIMEOUT;
2751 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
2752 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
2753 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
2754 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
2755 completionCode = MPT_SCANDV_DID_RESET;
2758 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
2759 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
2760 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
2761 if (pReply->Function == MPI_FUNCTION_CONFIG) {
2762 ConfigReply_t *pr = (ConfigReply_t *)mr;
2763 completionCode = MPT_SCANDV_GOOD;
2764 hd->pLocal->header.PageVersion = pr->Header.PageVersion;
2765 hd->pLocal->header.PageLength = pr->Header.PageLength;
2766 hd->pLocal->header.PageNumber = pr->Header.PageNumber;
2767 hd->pLocal->header.PageType = pr->Header.PageType;
2769 } else if (pReply->Function == MPI_FUNCTION_RAID_ACTION) {
2770 /* If the RAID Volume request is successful,
2771 * return GOOD, else indicate that
2772 * some type of error occurred.
2774 MpiRaidActionReply_t *pr = (MpiRaidActionReply_t *)mr;
2775 if (le16_to_cpu(pr->ActionStatus) == MPI_RAID_ACTION_ASTATUS_SUCCESS)
2776 completionCode = MPT_SCANDV_GOOD;
2778 completionCode = MPT_SCANDV_SOME_ERROR;
2779 memcpy(hd->pLocal->sense, pr, sizeof(hd->pLocal->sense));
2781 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID) {
2785 /* save sense data in global structure
2787 completionCode = MPT_SCANDV_SENSE;
2788 hd->pLocal->scsiStatus = scsi_status;
2789 sense_data = ((u8 *)hd->ioc->sense_buf_pool +
2790 (req_idx * MPT_SENSE_BUFFER_ALLOC));
2792 sz = min_t(int, pReq->SenseBufferLength,
2793 SCSI_STD_SENSE_BYTES);
2794 memcpy(hd->pLocal->sense, sense_data, sz);
2796 ddvprintk((KERN_NOTICE " Check Condition, sense ptr %p\n",
2798 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_FAILED) {
2799 if (pReq->CDB[0] == INQUIRY)
2800 completionCode = MPT_SCANDV_ISSUE_SENSE;
2802 completionCode = MPT_SCANDV_DID_RESET;
2804 else if (pReply->SCSIState & MPI_SCSI_STATE_NO_SCSI_STATUS)
2805 completionCode = MPT_SCANDV_DID_RESET;
2806 else if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
2807 completionCode = MPT_SCANDV_DID_RESET;
2809 completionCode = MPT_SCANDV_GOOD;
2810 hd->pLocal->scsiStatus = scsi_status;
2814 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
2815 if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
2816 completionCode = MPT_SCANDV_DID_RESET;
2818 completionCode = MPT_SCANDV_SOME_ERROR;
2822 completionCode = MPT_SCANDV_SOME_ERROR;
2825 } /* switch(status) */
2827 ddvtprintk((KERN_NOTICE " completionCode set to %08xh\n",
2829 } /* end of address reply case */
2831 hd->pLocal->completion = completionCode;
2833 /* MF and RF are freed in mpt_interrupt
2836 /* Free Chain buffers (will never chain) in scan or dv */
2837 //mptscsih_freeChainBuffers(ioc, req_idx);
2840 * Wake up the original calling thread
2842 hd->scandv_wait_done = 1;
2843 wake_up(&hd->scandv_waitq);
2848 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2849 /* mptscsih_timer_expired - Call back for timer process.
2850 * Used only for dv functionality.
2851 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
2855 mptscsih_timer_expired(unsigned long data)
2857 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) data;
2859 ddvprintk((MYIOC_s_WARN_FMT "Timer Expired! Cmd %p\n", hd->ioc->name, hd->cmdPtr));
2862 MPIHeader_t *cmd = (MPIHeader_t *)hd->cmdPtr;
2864 if (cmd->Function == MPI_FUNCTION_SCSI_IO_REQUEST) {
2865 /* Desire to issue a task management request here.
2866 * TM requests MUST be single threaded.
2867 * If old eh code and no TM current, issue request.
2868 * If new eh code, do nothing. Wait for OS cmd timeout
2871 ddvtprintk((MYIOC_s_NOTE_FMT "DV Cmd Timeout: NoOp\n", hd->ioc->name));
2873 /* Perform a FW reload */
2874 if (mpt_HardResetHandler(hd->ioc, NO_SLEEP) < 0) {
2875 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", hd->ioc->name);
2879 /* This should NEVER happen */
2880 printk(MYIOC_s_WARN_FMT "Null cmdPtr!!!!\n", hd->ioc->name);
2883 /* No more processing.
2884 * TM call will generate an interrupt for SCSI TM Management.
2885 * The FW will reply to all outstanding commands, callback will finish cleanup.
2886 * Hard reset clean-up will free all resources.
2888 ddvprintk((MYIOC_s_WARN_FMT "Timer Expired Complete!\n", hd->ioc->name));
2894 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2896 * mptscsih_do_cmd - Do internal command.
2897 * @hd: MPT_SCSI_HOST pointer
2898 * @io: INTERNAL_CMD pointer.
2900 * Issue the specified internally generated command and do command
2901 * specific cleanup. For bus scan / DV only.
2902 * NOTES: If command is Inquiry and status is good,
2903 * initialize a target structure, save the data
2905 * Remark: Single threaded access only.
2908 * < 0 if an illegal command or no resources
2912 * > 0 if command complete but some type of completion error.
2915 mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
2918 SCSIIORequest_t *pScsiReq;
2919 SCSIIORequest_t ReqCopy;
2920 int my_idx, ii, dir;
2924 char CDB[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
2927 in_isr = in_interrupt();
2929 dprintk((MYIOC_s_WARN_FMT "Internal SCSI IO request not allowed in ISR context!\n",
2935 /* Set command specific information
2940 dir = MPI_SCSIIO_CONTROL_READ;
2946 case TEST_UNIT_READY:
2948 dir = MPI_SCSIIO_CONTROL_READ;
2954 dir = MPI_SCSIIO_CONTROL_READ;
2956 CDB[4] = 1; /*Spin up the disk */
2964 dir = MPI_SCSIIO_CONTROL_READ;
2970 dir = MPI_SCSIIO_CONTROL_READ;
2972 if (io->flags & MPT_ICFLAG_ECHO) {
2978 if (io->flags & MPT_ICFLAG_BUF_CAP) {
2981 CDB[6] = (io->size >> 16) & 0xFF;
2982 CDB[7] = (io->size >> 8) & 0xFF;
2983 CDB[8] = io->size & 0xFF;
2989 dir = MPI_SCSIIO_CONTROL_WRITE;
2991 if (io->flags & MPT_ICFLAG_ECHO) {
2996 CDB[6] = (io->size >> 16) & 0xFF;
2997 CDB[7] = (io->size >> 8) & 0xFF;
2998 CDB[8] = io->size & 0xFF;
3004 dir = MPI_SCSIIO_CONTROL_READ;
3011 dir = MPI_SCSIIO_CONTROL_READ;
3016 case SYNCHRONIZE_CACHE:
3018 dir = MPI_SCSIIO_CONTROL_READ;
3020 // CDB[1] = 0x02; /* set immediate bit */
3029 /* Get and Populate a free Frame
3031 if ((mf = mpt_get_msg_frame(hd->ioc->InternalCtx, hd->ioc)) == NULL) {
3032 ddvprintk((MYIOC_s_WARN_FMT "No msg frames!\n",
3037 pScsiReq = (SCSIIORequest_t *) mf;
3039 /* Get the request index */
3040 my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3041 ADD_INDEX_LOG(my_idx); /* for debug */
3043 if (io->flags & MPT_ICFLAG_PHYS_DISK) {
3044 pScsiReq->TargetID = io->physDiskNum;
3046 pScsiReq->ChainOffset = 0;
3047 pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
3049 pScsiReq->TargetID = io->id;
3050 pScsiReq->Bus = io->channel;
3051 pScsiReq->ChainOffset = 0;
3052 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
3055 pScsiReq->CDBLength = cmdLen;
3056 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
3058 pScsiReq->Reserved = 0;
3060 pScsiReq->MsgFlags = mpt_msg_flags();
3061 /* MsgContext set in mpt_get_msg_fram call */
3063 int_to_scsilun(io->lun, (struct scsi_lun *)pScsiReq->LUN);
3065 if (io->flags & MPT_ICFLAG_TAGGED_CMD)
3066 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ);
3068 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3070 if (cmd == REQUEST_SENSE) {
3071 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3072 ddvprintk((MYIOC_s_INFO_FMT "Untagged! 0x%2x\n",
3073 hd->ioc->name, cmd));
3076 for (ii=0; ii < 16; ii++)
3077 pScsiReq->CDB[ii] = CDB[ii];
3079 pScsiReq->DataLength = cpu_to_le32(io->size);
3080 pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
3081 + (my_idx * MPT_SENSE_BUFFER_ALLOC));
3083 ddvprintk((MYIOC_s_INFO_FMT "Sending Command 0x%x for (%d:%d:%d)\n",
3084 hd->ioc->name, cmd, io->channel, io->id, io->lun));
3086 if (dir == MPI_SCSIIO_CONTROL_READ) {
3087 mpt_add_sge((char *) &pScsiReq->SGL,
3088 MPT_SGE_FLAGS_SSIMPLE_READ | io->size,
3091 mpt_add_sge((char *) &pScsiReq->SGL,
3092 MPT_SGE_FLAGS_SSIMPLE_WRITE | io->size,
3096 /* The ISR will free the request frame, but we need
3097 * the information to initialize the target. Duplicate.
3099 memcpy(&ReqCopy, pScsiReq, sizeof(SCSIIORequest_t));
3101 /* Issue this command after:
3104 * Wait until the reply has been received
3105 * ScsiScanDvCtx callback function will
3107 * set scandv_wait_done and call wake_up
3110 hd->timer.expires = jiffies + HZ*cmdTimeout;
3111 hd->scandv_wait_done = 0;
3113 /* Save cmd pointer, for resource free if timeout or
3118 add_timer(&hd->timer);
3119 mpt_put_msg_frame(hd->ioc->InternalCtx, hd->ioc, mf);
3120 wait_event(hd->scandv_waitq, hd->scandv_wait_done);
3123 rc = hd->pLocal->completion;
3124 hd->pLocal->skip = 0;
3126 /* Always set fatal error codes in some cases.
3128 if (rc == MPT_SCANDV_SELECTION_TIMEOUT)
3130 else if (rc == MPT_SCANDV_SOME_ERROR)
3134 /* This should never happen. */
3135 ddvprintk((MYIOC_s_INFO_FMT "_do_cmd: Null pLocal!!!\n",
3142 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3144 * mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
3145 * @hd: Pointer to a SCSI HOST structure
3146 * @vdevice: virtual target device
3148 * Uses the ISR, but with special processing.
3149 * MUST be single-threaded.
3153 mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
3157 /* Following parameters will not change
3160 iocmd.cmd = SYNCHRONIZE_CACHE;
3162 iocmd.physDiskNum = -1;
3164 iocmd.data_dma = -1;
3166 iocmd.rsvd = iocmd.rsvd2 = 0;
3167 iocmd.channel = vdevice->vtarget->channel;
3168 iocmd.id = vdevice->vtarget->id;
3169 iocmd.lun = vdevice->lun;
3171 if ((vdevice->vtarget->type == TYPE_DISK) &&
3172 (vdevice->configured_lun))
3173 mptscsih_do_cmd(hd, &iocmd);
3176 EXPORT_SYMBOL(mptscsih_remove);
3177 EXPORT_SYMBOL(mptscsih_shutdown);
3179 EXPORT_SYMBOL(mptscsih_suspend);
3180 EXPORT_SYMBOL(mptscsih_resume);
3182 EXPORT_SYMBOL(mptscsih_proc_info);
3183 EXPORT_SYMBOL(mptscsih_info);
3184 EXPORT_SYMBOL(mptscsih_qcmd);
3185 EXPORT_SYMBOL(mptscsih_slave_destroy);
3186 EXPORT_SYMBOL(mptscsih_slave_configure);
3187 EXPORT_SYMBOL(mptscsih_abort);
3188 EXPORT_SYMBOL(mptscsih_dev_reset);
3189 EXPORT_SYMBOL(mptscsih_bus_reset);
3190 EXPORT_SYMBOL(mptscsih_host_reset);
3191 EXPORT_SYMBOL(mptscsih_bios_param);
3192 EXPORT_SYMBOL(mptscsih_io_done);
3193 EXPORT_SYMBOL(mptscsih_taskmgmt_complete);
3194 EXPORT_SYMBOL(mptscsih_scandv_complete);
3195 EXPORT_SYMBOL(mptscsih_event_process);
3196 EXPORT_SYMBOL(mptscsih_ioc_reset);
3197 EXPORT_SYMBOL(mptscsih_change_queue_depth);
3198 EXPORT_SYMBOL(mptscsih_timer_expired);
3199 EXPORT_SYMBOL(mptscsih_TMHandler);
3201 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/