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/sched.h>
58 #include <linux/workqueue.h>
60 #include <scsi/scsi.h>
61 #include <scsi/scsi_cmnd.h>
62 #include <scsi/scsi_device.h>
63 #include <scsi/scsi_host.h>
64 #include <scsi/scsi_tcq.h>
65 #include <scsi/scsi_dbg.h>
69 #include "lsi/mpi_log_sas.h"
71 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
72 #define my_NAME "Fusion MPT SCSI Host driver"
73 #define my_VERSION MPT_LINUX_VERSION_COMMON
74 #define MYNAM "mptscsih"
76 MODULE_AUTHOR(MODULEAUTHOR);
77 MODULE_DESCRIPTION(my_NAME);
78 MODULE_LICENSE("GPL");
79 MODULE_VERSION(my_VERSION);
81 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
83 * Other private/forward protos...
85 int mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
86 static void mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq);
87 int mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
89 static int mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
90 SCSIIORequest_t *pReq, int req_idx);
91 static void mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx);
92 static void mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply);
93 static int mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd);
94 static int mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout );
95 static int SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc);
97 static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout);
99 int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
100 int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
102 int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
103 static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
104 static void mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice);
106 void mptscsih_remove(struct pci_dev *);
107 void mptscsih_shutdown(struct pci_dev *);
109 int mptscsih_suspend(struct pci_dev *pdev, pm_message_t state);
110 int mptscsih_resume(struct pci_dev *pdev);
113 #define SNS_LEN(scp) sizeof((scp)->sense_buffer)
115 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
117 * mptscsih_add_sge - Place a simple SGE at address pAddr.
118 * @pAddr: virtual address for SGE
119 * @flagslength: SGE flags and data transfer length
120 * @dma_addr: Physical address
122 * This routine places a MPT request frame back on the MPT adapter's
126 mptscsih_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
128 if (sizeof(dma_addr_t) == sizeof(u64)) {
129 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
130 u32 tmp = dma_addr & 0xFFFFFFFF;
132 pSge->FlagsLength = cpu_to_le32(flagslength);
133 pSge->Address.Low = cpu_to_le32(tmp);
134 tmp = (u32) ((u64)dma_addr >> 32);
135 pSge->Address.High = cpu_to_le32(tmp);
138 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
139 pSge->FlagsLength = cpu_to_le32(flagslength);
140 pSge->Address = cpu_to_le32(dma_addr);
142 } /* mptscsih_add_sge() */
144 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
146 * mptscsih_add_chain - Place a chain SGE at address pAddr.
147 * @pAddr: virtual address for SGE
148 * @next: nextChainOffset value (u32's)
149 * @length: length of next SGL segment
150 * @dma_addr: Physical address
152 * This routine places a MPT request frame back on the MPT adapter's
156 mptscsih_add_chain(char *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
158 if (sizeof(dma_addr_t) == sizeof(u64)) {
159 SGEChain64_t *pChain = (SGEChain64_t *) pAddr;
160 u32 tmp = dma_addr & 0xFFFFFFFF;
162 pChain->Length = cpu_to_le16(length);
163 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size();
165 pChain->NextChainOffset = next;
167 pChain->Address.Low = cpu_to_le32(tmp);
168 tmp = (u32) ((u64)dma_addr >> 32);
169 pChain->Address.High = cpu_to_le32(tmp);
171 SGEChain32_t *pChain = (SGEChain32_t *) pAddr;
172 pChain->Length = cpu_to_le16(length);
173 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size();
174 pChain->NextChainOffset = next;
175 pChain->Address = cpu_to_le32(dma_addr);
177 } /* mptscsih_add_chain() */
179 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
181 * mptscsih_getFreeChainBuffer - Function to get a free chain
182 * from the MPT_SCSI_HOST FreeChainQ.
183 * @ioc: Pointer to MPT_ADAPTER structure
184 * @req_idx: Index of the SCSI IO request frame. (output)
186 * return SUCCESS or FAILED
189 mptscsih_getFreeChainBuffer(MPT_ADAPTER *ioc, int *retIndex)
191 MPT_FRAME_HDR *chainBuf;
196 dsgprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer called\n",
198 spin_lock_irqsave(&ioc->FreeQlock, flags);
199 if (!list_empty(&ioc->FreeChainQ)) {
202 chainBuf = list_entry(ioc->FreeChainQ.next, MPT_FRAME_HDR,
203 u.frame.linkage.list);
204 list_del(&chainBuf->u.frame.linkage.list);
205 offset = (u8 *)chainBuf - (u8 *)ioc->ChainBuffer;
206 chain_idx = offset / ioc->req_sz;
208 dsgprintk((MYIOC_s_ERR_FMT "getFreeChainBuffer chainBuf=%p ChainBuffer=%p offset=%d chain_idx=%d\n",
209 ioc->name, chainBuf, ioc->ChainBuffer, offset, chain_idx));
212 chain_idx = MPT_HOST_NO_CHAIN;
213 dfailprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer failed\n",
216 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
218 *retIndex = chain_idx;
220 } /* mptscsih_getFreeChainBuffer() */
222 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
224 * mptscsih_AddSGE - Add a SGE (plus chain buffers) to the
225 * SCSIIORequest_t Message Frame.
226 * @ioc: Pointer to MPT_ADAPTER structure
227 * @SCpnt: Pointer to scsi_cmnd structure
228 * @pReq: Pointer to SCSIIORequest_t structure
233 mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
234 SCSIIORequest_t *pReq, int req_idx)
238 struct scatterlist *sg;
240 int sges_left, sg_done;
241 int chain_idx = MPT_HOST_NO_CHAIN;
243 int numSgeSlots, numSgeThisFrame;
244 u32 sgflags, sgdir, thisxfer = 0;
245 int chain_dma_off = 0;
251 sgdir = le32_to_cpu(pReq->Control) & MPI_SCSIIO_CONTROL_DATADIRECTION_MASK;
252 if (sgdir == MPI_SCSIIO_CONTROL_WRITE) {
253 sgdir = MPT_TRANSFER_HOST_TO_IOC;
255 sgdir = MPT_TRANSFER_IOC_TO_HOST;
258 psge = (char *) &pReq->SGL;
259 frm_sz = ioc->req_sz;
261 /* Map the data portion, if any.
262 * sges_left = 0 if no data transfer.
264 if ( (sges_left = SCpnt->use_sg) ) {
265 sges_left = pci_map_sg(ioc->pcidev,
266 (struct scatterlist *) SCpnt->request_buffer,
268 SCpnt->sc_data_direction);
271 } else if (SCpnt->request_bufflen) {
272 SCpnt->SCp.dma_handle = pci_map_single(ioc->pcidev,
273 SCpnt->request_buffer,
274 SCpnt->request_bufflen,
275 SCpnt->sc_data_direction);
276 dsgprintk((MYIOC_s_INFO_FMT "SG: non-SG for %p, len=%d\n",
277 ioc->name, SCpnt, SCpnt->request_bufflen));
278 mptscsih_add_sge((char *) &pReq->SGL,
279 0xD1000000|MPT_SGE_FLAGS_ADDRESSING|sgdir|SCpnt->request_bufflen,
280 SCpnt->SCp.dma_handle);
285 /* Handle the SG case.
287 sg = (struct scatterlist *) SCpnt->request_buffer;
289 sgeOffset = sizeof(SCSIIORequest_t) - sizeof(SGE_IO_UNION);
292 /* Prior to entering this loop - the following must be set
293 * current MF: sgeOffset (bytes)
294 * chainSge (Null if original MF is not a chain buffer)
295 * sg_done (num SGE done for this MF)
299 numSgeSlots = ((frm_sz - sgeOffset) / (sizeof(u32) + sizeof(dma_addr_t)) );
300 numSgeThisFrame = (sges_left < numSgeSlots) ? sges_left : numSgeSlots;
302 sgflags = MPT_SGE_FLAGS_SIMPLE_ELEMENT | MPT_SGE_FLAGS_ADDRESSING | sgdir;
304 /* Get first (num - 1) SG elements
305 * Skip any SG entries with a length of 0
306 * NOTE: at finish, sg and psge pointed to NEXT data/location positions
308 for (ii=0; ii < (numSgeThisFrame-1); ii++) {
309 thisxfer = sg_dma_len(sg);
311 sg ++; /* Get next SG element from the OS */
316 v2 = sg_dma_address(sg);
317 mptscsih_add_sge(psge, sgflags | thisxfer, v2);
319 sg++; /* Get next SG element from the OS */
320 psge += (sizeof(u32) + sizeof(dma_addr_t));
321 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
325 if (numSgeThisFrame == sges_left) {
326 /* Add last element, end of buffer and end of list flags.
328 sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT |
329 MPT_SGE_FLAGS_END_OF_BUFFER |
330 MPT_SGE_FLAGS_END_OF_LIST;
332 /* Add last SGE and set termination flags.
333 * Note: Last SGE may have a length of 0 - which should be ok.
335 thisxfer = sg_dma_len(sg);
337 v2 = sg_dma_address(sg);
338 mptscsih_add_sge(psge, sgflags | thisxfer, v2);
341 psge += (sizeof(u32) + sizeof(dma_addr_t));
343 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
347 /* The current buffer is a chain buffer,
348 * but there is not another one.
349 * Update the chain element
350 * Offset and Length fields.
352 mptscsih_add_chain((char *)chainSge, 0, sgeOffset, ioc->ChainBufferDMA + chain_dma_off);
354 /* The current buffer is the original MF
355 * and there is no Chain buffer.
357 pReq->ChainOffset = 0;
358 RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor) + 1) & 0x03;
359 dsgprintk((MYIOC_s_INFO_FMT
360 "Single Buffer RequestNB=%x, sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
361 ioc->RequestNB[req_idx] = RequestNB;
364 /* At least one chain buffer is needed.
365 * Complete the first MF
366 * - last SGE element, set the LastElement bit
367 * - set ChainOffset (words) for orig MF
368 * (OR finish previous MF chain buffer)
369 * - update MFStructPtr ChainIndex
370 * - Populate chain element
375 dsgprintk((MYIOC_s_INFO_FMT "SG: Chain Required! sg done %d\n",
376 ioc->name, sg_done));
378 /* Set LAST_ELEMENT flag for last non-chain element
379 * in the buffer. Since psge points at the NEXT
380 * SGE element, go back one SGE element, update the flags
381 * and reset the pointer. (Note: sgflags & thisxfer are already
385 u32 *ptmp = (u32 *) (psge - (sizeof(u32) + sizeof(dma_addr_t)));
386 sgflags = le32_to_cpu(*ptmp);
387 sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT;
388 *ptmp = cpu_to_le32(sgflags);
392 /* The current buffer is a chain buffer.
393 * chainSge points to the previous Chain Element.
394 * Update its chain element Offset and Length (must
395 * include chain element size) fields.
396 * Old chain element is now complete.
398 u8 nextChain = (u8) (sgeOffset >> 2);
399 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
400 mptscsih_add_chain((char *)chainSge, nextChain, sgeOffset, ioc->ChainBufferDMA + chain_dma_off);
402 /* The original MF buffer requires a chain buffer -
404 * Last element in this MF is a chain element.
406 pReq->ChainOffset = (u8) (sgeOffset >> 2);
407 RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor) + 1) & 0x03;
408 dsgprintk((MYIOC_s_ERR_FMT "Chain Buffer Needed, RequestNB=%x sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
409 ioc->RequestNB[req_idx] = RequestNB;
412 sges_left -= sg_done;
415 /* NOTE: psge points to the beginning of the chain element
416 * in current buffer. Get a chain buffer.
418 if ((mptscsih_getFreeChainBuffer(ioc, &newIndex)) == FAILED) {
419 dfailprintk((MYIOC_s_INFO_FMT
420 "getFreeChainBuffer FAILED SCSI cmd=%02x (%p)\n",
421 ioc->name, pReq->CDB[0], SCpnt));
425 /* Update the tracking arrays.
426 * If chainSge == NULL, update ReqToChain, else ChainToChain
429 ioc->ChainToChain[chain_idx] = newIndex;
431 ioc->ReqToChain[req_idx] = newIndex;
433 chain_idx = newIndex;
434 chain_dma_off = ioc->req_sz * chain_idx;
436 /* Populate the chainSGE for the current buffer.
437 * - Set chain buffer pointer to psge and fill
438 * out the Address and Flags fields.
440 chainSge = (char *) psge;
441 dsgprintk((KERN_INFO " Current buff @ %p (index 0x%x)",
444 /* Start the SGE for the next buffer
446 psge = (char *) (ioc->ChainBuffer + chain_dma_off);
450 dsgprintk((KERN_INFO " Chain buff @ %p (index 0x%x)\n",
453 /* Start the SGE for the next buffer
460 } /* mptscsih_AddSGE() */
463 mptscsih_issue_sep_command(MPT_ADAPTER *ioc, VirtTarget *vtarget,
467 SEPRequest_t *SEPMsg;
469 if (ioc->bus_type == FC)
472 if ((mf = mpt_get_msg_frame(ioc->InternalCtx, ioc)) == NULL) {
473 dfailprintk((MYIOC_s_WARN_FMT "%s: no msg frames!!\n",
474 ioc->name,__FUNCTION__));
478 SEPMsg = (SEPRequest_t *)mf;
479 SEPMsg->Function = MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR;
480 SEPMsg->Bus = vtarget->channel;
481 SEPMsg->TargetID = vtarget->id;
482 SEPMsg->Action = MPI_SEP_REQ_ACTION_WRITE_STATUS;
483 SEPMsg->SlotStatus = SlotStatus;
484 devtverboseprintk((MYIOC_s_WARN_FMT
485 "Sending SEP cmd=%x channel=%d id=%d\n",
486 ioc->name, SlotStatus, SEPMsg->Bus, SEPMsg->TargetID));
487 mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
490 #ifdef MPT_DEBUG_REPLY
492 * mptscsih_iocstatus_info_scsiio - IOCSTATUS information for SCSIIO
493 * @ioc: Pointer to MPT_ADAPTER structure
494 * @ioc_status: U32 IOCStatus word from IOC
495 * @scsi_status: U8 sam status from target
496 * @scsi_state: U8 scsi state
497 * @sc: original scsi cmnd pointer
498 * @mf: Pointer to MPT request frame
500 * Refer to lsi/mpi.h.
503 mptscsih_iocstatus_info_scsiio(MPT_ADAPTER *ioc, u32 ioc_status,
504 u8 scsi_status, u8 scsi_state, struct scsi_cmnd *sc)
506 char extend_desc[EVENT_DESCR_STR_SZ];
509 switch (ioc_status) {
511 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
512 desc = "SCSI Invalid Bus";
515 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
516 desc = "SCSI Invalid TargetID";
519 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
521 * Inquiry is issued for device scanning
523 if (sc->cmnd[0] != 0x12)
524 desc = "SCSI Device Not There";
527 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
528 desc = "SCSI Data Overrun";
531 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
532 desc = "SCSI I/O Data Error";
535 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
536 desc = "SCSI Protocol Error";
539 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
540 desc = "SCSI Task Terminated";
543 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
544 desc = "SCSI Residual Mismatch";
547 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
548 desc = "SCSI Task Management Failed";
551 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
552 desc = "SCSI IOC Terminated";
555 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
556 desc = "SCSI Ext Terminated";
563 snprintf(extend_desc, EVENT_DESCR_STR_SZ,
564 "[%d:%d:%d:%d] cmd=%02Xh, sam_status=%02Xh state=%02Xh",
565 sc->device->host->host_no,
566 sc->device->channel, sc->device->id, sc->device->lun,
567 sc->cmnd[0], scsi_status, scsi_state);
569 printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04X): %s: %s\n",
570 ioc->name, ioc_status, desc, extend_desc);
574 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
576 * mptscsih_io_done - Main SCSI IO callback routine registered to
577 * Fusion MPT (base) driver
578 * @ioc: Pointer to MPT_ADAPTER structure
579 * @mf: Pointer to original MPT request frame
580 * @r: Pointer to MPT reply frame (NULL if TurboReply)
582 * This routine is called from mpt.c::mpt_interrupt() at the completion
583 * of any SCSI IO request.
584 * This routine is registered with the Fusion MPT (base) driver at driver
585 * load/init time via the mpt_register() API call.
587 * Returns 1 indicating alloc'd request frame ptr should be freed.
590 mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
592 struct scsi_cmnd *sc;
594 SCSIIORequest_t *pScsiReq;
595 SCSIIOReply_t *pScsiReply;
596 u16 req_idx, req_idx_MR;
600 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
602 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
603 req_idx_MR = (mr != NULL) ?
604 le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx) : req_idx;
605 if ((req_idx != req_idx_MR) ||
606 (mf->u.frame.linkage.arg1 == 0xdeadbeaf)) {
607 printk(MYIOC_s_ERR_FMT "Received a mf that was already freed\n",
609 printk (MYIOC_s_ERR_FMT
610 "req_idx=%x req_idx_MR=%x mf=%p mr=%p sc=%p\n",
611 ioc->name, req_idx, req_idx_MR, mf, mr,
612 hd->ScsiLookup[req_idx_MR]);
616 sc = hd->ScsiLookup[req_idx];
617 hd->ScsiLookup[req_idx] = NULL;
619 MPIHeader_t *hdr = (MPIHeader_t *)mf;
621 /* Remark: writeSDP1 will use the ScsiDoneCtx
622 * If a SCSI I/O cmd, device disabled by OS and
623 * completion done. Cannot touch sc struct. Just free mem.
625 if (hdr->Function == MPI_FUNCTION_SCSI_IO_REQUEST)
626 printk(MYIOC_s_ERR_FMT "NULL ScsiCmd ptr!\n",
629 mptscsih_freeChainBuffers(ioc, req_idx);
633 if ((unsigned char *)mf != sc->host_scribble) {
634 mptscsih_freeChainBuffers(ioc, req_idx);
638 sc->host_scribble = NULL;
639 sc->result = DID_OK << 16; /* Set default reply as OK */
640 pScsiReq = (SCSIIORequest_t *) mf;
641 pScsiReply = (SCSIIOReply_t *) mr;
643 if((ioc->facts.MsgVersion >= MPI_VERSION_01_05) && pScsiReply){
644 dmfprintk((MYIOC_s_INFO_FMT
645 "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d,task-tag=%d)\n",
646 ioc->name, mf, mr, sc, req_idx, pScsiReply->TaskTag));
648 dmfprintk((MYIOC_s_INFO_FMT
649 "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n",
650 ioc->name, mf, mr, sc, req_idx));
653 if (pScsiReply == NULL) {
654 /* special context reply handling */
659 u8 scsi_state, scsi_status;
662 status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK;
663 scsi_state = pScsiReply->SCSIState;
664 scsi_status = pScsiReply->SCSIStatus;
665 xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
666 sc->resid = sc->request_bufflen - xfer_cnt;
667 log_info = le32_to_cpu(pScsiReply->IOCLogInfo);
670 * if we get a data underrun indication, yet no data was
671 * transferred and the SCSI status indicates that the
672 * command was never started, change the data underrun
675 if (status == MPI_IOCSTATUS_SCSI_DATA_UNDERRUN && xfer_cnt == 0 &&
676 (scsi_status == MPI_SCSI_STATUS_BUSY ||
677 scsi_status == MPI_SCSI_STATUS_RESERVATION_CONFLICT ||
678 scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)) {
679 status = MPI_IOCSTATUS_SUCCESS;
682 if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)
683 mptscsih_copy_sense_data(sc, hd, mf, pScsiReply);
686 * Look for + dump FCP ResponseInfo[]!
688 if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID &&
689 pScsiReply->ResponseInfo) {
690 printk(KERN_NOTICE "[%d:%d:%d:%d] "
691 "FCP_ResponseInfo=%08xh\n",
692 sc->device->host->host_no, sc->device->channel,
693 sc->device->id, sc->device->lun,
694 le32_to_cpu(pScsiReply->ResponseInfo));
698 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
700 * Maybe: DRIVER_BUSY | SUGGEST_RETRY | DID_SOFT_ERROR (retry)
701 * But not: DID_BUS_BUSY lest one risk
702 * killing interrupt handler:-(
704 sc->result = SAM_STAT_BUSY;
707 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
708 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
709 sc->result = DID_BAD_TARGET << 16;
712 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
713 /* Spoof to SCSI Selection Timeout! */
714 if (ioc->bus_type != FC)
715 sc->result = DID_NO_CONNECT << 16;
716 /* else fibre, just stall until rescan event */
718 sc->result = DID_REQUEUE << 16;
720 if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF)
721 hd->sel_timeout[pScsiReq->TargetID]++;
723 vdev = sc->device->hostdata;
726 vtarget = vdev->vtarget;
727 if (vtarget->tflags & MPT_TARGET_FLAGS_LED_ON) {
728 mptscsih_issue_sep_command(ioc, vtarget,
729 MPI_SEP_REQ_SLOTSTATUS_UNCONFIGURED);
730 vtarget->tflags &= ~MPT_TARGET_FLAGS_LED_ON;
734 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
735 if ( ioc->bus_type == SAS ) {
736 u16 ioc_status = le16_to_cpu(pScsiReply->IOCStatus);
737 if (ioc_status & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
738 if ((log_info & SAS_LOGINFO_MASK)
739 == SAS_LOGINFO_NEXUS_LOSS) {
740 sc->result = (DID_BUS_BUSY << 16);
744 } else if (ioc->bus_type == FC) {
746 * The FC IOC may kill a request for variety of
747 * reasons, some of which may be recovered by a
748 * retry, some which are unlikely to be
749 * recovered. Return DID_ERROR instead of
750 * DID_RESET to permit retry of the command,
751 * just not an infinite number of them
753 sc->result = DID_ERROR << 16;
758 * Allow non-SAS & non-NEXUS_LOSS to drop into below code
761 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
762 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
763 /* Linux handles an unsolicited DID_RESET better
764 * than an unsolicited DID_ABORT.
766 sc->result = DID_RESET << 16;
770 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
771 sc->resid = sc->request_bufflen - xfer_cnt;
772 if((xfer_cnt==0)||(sc->underflow > xfer_cnt))
773 sc->result=DID_SOFT_ERROR << 16;
774 else /* Sufficient data transfer occurred */
775 sc->result = (DID_OK << 16) | scsi_status;
776 dreplyprintk((KERN_NOTICE
777 "RESIDUAL_MISMATCH: result=%x on channel=%d id=%d\n",
778 sc->result, sc->device->channel, sc->device->id));
781 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
783 * Do upfront check for valid SenseData and give it
786 sc->result = (DID_OK << 16) | scsi_status;
787 if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
788 /* Have already saved the status and sense data
792 if (xfer_cnt < sc->underflow) {
793 if (scsi_status == SAM_STAT_BUSY)
794 sc->result = SAM_STAT_BUSY;
796 sc->result = DID_SOFT_ERROR << 16;
798 if (scsi_state & (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)) {
801 sc->result = DID_SOFT_ERROR << 16;
803 else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
804 /* Not real sure here either... */
805 sc->result = DID_RESET << 16;
809 dreplyprintk((KERN_NOTICE " sc->underflow={report ERR if < %02xh bytes xfer'd}\n",
811 dreplyprintk((KERN_NOTICE " ActBytesXferd=%02xh\n", xfer_cnt));
814 if (scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)
815 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
819 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
821 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
822 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
823 if (scsi_status == MPI_SCSI_STATUS_BUSY)
824 sc->result = (DID_BUS_BUSY << 16) | scsi_status;
826 sc->result = (DID_OK << 16) | scsi_status;
827 if (scsi_state == 0) {
829 } else if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
831 * If running against circa 200003dd 909 MPT f/w,
832 * may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL
833 * (QUEUE_FULL) returned from device! --> get 0x0000?128
834 * and with SenseBytes set to 0.
836 if (pScsiReply->SCSIStatus == MPI_SCSI_STATUS_TASK_SET_FULL)
837 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
840 else if (scsi_state &
841 (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)
846 sc->result = DID_SOFT_ERROR << 16;
848 else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
849 /* Not real sure here either... */
850 sc->result = DID_RESET << 16;
852 else if (scsi_state & MPI_SCSI_STATE_QUEUE_TAG_REJECTED) {
853 /* Device Inq. data indicates that it supports
854 * QTags, but rejects QTag messages.
855 * This command completed OK.
857 * Not real sure here either so do nothing... */
860 if (sc->result == MPI_SCSI_STATUS_TASK_SET_FULL)
861 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
864 * Reservation Conflict, Busy,
865 * Command Terminated, CHECK
869 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
870 sc->result = DID_SOFT_ERROR << 16;
873 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
874 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
875 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
876 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
877 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
878 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
879 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
880 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
881 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
886 sc->result = DID_SOFT_ERROR << 16;
889 } /* switch(status) */
891 #ifdef MPT_DEBUG_REPLY
894 mptscsih_iocstatus_info_scsiio(ioc, status,
895 scsi_status, scsi_state, sc);
897 dreplyprintk(("%s: [%d:%d:%d:%d] cmd=0x%02x "
898 "result=0x%08x\n\tiocstatus=0x%04X "
899 "scsi_state=0x%02X scsi_status=0x%02X "
900 "loginfo=0x%08X\n", __FUNCTION__,
901 sc->device->host->host_no, sc->device->channel, sc->device->id,
902 sc->device->lun, sc->cmnd[0], sc->result, status,
903 scsi_state, scsi_status, log_info));
905 dreplyprintk(("%s: [%d:%d:%d:%d] resid=%d "
906 "bufflen=%d xfer_cnt=%d\n", __FUNCTION__,
907 sc->device->host->host_no, sc->device->channel, sc->device->id,
908 sc->device->lun, sc->resid, sc->request_bufflen,
913 } /* end of address reply case */
915 /* Unmap the DMA buffers, if any. */
917 pci_unmap_sg(ioc->pcidev, (struct scatterlist *) sc->request_buffer,
918 sc->use_sg, sc->sc_data_direction);
919 } else if (sc->request_bufflen) {
920 pci_unmap_single(ioc->pcidev, sc->SCp.dma_handle,
921 sc->request_bufflen, sc->sc_data_direction);
924 sc->scsi_done(sc); /* Issue the command callback */
926 /* Free Chain buffers */
927 mptscsih_freeChainBuffers(ioc, req_idx);
932 * mptscsih_flush_running_cmds - For each command found, search
933 * Scsi_Host instance taskQ and reply to OS.
934 * Called only if recovering from a FW reload.
935 * @hd: Pointer to a SCSI HOST structure
939 * Must be called while new I/Os are being queued.
942 mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
944 MPT_ADAPTER *ioc = hd->ioc;
945 struct scsi_cmnd *SCpnt;
948 int max = ioc->req_depth;
950 dprintk((KERN_INFO MYNAM ": flush_ScsiLookup called\n"));
951 for (ii= 0; ii < max; ii++) {
952 if ((SCpnt = hd->ScsiLookup[ii]) != NULL) {
957 /* Null ScsiLookup index
959 hd->ScsiLookup[ii] = NULL;
961 mf = MPT_INDEX_2_MFPTR(ioc, ii);
962 dmfprintk(( "flush: ScsiDone (mf=%p,sc=%p)\n",
965 /* Free Chain buffers */
966 mptscsih_freeChainBuffers(ioc, ii);
968 /* Free Message frames */
969 mpt_free_msg_frame(ioc, mf);
971 if ((unsigned char *)mf != SCpnt->host_scribble)
974 /* Set status, free OS resources (SG DMA buffers)
978 pci_unmap_sg(ioc->pcidev,
979 (struct scatterlist *) SCpnt->request_buffer,
981 SCpnt->sc_data_direction);
982 } else if (SCpnt->request_bufflen) {
983 pci_unmap_single(ioc->pcidev,
984 SCpnt->SCp.dma_handle,
985 SCpnt->request_bufflen,
986 SCpnt->sc_data_direction);
988 SCpnt->result = DID_RESET << 16;
989 SCpnt->host_scribble = NULL;
991 SCpnt->scsi_done(SCpnt); /* Issue the command callback */
999 * mptscsih_search_running_cmds - Delete any commands associated
1000 * with the specified target and lun. Function called only
1001 * when a lun is disable by mid-layer.
1002 * Do NOT access the referenced scsi_cmnd structure or
1003 * members. Will cause either a paging or NULL ptr error.
1004 * (BUT, BUT, BUT, the code does reference it! - mdr)
1005 * @hd: Pointer to a SCSI HOST structure
1006 * @vdevice: per device private data
1010 * Called from slave_destroy.
1013 mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
1015 SCSIIORequest_t *mf = NULL;
1017 int max = hd->ioc->req_depth;
1018 struct scsi_cmnd *sc;
1019 struct scsi_lun lun;
1021 dsprintk((KERN_INFO MYNAM ": search_running channel %d id %d lun %d max %d\n",
1022 vdevice->vtarget->channel, vdevice->vtarget->id, vdevice->lun, max));
1024 for (ii=0; ii < max; ii++) {
1025 if ((sc = hd->ScsiLookup[ii]) != NULL) {
1027 mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii);
1030 int_to_scsilun(vdevice->lun, &lun);
1031 if ((mf->Bus != vdevice->vtarget->channel) ||
1032 (mf->TargetID != vdevice->vtarget->id) ||
1033 memcmp(lun.scsi_lun, mf->LUN, 8))
1035 dsprintk(( "search_running: found (sc=%p, mf = %p) "
1036 "channel %d id %d, lun %d \n", hd->ScsiLookup[ii],
1037 mf, mf->Bus, mf->TargetID, vdevice->lun));
1041 hd->ScsiLookup[ii] = NULL;
1042 mptscsih_freeChainBuffers(hd->ioc, ii);
1043 mpt_free_msg_frame(hd->ioc, (MPT_FRAME_HDR *)mf);
1044 if ((unsigned char *)mf != sc->host_scribble)
1047 pci_unmap_sg(hd->ioc->pcidev,
1048 (struct scatterlist *) sc->request_buffer,
1050 sc->sc_data_direction);
1051 } else if (sc->request_bufflen) {
1052 pci_unmap_single(hd->ioc->pcidev,
1054 sc->request_bufflen,
1055 sc->sc_data_direction);
1057 sc->host_scribble = NULL;
1058 sc->result = DID_NO_CONNECT << 16;
1065 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1067 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1069 * mptscsih_report_queue_full - Report QUEUE_FULL status returned
1070 * from a SCSI target device.
1071 * @sc: Pointer to scsi_cmnd structure
1072 * @pScsiReply: Pointer to SCSIIOReply_t
1073 * @pScsiReq: Pointer to original SCSI request
1075 * This routine periodically reports QUEUE_FULL status returned from a
1076 * SCSI target device. It reports this to the console via kernel
1077 * printk() API call, not more than once every 10 seconds.
1080 mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq)
1082 long time = jiffies;
1085 if (sc->device == NULL)
1087 if (sc->device->host == NULL)
1089 if ((hd = (MPT_SCSI_HOST *)sc->device->host->hostdata) == NULL)
1092 if (time - hd->last_queue_full > 10 * HZ) {
1093 dprintk((MYIOC_s_WARN_FMT "Device (%d:%d:%d) reported QUEUE_FULL!\n",
1094 hd->ioc->name, 0, sc->device->id, sc->device->lun));
1095 hd->last_queue_full = time;
1099 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1101 * mptscsih_remove - Removed scsi devices
1102 * @pdev: Pointer to pci_dev structure
1107 mptscsih_remove(struct pci_dev *pdev)
1109 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1110 struct Scsi_Host *host = ioc->sh;
1119 scsi_remove_host(host);
1121 if((hd = (MPT_SCSI_HOST *)host->hostdata) == NULL)
1124 mptscsih_shutdown(pdev);
1128 if (hd->ScsiLookup != NULL) {
1129 sz1 = hd->ioc->req_depth * sizeof(void *);
1130 kfree(hd->ScsiLookup);
1131 hd->ScsiLookup = NULL;
1134 dprintk((MYIOC_s_INFO_FMT
1135 "Free'd ScsiLookup (%d) memory\n",
1136 hd->ioc->name, sz1));
1138 kfree(hd->info_kbuf);
1140 /* NULL the Scsi_Host pointer
1144 scsi_host_put(host);
1150 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1152 * mptscsih_shutdown - reboot notifier
1156 mptscsih_shutdown(struct pci_dev *pdev)
1158 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1159 struct Scsi_Host *host = ioc->sh;
1165 hd = (MPT_SCSI_HOST *)host->hostdata;
1170 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1172 * mptscsih_suspend - Fusion MPT scsi driver suspend routine.
1177 mptscsih_suspend(struct pci_dev *pdev, pm_message_t state)
1179 mptscsih_shutdown(pdev);
1180 return mpt_suspend(pdev,state);
1183 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1185 * mptscsih_resume - Fusion MPT scsi driver resume routine.
1190 mptscsih_resume(struct pci_dev *pdev)
1192 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1193 struct Scsi_Host *host = ioc->sh;
1201 hd = (MPT_SCSI_HOST *)host->hostdata;
1210 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1212 * mptscsih_info - Return information about MPT adapter
1213 * @SChost: Pointer to Scsi_Host structure
1215 * (linux scsi_host_template.info routine)
1217 * Returns pointer to buffer where information was written.
1220 mptscsih_info(struct Scsi_Host *SChost)
1225 h = (MPT_SCSI_HOST *)SChost->hostdata;
1228 if (h->info_kbuf == NULL)
1229 if ((h->info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)
1230 return h->info_kbuf;
1231 h->info_kbuf[0] = '\0';
1233 mpt_print_ioc_summary(h->ioc, h->info_kbuf, &size, 0, 0);
1234 h->info_kbuf[size-1] = '\0';
1237 return h->info_kbuf;
1248 mptscsih_copy_mem_info(struct info_str *info, char *data, int len)
1250 if (info->pos + len > info->length)
1251 len = info->length - info->pos;
1253 if (info->pos + len < info->offset) {
1258 if (info->pos < info->offset) {
1259 data += (info->offset - info->pos);
1260 len -= (info->offset - info->pos);
1264 memcpy(info->buffer + info->pos, data, len);
1270 mptscsih_copy_info(struct info_str *info, char *fmt, ...)
1276 va_start(args, fmt);
1277 len = vsprintf(buf, fmt, args);
1280 mptscsih_copy_mem_info(info, buf, len);
1285 mptscsih_host_info(MPT_ADAPTER *ioc, char *pbuf, off_t offset, int len)
1287 struct info_str info;
1291 info.offset = offset;
1294 mptscsih_copy_info(&info, "%s: %s, ", ioc->name, ioc->prod_name);
1295 mptscsih_copy_info(&info, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING, ioc->facts.FWVersion.Word);
1296 mptscsih_copy_info(&info, "Ports=%d, ", ioc->facts.NumberOfPorts);
1297 mptscsih_copy_info(&info, "MaxQ=%d\n", ioc->req_depth);
1299 return ((info.pos > info.offset) ? info.pos - info.offset : 0);
1302 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1304 * mptscsih_proc_info - Return information about MPT adapter
1305 * @host: scsi host struct
1306 * @buffer: if write, user data; if read, buffer for user
1307 * @start: returns the buffer address
1308 * @offset: if write, 0; if read, the current offset into the buffer from
1309 * the previous read.
1310 * @length: if write, return length;
1311 * @func: write = 1; read = 0
1313 * (linux scsi_host_template.info routine)
1316 mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
1317 int length, int func)
1319 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
1320 MPT_ADAPTER *ioc = hd->ioc;
1325 * write is not supported
1331 size = mptscsih_host_info(ioc, buffer, offset, length);
1337 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1338 #define ADD_INDEX_LOG(req_ent) do { } while(0)
1340 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1342 * mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine.
1343 * @SCpnt: Pointer to scsi_cmnd structure
1344 * @done: Pointer SCSI mid-layer IO completion function
1346 * (linux scsi_host_template.queuecommand routine)
1347 * This is the primary SCSI IO start routine. Create a MPI SCSIIORequest
1348 * from a linux scsi_cmnd request and send it to the IOC.
1350 * Returns 0. (rtn value discarded by linux scsi mid-layer)
1353 mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1357 SCSIIORequest_t *pScsiReq;
1358 VirtDevice *vdev = SCpnt->device->hostdata;
1367 hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata;
1368 lun = SCpnt->device->lun;
1369 SCpnt->scsi_done = done;
1371 dmfprintk((MYIOC_s_INFO_FMT "qcmd: SCpnt=%p, done()=%p\n",
1372 (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt, done));
1374 if (hd->resetPending) {
1375 dtmprintk((MYIOC_s_WARN_FMT "qcmd: SCpnt=%p timeout + 60HZ\n",
1376 (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt));
1377 return SCSI_MLQUEUE_HOST_BUSY;
1381 * Put together a MPT SCSI request...
1383 if ((mf = mpt_get_msg_frame(hd->ioc->DoneCtx, hd->ioc)) == NULL) {
1384 dprintk((MYIOC_s_WARN_FMT "QueueCmd, no msg frames!!\n",
1386 return SCSI_MLQUEUE_HOST_BUSY;
1389 pScsiReq = (SCSIIORequest_t *) mf;
1391 my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
1393 ADD_INDEX_LOG(my_idx);
1395 /* TUR's being issued with scsictl=0x02000000 (DATA_IN)!
1396 * Seems we may receive a buffer (datalen>0) even when there
1397 * will be no data transfer! GRRRRR...
1399 if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
1400 datalen = SCpnt->request_bufflen;
1401 scsidir = MPI_SCSIIO_CONTROL_READ; /* DATA IN (host<--ioc<--dev) */
1402 } else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
1403 datalen = SCpnt->request_bufflen;
1404 scsidir = MPI_SCSIIO_CONTROL_WRITE; /* DATA OUT (host-->ioc-->dev) */
1407 scsidir = MPI_SCSIIO_CONTROL_NODATATRANSFER;
1410 /* Default to untagged. Once a target structure has been allocated,
1411 * use the Inquiry data to determine if device supports tagged.
1414 && (vdev->vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)
1415 && (SCpnt->device->tagged_supported)) {
1416 scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
1418 scsictl = scsidir | MPI_SCSIIO_CONTROL_UNTAGGED;
1421 /* Use the above information to set up the message frame
1423 pScsiReq->TargetID = (u8) vdev->vtarget->id;
1424 pScsiReq->Bus = vdev->vtarget->channel;
1425 pScsiReq->ChainOffset = 0;
1426 if (vdev->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
1427 pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
1429 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
1430 pScsiReq->CDBLength = SCpnt->cmd_len;
1431 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
1432 pScsiReq->Reserved = 0;
1433 pScsiReq->MsgFlags = mpt_msg_flags();
1434 int_to_scsilun(SCpnt->device->lun, (struct scsi_lun *)pScsiReq->LUN);
1435 pScsiReq->Control = cpu_to_le32(scsictl);
1438 * Write SCSI CDB into the message
1440 cmd_len = SCpnt->cmd_len;
1441 for (ii=0; ii < cmd_len; ii++)
1442 pScsiReq->CDB[ii] = SCpnt->cmnd[ii];
1444 for (ii=cmd_len; ii < 16; ii++)
1445 pScsiReq->CDB[ii] = 0;
1448 pScsiReq->DataLength = cpu_to_le32(datalen);
1450 /* SenseBuffer low address */
1451 pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
1452 + (my_idx * MPT_SENSE_BUFFER_ALLOC));
1454 /* Now add the SG list
1455 * Always have a SGE even if null length.
1458 /* Add a NULL SGE */
1459 mptscsih_add_sge((char *)&pScsiReq->SGL, MPT_SGE_FLAGS_SSIMPLE_READ | 0,
1462 /* Add a 32 or 64 bit SGE */
1463 if (mptscsih_AddSGE(hd->ioc, SCpnt, pScsiReq, my_idx) != SUCCESS)
1467 SCpnt->host_scribble = (unsigned char *)mf;
1468 hd->ScsiLookup[my_idx] = SCpnt;
1470 mpt_put_msg_frame(hd->ioc->DoneCtx, hd->ioc, mf);
1471 dmfprintk((MYIOC_s_INFO_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n",
1472 hd->ioc->name, SCpnt, mf, my_idx));
1473 DBG_DUMP_REQUEST_FRAME(mf)
1477 hd->ScsiLookup[my_idx] = NULL;
1478 mptscsih_freeChainBuffers(hd->ioc, my_idx);
1479 mpt_free_msg_frame(hd->ioc, mf);
1480 return SCSI_MLQUEUE_HOST_BUSY;
1483 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1485 * mptscsih_freeChainBuffers - Function to free chain buffers associated
1486 * with a SCSI IO request
1487 * @hd: Pointer to the MPT_SCSI_HOST instance
1488 * @req_idx: Index of the SCSI IO request frame.
1490 * Called if SG chain buffer allocation fails and mptscsih callbacks.
1494 mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
1496 MPT_FRAME_HDR *chain;
1497 unsigned long flags;
1501 /* Get the first chain index and reset
1504 chain_idx = ioc->ReqToChain[req_idx];
1505 ioc->ReqToChain[req_idx] = MPT_HOST_NO_CHAIN;
1507 while (chain_idx != MPT_HOST_NO_CHAIN) {
1509 /* Save the next chain buffer index */
1510 next = ioc->ChainToChain[chain_idx];
1512 /* Free this chain buffer and reset
1515 ioc->ChainToChain[chain_idx] = MPT_HOST_NO_CHAIN;
1517 chain = (MPT_FRAME_HDR *) (ioc->ChainBuffer
1518 + (chain_idx * ioc->req_sz));
1520 spin_lock_irqsave(&ioc->FreeQlock, flags);
1521 list_add_tail(&chain->u.frame.linkage.list, &ioc->FreeChainQ);
1522 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1524 dmfprintk((MYIOC_s_INFO_FMT "FreeChainBuffers (index %d)\n",
1525 ioc->name, chain_idx));
1533 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1538 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1540 * mptscsih_TMHandler - Generic handler for SCSI Task Management.
1541 * Fall through to mpt_HardResetHandler if: not operational, too many
1542 * failed TM requests or handshake failure.
1544 * @ioc: Pointer to MPT_ADAPTER structure
1545 * @type: Task Management type
1546 * @id: Logical Target ID for reset (if appropriate)
1547 * @lun: Logical Unit for reset (if appropriate)
1548 * @ctx2abort: Context for the task to be aborted (if appropriate)
1550 * Remark: Currently invoked from a non-interrupt thread (_bh).
1552 * Remark: With old EH code, at most 1 SCSI TaskMgmt function per IOC
1555 * Returns 0 for SUCCESS, or FAILED.
1558 mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout)
1563 unsigned long flags;
1566 dtmprintk((MYIOC_s_INFO_FMT "TMHandler Entered!\n", ioc->name));
1568 // SJR - CHECKME - Can we avoid this here?
1569 // (mpt_HardResetHandler has this check...)
1570 spin_lock_irqsave(&ioc->diagLock, flags);
1571 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)) {
1572 spin_unlock_irqrestore(&ioc->diagLock, flags);
1575 spin_unlock_irqrestore(&ioc->diagLock, flags);
1577 /* Wait a fixed amount of time for the TM pending flag to be cleared.
1578 * If we time out and not bus reset, then we return a FAILED status
1580 * The call to mptscsih_tm_pending_wait() will set the pending flag
1582 * successful. Otherwise, reload the FW.
1584 if (mptscsih_tm_pending_wait(hd) == FAILED) {
1585 if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
1586 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler abort: "
1587 "Timed out waiting for last TM (%d) to complete! \n",
1588 hd->ioc->name, hd->tmPending));
1590 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) {
1591 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler target "
1592 "reset: Timed out waiting for last TM (%d) "
1593 "to complete! \n", hd->ioc->name,
1596 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
1597 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler bus reset: "
1598 "Timed out waiting for last TM (%d) to complete! \n",
1599 hd->ioc->name, hd->tmPending));
1603 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
1604 hd->tmPending |= (1 << type);
1605 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1608 ioc_raw_state = mpt_GetIocState(hd->ioc, 0);
1610 if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) {
1611 printk(MYIOC_s_WARN_FMT
1612 "TM Handler for type=%x: IOC Not operational (0x%x)!\n",
1613 ioc->name, type, ioc_raw_state);
1614 printk(KERN_WARNING " Issuing HardReset!!\n");
1615 if (mpt_HardResetHandler(ioc, CAN_SLEEP) < 0)
1616 printk((KERN_WARNING "TMHandler: HardReset "
1621 if (ioc_raw_state & MPI_DOORBELL_ACTIVE) {
1622 printk(MYIOC_s_WARN_FMT
1623 "TM Handler for type=%x: ioc_state: "
1624 "DOORBELL_ACTIVE (0x%x)!\n",
1625 ioc->name, type, ioc_raw_state);
1629 /* Isse the Task Mgmt request.
1631 if (hd->hard_resets < -1)
1634 rc = mptscsih_IssueTaskMgmt(hd, type, channel, id, lun,
1635 ctx2abort, timeout);
1637 printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n",
1640 dtmprintk((MYIOC_s_INFO_FMT "Issue of TaskMgmt Successful!\n",
1643 dtmprintk((MYIOC_s_INFO_FMT "TMHandler rc = %d!\n", hd->ioc->name, rc));
1649 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1651 * mptscsih_IssueTaskMgmt - Generic send Task Management function.
1652 * @hd: Pointer to MPT_SCSI_HOST structure
1653 * @type: Task Management type
1654 * @id: Logical Target ID for reset (if appropriate)
1655 * @lun: Logical Unit for reset (if appropriate)
1656 * @ctx2abort: Context for the task to be aborted (if appropriate)
1658 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
1659 * or a non-interrupt thread. In the former, must not call schedule().
1661 * Not all fields are meaningfull for all task types.
1663 * Returns 0 for SUCCESS, or FAILED.
1667 mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout)
1670 SCSITaskMgmt_t *pScsiTm;
1674 /* Return Fail to calling function if no message frames available.
1676 if ((mf = mpt_get_msg_frame(hd->ioc->TaskCtx, hd->ioc)) == NULL) {
1677 dfailprintk((MYIOC_s_ERR_FMT "IssueTaskMgmt, no msg frames!!\n",
1681 dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt request @ %p\n",
1682 hd->ioc->name, mf));
1684 /* Format the Request
1686 pScsiTm = (SCSITaskMgmt_t *) mf;
1687 pScsiTm->TargetID = id;
1688 pScsiTm->Bus = channel;
1689 pScsiTm->ChainOffset = 0;
1690 pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
1692 pScsiTm->Reserved = 0;
1693 pScsiTm->TaskType = type;
1694 pScsiTm->Reserved1 = 0;
1695 pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)
1696 ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0;
1698 int_to_scsilun(lun, (struct scsi_lun *)pScsiTm->LUN);
1700 for (ii=0; ii < 7; ii++)
1701 pScsiTm->Reserved2[ii] = 0;
1703 pScsiTm->TaskMsgContext = ctx2abort;
1705 dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt: ctx2abort (0x%08x) "
1706 "type=%d\n", hd->ioc->name, ctx2abort, type));
1708 DBG_DUMP_TM_REQUEST_FRAME((u32 *)pScsiTm);
1710 if ((retval = mpt_send_handshake_request(hd->ioc->TaskCtx, hd->ioc,
1711 sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, CAN_SLEEP)) != 0) {
1712 dfailprintk((MYIOC_s_ERR_FMT "send_handshake FAILED!"
1713 " (hd %p, ioc %p, mf %p, rc=%d) \n", hd->ioc->name, hd,
1714 hd->ioc, mf, retval));
1718 if(mptscsih_tm_wait_for_completion(hd, timeout) == FAILED) {
1719 dfailprintk((MYIOC_s_ERR_FMT "task management request TIMED OUT!"
1720 " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
1722 dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
1724 retval = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
1725 dtmprintk((MYIOC_s_INFO_FMT "rc=%d \n",
1726 hd->ioc->name, retval));
1731 * Handle success case, see if theres a non-zero ioc_status.
1733 if (hd->tm_iocstatus == MPI_IOCSTATUS_SUCCESS ||
1734 hd->tm_iocstatus == MPI_IOCSTATUS_SCSI_TASK_TERMINATED ||
1735 hd->tm_iocstatus == MPI_IOCSTATUS_SCSI_IOC_TERMINATED)
1745 * Free task managment mf, and corresponding tm flags
1747 mpt_free_msg_frame(hd->ioc, mf);
1749 hd->tmState = TM_STATE_NONE;
1754 mptscsih_get_tm_timeout(MPT_ADAPTER *ioc)
1756 switch (ioc->bus_type) {
1767 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1769 * mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant
1770 * @SCpnt: Pointer to scsi_cmnd structure, IO to be aborted
1772 * (linux scsi_host_template.eh_abort_handler routine)
1774 * Returns SUCCESS or FAILED.
1777 mptscsih_abort(struct scsi_cmnd * SCpnt)
1785 ulong sn = SCpnt->serial_number;
1787 /* If we can't locate our host adapter structure, return FAILED status.
1789 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL) {
1790 SCpnt->result = DID_RESET << 16;
1791 SCpnt->scsi_done(SCpnt);
1792 dfailprintk((KERN_INFO MYNAM ": mptscsih_abort: "
1793 "Can't locate host! (sc=%p)\n",
1798 /* Find this command
1800 if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) {
1801 /* Cmd not found in ScsiLookup.
1804 SCpnt->result = DID_RESET << 16;
1805 dtmprintk((KERN_INFO MYNAM ": %s: mptscsih_abort: "
1806 "Command not in the active list! (sc=%p)\n",
1807 hd->ioc->name, SCpnt));
1811 if (hd->resetPending)
1814 if (hd->timeouts < -1)
1817 printk(KERN_WARNING MYNAM ": %s: attempting task abort! (sc=%p)\n",
1818 hd->ioc->name, SCpnt);
1819 scsi_print_command(SCpnt);
1821 /* Most important! Set TaskMsgContext to SCpnt's MsgContext!
1822 * (the IO to be ABORT'd)
1824 * NOTE: Since we do not byteswap MsgContext, we do not
1825 * swap it here either. It is an opaque cookie to
1826 * the controller, so it does not matter. -DaveM
1828 mf = MPT_INDEX_2_MFPTR(hd->ioc, scpnt_idx);
1829 ctx2abort = mf->u.frame.hwhdr.msgctxu.MsgContext;
1831 hd->abortSCpnt = SCpnt;
1833 vdev = SCpnt->device->hostdata;
1834 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
1835 vdev->vtarget->channel, vdev->vtarget->id, vdev->lun,
1836 ctx2abort, mptscsih_get_tm_timeout(hd->ioc));
1838 if (SCPNT_TO_LOOKUP_IDX(SCpnt) == scpnt_idx &&
1839 SCpnt->serial_number == sn)
1842 printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n",
1844 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1852 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1854 * mptscsih_dev_reset - Perform a SCSI TARGET_RESET! new_eh variant
1855 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1857 * (linux scsi_host_template.eh_dev_reset_handler routine)
1859 * Returns SUCCESS or FAILED.
1862 mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
1868 /* If we can't locate our host adapter structure, return FAILED status.
1870 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1871 dtmprintk((KERN_INFO MYNAM ": mptscsih_dev_reset: "
1872 "Can't locate host! (sc=%p)\n",
1877 if (hd->resetPending)
1880 printk(KERN_WARNING MYNAM ": %s: attempting target reset! (sc=%p)\n",
1881 hd->ioc->name, SCpnt);
1882 scsi_print_command(SCpnt);
1884 vdev = SCpnt->device->hostdata;
1885 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
1886 vdev->vtarget->channel, vdev->vtarget->id,
1887 0, 0, mptscsih_get_tm_timeout(hd->ioc));
1889 printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n",
1891 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1900 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1902 * mptscsih_bus_reset - Perform a SCSI BUS_RESET! new_eh variant
1903 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1905 * (linux scsi_host_template.eh_bus_reset_handler routine)
1907 * Returns SUCCESS or FAILED.
1910 mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
1916 /* If we can't locate our host adapter structure, return FAILED status.
1918 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1919 dtmprintk((KERN_INFO MYNAM ": mptscsih_bus_reset: "
1920 "Can't locate host! (sc=%p)\n",
1925 printk(KERN_WARNING MYNAM ": %s: attempting bus reset! (sc=%p)\n",
1926 hd->ioc->name, SCpnt);
1927 scsi_print_command(SCpnt);
1929 if (hd->timeouts < -1)
1932 vdev = SCpnt->device->hostdata;
1933 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
1934 vdev->vtarget->channel, 0, 0, 0, mptscsih_get_tm_timeout(hd->ioc));
1936 printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n",
1938 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1946 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1948 * mptscsih_host_reset - Perform a SCSI host adapter RESET (new_eh variant)
1949 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1951 * (linux scsi_host_template.eh_host_reset_handler routine)
1953 * Returns SUCCESS or FAILED.
1956 mptscsih_host_reset(struct scsi_cmnd *SCpnt)
1959 int status = SUCCESS;
1961 /* If we can't locate the host to reset, then we failed. */
1962 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1963 dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
1964 "Can't locate host! (sc=%p)\n",
1969 printk(KERN_WARNING MYNAM ": %s: Attempting host reset! (sc=%p)\n",
1970 hd->ioc->name, SCpnt);
1972 /* If our attempts to reset the host failed, then return a failed
1973 * status. The host will be taken off line by the SCSI mid-layer.
1975 if (mpt_HardResetHandler(hd->ioc, CAN_SLEEP) < 0){
1978 /* Make sure TM pending is cleared and TM state is set to
1982 hd->tmState = TM_STATE_NONE;
1985 dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
1987 (status == SUCCESS) ? "SUCCESS" : "FAILED" ) );
1992 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1994 * mptscsih_tm_pending_wait - wait for pending task management request to complete
1995 * @hd: Pointer to MPT host structure.
1997 * Returns {SUCCESS,FAILED}.
2000 mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd)
2002 unsigned long flags;
2003 int loop_count = 4 * 10; /* Wait 10 seconds */
2004 int status = FAILED;
2007 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
2008 if (hd->tmState == TM_STATE_NONE) {
2009 hd->tmState = TM_STATE_IN_PROGRESS;
2011 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2015 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2017 } while (--loop_count);
2022 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2024 * mptscsih_tm_wait_for_completion - wait for completion of TM task
2025 * @hd: Pointer to MPT host structure.
2027 * Returns {SUCCESS,FAILED}.
2030 mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout )
2032 unsigned long flags;
2033 int loop_count = 4 * timeout;
2034 int status = FAILED;
2037 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
2038 if(hd->tmPending == 0) {
2040 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2043 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2045 } while (--loop_count);
2050 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2052 mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code)
2056 switch (response_code) {
2057 case MPI_SCSITASKMGMT_RSP_TM_COMPLETE:
2058 desc = "The task completed.";
2060 case MPI_SCSITASKMGMT_RSP_INVALID_FRAME:
2061 desc = "The IOC received an invalid frame status.";
2063 case MPI_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED:
2064 desc = "The task type is not supported.";
2066 case MPI_SCSITASKMGMT_RSP_TM_FAILED:
2067 desc = "The requested task failed.";
2069 case MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED:
2070 desc = "The task completed successfully.";
2072 case MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN:
2073 desc = "The LUN request is invalid.";
2075 case MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC:
2076 desc = "The task is in the IOC queue and has not been sent to target.";
2082 printk(MYIOC_s_INFO_FMT "Response Code(0x%08x): F/W: %s\n",
2083 ioc->name, response_code, desc);
2086 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2088 * mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
2089 * @ioc: Pointer to MPT_ADAPTER structure
2090 * @mf: Pointer to SCSI task mgmt request frame
2091 * @mr: Pointer to SCSI task mgmt reply frame
2093 * This routine is called from mptbase.c::mpt_interrupt() at the completion
2094 * of any SCSI task management request.
2095 * This routine is registered with the MPT (base) driver at driver
2096 * load/init time via the mpt_register() API call.
2098 * Returns 1 indicating alloc'd request frame ptr should be freed.
2101 mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
2103 SCSITaskMgmtReply_t *pScsiTmReply;
2104 SCSITaskMgmt_t *pScsiTmReq;
2106 unsigned long flags;
2109 u32 termination_count;
2111 dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt completed (mf=%p,mr=%p)\n",
2112 ioc->name, mf, mr));
2114 dtmprintk((MYIOC_s_WARN_FMT
2115 "TaskMgmt Complete: NULL Scsi Host Ptr\n", ioc->name));
2120 dtmprintk((MYIOC_s_WARN_FMT
2121 "ERROR! TaskMgmt Reply: NULL Request %p\n", ioc->name, mf));
2125 hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
2126 pScsiTmReply = (SCSITaskMgmtReply_t*)mr;
2127 pScsiTmReq = (SCSITaskMgmt_t*)mf;
2128 tmType = pScsiTmReq->TaskType;
2129 iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2130 termination_count = le32_to_cpu(pScsiTmReply->TerminationCount);
2132 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05 &&
2133 pScsiTmReply->ResponseCode)
2134 mptscsih_taskmgmt_response_code(ioc,
2135 pScsiTmReply->ResponseCode);
2136 DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply);
2138 #if defined(MPT_DEBUG_REPLY) || defined(MPT_DEBUG_TM)
2139 printk("%s: ha=%d [%d:%d:0] task_type=0x%02X "
2140 "iocstatus=0x%04X\n\tloginfo=0x%08X response_code=0x%02X "
2141 "term_cmnds=%d\n", __FUNCTION__, ioc->id, pScsiTmReply->Bus,
2142 pScsiTmReply->TargetID, pScsiTmReq->TaskType,
2143 le16_to_cpu(pScsiTmReply->IOCStatus),
2144 le32_to_cpu(pScsiTmReply->IOCLogInfo),pScsiTmReply->ResponseCode,
2145 le32_to_cpu(pScsiTmReply->TerminationCount));
2148 dtmprintk((MYIOC_s_WARN_FMT " TaskMgmt SUCCESS\n", ioc->name));
2149 hd->abortSCpnt = NULL;
2153 /* Error? (anything non-zero?) */
2155 /* clear flags and continue.
2159 case MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK:
2160 if (termination_count == 1)
2161 iocstatus = MPI_IOCSTATUS_SCSI_TASK_TERMINATED;
2162 hd->abortSCpnt = NULL;
2165 case MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS:
2167 /* If an internal command is present
2168 * or the TM failed - reload the FW.
2169 * FC FW may respond FAILED to an ABORT
2171 if (iocstatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED ||
2173 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
2174 printk((KERN_WARNING " Firmware Reload FAILED!!\n"));
2177 case MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET:
2183 spin_lock_irqsave(&ioc->FreeQlock, flags);
2185 hd->tmState = TM_STATE_NONE;
2186 hd->tm_iocstatus = iocstatus;
2187 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2192 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2194 * This is anyones guess quite frankly.
2197 mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
2198 sector_t capacity, int geom[])
2208 dummy = heads * sectors;
2209 cylinders = capacity;
2210 sector_div(cylinders,dummy);
2213 * Handle extended translation size for logical drives
2216 if ((ulong)capacity >= 0x200000) {
2219 dummy = heads * sectors;
2220 cylinders = capacity;
2221 sector_div(cylinders,dummy);
2227 geom[2] = cylinders;
2229 dprintk((KERN_NOTICE
2230 ": bios_param: Id=%i Lun=%i Channel=%i CHS=%i/%i/%i\n",
2231 sdev->id, sdev->lun, sdev->channel, (int)cylinders, heads, sectors));
2236 /* Search IOC page 3 to determine if this is hidden physical disk
2240 mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id)
2242 struct inactive_raid_component_info *component_info;
2246 if (!ioc->raid_data.pIocPg3)
2248 for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2249 if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) &&
2250 (channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) {
2257 * Check inactive list for matching phys disks
2259 if (list_empty(&ioc->raid_data.inactive_list))
2262 down(&ioc->raid_data.inactive_list_mutex);
2263 list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
2265 if ((component_info->d.PhysDiskID == id) &&
2266 (component_info->d.PhysDiskBus == channel))
2269 up(&ioc->raid_data.inactive_list_mutex);
2274 EXPORT_SYMBOL(mptscsih_is_phys_disk);
2277 mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id)
2279 struct inactive_raid_component_info *component_info;
2283 if (!ioc->raid_data.pIocPg3)
2285 for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2286 if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) &&
2287 (channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) {
2288 rc = ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum;
2294 * Check inactive list for matching phys disks
2296 if (list_empty(&ioc->raid_data.inactive_list))
2299 down(&ioc->raid_data.inactive_list_mutex);
2300 list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
2302 if ((component_info->d.PhysDiskID == id) &&
2303 (component_info->d.PhysDiskBus == channel))
2304 rc = component_info->d.PhysDiskNum;
2306 up(&ioc->raid_data.inactive_list_mutex);
2311 EXPORT_SYMBOL(mptscsih_raid_id_to_num);
2314 * OS entry point to allow for host driver to free allocated memory
2315 * Called if no device present or device being unloaded
2318 mptscsih_slave_destroy(struct scsi_device *sdev)
2320 struct Scsi_Host *host = sdev->host;
2321 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
2322 VirtTarget *vtarget;
2323 VirtDevice *vdevice;
2324 struct scsi_target *starget;
2326 starget = scsi_target(sdev);
2327 vtarget = starget->hostdata;
2328 vdevice = sdev->hostdata;
2330 mptscsih_search_running_cmds(hd, vdevice);
2331 vtarget->num_luns--;
2332 mptscsih_synchronize_cache(hd, vdevice);
2334 sdev->hostdata = NULL;
2337 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2339 * mptscsih_change_queue_depth - This function will set a devices queue depth
2340 * @sdev: per scsi_device pointer
2341 * @qdepth: requested queue depth
2343 * Adding support for new 'change_queue_depth' api.
2346 mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
2348 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sdev->host->hostdata;
2349 VirtTarget *vtarget;
2350 struct scsi_target *starget;
2354 starget = scsi_target(sdev);
2355 vtarget = starget->hostdata;
2357 if (hd->ioc->bus_type == SPI) {
2358 if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
2360 else if (sdev->type == TYPE_DISK &&
2361 vtarget->minSyncFactor <= MPT_ULTRA160)
2362 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2364 max_depth = MPT_SCSI_CMD_PER_DEV_LOW;
2366 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2368 if (qdepth > max_depth)
2373 tagged = MSG_SIMPLE_TAG;
2375 scsi_adjust_queue_depth(sdev, tagged, qdepth);
2376 return sdev->queue_depth;
2380 * OS entry point to adjust the queue_depths on a per-device basis.
2381 * Called once per device the bus scan. Use it to force the queue_depth
2382 * member to 1 if a device does not support Q tags.
2383 * Return non-zero if fails.
2386 mptscsih_slave_configure(struct scsi_device *sdev)
2388 struct Scsi_Host *sh = sdev->host;
2389 VirtTarget *vtarget;
2390 VirtDevice *vdevice;
2391 struct scsi_target *starget;
2392 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sh->hostdata;
2394 starget = scsi_target(sdev);
2395 vtarget = starget->hostdata;
2396 vdevice = sdev->hostdata;
2398 dsprintk((MYIOC_s_INFO_FMT
2399 "device @ %p, channel=%d, id=%d, lun=%d\n",
2400 hd->ioc->name, sdev, sdev->channel, sdev->id, sdev->lun));
2401 if (hd->ioc->bus_type == SPI)
2402 dsprintk((MYIOC_s_INFO_FMT
2403 "sdtr %d wdtr %d ppr %d inq length=%d\n",
2404 hd->ioc->name, sdev->sdtr, sdev->wdtr,
2405 sdev->ppr, sdev->inquiry_len));
2407 if (sdev->id > sh->max_id) {
2408 /* error case, should never happen */
2409 scsi_adjust_queue_depth(sdev, 0, 1);
2410 goto slave_configure_exit;
2413 vdevice->configured_lun = 1;
2414 mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH);
2416 dsprintk((MYIOC_s_INFO_FMT
2417 "Queue depth=%d, tflags=%x\n",
2418 hd->ioc->name, sdev->queue_depth, vtarget->tflags));
2420 if (hd->ioc->bus_type == SPI)
2421 dsprintk((MYIOC_s_INFO_FMT
2422 "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
2423 hd->ioc->name, vtarget->negoFlags, vtarget->maxOffset,
2424 vtarget->minSyncFactor));
2426 slave_configure_exit:
2428 dsprintk((MYIOC_s_INFO_FMT
2429 "tagged %d, simple %d, ordered %d\n",
2430 hd->ioc->name,sdev->tagged_supported, sdev->simple_tags,
2431 sdev->ordered_tags));
2436 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2438 * Private routines...
2441 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2442 /* Utility function to copy sense data from the scsi_cmnd buffer
2443 * to the FC and SCSI target structures.
2447 mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
2450 SCSIIORequest_t *pReq;
2451 u32 sense_count = le32_to_cpu(pScsiReply->SenseCount);
2453 /* Get target structure
2455 pReq = (SCSIIORequest_t *) mf;
2456 vdev = sc->device->hostdata;
2462 /* Copy the sense received into the scsi command block. */
2463 req_index = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2464 sense_data = ((u8 *)hd->ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC));
2465 memcpy(sc->sense_buffer, sense_data, SNS_LEN(sc));
2467 /* Log SMART data (asc = 0x5D, non-IM case only) if required.
2469 if ((hd->ioc->events) && (hd->ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) {
2470 if ((sense_data[12] == 0x5D) && (vdev->vtarget->raidVolume == 0)) {
2472 MPT_ADAPTER *ioc = hd->ioc;
2474 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
2475 ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
2476 ioc->events[idx].eventContext = ioc->eventContext;
2478 ioc->events[idx].data[0] = (pReq->LUN[1] << 24) ||
2479 (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) ||
2480 (sc->device->channel << 8) || sc->device->id;
2482 ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12];
2484 ioc->eventContext++;
2485 if (hd->ioc->pcidev->vendor ==
2486 PCI_VENDOR_ID_IBM) {
2487 mptscsih_issue_sep_command(hd->ioc,
2488 vdev->vtarget, MPI_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT);
2489 vdev->vtarget->tflags |=
2490 MPT_TARGET_FLAGS_LED_ON;
2495 dprintk((MYIOC_s_INFO_FMT "Hmmm... SenseData len=0! (?)\n",
2501 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc)
2506 hd = (MPT_SCSI_HOST *) sc->device->host->hostdata;
2508 for (i = 0; i < hd->ioc->req_depth; i++) {
2509 if (hd->ScsiLookup[i] == sc) {
2517 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2519 mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2522 unsigned long flags;
2525 dtmprintk((KERN_WARNING MYNAM
2526 ": IOC %s_reset routed to SCSI host driver!\n",
2527 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
2528 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
2530 /* If a FW reload request arrives after base installed but
2531 * before all scsi hosts have been attached, then an alt_ioc
2532 * may have a NULL sh pointer.
2534 if ((ioc->sh == NULL) || (ioc->sh->hostdata == NULL))
2537 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2539 if (reset_phase == MPT_IOC_SETUP_RESET) {
2540 dtmprintk((MYIOC_s_WARN_FMT "Setup-Diag Reset\n", ioc->name));
2543 * 1. Set Hard Reset Pending Flag
2544 * All new commands go to doneQ
2546 hd->resetPending = 1;
2548 } else if (reset_phase == MPT_IOC_PRE_RESET) {
2549 dtmprintk((MYIOC_s_WARN_FMT "Pre-Diag Reset\n", ioc->name));
2551 /* 2. Flush running commands
2552 * Clean ScsiLookup (and associated memory)
2556 /* 2b. Reply to OS all known outstanding I/O commands.
2558 mptscsih_flush_running_cmds(hd);
2560 /* 2c. If there was an internal command that
2561 * has not completed, configuration or io request,
2562 * free these resources.
2565 del_timer(&hd->timer);
2566 mpt_free_msg_frame(ioc, hd->cmdPtr);
2569 dtmprintk((MYIOC_s_WARN_FMT "Pre-Reset complete.\n", ioc->name));
2572 dtmprintk((MYIOC_s_WARN_FMT "Post-Diag Reset\n", ioc->name));
2574 /* Once a FW reload begins, all new OS commands are
2575 * redirected to the doneQ w/ a reset status.
2576 * Init all control structures.
2579 /* ScsiLookup initialization
2581 for (ii=0; ii < hd->ioc->req_depth; ii++)
2582 hd->ScsiLookup[ii] = NULL;
2584 /* 2. Chain Buffer initialization
2587 /* 4. Renegotiate to all devices, if SPI
2590 /* 5. Enable new commands to be posted
2592 spin_lock_irqsave(&ioc->FreeQlock, flags);
2594 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2595 hd->resetPending = 0;
2596 hd->tmState = TM_STATE_NONE;
2598 /* 6. If there was an internal command,
2599 * wake this process up.
2603 * Wake up the original calling thread
2605 hd->pLocal = &hd->localReply;
2606 hd->pLocal->completion = MPT_SCANDV_DID_RESET;
2607 hd->scandv_wait_done = 1;
2608 wake_up(&hd->scandv_waitq);
2612 dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name));
2616 return 1; /* currently means nothing really */
2619 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2621 mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2624 u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
2626 devtverboseprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
2629 if (ioc->sh == NULL ||
2630 ((hd = (MPT_SCSI_HOST *)ioc->sh->hostdata) == NULL))
2634 case MPI_EVENT_UNIT_ATTENTION: /* 03 */
2637 case MPI_EVENT_IOC_BUS_RESET: /* 04 */
2638 case MPI_EVENT_EXT_BUS_RESET: /* 05 */
2639 if (hd && (ioc->bus_type == SPI) && (hd->soft_resets < -1))
2642 case MPI_EVENT_LOGOUT: /* 09 */
2646 case MPI_EVENT_RESCAN: /* 06 */
2650 * CHECKME! Don't think we need to do
2651 * anything for these, but...
2653 case MPI_EVENT_LINK_STATUS_CHANGE: /* 07 */
2654 case MPI_EVENT_LOOP_STATE_CHANGE: /* 08 */
2656 * CHECKME! Falling thru...
2660 case MPI_EVENT_INTEGRATED_RAID: /* 0B */
2663 case MPI_EVENT_NONE: /* 00 */
2664 case MPI_EVENT_LOG_DATA: /* 01 */
2665 case MPI_EVENT_STATE_CHANGE: /* 02 */
2666 case MPI_EVENT_EVENT_CHANGE: /* 0A */
2668 dprintk((KERN_INFO " Ignoring event (=%02Xh)\n", event));
2672 return 1; /* currently means nothing really */
2675 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2677 * Bus Scan and Domain Validation functionality ...
2680 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2682 * mptscsih_scandv_complete - Scan and DV callback routine registered
2683 * to Fustion MPT (base) driver.
2685 * @ioc: Pointer to MPT_ADAPTER structure
2686 * @mf: Pointer to original MPT request frame
2687 * @mr: Pointer to MPT reply frame (NULL if TurboReply)
2689 * This routine is called from mpt.c::mpt_interrupt() at the completion
2690 * of any SCSI IO request.
2691 * This routine is registered with the Fusion MPT (base) driver at driver
2692 * load/init time via the mpt_register() API call.
2694 * Returns 1 indicating alloc'd request frame ptr should be freed.
2696 * Remark: Sets a completion code and (possibly) saves sense data
2697 * in the IOC member localReply structure.
2698 * Used ONLY for DV and other internal commands.
2701 mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
2704 SCSIIORequest_t *pReq;
2708 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2711 (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) {
2712 printk(MYIOC_s_ERR_FMT
2713 "ScanDvComplete, %s req frame ptr! (=%p)\n",
2714 ioc->name, mf?"BAD":"NULL", (void *) mf);
2718 del_timer(&hd->timer);
2719 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2720 hd->ScsiLookup[req_idx] = NULL;
2721 pReq = (SCSIIORequest_t *) mf;
2723 if (mf != hd->cmdPtr) {
2724 printk(MYIOC_s_WARN_FMT "ScanDvComplete (mf=%p, cmdPtr=%p, idx=%d)\n",
2725 hd->ioc->name, (void *)mf, (void *) hd->cmdPtr, req_idx);
2729 ddvprintk((MYIOC_s_INFO_FMT "ScanDvComplete (mf=%p,mr=%p,idx=%d)\n",
2730 hd->ioc->name, mf, mr, req_idx));
2732 hd->pLocal = &hd->localReply;
2733 hd->pLocal->scsiStatus = 0;
2735 /* If target struct exists, clear sense valid flag.
2738 completionCode = MPT_SCANDV_GOOD;
2740 SCSIIOReply_t *pReply;
2744 pReply = (SCSIIOReply_t *) mr;
2746 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2747 scsi_status = pReply->SCSIStatus;
2749 ddvtprintk((KERN_NOTICE " IOCStatus=%04xh, SCSIState=%02xh, SCSIStatus=%02xh, IOCLogInfo=%08xh\n",
2750 status, pReply->SCSIState, scsi_status,
2751 le32_to_cpu(pReply->IOCLogInfo)));
2755 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
2756 completionCode = MPT_SCANDV_SELECTION_TIMEOUT;
2759 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
2760 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
2761 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
2762 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
2763 completionCode = MPT_SCANDV_DID_RESET;
2766 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
2767 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
2768 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
2769 if (pReply->Function == MPI_FUNCTION_CONFIG) {
2770 ConfigReply_t *pr = (ConfigReply_t *)mr;
2771 completionCode = MPT_SCANDV_GOOD;
2772 hd->pLocal->header.PageVersion = pr->Header.PageVersion;
2773 hd->pLocal->header.PageLength = pr->Header.PageLength;
2774 hd->pLocal->header.PageNumber = pr->Header.PageNumber;
2775 hd->pLocal->header.PageType = pr->Header.PageType;
2777 } else if (pReply->Function == MPI_FUNCTION_RAID_ACTION) {
2778 /* If the RAID Volume request is successful,
2779 * return GOOD, else indicate that
2780 * some type of error occurred.
2782 MpiRaidActionReply_t *pr = (MpiRaidActionReply_t *)mr;
2783 if (le16_to_cpu(pr->ActionStatus) == MPI_RAID_ACTION_ASTATUS_SUCCESS)
2784 completionCode = MPT_SCANDV_GOOD;
2786 completionCode = MPT_SCANDV_SOME_ERROR;
2787 memcpy(hd->pLocal->sense, pr, sizeof(hd->pLocal->sense));
2789 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID) {
2793 /* save sense data in global structure
2795 completionCode = MPT_SCANDV_SENSE;
2796 hd->pLocal->scsiStatus = scsi_status;
2797 sense_data = ((u8 *)hd->ioc->sense_buf_pool +
2798 (req_idx * MPT_SENSE_BUFFER_ALLOC));
2800 sz = min_t(int, pReq->SenseBufferLength,
2801 SCSI_STD_SENSE_BYTES);
2802 memcpy(hd->pLocal->sense, sense_data, sz);
2804 ddvprintk((KERN_NOTICE " Check Condition, sense ptr %p\n",
2806 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_FAILED) {
2807 if (pReq->CDB[0] == INQUIRY)
2808 completionCode = MPT_SCANDV_ISSUE_SENSE;
2810 completionCode = MPT_SCANDV_DID_RESET;
2812 else if (pReply->SCSIState & MPI_SCSI_STATE_NO_SCSI_STATUS)
2813 completionCode = MPT_SCANDV_DID_RESET;
2814 else if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
2815 completionCode = MPT_SCANDV_DID_RESET;
2817 completionCode = MPT_SCANDV_GOOD;
2818 hd->pLocal->scsiStatus = scsi_status;
2822 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
2823 if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
2824 completionCode = MPT_SCANDV_DID_RESET;
2826 completionCode = MPT_SCANDV_SOME_ERROR;
2830 completionCode = MPT_SCANDV_SOME_ERROR;
2833 } /* switch(status) */
2835 ddvtprintk((KERN_NOTICE " completionCode set to %08xh\n",
2837 } /* end of address reply case */
2839 hd->pLocal->completion = completionCode;
2841 /* MF and RF are freed in mpt_interrupt
2844 /* Free Chain buffers (will never chain) in scan or dv */
2845 //mptscsih_freeChainBuffers(ioc, req_idx);
2848 * Wake up the original calling thread
2850 hd->scandv_wait_done = 1;
2851 wake_up(&hd->scandv_waitq);
2856 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2857 /* mptscsih_timer_expired - Call back for timer process.
2858 * Used only for dv functionality.
2859 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
2863 mptscsih_timer_expired(unsigned long data)
2865 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) data;
2867 ddvprintk((MYIOC_s_WARN_FMT "Timer Expired! Cmd %p\n", hd->ioc->name, hd->cmdPtr));
2870 MPIHeader_t *cmd = (MPIHeader_t *)hd->cmdPtr;
2872 if (cmd->Function == MPI_FUNCTION_SCSI_IO_REQUEST) {
2873 /* Desire to issue a task management request here.
2874 * TM requests MUST be single threaded.
2875 * If old eh code and no TM current, issue request.
2876 * If new eh code, do nothing. Wait for OS cmd timeout
2879 ddvtprintk((MYIOC_s_NOTE_FMT "DV Cmd Timeout: NoOp\n", hd->ioc->name));
2881 /* Perform a FW reload */
2882 if (mpt_HardResetHandler(hd->ioc, NO_SLEEP) < 0) {
2883 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", hd->ioc->name);
2887 /* This should NEVER happen */
2888 printk(MYIOC_s_WARN_FMT "Null cmdPtr!!!!\n", hd->ioc->name);
2891 /* No more processing.
2892 * TM call will generate an interrupt for SCSI TM Management.
2893 * The FW will reply to all outstanding commands, callback will finish cleanup.
2894 * Hard reset clean-up will free all resources.
2896 ddvprintk((MYIOC_s_WARN_FMT "Timer Expired Complete!\n", hd->ioc->name));
2902 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2904 * mptscsih_do_cmd - Do internal command.
2905 * @hd: MPT_SCSI_HOST pointer
2906 * @io: INTERNAL_CMD pointer.
2908 * Issue the specified internally generated command and do command
2909 * specific cleanup. For bus scan / DV only.
2910 * NOTES: If command is Inquiry and status is good,
2911 * initialize a target structure, save the data
2913 * Remark: Single threaded access only.
2916 * < 0 if an illegal command or no resources
2920 * > 0 if command complete but some type of completion error.
2923 mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
2926 SCSIIORequest_t *pScsiReq;
2927 SCSIIORequest_t ReqCopy;
2928 int my_idx, ii, dir;
2932 char CDB[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
2935 in_isr = in_interrupt();
2937 dprintk((MYIOC_s_WARN_FMT "Internal SCSI IO request not allowed in ISR context!\n",
2943 /* Set command specific information
2948 dir = MPI_SCSIIO_CONTROL_READ;
2954 case TEST_UNIT_READY:
2956 dir = MPI_SCSIIO_CONTROL_READ;
2962 dir = MPI_SCSIIO_CONTROL_READ;
2964 CDB[4] = 1; /*Spin up the disk */
2972 dir = MPI_SCSIIO_CONTROL_READ;
2978 dir = MPI_SCSIIO_CONTROL_READ;
2980 if (io->flags & MPT_ICFLAG_ECHO) {
2986 if (io->flags & MPT_ICFLAG_BUF_CAP) {
2989 CDB[6] = (io->size >> 16) & 0xFF;
2990 CDB[7] = (io->size >> 8) & 0xFF;
2991 CDB[8] = io->size & 0xFF;
2997 dir = MPI_SCSIIO_CONTROL_WRITE;
2999 if (io->flags & MPT_ICFLAG_ECHO) {
3004 CDB[6] = (io->size >> 16) & 0xFF;
3005 CDB[7] = (io->size >> 8) & 0xFF;
3006 CDB[8] = io->size & 0xFF;
3012 dir = MPI_SCSIIO_CONTROL_READ;
3019 dir = MPI_SCSIIO_CONTROL_READ;
3024 case SYNCHRONIZE_CACHE:
3026 dir = MPI_SCSIIO_CONTROL_READ;
3028 // CDB[1] = 0x02; /* set immediate bit */
3037 /* Get and Populate a free Frame
3039 if ((mf = mpt_get_msg_frame(hd->ioc->InternalCtx, hd->ioc)) == NULL) {
3040 ddvprintk((MYIOC_s_WARN_FMT "No msg frames!\n",
3045 pScsiReq = (SCSIIORequest_t *) mf;
3047 /* Get the request index */
3048 my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3049 ADD_INDEX_LOG(my_idx); /* for debug */
3051 if (io->flags & MPT_ICFLAG_PHYS_DISK) {
3052 pScsiReq->TargetID = io->physDiskNum;
3054 pScsiReq->ChainOffset = 0;
3055 pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
3057 pScsiReq->TargetID = io->id;
3058 pScsiReq->Bus = io->channel;
3059 pScsiReq->ChainOffset = 0;
3060 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
3063 pScsiReq->CDBLength = cmdLen;
3064 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
3066 pScsiReq->Reserved = 0;
3068 pScsiReq->MsgFlags = mpt_msg_flags();
3069 /* MsgContext set in mpt_get_msg_fram call */
3071 int_to_scsilun(io->lun, (struct scsi_lun *)pScsiReq->LUN);
3073 if (io->flags & MPT_ICFLAG_TAGGED_CMD)
3074 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ);
3076 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3078 if (cmd == REQUEST_SENSE) {
3079 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3080 ddvprintk((MYIOC_s_INFO_FMT "Untagged! 0x%2x\n",
3081 hd->ioc->name, cmd));
3084 for (ii=0; ii < 16; ii++)
3085 pScsiReq->CDB[ii] = CDB[ii];
3087 pScsiReq->DataLength = cpu_to_le32(io->size);
3088 pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
3089 + (my_idx * MPT_SENSE_BUFFER_ALLOC));
3091 ddvprintk((MYIOC_s_INFO_FMT "Sending Command 0x%x for (%d:%d:%d)\n",
3092 hd->ioc->name, cmd, io->channel, io->id, io->lun));
3094 if (dir == MPI_SCSIIO_CONTROL_READ) {
3095 mpt_add_sge((char *) &pScsiReq->SGL,
3096 MPT_SGE_FLAGS_SSIMPLE_READ | io->size,
3099 mpt_add_sge((char *) &pScsiReq->SGL,
3100 MPT_SGE_FLAGS_SSIMPLE_WRITE | io->size,
3104 /* The ISR will free the request frame, but we need
3105 * the information to initialize the target. Duplicate.
3107 memcpy(&ReqCopy, pScsiReq, sizeof(SCSIIORequest_t));
3109 /* Issue this command after:
3112 * Wait until the reply has been received
3113 * ScsiScanDvCtx callback function will
3115 * set scandv_wait_done and call wake_up
3118 hd->timer.expires = jiffies + HZ*cmdTimeout;
3119 hd->scandv_wait_done = 0;
3121 /* Save cmd pointer, for resource free if timeout or
3126 add_timer(&hd->timer);
3127 mpt_put_msg_frame(hd->ioc->InternalCtx, hd->ioc, mf);
3128 wait_event(hd->scandv_waitq, hd->scandv_wait_done);
3131 rc = hd->pLocal->completion;
3132 hd->pLocal->skip = 0;
3134 /* Always set fatal error codes in some cases.
3136 if (rc == MPT_SCANDV_SELECTION_TIMEOUT)
3138 else if (rc == MPT_SCANDV_SOME_ERROR)
3142 /* This should never happen. */
3143 ddvprintk((MYIOC_s_INFO_FMT "_do_cmd: Null pLocal!!!\n",
3150 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3152 * mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
3153 * @hd: Pointer to a SCSI HOST structure
3154 * @vdevice: virtual target device
3156 * Uses the ISR, but with special processing.
3157 * MUST be single-threaded.
3161 mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
3165 /* Following parameters will not change
3168 iocmd.cmd = SYNCHRONIZE_CACHE;
3170 iocmd.physDiskNum = -1;
3172 iocmd.data_dma = -1;
3174 iocmd.rsvd = iocmd.rsvd2 = 0;
3175 iocmd.channel = vdevice->vtarget->channel;
3176 iocmd.id = vdevice->vtarget->id;
3177 iocmd.lun = vdevice->lun;
3179 if ((vdevice->vtarget->type == TYPE_DISK) &&
3180 (vdevice->configured_lun))
3181 mptscsih_do_cmd(hd, &iocmd);
3184 EXPORT_SYMBOL(mptscsih_remove);
3185 EXPORT_SYMBOL(mptscsih_shutdown);
3187 EXPORT_SYMBOL(mptscsih_suspend);
3188 EXPORT_SYMBOL(mptscsih_resume);
3190 EXPORT_SYMBOL(mptscsih_proc_info);
3191 EXPORT_SYMBOL(mptscsih_info);
3192 EXPORT_SYMBOL(mptscsih_qcmd);
3193 EXPORT_SYMBOL(mptscsih_slave_destroy);
3194 EXPORT_SYMBOL(mptscsih_slave_configure);
3195 EXPORT_SYMBOL(mptscsih_abort);
3196 EXPORT_SYMBOL(mptscsih_dev_reset);
3197 EXPORT_SYMBOL(mptscsih_bus_reset);
3198 EXPORT_SYMBOL(mptscsih_host_reset);
3199 EXPORT_SYMBOL(mptscsih_bios_param);
3200 EXPORT_SYMBOL(mptscsih_io_done);
3201 EXPORT_SYMBOL(mptscsih_taskmgmt_complete);
3202 EXPORT_SYMBOL(mptscsih_scandv_complete);
3203 EXPORT_SYMBOL(mptscsih_event_process);
3204 EXPORT_SYMBOL(mptscsih_ioc_reset);
3205 EXPORT_SYMBOL(mptscsih_change_queue_depth);
3206 EXPORT_SYMBOL(mptscsih_timer_expired);
3207 EXPORT_SYMBOL(mptscsih_TMHandler);
3209 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/