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@lsil.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 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
492 * mptscsih_io_done - Main SCSI IO callback routine registered to
493 * Fusion MPT (base) driver
494 * @ioc: Pointer to MPT_ADAPTER structure
495 * @mf: Pointer to original MPT request frame
496 * @r: Pointer to MPT reply frame (NULL if TurboReply)
498 * This routine is called from mpt.c::mpt_interrupt() at the completion
499 * of any SCSI IO request.
500 * This routine is registered with the Fusion MPT (base) driver at driver
501 * load/init time via the mpt_register() API call.
503 * Returns 1 indicating alloc'd request frame ptr should be freed.
506 mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
508 struct scsi_cmnd *sc;
510 SCSIIORequest_t *pScsiReq;
511 SCSIIOReply_t *pScsiReply;
512 u16 req_idx, req_idx_MR;
516 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
518 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
519 req_idx_MR = (mr != NULL) ?
520 le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx) : req_idx;
521 if ((req_idx != req_idx_MR) ||
522 (mf->u.frame.linkage.arg1 == 0xdeadbeaf)) {
523 printk(MYIOC_s_ERR_FMT "Received a mf that was already freed\n",
525 printk (MYIOC_s_ERR_FMT
526 "req_idx=%x req_idx_MR=%x mf=%p mr=%p sc=%p\n",
527 ioc->name, req_idx, req_idx_MR, mf, mr,
528 hd->ScsiLookup[req_idx_MR]);
532 sc = hd->ScsiLookup[req_idx];
533 hd->ScsiLookup[req_idx] = NULL;
535 MPIHeader_t *hdr = (MPIHeader_t *)mf;
537 /* Remark: writeSDP1 will use the ScsiDoneCtx
538 * If a SCSI I/O cmd, device disabled by OS and
539 * completion done. Cannot touch sc struct. Just free mem.
541 if (hdr->Function == MPI_FUNCTION_SCSI_IO_REQUEST)
542 printk(MYIOC_s_ERR_FMT "NULL ScsiCmd ptr!\n",
545 mptscsih_freeChainBuffers(ioc, req_idx);
549 if ((unsigned char *)mf != sc->host_scribble) {
550 mptscsih_freeChainBuffers(ioc, req_idx);
554 sc->host_scribble = NULL;
555 sc->result = DID_OK << 16; /* Set default reply as OK */
556 pScsiReq = (SCSIIORequest_t *) mf;
557 pScsiReply = (SCSIIOReply_t *) mr;
559 if((ioc->facts.MsgVersion >= MPI_VERSION_01_05) && pScsiReply){
560 dmfprintk((MYIOC_s_INFO_FMT
561 "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d,task-tag=%d)\n",
562 ioc->name, mf, mr, sc, req_idx, pScsiReply->TaskTag));
564 dmfprintk((MYIOC_s_INFO_FMT
565 "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n",
566 ioc->name, mf, mr, sc, req_idx));
569 if (pScsiReply == NULL) {
570 /* special context reply handling */
575 u8 scsi_state, scsi_status;
577 status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK;
578 scsi_state = pScsiReply->SCSIState;
579 scsi_status = pScsiReply->SCSIStatus;
580 xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
581 sc->resid = sc->request_bufflen - xfer_cnt;
584 * if we get a data underrun indication, yet no data was
585 * transferred and the SCSI status indicates that the
586 * command was never started, change the data underrun
589 if (status == MPI_IOCSTATUS_SCSI_DATA_UNDERRUN && xfer_cnt == 0 &&
590 (scsi_status == MPI_SCSI_STATUS_BUSY ||
591 scsi_status == MPI_SCSI_STATUS_RESERVATION_CONFLICT ||
592 scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)) {
593 status = MPI_IOCSTATUS_SUCCESS;
596 dreplyprintk((KERN_NOTICE "Reply ha=%d id=%d lun=%d:\n"
597 "IOCStatus=%04xh SCSIState=%02xh SCSIStatus=%02xh\n"
598 "resid=%d bufflen=%d xfer_cnt=%d\n",
599 ioc->id, sc->device->id, sc->device->lun,
600 status, scsi_state, scsi_status, sc->resid,
601 sc->request_bufflen, xfer_cnt));
603 if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)
604 mptscsih_copy_sense_data(sc, hd, mf, pScsiReply);
607 * Look for + dump FCP ResponseInfo[]!
609 if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID &&
610 pScsiReply->ResponseInfo) {
611 printk(KERN_NOTICE "ha=%d id=%d lun=%d: "
612 "FCP_ResponseInfo=%08xh\n",
613 ioc->id, sc->device->id, sc->device->lun,
614 le32_to_cpu(pScsiReply->ResponseInfo));
618 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
620 * Maybe: DRIVER_BUSY | SUGGEST_RETRY | DID_SOFT_ERROR (retry)
621 * But not: DID_BUS_BUSY lest one risk
622 * killing interrupt handler:-(
624 sc->result = SAM_STAT_BUSY;
627 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
628 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
629 sc->result = DID_BAD_TARGET << 16;
632 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
633 /* Spoof to SCSI Selection Timeout! */
634 if (ioc->bus_type != FC)
635 sc->result = DID_NO_CONNECT << 16;
636 /* else fibre, just stall until rescan event */
638 sc->result = DID_REQUEUE << 16;
640 if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF)
641 hd->sel_timeout[pScsiReq->TargetID]++;
643 vdev = sc->device->hostdata;
646 vtarget = vdev->vtarget;
647 if (vtarget->tflags & MPT_TARGET_FLAGS_LED_ON) {
648 mptscsih_issue_sep_command(ioc, vtarget,
649 MPI_SEP_REQ_SLOTSTATUS_UNCONFIGURED);
650 vtarget->tflags &= ~MPT_TARGET_FLAGS_LED_ON;
654 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
655 if ( ioc->bus_type == SAS ) {
656 u16 ioc_status = le16_to_cpu(pScsiReply->IOCStatus);
657 if (ioc_status & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
658 u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
659 log_info &=SAS_LOGINFO_MASK;
660 if (log_info == SAS_LOGINFO_NEXUS_LOSS) {
661 sc->result = (DID_BUS_BUSY << 16);
665 } else if (ioc->bus_type == FC) {
667 * The FC IOC may kill a request for variety of
668 * reasons, some of which may be recovered by a
669 * retry, some which are unlikely to be
670 * recovered. Return DID_ERROR instead of
671 * DID_RESET to permit retry of the command,
672 * just not an infinite number of them
674 sc->result = DID_ERROR << 16;
679 * Allow non-SAS & non-NEXUS_LOSS to drop into below code
682 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
683 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
684 /* Linux handles an unsolicited DID_RESET better
685 * than an unsolicited DID_ABORT.
687 sc->result = DID_RESET << 16;
691 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
692 sc->resid = sc->request_bufflen - xfer_cnt;
693 if((xfer_cnt==0)||(sc->underflow > xfer_cnt))
694 sc->result=DID_SOFT_ERROR << 16;
695 else /* Sufficient data transfer occurred */
696 sc->result = (DID_OK << 16) | scsi_status;
697 dreplyprintk((KERN_NOTICE
698 "RESIDUAL_MISMATCH: result=%x on id=%d\n", sc->result, sc->device->id));
701 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
703 * Do upfront check for valid SenseData and give it
706 sc->result = (DID_OK << 16) | scsi_status;
707 if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
708 /* Have already saved the status and sense data
712 if (xfer_cnt < sc->underflow) {
713 if (scsi_status == SAM_STAT_BUSY)
714 sc->result = SAM_STAT_BUSY;
716 sc->result = DID_SOFT_ERROR << 16;
718 if (scsi_state & (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)) {
721 sc->result = DID_SOFT_ERROR << 16;
723 else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
724 /* Not real sure here either... */
725 sc->result = DID_RESET << 16;
729 dreplyprintk((KERN_NOTICE " sc->underflow={report ERR if < %02xh bytes xfer'd}\n",
731 dreplyprintk((KERN_NOTICE " ActBytesXferd=%02xh\n", xfer_cnt));
734 if (scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)
735 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
739 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
741 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
742 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
743 if (scsi_status == MPI_SCSI_STATUS_BUSY)
744 sc->result = (DID_BUS_BUSY << 16) | scsi_status;
746 sc->result = (DID_OK << 16) | scsi_status;
747 if (scsi_state == 0) {
749 } else if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
751 * If running against circa 200003dd 909 MPT f/w,
752 * may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL
753 * (QUEUE_FULL) returned from device! --> get 0x0000?128
754 * and with SenseBytes set to 0.
756 if (pScsiReply->SCSIStatus == MPI_SCSI_STATUS_TASK_SET_FULL)
757 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
760 else if (scsi_state &
761 (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)
766 sc->result = DID_SOFT_ERROR << 16;
768 else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
769 /* Not real sure here either... */
770 sc->result = DID_RESET << 16;
772 else if (scsi_state & MPI_SCSI_STATE_QUEUE_TAG_REJECTED) {
773 /* Device Inq. data indicates that it supports
774 * QTags, but rejects QTag messages.
775 * This command completed OK.
777 * Not real sure here either so do nothing... */
780 if (sc->result == MPI_SCSI_STATUS_TASK_SET_FULL)
781 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
784 * Reservation Conflict, Busy,
785 * Command Terminated, CHECK
789 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
790 sc->result = DID_SOFT_ERROR << 16;
793 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
794 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
795 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
796 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
797 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
798 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
799 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
800 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
801 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
806 sc->result = DID_SOFT_ERROR << 16;
809 } /* switch(status) */
811 dreplyprintk((KERN_NOTICE " sc->result is %08xh\n", sc->result));
812 } /* end of address reply case */
814 /* Unmap the DMA buffers, if any. */
816 pci_unmap_sg(ioc->pcidev, (struct scatterlist *) sc->request_buffer,
817 sc->use_sg, sc->sc_data_direction);
818 } else if (sc->request_bufflen) {
819 pci_unmap_single(ioc->pcidev, sc->SCp.dma_handle,
820 sc->request_bufflen, sc->sc_data_direction);
823 sc->scsi_done(sc); /* Issue the command callback */
825 /* Free Chain buffers */
826 mptscsih_freeChainBuffers(ioc, req_idx);
831 * mptscsih_flush_running_cmds - For each command found, search
832 * Scsi_Host instance taskQ and reply to OS.
833 * Called only if recovering from a FW reload.
834 * @hd: Pointer to a SCSI HOST structure
838 * Must be called while new I/Os are being queued.
841 mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
843 MPT_ADAPTER *ioc = hd->ioc;
844 struct scsi_cmnd *SCpnt;
847 int max = ioc->req_depth;
849 dprintk((KERN_INFO MYNAM ": flush_ScsiLookup called\n"));
850 for (ii= 0; ii < max; ii++) {
851 if ((SCpnt = hd->ScsiLookup[ii]) != NULL) {
856 /* Null ScsiLookup index
858 hd->ScsiLookup[ii] = NULL;
860 mf = MPT_INDEX_2_MFPTR(ioc, ii);
861 dmfprintk(( "flush: ScsiDone (mf=%p,sc=%p)\n",
864 /* Free Chain buffers */
865 mptscsih_freeChainBuffers(ioc, ii);
867 /* Free Message frames */
868 mpt_free_msg_frame(ioc, mf);
870 if ((unsigned char *)mf != SCpnt->host_scribble)
873 /* Set status, free OS resources (SG DMA buffers)
877 pci_unmap_sg(ioc->pcidev,
878 (struct scatterlist *) SCpnt->request_buffer,
880 SCpnt->sc_data_direction);
881 } else if (SCpnt->request_bufflen) {
882 pci_unmap_single(ioc->pcidev,
883 SCpnt->SCp.dma_handle,
884 SCpnt->request_bufflen,
885 SCpnt->sc_data_direction);
887 SCpnt->result = DID_RESET << 16;
888 SCpnt->host_scribble = NULL;
890 SCpnt->scsi_done(SCpnt); /* Issue the command callback */
898 * mptscsih_search_running_cmds - Delete any commands associated
899 * with the specified target and lun. Function called only
900 * when a lun is disable by mid-layer.
901 * Do NOT access the referenced scsi_cmnd structure or
902 * members. Will cause either a paging or NULL ptr error.
903 * (BUT, BUT, BUT, the code does reference it! - mdr)
904 * @hd: Pointer to a SCSI HOST structure
905 * @vdevice: per device private data
909 * Called from slave_destroy.
912 mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
914 SCSIIORequest_t *mf = NULL;
916 int max = hd->ioc->req_depth;
917 struct scsi_cmnd *sc;
920 dsprintk((KERN_INFO MYNAM ": search_running channel %d id %d lun %d max %d\n",
921 vdevice->vtarget->channel, vdevice->vtarget->id, vdevice->lun, max));
923 for (ii=0; ii < max; ii++) {
924 if ((sc = hd->ScsiLookup[ii]) != NULL) {
926 mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii);
929 int_to_scsilun(vdevice->lun, &lun);
930 if ((mf->Bus != vdevice->vtarget->channel) ||
931 (mf->TargetID != vdevice->vtarget->id) ||
932 memcmp(lun.scsi_lun, mf->LUN, 8))
934 dsprintk(( "search_running: found (sc=%p, mf = %p) "
935 "channel %d id %d, lun %d \n", hd->ScsiLookup[ii],
936 mf, mf->Bus, mf->TargetID, vdevice->lun));
940 hd->ScsiLookup[ii] = NULL;
941 mptscsih_freeChainBuffers(hd->ioc, ii);
942 mpt_free_msg_frame(hd->ioc, (MPT_FRAME_HDR *)mf);
943 if ((unsigned char *)mf != sc->host_scribble)
946 pci_unmap_sg(hd->ioc->pcidev,
947 (struct scatterlist *) sc->request_buffer,
949 sc->sc_data_direction);
950 } else if (sc->request_bufflen) {
951 pci_unmap_single(hd->ioc->pcidev,
954 sc->sc_data_direction);
956 sc->host_scribble = NULL;
957 sc->result = DID_NO_CONNECT << 16;
964 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
966 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
968 * mptscsih_report_queue_full - Report QUEUE_FULL status returned
969 * from a SCSI target device.
970 * @sc: Pointer to scsi_cmnd structure
971 * @pScsiReply: Pointer to SCSIIOReply_t
972 * @pScsiReq: Pointer to original SCSI request
974 * This routine periodically reports QUEUE_FULL status returned from a
975 * SCSI target device. It reports this to the console via kernel
976 * printk() API call, not more than once every 10 seconds.
979 mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq)
984 if (sc->device == NULL)
986 if (sc->device->host == NULL)
988 if ((hd = (MPT_SCSI_HOST *)sc->device->host->hostdata) == NULL)
991 if (time - hd->last_queue_full > 10 * HZ) {
992 dprintk((MYIOC_s_WARN_FMT "Device (%d:%d:%d) reported QUEUE_FULL!\n",
993 hd->ioc->name, 0, sc->device->id, sc->device->lun));
994 hd->last_queue_full = time;
998 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1000 * mptscsih_remove - Removed scsi devices
1001 * @pdev: Pointer to pci_dev structure
1006 mptscsih_remove(struct pci_dev *pdev)
1008 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1009 struct Scsi_Host *host = ioc->sh;
1018 scsi_remove_host(host);
1020 if((hd = (MPT_SCSI_HOST *)host->hostdata) == NULL)
1023 mptscsih_shutdown(pdev);
1027 if (hd->ScsiLookup != NULL) {
1028 sz1 = hd->ioc->req_depth * sizeof(void *);
1029 kfree(hd->ScsiLookup);
1030 hd->ScsiLookup = NULL;
1033 dprintk((MYIOC_s_INFO_FMT
1034 "Free'd ScsiLookup (%d) memory\n",
1035 hd->ioc->name, sz1));
1037 kfree(hd->info_kbuf);
1039 /* NULL the Scsi_Host pointer
1043 scsi_host_put(host);
1049 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1051 * mptscsih_shutdown - reboot notifier
1055 mptscsih_shutdown(struct pci_dev *pdev)
1057 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1058 struct Scsi_Host *host = ioc->sh;
1064 hd = (MPT_SCSI_HOST *)host->hostdata;
1069 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1071 * mptscsih_suspend - Fusion MPT scsi driver suspend routine.
1076 mptscsih_suspend(struct pci_dev *pdev, pm_message_t state)
1078 mptscsih_shutdown(pdev);
1079 return mpt_suspend(pdev,state);
1082 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1084 * mptscsih_resume - Fusion MPT scsi driver resume routine.
1089 mptscsih_resume(struct pci_dev *pdev)
1091 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1092 struct Scsi_Host *host = ioc->sh;
1100 hd = (MPT_SCSI_HOST *)host->hostdata;
1109 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1111 * mptscsih_info - Return information about MPT adapter
1112 * @SChost: Pointer to Scsi_Host structure
1114 * (linux scsi_host_template.info routine)
1116 * Returns pointer to buffer where information was written.
1119 mptscsih_info(struct Scsi_Host *SChost)
1124 h = (MPT_SCSI_HOST *)SChost->hostdata;
1127 if (h->info_kbuf == NULL)
1128 if ((h->info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)
1129 return h->info_kbuf;
1130 h->info_kbuf[0] = '\0';
1132 mpt_print_ioc_summary(h->ioc, h->info_kbuf, &size, 0, 0);
1133 h->info_kbuf[size-1] = '\0';
1136 return h->info_kbuf;
1147 mptscsih_copy_mem_info(struct info_str *info, char *data, int len)
1149 if (info->pos + len > info->length)
1150 len = info->length - info->pos;
1152 if (info->pos + len < info->offset) {
1157 if (info->pos < info->offset) {
1158 data += (info->offset - info->pos);
1159 len -= (info->offset - info->pos);
1163 memcpy(info->buffer + info->pos, data, len);
1169 mptscsih_copy_info(struct info_str *info, char *fmt, ...)
1175 va_start(args, fmt);
1176 len = vsprintf(buf, fmt, args);
1179 mptscsih_copy_mem_info(info, buf, len);
1184 mptscsih_host_info(MPT_ADAPTER *ioc, char *pbuf, off_t offset, int len)
1186 struct info_str info;
1190 info.offset = offset;
1193 mptscsih_copy_info(&info, "%s: %s, ", ioc->name, ioc->prod_name);
1194 mptscsih_copy_info(&info, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING, ioc->facts.FWVersion.Word);
1195 mptscsih_copy_info(&info, "Ports=%d, ", ioc->facts.NumberOfPorts);
1196 mptscsih_copy_info(&info, "MaxQ=%d\n", ioc->req_depth);
1198 return ((info.pos > info.offset) ? info.pos - info.offset : 0);
1201 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1203 * mptscsih_proc_info - Return information about MPT adapter
1204 * @host: scsi host struct
1205 * @buffer: if write, user data; if read, buffer for user
1206 * @start: returns the buffer address
1207 * @offset: if write, 0; if read, the current offset into the buffer from
1208 * the previous read.
1209 * @length: if write, return length;
1210 * @func: write = 1; read = 0
1212 * (linux scsi_host_template.info routine)
1215 mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
1216 int length, int func)
1218 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
1219 MPT_ADAPTER *ioc = hd->ioc;
1224 * write is not supported
1230 size = mptscsih_host_info(ioc, buffer, offset, length);
1236 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1237 #define ADD_INDEX_LOG(req_ent) do { } while(0)
1239 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1241 * mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine.
1242 * @SCpnt: Pointer to scsi_cmnd structure
1243 * @done: Pointer SCSI mid-layer IO completion function
1245 * (linux scsi_host_template.queuecommand routine)
1246 * This is the primary SCSI IO start routine. Create a MPI SCSIIORequest
1247 * from a linux scsi_cmnd request and send it to the IOC.
1249 * Returns 0. (rtn value discarded by linux scsi mid-layer)
1252 mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1256 SCSIIORequest_t *pScsiReq;
1257 VirtDevice *vdev = SCpnt->device->hostdata;
1266 hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata;
1267 lun = SCpnt->device->lun;
1268 SCpnt->scsi_done = done;
1270 dmfprintk((MYIOC_s_INFO_FMT "qcmd: SCpnt=%p, done()=%p\n",
1271 (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt, done));
1273 if (hd->resetPending) {
1274 dtmprintk((MYIOC_s_WARN_FMT "qcmd: SCpnt=%p timeout + 60HZ\n",
1275 (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt));
1276 return SCSI_MLQUEUE_HOST_BUSY;
1280 * Put together a MPT SCSI request...
1282 if ((mf = mpt_get_msg_frame(hd->ioc->DoneCtx, hd->ioc)) == NULL) {
1283 dprintk((MYIOC_s_WARN_FMT "QueueCmd, no msg frames!!\n",
1285 return SCSI_MLQUEUE_HOST_BUSY;
1288 pScsiReq = (SCSIIORequest_t *) mf;
1290 my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
1292 ADD_INDEX_LOG(my_idx);
1294 /* TUR's being issued with scsictl=0x02000000 (DATA_IN)!
1295 * Seems we may receive a buffer (datalen>0) even when there
1296 * will be no data transfer! GRRRRR...
1298 if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
1299 datalen = SCpnt->request_bufflen;
1300 scsidir = MPI_SCSIIO_CONTROL_READ; /* DATA IN (host<--ioc<--dev) */
1301 } else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
1302 datalen = SCpnt->request_bufflen;
1303 scsidir = MPI_SCSIIO_CONTROL_WRITE; /* DATA OUT (host-->ioc-->dev) */
1306 scsidir = MPI_SCSIIO_CONTROL_NODATATRANSFER;
1309 /* Default to untagged. Once a target structure has been allocated,
1310 * use the Inquiry data to determine if device supports tagged.
1313 && (vdev->vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)
1314 && (SCpnt->device->tagged_supported)) {
1315 scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
1317 scsictl = scsidir | MPI_SCSIIO_CONTROL_UNTAGGED;
1320 /* Use the above information to set up the message frame
1322 pScsiReq->TargetID = (u8) vdev->vtarget->id;
1323 pScsiReq->Bus = vdev->vtarget->channel;
1324 pScsiReq->ChainOffset = 0;
1325 if (vdev->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
1326 pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
1328 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
1329 pScsiReq->CDBLength = SCpnt->cmd_len;
1330 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
1331 pScsiReq->Reserved = 0;
1332 pScsiReq->MsgFlags = mpt_msg_flags();
1333 int_to_scsilun(SCpnt->device->lun, (struct scsi_lun *)pScsiReq->LUN);
1334 pScsiReq->Control = cpu_to_le32(scsictl);
1337 * Write SCSI CDB into the message
1339 cmd_len = SCpnt->cmd_len;
1340 for (ii=0; ii < cmd_len; ii++)
1341 pScsiReq->CDB[ii] = SCpnt->cmnd[ii];
1343 for (ii=cmd_len; ii < 16; ii++)
1344 pScsiReq->CDB[ii] = 0;
1347 pScsiReq->DataLength = cpu_to_le32(datalen);
1349 /* SenseBuffer low address */
1350 pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
1351 + (my_idx * MPT_SENSE_BUFFER_ALLOC));
1353 /* Now add the SG list
1354 * Always have a SGE even if null length.
1357 /* Add a NULL SGE */
1358 mptscsih_add_sge((char *)&pScsiReq->SGL, MPT_SGE_FLAGS_SSIMPLE_READ | 0,
1361 /* Add a 32 or 64 bit SGE */
1362 if (mptscsih_AddSGE(hd->ioc, SCpnt, pScsiReq, my_idx) != SUCCESS)
1366 SCpnt->host_scribble = (unsigned char *)mf;
1367 hd->ScsiLookup[my_idx] = SCpnt;
1369 mpt_put_msg_frame(hd->ioc->DoneCtx, hd->ioc, mf);
1370 dmfprintk((MYIOC_s_INFO_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n",
1371 hd->ioc->name, SCpnt, mf, my_idx));
1372 DBG_DUMP_REQUEST_FRAME(mf)
1376 hd->ScsiLookup[my_idx] = NULL;
1377 mptscsih_freeChainBuffers(hd->ioc, my_idx);
1378 mpt_free_msg_frame(hd->ioc, mf);
1379 return SCSI_MLQUEUE_HOST_BUSY;
1382 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1384 * mptscsih_freeChainBuffers - Function to free chain buffers associated
1385 * with a SCSI IO request
1386 * @hd: Pointer to the MPT_SCSI_HOST instance
1387 * @req_idx: Index of the SCSI IO request frame.
1389 * Called if SG chain buffer allocation fails and mptscsih callbacks.
1393 mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
1395 MPT_FRAME_HDR *chain;
1396 unsigned long flags;
1400 /* Get the first chain index and reset
1403 chain_idx = ioc->ReqToChain[req_idx];
1404 ioc->ReqToChain[req_idx] = MPT_HOST_NO_CHAIN;
1406 while (chain_idx != MPT_HOST_NO_CHAIN) {
1408 /* Save the next chain buffer index */
1409 next = ioc->ChainToChain[chain_idx];
1411 /* Free this chain buffer and reset
1414 ioc->ChainToChain[chain_idx] = MPT_HOST_NO_CHAIN;
1416 chain = (MPT_FRAME_HDR *) (ioc->ChainBuffer
1417 + (chain_idx * ioc->req_sz));
1419 spin_lock_irqsave(&ioc->FreeQlock, flags);
1420 list_add_tail(&chain->u.frame.linkage.list, &ioc->FreeChainQ);
1421 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1423 dmfprintk((MYIOC_s_INFO_FMT "FreeChainBuffers (index %d)\n",
1424 ioc->name, chain_idx));
1432 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1437 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1439 * mptscsih_TMHandler - Generic handler for SCSI Task Management.
1440 * Fall through to mpt_HardResetHandler if: not operational, too many
1441 * failed TM requests or handshake failure.
1443 * @ioc: Pointer to MPT_ADAPTER structure
1444 * @type: Task Management type
1445 * @id: Logical Target ID for reset (if appropriate)
1446 * @lun: Logical Unit for reset (if appropriate)
1447 * @ctx2abort: Context for the task to be aborted (if appropriate)
1449 * Remark: Currently invoked from a non-interrupt thread (_bh).
1451 * Remark: With old EH code, at most 1 SCSI TaskMgmt function per IOC
1454 * Returns 0 for SUCCESS or -1 if FAILED.
1457 mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout)
1463 unsigned long flags;
1465 /* If FW is being reloaded currently, return success to
1466 * the calling function.
1473 printk(KERN_ERR MYNAM " TMHandler" " NULL ioc!\n");
1476 dtmprintk((MYIOC_s_INFO_FMT "TMHandler Entered!\n", ioc->name));
1478 // SJR - CHECKME - Can we avoid this here?
1479 // (mpt_HardResetHandler has this check...)
1480 spin_lock_irqsave(&ioc->diagLock, flags);
1481 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)) {
1482 spin_unlock_irqrestore(&ioc->diagLock, flags);
1485 spin_unlock_irqrestore(&ioc->diagLock, flags);
1487 /* Wait a fixed amount of time for the TM pending flag to be cleared.
1488 * If we time out and not bus reset, then we return a FAILED status to the caller.
1489 * The call to mptscsih_tm_pending_wait() will set the pending flag if we are
1490 * successful. Otherwise, reload the FW.
1492 if (mptscsih_tm_pending_wait(hd) == FAILED) {
1493 if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
1494 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler abort: "
1495 "Timed out waiting for last TM (%d) to complete! \n",
1496 hd->ioc->name, hd->tmPending));
1498 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) {
1499 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler target reset: "
1500 "Timed out waiting for last TM (%d) to complete! \n",
1501 hd->ioc->name, hd->tmPending));
1503 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
1504 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler bus reset: "
1505 "Timed out waiting for last TM (%d) to complete! \n",
1506 hd->ioc->name, hd->tmPending));
1507 if (hd->tmPending & (1 << MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS))
1513 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
1514 hd->tmPending |= (1 << type);
1515 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1520 ioc_raw_state = mpt_GetIocState(hd->ioc, 0);
1522 #ifdef MPT_DEBUG_RESET
1523 if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) {
1524 printk(MYIOC_s_WARN_FMT
1525 "TM Handler: IOC Not operational(0x%x)!\n",
1526 hd->ioc->name, ioc_raw_state);
1530 if (doTask && ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL)
1531 && !(ioc_raw_state & MPI_DOORBELL_ACTIVE)) {
1533 /* Isse the Task Mgmt request.
1535 if (hd->hard_resets < -1)
1537 rc = mptscsih_IssueTaskMgmt(hd, type, channel, id, lun, ctx2abort, timeout);
1539 printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n", hd->ioc->name);
1541 dtmprintk((MYIOC_s_INFO_FMT "Issue of TaskMgmt Successful!\n", hd->ioc->name));
1545 /* Only fall through to the HRH if this is a bus reset
1547 if ((type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) && (rc ||
1548 ioc->reload_fw || (ioc->alt_ioc && ioc->alt_ioc->reload_fw))) {
1549 dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
1551 rc = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
1555 * Check IOCStatus from TM reply message
1557 if (hd->tm_iocstatus != MPI_IOCSTATUS_SUCCESS)
1560 dtmprintk((MYIOC_s_INFO_FMT "TMHandler rc = %d!\n", hd->ioc->name, rc));
1566 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1568 * mptscsih_IssueTaskMgmt - Generic send Task Management function.
1569 * @hd: Pointer to MPT_SCSI_HOST structure
1570 * @type: Task Management type
1571 * @id: Logical Target ID for reset (if appropriate)
1572 * @lun: Logical Unit for reset (if appropriate)
1573 * @ctx2abort: Context for the task to be aborted (if appropriate)
1575 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
1576 * or a non-interrupt thread. In the former, must not call schedule().
1578 * Not all fields are meaningfull for all task types.
1580 * Returns 0 for SUCCESS, -999 for "no msg frames",
1581 * else other non-zero value returned.
1584 mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout)
1587 SCSITaskMgmt_t *pScsiTm;
1591 /* Return Fail to calling function if no message frames available.
1593 if ((mf = mpt_get_msg_frame(hd->ioc->TaskCtx, hd->ioc)) == NULL) {
1594 dfailprintk((MYIOC_s_ERR_FMT "IssueTaskMgmt, no msg frames!!\n",
1598 dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt request @ %p\n",
1599 hd->ioc->name, mf));
1601 /* Format the Request
1603 pScsiTm = (SCSITaskMgmt_t *) mf;
1604 pScsiTm->TargetID = id;
1605 pScsiTm->Bus = channel;
1606 pScsiTm->ChainOffset = 0;
1607 pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
1609 pScsiTm->Reserved = 0;
1610 pScsiTm->TaskType = type;
1611 pScsiTm->Reserved1 = 0;
1612 pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)
1613 ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0;
1615 int_to_scsilun(lun, (struct scsi_lun *)pScsiTm->LUN);
1617 for (ii=0; ii < 7; ii++)
1618 pScsiTm->Reserved2[ii] = 0;
1620 pScsiTm->TaskMsgContext = ctx2abort;
1622 dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt: ctx2abort (0x%08x) type=%d\n",
1623 hd->ioc->name, ctx2abort, type));
1625 DBG_DUMP_TM_REQUEST_FRAME((u32 *)pScsiTm);
1627 if ((retval = mpt_send_handshake_request(hd->ioc->TaskCtx, hd->ioc,
1628 sizeof(SCSITaskMgmt_t), (u32*)pScsiTm,
1630 dfailprintk((MYIOC_s_ERR_FMT "_send_handshake FAILED!"
1631 " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
1633 mpt_free_msg_frame(hd->ioc, mf);
1637 if(mptscsih_tm_wait_for_completion(hd, timeout) == FAILED) {
1638 dfailprintk((MYIOC_s_ERR_FMT "_wait_for_completion FAILED!"
1639 " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
1641 mpt_free_msg_frame(hd->ioc, mf);
1642 dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
1644 retval = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
1651 mptscsih_get_tm_timeout(MPT_ADAPTER *ioc)
1653 switch (ioc->bus_type) {
1664 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1666 * mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant
1667 * @SCpnt: Pointer to scsi_cmnd structure, IO to be aborted
1669 * (linux scsi_host_template.eh_abort_handler routine)
1671 * Returns SUCCESS or FAILED.
1674 mptscsih_abort(struct scsi_cmnd * SCpnt)
1682 ulong sn = SCpnt->serial_number;
1684 /* If we can't locate our host adapter structure, return FAILED status.
1686 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL) {
1687 SCpnt->result = DID_RESET << 16;
1688 SCpnt->scsi_done(SCpnt);
1689 dfailprintk((KERN_INFO MYNAM ": mptscsih_abort: "
1690 "Can't locate host! (sc=%p)\n",
1695 /* Find this command
1697 if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) {
1698 /* Cmd not found in ScsiLookup.
1701 SCpnt->result = DID_RESET << 16;
1702 dtmprintk((KERN_INFO MYNAM ": %s: mptscsih_abort: "
1703 "Command not in the active list! (sc=%p)\n",
1704 hd->ioc->name, SCpnt));
1708 if (hd->resetPending) {
1712 if (hd->timeouts < -1)
1715 printk(KERN_WARNING MYNAM ": %s: attempting task abort! (sc=%p)\n",
1716 hd->ioc->name, SCpnt);
1717 scsi_print_command(SCpnt);
1719 /* Most important! Set TaskMsgContext to SCpnt's MsgContext!
1720 * (the IO to be ABORT'd)
1722 * NOTE: Since we do not byteswap MsgContext, we do not
1723 * swap it here either. It is an opaque cookie to
1724 * the controller, so it does not matter. -DaveM
1726 mf = MPT_INDEX_2_MFPTR(hd->ioc, scpnt_idx);
1727 ctx2abort = mf->u.frame.hwhdr.msgctxu.MsgContext;
1729 hd->abortSCpnt = SCpnt;
1731 vdev = SCpnt->device->hostdata;
1732 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
1733 vdev->vtarget->channel, vdev->vtarget->id, vdev->lun,
1734 ctx2abort, mptscsih_get_tm_timeout(hd->ioc));
1736 if (SCPNT_TO_LOOKUP_IDX(SCpnt) == scpnt_idx &&
1737 SCpnt->serial_number == sn) {
1741 printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n",
1743 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1748 if(retval != FAILED ) {
1750 hd->tmState = TM_STATE_NONE;
1755 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1757 * mptscsih_dev_reset - Perform a SCSI TARGET_RESET! new_eh variant
1758 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1760 * (linux scsi_host_template.eh_dev_reset_handler routine)
1762 * Returns SUCCESS or FAILED.
1765 mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
1771 /* If we can't locate our host adapter structure, return FAILED status.
1773 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1774 dtmprintk((KERN_INFO MYNAM ": mptscsih_dev_reset: "
1775 "Can't locate host! (sc=%p)\n",
1780 if (hd->resetPending)
1783 printk(KERN_WARNING MYNAM ": %s: attempting target reset! (sc=%p)\n",
1784 hd->ioc->name, SCpnt);
1785 scsi_print_command(SCpnt);
1787 vdev = SCpnt->device->hostdata;
1788 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
1789 vdev->vtarget->channel, vdev->vtarget->id,
1790 0, 0, mptscsih_get_tm_timeout(hd->ioc));
1792 printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n",
1794 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1799 if(retval != FAILED ) {
1801 hd->tmState = TM_STATE_NONE;
1806 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1808 * mptscsih_bus_reset - Perform a SCSI BUS_RESET! new_eh variant
1809 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1811 * (linux scsi_host_template.eh_bus_reset_handler routine)
1813 * Returns SUCCESS or FAILED.
1816 mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
1822 /* If we can't locate our host adapter structure, return FAILED status.
1824 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1825 dtmprintk((KERN_INFO MYNAM ": mptscsih_bus_reset: "
1826 "Can't locate host! (sc=%p)\n",
1831 printk(KERN_WARNING MYNAM ": %s: attempting bus reset! (sc=%p)\n",
1832 hd->ioc->name, SCpnt);
1833 scsi_print_command(SCpnt);
1835 if (hd->timeouts < -1)
1838 vdev = SCpnt->device->hostdata;
1839 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
1840 vdev->vtarget->channel, 0, 0, 0, mptscsih_get_tm_timeout(hd->ioc));
1842 printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n",
1844 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1849 if(retval != FAILED ) {
1851 hd->tmState = TM_STATE_NONE;
1856 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1858 * mptscsih_host_reset - Perform a SCSI host adapter RESET (new_eh variant)
1859 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1861 * (linux scsi_host_template.eh_host_reset_handler routine)
1863 * Returns SUCCESS or FAILED.
1866 mptscsih_host_reset(struct scsi_cmnd *SCpnt)
1869 int status = SUCCESS;
1871 /* If we can't locate the host to reset, then we failed. */
1872 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1873 dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
1874 "Can't locate host! (sc=%p)\n",
1879 printk(KERN_WARNING MYNAM ": %s: Attempting host reset! (sc=%p)\n",
1880 hd->ioc->name, SCpnt);
1882 /* If our attempts to reset the host failed, then return a failed
1883 * status. The host will be taken off line by the SCSI mid-layer.
1885 if (mpt_HardResetHandler(hd->ioc, CAN_SLEEP) < 0){
1888 /* Make sure TM pending is cleared and TM state is set to
1892 hd->tmState = TM_STATE_NONE;
1895 dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
1897 (status == SUCCESS) ? "SUCCESS" : "FAILED" ) );
1902 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1904 * mptscsih_tm_pending_wait - wait for pending task management request to complete
1905 * @hd: Pointer to MPT host structure.
1907 * Returns {SUCCESS,FAILED}.
1910 mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd)
1912 unsigned long flags;
1913 int loop_count = 4 * 10; /* Wait 10 seconds */
1914 int status = FAILED;
1917 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
1918 if (hd->tmState == TM_STATE_NONE) {
1919 hd->tmState = TM_STATE_IN_PROGRESS;
1921 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1925 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1927 } while (--loop_count);
1932 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1934 * mptscsih_tm_wait_for_completion - wait for completion of TM task
1935 * @hd: Pointer to MPT host structure.
1936 * @timeout: timeout in seconds
1938 * Returns {SUCCESS,FAILED}.
1941 mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout )
1943 unsigned long flags;
1944 int loop_count = 4 * timeout;
1945 int status = FAILED;
1948 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
1949 if(hd->tmPending == 0) {
1951 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1954 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1956 } while (--loop_count);
1961 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1963 mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code)
1967 switch (response_code) {
1968 case MPI_SCSITASKMGMT_RSP_TM_COMPLETE:
1969 desc = "The task completed.";
1971 case MPI_SCSITASKMGMT_RSP_INVALID_FRAME:
1972 desc = "The IOC received an invalid frame status.";
1974 case MPI_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED:
1975 desc = "The task type is not supported.";
1977 case MPI_SCSITASKMGMT_RSP_TM_FAILED:
1978 desc = "The requested task failed.";
1980 case MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED:
1981 desc = "The task completed successfully.";
1983 case MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN:
1984 desc = "The LUN request is invalid.";
1986 case MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC:
1987 desc = "The task is in the IOC queue and has not been sent to target.";
1993 printk(MYIOC_s_INFO_FMT "Response Code(0x%08x): F/W: %s\n",
1994 ioc->name, response_code, desc);
1997 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1999 * mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
2000 * @ioc: Pointer to MPT_ADAPTER structure
2001 * @mf: Pointer to SCSI task mgmt request frame
2002 * @mr: Pointer to SCSI task mgmt reply frame
2004 * This routine is called from mptbase.c::mpt_interrupt() at the completion
2005 * of any SCSI task management request.
2006 * This routine is registered with the MPT (base) driver at driver
2007 * load/init time via the mpt_register() API call.
2009 * Returns 1 indicating alloc'd request frame ptr should be freed.
2012 mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
2014 SCSITaskMgmtReply_t *pScsiTmReply;
2015 SCSITaskMgmt_t *pScsiTmReq;
2017 unsigned long flags;
2021 dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt completed (mf=%p,mr=%p)\n",
2022 ioc->name, mf, mr));
2024 /* Depending on the thread, a timer is activated for
2025 * the TM request. Delete this timer on completion of TM.
2026 * Decrement count of outstanding TM requests.
2028 hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
2030 dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt Complete: NULL Scsi Host Ptr\n",
2036 dtmprintk((MYIOC_s_WARN_FMT "ERROR! TaskMgmt Reply: NULL Request %p\n",
2040 pScsiTmReply = (SCSITaskMgmtReply_t*)mr;
2041 pScsiTmReq = (SCSITaskMgmt_t*)mf;
2043 /* Figure out if this was ABORT_TASK, TARGET_RESET, or BUS_RESET! */
2044 tmType = pScsiTmReq->TaskType;
2046 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05 &&
2047 pScsiTmReply->ResponseCode)
2048 mptscsih_taskmgmt_response_code(ioc,
2049 pScsiTmReply->ResponseCode);
2051 dtmprintk((MYIOC_s_WARN_FMT " TaskType = %d, TerminationCount=%d\n",
2052 ioc->name, tmType, le32_to_cpu(pScsiTmReply->TerminationCount)));
2053 DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply);
2055 iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2056 hd->tm_iocstatus = iocstatus;
2057 dtmprintk((MYIOC_s_WARN_FMT " SCSI TaskMgmt (%d) IOCStatus=%04x IOCLogInfo=%08x\n",
2058 ioc->name, tmType, iocstatus, le32_to_cpu(pScsiTmReply->IOCLogInfo)));
2059 /* Error? (anything non-zero?) */
2062 /* clear flags and continue.
2064 if (tmType == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK)
2065 hd->abortSCpnt = NULL;
2067 /* If an internal command is present
2068 * or the TM failed - reload the FW.
2069 * FC FW may respond FAILED to an ABORT
2071 if (tmType == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
2073 (iocstatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED)) {
2074 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0) {
2075 printk((KERN_WARNING
2076 " Firmware Reload FAILED!!\n"));
2081 dtmprintk((MYIOC_s_WARN_FMT " TaskMgmt SUCCESS\n", ioc->name));
2083 hd->abortSCpnt = NULL;
2088 spin_lock_irqsave(&ioc->FreeQlock, flags);
2090 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2091 hd->tmState = TM_STATE_NONE;
2096 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2098 * This is anyones guess quite frankly.
2101 mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
2102 sector_t capacity, int geom[])
2112 dummy = heads * sectors;
2113 cylinders = capacity;
2114 sector_div(cylinders,dummy);
2117 * Handle extended translation size for logical drives
2120 if ((ulong)capacity >= 0x200000) {
2123 dummy = heads * sectors;
2124 cylinders = capacity;
2125 sector_div(cylinders,dummy);
2131 geom[2] = cylinders;
2133 dprintk((KERN_NOTICE
2134 ": bios_param: Id=%i Lun=%i Channel=%i CHS=%i/%i/%i\n",
2135 sdev->id, sdev->lun, sdev->channel, (int)cylinders, heads, sectors));
2140 /* Search IOC page 3 to determine if this is hidden physical disk
2144 mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id)
2149 if (!ioc->raid_data.pIocPg3)
2151 for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2152 if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) &&
2153 (channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) {
2162 EXPORT_SYMBOL(mptscsih_is_phys_disk);
2165 mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id)
2170 if (!ioc->raid_data.pIocPg3)
2172 for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2173 if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) &&
2174 (channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) {
2175 rc = ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum;
2183 EXPORT_SYMBOL(mptscsih_raid_id_to_num);
2186 * OS entry point to allow for host driver to free allocated memory
2187 * Called if no device present or device being unloaded
2190 mptscsih_slave_destroy(struct scsi_device *sdev)
2192 struct Scsi_Host *host = sdev->host;
2193 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
2194 VirtTarget *vtarget;
2195 VirtDevice *vdevice;
2196 struct scsi_target *starget;
2198 starget = scsi_target(sdev);
2199 vtarget = starget->hostdata;
2200 vdevice = sdev->hostdata;
2202 mptscsih_search_running_cmds(hd, vdevice);
2203 vtarget->num_luns--;
2204 mptscsih_synchronize_cache(hd, vdevice);
2206 sdev->hostdata = NULL;
2209 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2211 * mptscsih_change_queue_depth - This function will set a devices queue depth
2212 * @sdev: per scsi_device pointer
2213 * @qdepth: requested queue depth
2215 * Adding support for new 'change_queue_depth' api.
2218 mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
2220 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sdev->host->hostdata;
2221 VirtTarget *vtarget;
2222 struct scsi_target *starget;
2226 starget = scsi_target(sdev);
2227 vtarget = starget->hostdata;
2229 if (hd->ioc->bus_type == SPI) {
2230 if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
2232 else if (sdev->type == TYPE_DISK &&
2233 vtarget->minSyncFactor <= MPT_ULTRA160)
2234 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2236 max_depth = MPT_SCSI_CMD_PER_DEV_LOW;
2238 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2240 if (qdepth > max_depth)
2245 tagged = MSG_SIMPLE_TAG;
2247 scsi_adjust_queue_depth(sdev, tagged, qdepth);
2248 return sdev->queue_depth;
2252 * OS entry point to adjust the queue_depths on a per-device basis.
2253 * Called once per device the bus scan. Use it to force the queue_depth
2254 * member to 1 if a device does not support Q tags.
2255 * Return non-zero if fails.
2258 mptscsih_slave_configure(struct scsi_device *sdev)
2260 struct Scsi_Host *sh = sdev->host;
2261 VirtTarget *vtarget;
2262 VirtDevice *vdevice;
2263 struct scsi_target *starget;
2264 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sh->hostdata;
2266 starget = scsi_target(sdev);
2267 vtarget = starget->hostdata;
2268 vdevice = sdev->hostdata;
2270 dsprintk((MYIOC_s_INFO_FMT
2271 "device @ %p, channel=%d, id=%d, lun=%d\n",
2272 hd->ioc->name, sdev, sdev->channel, sdev->id, sdev->lun));
2273 if (hd->ioc->bus_type == SPI)
2274 dsprintk((MYIOC_s_INFO_FMT
2275 "sdtr %d wdtr %d ppr %d inq length=%d\n",
2276 hd->ioc->name, sdev->sdtr, sdev->wdtr,
2277 sdev->ppr, sdev->inquiry_len));
2279 if (sdev->id > sh->max_id) {
2280 /* error case, should never happen */
2281 scsi_adjust_queue_depth(sdev, 0, 1);
2282 goto slave_configure_exit;
2285 vdevice->configured_lun = 1;
2286 mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH);
2288 dsprintk((MYIOC_s_INFO_FMT
2289 "Queue depth=%d, tflags=%x\n",
2290 hd->ioc->name, sdev->queue_depth, vtarget->tflags));
2292 if (hd->ioc->bus_type == SPI)
2293 dsprintk((MYIOC_s_INFO_FMT
2294 "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
2295 hd->ioc->name, vtarget->negoFlags, vtarget->maxOffset,
2296 vtarget->minSyncFactor));
2298 slave_configure_exit:
2300 dsprintk((MYIOC_s_INFO_FMT
2301 "tagged %d, simple %d, ordered %d\n",
2302 hd->ioc->name,sdev->tagged_supported, sdev->simple_tags,
2303 sdev->ordered_tags));
2308 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2310 * Private routines...
2313 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2314 /* Utility function to copy sense data from the scsi_cmnd buffer
2315 * to the FC and SCSI target structures.
2319 mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
2322 SCSIIORequest_t *pReq;
2323 u32 sense_count = le32_to_cpu(pScsiReply->SenseCount);
2325 /* Get target structure
2327 pReq = (SCSIIORequest_t *) mf;
2328 vdev = sc->device->hostdata;
2334 /* Copy the sense received into the scsi command block. */
2335 req_index = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2336 sense_data = ((u8 *)hd->ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC));
2337 memcpy(sc->sense_buffer, sense_data, SNS_LEN(sc));
2339 /* Log SMART data (asc = 0x5D, non-IM case only) if required.
2341 if ((hd->ioc->events) && (hd->ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) {
2342 if ((sense_data[12] == 0x5D) && (vdev->vtarget->raidVolume == 0)) {
2344 MPT_ADAPTER *ioc = hd->ioc;
2346 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
2347 ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
2348 ioc->events[idx].eventContext = ioc->eventContext;
2350 ioc->events[idx].data[0] = (pReq->LUN[1] << 24) ||
2351 (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) ||
2352 (sc->device->channel << 8) || sc->device->id;
2354 ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12];
2356 ioc->eventContext++;
2357 if (hd->ioc->pcidev->vendor ==
2358 PCI_VENDOR_ID_IBM) {
2359 mptscsih_issue_sep_command(hd->ioc,
2360 vdev->vtarget, MPI_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT);
2361 vdev->vtarget->tflags |=
2362 MPT_TARGET_FLAGS_LED_ON;
2367 dprintk((MYIOC_s_INFO_FMT "Hmmm... SenseData len=0! (?)\n",
2373 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc)
2378 hd = (MPT_SCSI_HOST *) sc->device->host->hostdata;
2380 for (i = 0; i < hd->ioc->req_depth; i++) {
2381 if (hd->ScsiLookup[i] == sc) {
2389 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2391 mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2394 unsigned long flags;
2397 dtmprintk((KERN_WARNING MYNAM
2398 ": IOC %s_reset routed to SCSI host driver!\n",
2399 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
2400 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
2402 /* If a FW reload request arrives after base installed but
2403 * before all scsi hosts have been attached, then an alt_ioc
2404 * may have a NULL sh pointer.
2406 if ((ioc->sh == NULL) || (ioc->sh->hostdata == NULL))
2409 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2411 if (reset_phase == MPT_IOC_SETUP_RESET) {
2412 dtmprintk((MYIOC_s_WARN_FMT "Setup-Diag Reset\n", ioc->name));
2415 * 1. Set Hard Reset Pending Flag
2416 * All new commands go to doneQ
2418 hd->resetPending = 1;
2420 } else if (reset_phase == MPT_IOC_PRE_RESET) {
2421 dtmprintk((MYIOC_s_WARN_FMT "Pre-Diag Reset\n", ioc->name));
2423 /* 2. Flush running commands
2424 * Clean ScsiLookup (and associated memory)
2428 /* 2b. Reply to OS all known outstanding I/O commands.
2430 mptscsih_flush_running_cmds(hd);
2432 /* 2c. If there was an internal command that
2433 * has not completed, configuration or io request,
2434 * free these resources.
2437 del_timer(&hd->timer);
2438 mpt_free_msg_frame(ioc, hd->cmdPtr);
2441 dtmprintk((MYIOC_s_WARN_FMT "Pre-Reset complete.\n", ioc->name));
2444 dtmprintk((MYIOC_s_WARN_FMT "Post-Diag Reset\n", ioc->name));
2446 /* Once a FW reload begins, all new OS commands are
2447 * redirected to the doneQ w/ a reset status.
2448 * Init all control structures.
2451 /* ScsiLookup initialization
2453 for (ii=0; ii < hd->ioc->req_depth; ii++)
2454 hd->ScsiLookup[ii] = NULL;
2456 /* 2. Chain Buffer initialization
2459 /* 4. Renegotiate to all devices, if SPI
2462 /* 5. Enable new commands to be posted
2464 spin_lock_irqsave(&ioc->FreeQlock, flags);
2466 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2467 hd->resetPending = 0;
2468 hd->tmState = TM_STATE_NONE;
2470 /* 6. If there was an internal command,
2471 * wake this process up.
2475 * Wake up the original calling thread
2477 hd->pLocal = &hd->localReply;
2478 hd->pLocal->completion = MPT_SCANDV_DID_RESET;
2479 hd->scandv_wait_done = 1;
2480 wake_up(&hd->scandv_waitq);
2484 dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name));
2488 return 1; /* currently means nothing really */
2491 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2493 mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2496 u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
2498 devtverboseprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
2501 if (ioc->sh == NULL ||
2502 ((hd = (MPT_SCSI_HOST *)ioc->sh->hostdata) == NULL))
2506 case MPI_EVENT_UNIT_ATTENTION: /* 03 */
2509 case MPI_EVENT_IOC_BUS_RESET: /* 04 */
2510 case MPI_EVENT_EXT_BUS_RESET: /* 05 */
2511 if (hd && (ioc->bus_type == SPI) && (hd->soft_resets < -1))
2514 case MPI_EVENT_LOGOUT: /* 09 */
2518 case MPI_EVENT_RESCAN: /* 06 */
2522 * CHECKME! Don't think we need to do
2523 * anything for these, but...
2525 case MPI_EVENT_LINK_STATUS_CHANGE: /* 07 */
2526 case MPI_EVENT_LOOP_STATE_CHANGE: /* 08 */
2528 * CHECKME! Falling thru...
2532 case MPI_EVENT_INTEGRATED_RAID: /* 0B */
2535 case MPI_EVENT_NONE: /* 00 */
2536 case MPI_EVENT_LOG_DATA: /* 01 */
2537 case MPI_EVENT_STATE_CHANGE: /* 02 */
2538 case MPI_EVENT_EVENT_CHANGE: /* 0A */
2540 dprintk((KERN_INFO " Ignoring event (=%02Xh)\n", event));
2544 return 1; /* currently means nothing really */
2547 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2549 * Bus Scan and Domain Validation functionality ...
2552 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2554 * mptscsih_scandv_complete - Scan and DV callback routine registered
2555 * to Fustion MPT (base) driver.
2557 * @ioc: Pointer to MPT_ADAPTER structure
2558 * @mf: Pointer to original MPT request frame
2559 * @mr: Pointer to MPT reply frame (NULL if TurboReply)
2561 * This routine is called from mpt.c::mpt_interrupt() at the completion
2562 * of any SCSI IO request.
2563 * This routine is registered with the Fusion MPT (base) driver at driver
2564 * load/init time via the mpt_register() API call.
2566 * Returns 1 indicating alloc'd request frame ptr should be freed.
2568 * Remark: Sets a completion code and (possibly) saves sense data
2569 * in the IOC member localReply structure.
2570 * Used ONLY for DV and other internal commands.
2573 mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
2576 SCSIIORequest_t *pReq;
2580 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2583 (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) {
2584 printk(MYIOC_s_ERR_FMT
2585 "ScanDvComplete, %s req frame ptr! (=%p)\n",
2586 ioc->name, mf?"BAD":"NULL", (void *) mf);
2590 del_timer(&hd->timer);
2591 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2592 hd->ScsiLookup[req_idx] = NULL;
2593 pReq = (SCSIIORequest_t *) mf;
2595 if (mf != hd->cmdPtr) {
2596 printk(MYIOC_s_WARN_FMT "ScanDvComplete (mf=%p, cmdPtr=%p, idx=%d)\n",
2597 hd->ioc->name, (void *)mf, (void *) hd->cmdPtr, req_idx);
2601 ddvprintk((MYIOC_s_INFO_FMT "ScanDvComplete (mf=%p,mr=%p,idx=%d)\n",
2602 hd->ioc->name, mf, mr, req_idx));
2604 hd->pLocal = &hd->localReply;
2605 hd->pLocal->scsiStatus = 0;
2607 /* If target struct exists, clear sense valid flag.
2610 completionCode = MPT_SCANDV_GOOD;
2612 SCSIIOReply_t *pReply;
2616 pReply = (SCSIIOReply_t *) mr;
2618 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2619 scsi_status = pReply->SCSIStatus;
2621 ddvtprintk((KERN_NOTICE " IOCStatus=%04xh, SCSIState=%02xh, SCSIStatus=%02xh, IOCLogInfo=%08xh\n",
2622 status, pReply->SCSIState, scsi_status,
2623 le32_to_cpu(pReply->IOCLogInfo)));
2627 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
2628 completionCode = MPT_SCANDV_SELECTION_TIMEOUT;
2631 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
2632 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
2633 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
2634 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
2635 completionCode = MPT_SCANDV_DID_RESET;
2638 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
2639 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
2640 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
2641 if (pReply->Function == MPI_FUNCTION_CONFIG) {
2642 ConfigReply_t *pr = (ConfigReply_t *)mr;
2643 completionCode = MPT_SCANDV_GOOD;
2644 hd->pLocal->header.PageVersion = pr->Header.PageVersion;
2645 hd->pLocal->header.PageLength = pr->Header.PageLength;
2646 hd->pLocal->header.PageNumber = pr->Header.PageNumber;
2647 hd->pLocal->header.PageType = pr->Header.PageType;
2649 } else if (pReply->Function == MPI_FUNCTION_RAID_ACTION) {
2650 /* If the RAID Volume request is successful,
2651 * return GOOD, else indicate that
2652 * some type of error occurred.
2654 MpiRaidActionReply_t *pr = (MpiRaidActionReply_t *)mr;
2655 if (le16_to_cpu(pr->ActionStatus) == MPI_RAID_ACTION_ASTATUS_SUCCESS)
2656 completionCode = MPT_SCANDV_GOOD;
2658 completionCode = MPT_SCANDV_SOME_ERROR;
2659 memcpy(hd->pLocal->sense, pr, sizeof(hd->pLocal->sense));
2661 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID) {
2665 /* save sense data in global structure
2667 completionCode = MPT_SCANDV_SENSE;
2668 hd->pLocal->scsiStatus = scsi_status;
2669 sense_data = ((u8 *)hd->ioc->sense_buf_pool +
2670 (req_idx * MPT_SENSE_BUFFER_ALLOC));
2672 sz = min_t(int, pReq->SenseBufferLength,
2673 SCSI_STD_SENSE_BYTES);
2674 memcpy(hd->pLocal->sense, sense_data, sz);
2676 ddvprintk((KERN_NOTICE " Check Condition, sense ptr %p\n",
2678 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_FAILED) {
2679 if (pReq->CDB[0] == INQUIRY)
2680 completionCode = MPT_SCANDV_ISSUE_SENSE;
2682 completionCode = MPT_SCANDV_DID_RESET;
2684 else if (pReply->SCSIState & MPI_SCSI_STATE_NO_SCSI_STATUS)
2685 completionCode = MPT_SCANDV_DID_RESET;
2686 else if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
2687 completionCode = MPT_SCANDV_DID_RESET;
2689 completionCode = MPT_SCANDV_GOOD;
2690 hd->pLocal->scsiStatus = scsi_status;
2694 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
2695 if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
2696 completionCode = MPT_SCANDV_DID_RESET;
2698 completionCode = MPT_SCANDV_SOME_ERROR;
2702 completionCode = MPT_SCANDV_SOME_ERROR;
2705 } /* switch(status) */
2707 ddvtprintk((KERN_NOTICE " completionCode set to %08xh\n",
2709 } /* end of address reply case */
2711 hd->pLocal->completion = completionCode;
2713 /* MF and RF are freed in mpt_interrupt
2716 /* Free Chain buffers (will never chain) in scan or dv */
2717 //mptscsih_freeChainBuffers(ioc, req_idx);
2720 * Wake up the original calling thread
2722 hd->scandv_wait_done = 1;
2723 wake_up(&hd->scandv_waitq);
2728 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2729 /* mptscsih_timer_expired - Call back for timer process.
2730 * Used only for dv functionality.
2731 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
2735 mptscsih_timer_expired(unsigned long data)
2737 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) data;
2739 ddvprintk((MYIOC_s_WARN_FMT "Timer Expired! Cmd %p\n", hd->ioc->name, hd->cmdPtr));
2742 MPIHeader_t *cmd = (MPIHeader_t *)hd->cmdPtr;
2744 if (cmd->Function == MPI_FUNCTION_SCSI_IO_REQUEST) {
2745 /* Desire to issue a task management request here.
2746 * TM requests MUST be single threaded.
2747 * If old eh code and no TM current, issue request.
2748 * If new eh code, do nothing. Wait for OS cmd timeout
2751 ddvtprintk((MYIOC_s_NOTE_FMT "DV Cmd Timeout: NoOp\n", hd->ioc->name));
2753 /* Perform a FW reload */
2754 if (mpt_HardResetHandler(hd->ioc, NO_SLEEP) < 0) {
2755 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", hd->ioc->name);
2759 /* This should NEVER happen */
2760 printk(MYIOC_s_WARN_FMT "Null cmdPtr!!!!\n", hd->ioc->name);
2763 /* No more processing.
2764 * TM call will generate an interrupt for SCSI TM Management.
2765 * The FW will reply to all outstanding commands, callback will finish cleanup.
2766 * Hard reset clean-up will free all resources.
2768 ddvprintk((MYIOC_s_WARN_FMT "Timer Expired Complete!\n", hd->ioc->name));
2774 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2776 * mptscsih_do_cmd - Do internal command.
2777 * @hd: MPT_SCSI_HOST pointer
2778 * @io: INTERNAL_CMD pointer.
2780 * Issue the specified internally generated command and do command
2781 * specific cleanup. For bus scan / DV only.
2782 * NOTES: If command is Inquiry and status is good,
2783 * initialize a target structure, save the data
2785 * Remark: Single threaded access only.
2788 * < 0 if an illegal command or no resources
2792 * > 0 if command complete but some type of completion error.
2795 mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
2798 SCSIIORequest_t *pScsiReq;
2799 SCSIIORequest_t ReqCopy;
2800 int my_idx, ii, dir;
2804 char CDB[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
2807 in_isr = in_interrupt();
2809 dprintk((MYIOC_s_WARN_FMT "Internal SCSI IO request not allowed in ISR context!\n",
2815 /* Set command specific information
2820 dir = MPI_SCSIIO_CONTROL_READ;
2826 case TEST_UNIT_READY:
2828 dir = MPI_SCSIIO_CONTROL_READ;
2834 dir = MPI_SCSIIO_CONTROL_READ;
2836 CDB[4] = 1; /*Spin up the disk */
2844 dir = MPI_SCSIIO_CONTROL_READ;
2850 dir = MPI_SCSIIO_CONTROL_READ;
2852 if (io->flags & MPT_ICFLAG_ECHO) {
2858 if (io->flags & MPT_ICFLAG_BUF_CAP) {
2861 CDB[6] = (io->size >> 16) & 0xFF;
2862 CDB[7] = (io->size >> 8) & 0xFF;
2863 CDB[8] = io->size & 0xFF;
2869 dir = MPI_SCSIIO_CONTROL_WRITE;
2871 if (io->flags & MPT_ICFLAG_ECHO) {
2876 CDB[6] = (io->size >> 16) & 0xFF;
2877 CDB[7] = (io->size >> 8) & 0xFF;
2878 CDB[8] = io->size & 0xFF;
2884 dir = MPI_SCSIIO_CONTROL_READ;
2891 dir = MPI_SCSIIO_CONTROL_READ;
2896 case SYNCHRONIZE_CACHE:
2898 dir = MPI_SCSIIO_CONTROL_READ;
2900 // CDB[1] = 0x02; /* set immediate bit */
2909 /* Get and Populate a free Frame
2911 if ((mf = mpt_get_msg_frame(hd->ioc->InternalCtx, hd->ioc)) == NULL) {
2912 ddvprintk((MYIOC_s_WARN_FMT "No msg frames!\n",
2917 pScsiReq = (SCSIIORequest_t *) mf;
2919 /* Get the request index */
2920 my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2921 ADD_INDEX_LOG(my_idx); /* for debug */
2923 if (io->flags & MPT_ICFLAG_PHYS_DISK) {
2924 pScsiReq->TargetID = io->physDiskNum;
2926 pScsiReq->ChainOffset = 0;
2927 pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
2929 pScsiReq->TargetID = io->id;
2930 pScsiReq->Bus = io->channel;
2931 pScsiReq->ChainOffset = 0;
2932 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
2935 pScsiReq->CDBLength = cmdLen;
2936 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
2938 pScsiReq->Reserved = 0;
2940 pScsiReq->MsgFlags = mpt_msg_flags();
2941 /* MsgContext set in mpt_get_msg_fram call */
2943 int_to_scsilun(io->lun, (struct scsi_lun *)pScsiReq->LUN);
2945 if (io->flags & MPT_ICFLAG_TAGGED_CMD)
2946 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ);
2948 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
2950 if (cmd == REQUEST_SENSE) {
2951 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
2952 ddvprintk((MYIOC_s_INFO_FMT "Untagged! 0x%2x\n",
2953 hd->ioc->name, cmd));
2956 for (ii=0; ii < 16; ii++)
2957 pScsiReq->CDB[ii] = CDB[ii];
2959 pScsiReq->DataLength = cpu_to_le32(io->size);
2960 pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
2961 + (my_idx * MPT_SENSE_BUFFER_ALLOC));
2963 ddvprintk((MYIOC_s_INFO_FMT "Sending Command 0x%x for (%d:%d:%d)\n",
2964 hd->ioc->name, cmd, io->channel, io->id, io->lun));
2966 if (dir == MPI_SCSIIO_CONTROL_READ) {
2967 mpt_add_sge((char *) &pScsiReq->SGL,
2968 MPT_SGE_FLAGS_SSIMPLE_READ | io->size,
2971 mpt_add_sge((char *) &pScsiReq->SGL,
2972 MPT_SGE_FLAGS_SSIMPLE_WRITE | io->size,
2976 /* The ISR will free the request frame, but we need
2977 * the information to initialize the target. Duplicate.
2979 memcpy(&ReqCopy, pScsiReq, sizeof(SCSIIORequest_t));
2981 /* Issue this command after:
2984 * Wait until the reply has been received
2985 * ScsiScanDvCtx callback function will
2987 * set scandv_wait_done and call wake_up
2990 hd->timer.expires = jiffies + HZ*cmdTimeout;
2991 hd->scandv_wait_done = 0;
2993 /* Save cmd pointer, for resource free if timeout or
2998 add_timer(&hd->timer);
2999 mpt_put_msg_frame(hd->ioc->InternalCtx, hd->ioc, mf);
3000 wait_event(hd->scandv_waitq, hd->scandv_wait_done);
3003 rc = hd->pLocal->completion;
3004 hd->pLocal->skip = 0;
3006 /* Always set fatal error codes in some cases.
3008 if (rc == MPT_SCANDV_SELECTION_TIMEOUT)
3010 else if (rc == MPT_SCANDV_SOME_ERROR)
3014 /* This should never happen. */
3015 ddvprintk((MYIOC_s_INFO_FMT "_do_cmd: Null pLocal!!!\n",
3022 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3024 * mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
3025 * @hd: Pointer to a SCSI HOST structure
3026 * @vdevice: virtual target device
3028 * Uses the ISR, but with special processing.
3029 * MUST be single-threaded.
3033 mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
3037 /* Following parameters will not change
3040 iocmd.cmd = SYNCHRONIZE_CACHE;
3042 iocmd.physDiskNum = -1;
3044 iocmd.data_dma = -1;
3046 iocmd.rsvd = iocmd.rsvd2 = 0;
3047 iocmd.channel = vdevice->vtarget->channel;
3048 iocmd.id = vdevice->vtarget->id;
3049 iocmd.lun = vdevice->lun;
3051 if ((vdevice->vtarget->type == TYPE_DISK) &&
3052 (vdevice->configured_lun))
3053 mptscsih_do_cmd(hd, &iocmd);
3056 EXPORT_SYMBOL(mptscsih_remove);
3057 EXPORT_SYMBOL(mptscsih_shutdown);
3059 EXPORT_SYMBOL(mptscsih_suspend);
3060 EXPORT_SYMBOL(mptscsih_resume);
3062 EXPORT_SYMBOL(mptscsih_proc_info);
3063 EXPORT_SYMBOL(mptscsih_info);
3064 EXPORT_SYMBOL(mptscsih_qcmd);
3065 EXPORT_SYMBOL(mptscsih_slave_destroy);
3066 EXPORT_SYMBOL(mptscsih_slave_configure);
3067 EXPORT_SYMBOL(mptscsih_abort);
3068 EXPORT_SYMBOL(mptscsih_dev_reset);
3069 EXPORT_SYMBOL(mptscsih_bus_reset);
3070 EXPORT_SYMBOL(mptscsih_host_reset);
3071 EXPORT_SYMBOL(mptscsih_bios_param);
3072 EXPORT_SYMBOL(mptscsih_io_done);
3073 EXPORT_SYMBOL(mptscsih_taskmgmt_complete);
3074 EXPORT_SYMBOL(mptscsih_scandv_complete);
3075 EXPORT_SYMBOL(mptscsih_event_process);
3076 EXPORT_SYMBOL(mptscsih_ioc_reset);
3077 EXPORT_SYMBOL(mptscsih_change_queue_depth);
3078 EXPORT_SYMBOL(mptscsih_timer_expired);
3079 EXPORT_SYMBOL(mptscsih_TMHandler);
3081 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/