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-2005 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");
80 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
82 typedef struct _BIG_SENSE_BUF {
83 u8 data[MPT_SENSE_BUFFER_ALLOC];
86 #define MPT_SCANDV_GOOD (0x00000000) /* must be 0 */
87 #define MPT_SCANDV_DID_RESET (0x00000001)
88 #define MPT_SCANDV_SENSE (0x00000002)
89 #define MPT_SCANDV_SOME_ERROR (0x00000004)
90 #define MPT_SCANDV_SELECTION_TIMEOUT (0x00000008)
91 #define MPT_SCANDV_ISSUE_SENSE (0x00000010)
92 #define MPT_SCANDV_FALLBACK (0x00000020)
94 #define MPT_SCANDV_MAX_RETRIES (10)
96 #define MPT_ICFLAG_BUF_CAP 0x01 /* ReadBuffer Read Capacity format */
97 #define MPT_ICFLAG_ECHO 0x02 /* ReadBuffer Echo buffer format */
98 #define MPT_ICFLAG_EBOS 0x04 /* ReadBuffer Echo buffer has EBOS */
99 #define MPT_ICFLAG_PHYS_DISK 0x08 /* Any SCSI IO but do Phys Disk Format */
100 #define MPT_ICFLAG_TAGGED_CMD 0x10 /* Do tagged IO */
101 #define MPT_ICFLAG_DID_RESET 0x20 /* Bus Reset occurred with this command */
102 #define MPT_ICFLAG_RESERVED 0x40 /* Reserved has been issued */
104 typedef struct _internal_cmd {
105 char *data; /* data pointer */
106 dma_addr_t data_dma; /* data dma address */
107 int size; /* transfer size */
108 u8 cmd; /* SCSI Op Code */
109 u8 bus; /* bus number */
110 u8 id; /* SCSI ID (virtual) */
112 u8 flags; /* Bit Field - See above */
113 u8 physDiskNum; /* Phys disk number, -1 else */
119 * Other private/forward protos...
121 int mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
122 static void mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq);
123 int mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
125 static int mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
126 SCSIIORequest_t *pReq, int req_idx);
127 static void mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx);
128 static void mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply);
129 static int mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd);
130 static int mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout );
131 static int SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc);
133 static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout);
135 int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
136 int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
138 static void mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, struct scsi_device *sdev);
139 static void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *vtarget, struct scsi_device *sdev);
140 static int mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus);
141 int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
142 static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
143 static void mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice);
145 void mptscsih_remove(struct pci_dev *);
146 void mptscsih_shutdown(struct pci_dev *);
148 int mptscsih_suspend(struct pci_dev *pdev, pm_message_t state);
149 int mptscsih_resume(struct pci_dev *pdev);
152 #define SNS_LEN(scp) sizeof((scp)->sense_buffer)
154 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
156 * mptscsih_add_sge - Place a simple SGE at address pAddr.
157 * @pAddr: virtual address for SGE
158 * @flagslength: SGE flags and data transfer length
159 * @dma_addr: Physical address
161 * This routine places a MPT request frame back on the MPT adapter's
165 mptscsih_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
167 if (sizeof(dma_addr_t) == sizeof(u64)) {
168 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
169 u32 tmp = dma_addr & 0xFFFFFFFF;
171 pSge->FlagsLength = cpu_to_le32(flagslength);
172 pSge->Address.Low = cpu_to_le32(tmp);
173 tmp = (u32) ((u64)dma_addr >> 32);
174 pSge->Address.High = cpu_to_le32(tmp);
177 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
178 pSge->FlagsLength = cpu_to_le32(flagslength);
179 pSge->Address = cpu_to_le32(dma_addr);
181 } /* mptscsih_add_sge() */
183 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
185 * mptscsih_add_chain - Place a chain SGE at address pAddr.
186 * @pAddr: virtual address for SGE
187 * @next: nextChainOffset value (u32's)
188 * @length: length of next SGL segment
189 * @dma_addr: Physical address
191 * This routine places a MPT request frame back on the MPT adapter's
195 mptscsih_add_chain(char *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
197 if (sizeof(dma_addr_t) == sizeof(u64)) {
198 SGEChain64_t *pChain = (SGEChain64_t *) pAddr;
199 u32 tmp = dma_addr & 0xFFFFFFFF;
201 pChain->Length = cpu_to_le16(length);
202 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size();
204 pChain->NextChainOffset = next;
206 pChain->Address.Low = cpu_to_le32(tmp);
207 tmp = (u32) ((u64)dma_addr >> 32);
208 pChain->Address.High = cpu_to_le32(tmp);
210 SGEChain32_t *pChain = (SGEChain32_t *) pAddr;
211 pChain->Length = cpu_to_le16(length);
212 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size();
213 pChain->NextChainOffset = next;
214 pChain->Address = cpu_to_le32(dma_addr);
216 } /* mptscsih_add_chain() */
218 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
220 * mptscsih_getFreeChainBuffer - Function to get a free chain
221 * from the MPT_SCSI_HOST FreeChainQ.
222 * @ioc: Pointer to MPT_ADAPTER structure
223 * @req_idx: Index of the SCSI IO request frame. (output)
225 * return SUCCESS or FAILED
228 mptscsih_getFreeChainBuffer(MPT_ADAPTER *ioc, int *retIndex)
230 MPT_FRAME_HDR *chainBuf;
235 dsgprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer called\n",
237 spin_lock_irqsave(&ioc->FreeQlock, flags);
238 if (!list_empty(&ioc->FreeChainQ)) {
241 chainBuf = list_entry(ioc->FreeChainQ.next, MPT_FRAME_HDR,
242 u.frame.linkage.list);
243 list_del(&chainBuf->u.frame.linkage.list);
244 offset = (u8 *)chainBuf - (u8 *)ioc->ChainBuffer;
245 chain_idx = offset / ioc->req_sz;
247 dsgprintk((MYIOC_s_ERR_FMT "getFreeChainBuffer chainBuf=%p ChainBuffer=%p offset=%d chain_idx=%d\n",
248 ioc->name, chainBuf, ioc->ChainBuffer, offset, chain_idx));
251 chain_idx = MPT_HOST_NO_CHAIN;
252 dfailprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer failed\n",
255 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
257 *retIndex = chain_idx;
259 } /* mptscsih_getFreeChainBuffer() */
261 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
263 * mptscsih_AddSGE - Add a SGE (plus chain buffers) to the
264 * SCSIIORequest_t Message Frame.
265 * @ioc: Pointer to MPT_ADAPTER structure
266 * @SCpnt: Pointer to scsi_cmnd structure
267 * @pReq: Pointer to SCSIIORequest_t structure
272 mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
273 SCSIIORequest_t *pReq, int req_idx)
277 struct scatterlist *sg;
279 int sges_left, sg_done;
280 int chain_idx = MPT_HOST_NO_CHAIN;
282 int numSgeSlots, numSgeThisFrame;
283 u32 sgflags, sgdir, thisxfer = 0;
284 int chain_dma_off = 0;
290 sgdir = le32_to_cpu(pReq->Control) & MPI_SCSIIO_CONTROL_DATADIRECTION_MASK;
291 if (sgdir == MPI_SCSIIO_CONTROL_WRITE) {
292 sgdir = MPT_TRANSFER_HOST_TO_IOC;
294 sgdir = MPT_TRANSFER_IOC_TO_HOST;
297 psge = (char *) &pReq->SGL;
298 frm_sz = ioc->req_sz;
300 /* Map the data portion, if any.
301 * sges_left = 0 if no data transfer.
303 if ( (sges_left = SCpnt->use_sg) ) {
304 sges_left = pci_map_sg(ioc->pcidev,
305 (struct scatterlist *) SCpnt->request_buffer,
307 SCpnt->sc_data_direction);
310 } else if (SCpnt->request_bufflen) {
311 SCpnt->SCp.dma_handle = pci_map_single(ioc->pcidev,
312 SCpnt->request_buffer,
313 SCpnt->request_bufflen,
314 SCpnt->sc_data_direction);
315 dsgprintk((MYIOC_s_INFO_FMT "SG: non-SG for %p, len=%d\n",
316 ioc->name, SCpnt, SCpnt->request_bufflen));
317 mptscsih_add_sge((char *) &pReq->SGL,
318 0xD1000000|MPT_SGE_FLAGS_ADDRESSING|sgdir|SCpnt->request_bufflen,
319 SCpnt->SCp.dma_handle);
324 /* Handle the SG case.
326 sg = (struct scatterlist *) SCpnt->request_buffer;
328 sgeOffset = sizeof(SCSIIORequest_t) - sizeof(SGE_IO_UNION);
331 /* Prior to entering this loop - the following must be set
332 * current MF: sgeOffset (bytes)
333 * chainSge (Null if original MF is not a chain buffer)
334 * sg_done (num SGE done for this MF)
338 numSgeSlots = ((frm_sz - sgeOffset) / (sizeof(u32) + sizeof(dma_addr_t)) );
339 numSgeThisFrame = (sges_left < numSgeSlots) ? sges_left : numSgeSlots;
341 sgflags = MPT_SGE_FLAGS_SIMPLE_ELEMENT | MPT_SGE_FLAGS_ADDRESSING | sgdir;
343 /* Get first (num - 1) SG elements
344 * Skip any SG entries with a length of 0
345 * NOTE: at finish, sg and psge pointed to NEXT data/location positions
347 for (ii=0; ii < (numSgeThisFrame-1); ii++) {
348 thisxfer = sg_dma_len(sg);
350 sg ++; /* Get next SG element from the OS */
355 v2 = sg_dma_address(sg);
356 mptscsih_add_sge(psge, sgflags | thisxfer, v2);
358 sg++; /* Get next SG element from the OS */
359 psge += (sizeof(u32) + sizeof(dma_addr_t));
360 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
364 if (numSgeThisFrame == sges_left) {
365 /* Add last element, end of buffer and end of list flags.
367 sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT |
368 MPT_SGE_FLAGS_END_OF_BUFFER |
369 MPT_SGE_FLAGS_END_OF_LIST;
371 /* Add last SGE and set termination flags.
372 * Note: Last SGE may have a length of 0 - which should be ok.
374 thisxfer = sg_dma_len(sg);
376 v2 = sg_dma_address(sg);
377 mptscsih_add_sge(psge, sgflags | thisxfer, v2);
380 psge += (sizeof(u32) + sizeof(dma_addr_t));
382 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
386 /* The current buffer is a chain buffer,
387 * but there is not another one.
388 * Update the chain element
389 * Offset and Length fields.
391 mptscsih_add_chain((char *)chainSge, 0, sgeOffset, ioc->ChainBufferDMA + chain_dma_off);
393 /* The current buffer is the original MF
394 * and there is no Chain buffer.
396 pReq->ChainOffset = 0;
397 RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor) + 1) & 0x03;
398 dsgprintk((MYIOC_s_INFO_FMT
399 "Single Buffer RequestNB=%x, sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
400 ioc->RequestNB[req_idx] = RequestNB;
403 /* At least one chain buffer is needed.
404 * Complete the first MF
405 * - last SGE element, set the LastElement bit
406 * - set ChainOffset (words) for orig MF
407 * (OR finish previous MF chain buffer)
408 * - update MFStructPtr ChainIndex
409 * - Populate chain element
414 dsgprintk((MYIOC_s_INFO_FMT "SG: Chain Required! sg done %d\n",
415 ioc->name, sg_done));
417 /* Set LAST_ELEMENT flag for last non-chain element
418 * in the buffer. Since psge points at the NEXT
419 * SGE element, go back one SGE element, update the flags
420 * and reset the pointer. (Note: sgflags & thisxfer are already
424 u32 *ptmp = (u32 *) (psge - (sizeof(u32) + sizeof(dma_addr_t)));
425 sgflags = le32_to_cpu(*ptmp);
426 sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT;
427 *ptmp = cpu_to_le32(sgflags);
431 /* The current buffer is a chain buffer.
432 * chainSge points to the previous Chain Element.
433 * Update its chain element Offset and Length (must
434 * include chain element size) fields.
435 * Old chain element is now complete.
437 u8 nextChain = (u8) (sgeOffset >> 2);
438 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
439 mptscsih_add_chain((char *)chainSge, nextChain, sgeOffset, ioc->ChainBufferDMA + chain_dma_off);
441 /* The original MF buffer requires a chain buffer -
443 * Last element in this MF is a chain element.
445 pReq->ChainOffset = (u8) (sgeOffset >> 2);
446 RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor) + 1) & 0x03;
447 dsgprintk((MYIOC_s_ERR_FMT "Chain Buffer Needed, RequestNB=%x sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
448 ioc->RequestNB[req_idx] = RequestNB;
451 sges_left -= sg_done;
454 /* NOTE: psge points to the beginning of the chain element
455 * in current buffer. Get a chain buffer.
457 if ((mptscsih_getFreeChainBuffer(ioc, &newIndex)) == FAILED) {
458 dfailprintk((MYIOC_s_INFO_FMT
459 "getFreeChainBuffer FAILED SCSI cmd=%02x (%p)\n",
460 ioc->name, pReq->CDB[0], SCpnt));
464 /* Update the tracking arrays.
465 * If chainSge == NULL, update ReqToChain, else ChainToChain
468 ioc->ChainToChain[chain_idx] = newIndex;
470 ioc->ReqToChain[req_idx] = newIndex;
472 chain_idx = newIndex;
473 chain_dma_off = ioc->req_sz * chain_idx;
475 /* Populate the chainSGE for the current buffer.
476 * - Set chain buffer pointer to psge and fill
477 * out the Address and Flags fields.
479 chainSge = (char *) psge;
480 dsgprintk((KERN_INFO " Current buff @ %p (index 0x%x)",
483 /* Start the SGE for the next buffer
485 psge = (char *) (ioc->ChainBuffer + chain_dma_off);
489 dsgprintk((KERN_INFO " Chain buff @ %p (index 0x%x)\n",
492 /* Start the SGE for the next buffer
499 } /* mptscsih_AddSGE() */
502 mptscsih_issue_sep_command(MPT_ADAPTER *ioc, VirtTarget *vtarget,
506 SEPRequest_t *SEPMsg;
508 if (ioc->bus_type == FC)
511 if ((mf = mpt_get_msg_frame(ioc->InternalCtx, ioc)) == NULL) {
512 dfailprintk((MYIOC_s_WARN_FMT "%s: no msg frames!!\n",
513 ioc->name,__FUNCTION__));
517 SEPMsg = (SEPRequest_t *)mf;
518 SEPMsg->Function = MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR;
519 SEPMsg->Bus = vtarget->bus_id;
520 SEPMsg->TargetID = vtarget->target_id;
521 SEPMsg->Action = MPI_SEP_REQ_ACTION_WRITE_STATUS;
522 SEPMsg->SlotStatus = SlotStatus;
523 devtverboseprintk((MYIOC_s_WARN_FMT
524 "Sending SEP cmd=%x id=%d bus=%d\n",
525 ioc->name, SlotStatus, SEPMsg->TargetID, SEPMsg->Bus));
526 mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
529 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
531 * mptscsih_io_done - Main SCSI IO callback routine registered to
532 * Fusion MPT (base) driver
533 * @ioc: Pointer to MPT_ADAPTER structure
534 * @mf: Pointer to original MPT request frame
535 * @r: Pointer to MPT reply frame (NULL if TurboReply)
537 * This routine is called from mpt.c::mpt_interrupt() at the completion
538 * of any SCSI IO request.
539 * This routine is registered with the Fusion MPT (base) driver at driver
540 * load/init time via the mpt_register() API call.
542 * Returns 1 indicating alloc'd request frame ptr should be freed.
545 mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
547 struct scsi_cmnd *sc;
549 SCSIIORequest_t *pScsiReq;
550 SCSIIOReply_t *pScsiReply;
551 u16 req_idx, req_idx_MR;
555 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
557 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
558 req_idx_MR = (mr != NULL) ?
559 le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx) : req_idx;
560 if ((req_idx != req_idx_MR) ||
561 (mf->u.frame.linkage.arg1 == 0xdeadbeaf)) {
562 printk(MYIOC_s_ERR_FMT "Received a mf that was already freed\n",
564 printk (MYIOC_s_ERR_FMT
565 "req_idx=%x req_idx_MR=%x mf=%p mr=%p sc=%p\n",
566 ioc->name, req_idx, req_idx_MR, mf, mr,
567 hd->ScsiLookup[req_idx_MR]);
571 sc = hd->ScsiLookup[req_idx];
572 hd->ScsiLookup[req_idx] = NULL;
574 MPIHeader_t *hdr = (MPIHeader_t *)mf;
576 /* Remark: writeSDP1 will use the ScsiDoneCtx
577 * If a SCSI I/O cmd, device disabled by OS and
578 * completion done. Cannot touch sc struct. Just free mem.
580 if (hdr->Function == MPI_FUNCTION_SCSI_IO_REQUEST)
581 printk(MYIOC_s_ERR_FMT "NULL ScsiCmd ptr!\n",
584 mptscsih_freeChainBuffers(ioc, req_idx);
588 if ((unsigned char *)mf != sc->host_scribble) {
589 mptscsih_freeChainBuffers(ioc, req_idx);
593 sc->host_scribble = NULL;
594 sc->result = DID_OK << 16; /* Set default reply as OK */
595 pScsiReq = (SCSIIORequest_t *) mf;
596 pScsiReply = (SCSIIOReply_t *) mr;
598 if((ioc->facts.MsgVersion >= MPI_VERSION_01_05) && pScsiReply){
599 dmfprintk((MYIOC_s_INFO_FMT
600 "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d,task-tag=%d)\n",
601 ioc->name, mf, mr, sc, req_idx, pScsiReply->TaskTag));
603 dmfprintk((MYIOC_s_INFO_FMT
604 "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n",
605 ioc->name, mf, mr, sc, req_idx));
608 if (pScsiReply == NULL) {
609 /* special context reply handling */
614 u8 scsi_state, scsi_status;
616 status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK;
617 scsi_state = pScsiReply->SCSIState;
618 scsi_status = pScsiReply->SCSIStatus;
619 xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
620 sc->resid = sc->request_bufflen - xfer_cnt;
623 * if we get a data underrun indication, yet no data was
624 * transferred and the SCSI status indicates that the
625 * command was never started, change the data underrun
628 if (status == MPI_IOCSTATUS_SCSI_DATA_UNDERRUN && xfer_cnt == 0 &&
629 (scsi_status == MPI_SCSI_STATUS_BUSY ||
630 scsi_status == MPI_SCSI_STATUS_RESERVATION_CONFLICT ||
631 scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)) {
632 status = MPI_IOCSTATUS_SUCCESS;
635 dreplyprintk((KERN_NOTICE "Reply ha=%d id=%d lun=%d:\n"
636 "IOCStatus=%04xh SCSIState=%02xh SCSIStatus=%02xh\n"
637 "resid=%d bufflen=%d xfer_cnt=%d\n",
638 ioc->id, sc->device->id, sc->device->lun,
639 status, scsi_state, scsi_status, sc->resid,
640 sc->request_bufflen, xfer_cnt));
642 if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)
643 mptscsih_copy_sense_data(sc, hd, mf, pScsiReply);
646 * Look for + dump FCP ResponseInfo[]!
648 if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID &&
649 pScsiReply->ResponseInfo) {
650 printk(KERN_NOTICE "ha=%d id=%d lun=%d: "
651 "FCP_ResponseInfo=%08xh\n",
652 ioc->id, sc->device->id, sc->device->lun,
653 le32_to_cpu(pScsiReply->ResponseInfo));
657 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
659 * Maybe: DRIVER_BUSY | SUGGEST_RETRY | DID_SOFT_ERROR (retry)
660 * But not: DID_BUS_BUSY lest one risk
661 * killing interrupt handler:-(
663 sc->result = SAM_STAT_BUSY;
666 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
667 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
668 sc->result = DID_BAD_TARGET << 16;
671 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
672 /* Spoof to SCSI Selection Timeout! */
673 if (ioc->bus_type != FC)
674 sc->result = DID_NO_CONNECT << 16;
675 /* else fibre, just stall until rescan event */
677 sc->result = DID_REQUEUE << 16;
679 if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF)
680 hd->sel_timeout[pScsiReq->TargetID]++;
682 vdev = sc->device->hostdata;
685 vtarget = vdev->vtarget;
686 if (vtarget->tflags & MPT_TARGET_FLAGS_LED_ON) {
687 mptscsih_issue_sep_command(ioc, vtarget,
688 MPI_SEP_REQ_SLOTSTATUS_UNCONFIGURED);
689 vtarget->tflags &= ~MPT_TARGET_FLAGS_LED_ON;
693 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
694 if ( ioc->bus_type == SAS ) {
695 u16 ioc_status = le16_to_cpu(pScsiReply->IOCStatus);
696 if (ioc_status & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
697 u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
698 log_info &=SAS_LOGINFO_MASK;
699 if (log_info == SAS_LOGINFO_NEXUS_LOSS) {
700 sc->result = (DID_BUS_BUSY << 16);
704 } else if (ioc->bus_type == FC) {
706 * The FC IOC may kill a request for variety of
707 * reasons, some of which may be recovered by a
708 * retry, some which are unlikely to be
709 * recovered. Return DID_ERROR instead of
710 * DID_RESET to permit retry of the command,
711 * just not an infinite number of them
713 sc->result = DID_ERROR << 16;
718 * Allow non-SAS & non-NEXUS_LOSS to drop into below code
721 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
722 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
723 /* Linux handles an unsolicited DID_RESET better
724 * than an unsolicited DID_ABORT.
726 sc->result = DID_RESET << 16;
730 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
731 sc->resid = sc->request_bufflen - xfer_cnt;
732 if((xfer_cnt==0)||(sc->underflow > xfer_cnt))
733 sc->result=DID_SOFT_ERROR << 16;
734 else /* Sufficient data transfer occurred */
735 sc->result = (DID_OK << 16) | scsi_status;
736 dreplyprintk((KERN_NOTICE
737 "RESIDUAL_MISMATCH: result=%x on id=%d\n", sc->result, sc->device->id));
740 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
742 * Do upfront check for valid SenseData and give it
745 sc->result = (DID_OK << 16) | scsi_status;
746 if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
747 /* Have already saved the status and sense data
751 if (xfer_cnt < sc->underflow) {
752 if (scsi_status == SAM_STAT_BUSY)
753 sc->result = SAM_STAT_BUSY;
755 sc->result = DID_SOFT_ERROR << 16;
757 if (scsi_state & (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)) {
760 sc->result = DID_SOFT_ERROR << 16;
762 else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
763 /* Not real sure here either... */
764 sc->result = DID_RESET << 16;
768 dreplyprintk((KERN_NOTICE " sc->underflow={report ERR if < %02xh bytes xfer'd}\n",
770 dreplyprintk((KERN_NOTICE " ActBytesXferd=%02xh\n", xfer_cnt));
773 if (scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)
774 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
778 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
780 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
781 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
782 if (scsi_status == MPI_SCSI_STATUS_BUSY)
783 sc->result = (DID_BUS_BUSY << 16) | scsi_status;
785 sc->result = (DID_OK << 16) | scsi_status;
786 if (scsi_state == 0) {
788 } else if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
790 * If running against circa 200003dd 909 MPT f/w,
791 * may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL
792 * (QUEUE_FULL) returned from device! --> get 0x0000?128
793 * and with SenseBytes set to 0.
795 if (pScsiReply->SCSIStatus == MPI_SCSI_STATUS_TASK_SET_FULL)
796 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
799 else if (scsi_state &
800 (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)
805 sc->result = DID_SOFT_ERROR << 16;
807 else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
808 /* Not real sure here either... */
809 sc->result = DID_RESET << 16;
811 else if (scsi_state & MPI_SCSI_STATE_QUEUE_TAG_REJECTED) {
812 /* Device Inq. data indicates that it supports
813 * QTags, but rejects QTag messages.
814 * This command completed OK.
816 * Not real sure here either so do nothing... */
819 if (sc->result == MPI_SCSI_STATUS_TASK_SET_FULL)
820 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
823 * Reservation Conflict, Busy,
824 * Command Terminated, CHECK
828 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
829 sc->result = DID_SOFT_ERROR << 16;
832 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
833 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
834 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
835 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
836 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
837 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
838 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
839 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
840 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
845 sc->result = DID_SOFT_ERROR << 16;
848 } /* switch(status) */
850 dreplyprintk((KERN_NOTICE " sc->result is %08xh\n", sc->result));
851 } /* end of address reply case */
853 /* Unmap the DMA buffers, if any. */
855 pci_unmap_sg(ioc->pcidev, (struct scatterlist *) sc->request_buffer,
856 sc->use_sg, sc->sc_data_direction);
857 } else if (sc->request_bufflen) {
858 pci_unmap_single(ioc->pcidev, sc->SCp.dma_handle,
859 sc->request_bufflen, sc->sc_data_direction);
862 sc->scsi_done(sc); /* Issue the command callback */
864 /* Free Chain buffers */
865 mptscsih_freeChainBuffers(ioc, req_idx);
870 * mptscsih_flush_running_cmds - For each command found, search
871 * Scsi_Host instance taskQ and reply to OS.
872 * Called only if recovering from a FW reload.
873 * @hd: Pointer to a SCSI HOST structure
877 * Must be called while new I/Os are being queued.
880 mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
882 MPT_ADAPTER *ioc = hd->ioc;
883 struct scsi_cmnd *SCpnt;
886 int max = ioc->req_depth;
888 dprintk((KERN_INFO MYNAM ": flush_ScsiLookup called\n"));
889 for (ii= 0; ii < max; ii++) {
890 if ((SCpnt = hd->ScsiLookup[ii]) != NULL) {
895 /* Null ScsiLookup index
897 hd->ScsiLookup[ii] = NULL;
899 mf = MPT_INDEX_2_MFPTR(ioc, ii);
900 dmfprintk(( "flush: ScsiDone (mf=%p,sc=%p)\n",
903 /* Free Chain buffers */
904 mptscsih_freeChainBuffers(ioc, ii);
906 /* Free Message frames */
907 mpt_free_msg_frame(ioc, mf);
909 if ((unsigned char *)mf != SCpnt->host_scribble)
912 /* Set status, free OS resources (SG DMA buffers)
916 pci_unmap_sg(ioc->pcidev,
917 (struct scatterlist *) SCpnt->request_buffer,
919 SCpnt->sc_data_direction);
920 } else if (SCpnt->request_bufflen) {
921 pci_unmap_single(ioc->pcidev,
922 SCpnt->SCp.dma_handle,
923 SCpnt->request_bufflen,
924 SCpnt->sc_data_direction);
926 SCpnt->result = DID_RESET << 16;
927 SCpnt->host_scribble = NULL;
929 SCpnt->scsi_done(SCpnt); /* Issue the command callback */
937 * mptscsih_search_running_cmds - Delete any commands associated
938 * with the specified target and lun. Function called only
939 * when a lun is disable by mid-layer.
940 * Do NOT access the referenced scsi_cmnd structure or
941 * members. Will cause either a paging or NULL ptr error.
942 * (BUT, BUT, BUT, the code does reference it! - mdr)
943 * @hd: Pointer to a SCSI HOST structure
944 * @vdevice: per device private data
948 * Called from slave_destroy.
951 mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
953 SCSIIORequest_t *mf = NULL;
955 int max = hd->ioc->req_depth;
956 struct scsi_cmnd *sc;
958 dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n",
959 vdevice->vtarget->target_id, vdevice->lun, max));
961 for (ii=0; ii < max; ii++) {
962 if ((sc = hd->ScsiLookup[ii]) != NULL) {
964 mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii);
967 dsprintk(( "search_running: found (sc=%p, mf = %p) target %d, lun %d \n",
968 hd->ScsiLookup[ii], mf, mf->TargetID, mf->LUN[1]));
969 if ((mf->TargetID != ((u8)vdevice->vtarget->target_id)) || (mf->LUN[1] != ((u8) vdevice->lun)))
974 hd->ScsiLookup[ii] = NULL;
975 mptscsih_freeChainBuffers(hd->ioc, ii);
976 mpt_free_msg_frame(hd->ioc, (MPT_FRAME_HDR *)mf);
977 if ((unsigned char *)mf != sc->host_scribble)
980 pci_unmap_sg(hd->ioc->pcidev,
981 (struct scatterlist *) sc->request_buffer,
983 sc->sc_data_direction);
984 } else if (sc->request_bufflen) {
985 pci_unmap_single(hd->ioc->pcidev,
988 sc->sc_data_direction);
990 sc->host_scribble = NULL;
991 sc->result = DID_NO_CONNECT << 16;
998 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1000 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1002 * mptscsih_report_queue_full - Report QUEUE_FULL status returned
1003 * from a SCSI target device.
1004 * @sc: Pointer to scsi_cmnd structure
1005 * @pScsiReply: Pointer to SCSIIOReply_t
1006 * @pScsiReq: Pointer to original SCSI request
1008 * This routine periodically reports QUEUE_FULL status returned from a
1009 * SCSI target device. It reports this to the console via kernel
1010 * printk() API call, not more than once every 10 seconds.
1013 mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq)
1015 long time = jiffies;
1018 if (sc->device == NULL)
1020 if (sc->device->host == NULL)
1022 if ((hd = (MPT_SCSI_HOST *)sc->device->host->hostdata) == NULL)
1025 if (time - hd->last_queue_full > 10 * HZ) {
1026 dprintk((MYIOC_s_WARN_FMT "Device (%d:%d:%d) reported QUEUE_FULL!\n",
1027 hd->ioc->name, 0, sc->device->id, sc->device->lun));
1028 hd->last_queue_full = time;
1032 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1034 * mptscsih_remove - Removed scsi devices
1035 * @pdev: Pointer to pci_dev structure
1040 mptscsih_remove(struct pci_dev *pdev)
1042 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1043 struct Scsi_Host *host = ioc->sh;
1052 scsi_remove_host(host);
1054 if((hd = (MPT_SCSI_HOST *)host->hostdata) == NULL)
1057 mptscsih_shutdown(pdev);
1061 if (hd->ScsiLookup != NULL) {
1062 sz1 = hd->ioc->req_depth * sizeof(void *);
1063 kfree(hd->ScsiLookup);
1064 hd->ScsiLookup = NULL;
1068 * Free pointer array.
1073 dprintk((MYIOC_s_INFO_FMT
1074 "Free'd ScsiLookup (%d) memory\n",
1075 hd->ioc->name, sz1));
1077 kfree(hd->info_kbuf);
1079 /* NULL the Scsi_Host pointer
1083 scsi_host_put(host);
1089 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1091 * mptscsih_shutdown - reboot notifier
1095 mptscsih_shutdown(struct pci_dev *pdev)
1097 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1098 struct Scsi_Host *host = ioc->sh;
1104 hd = (MPT_SCSI_HOST *)host->hostdata;
1109 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1111 * mptscsih_suspend - Fusion MPT scsi driver suspend routine.
1116 mptscsih_suspend(struct pci_dev *pdev, pm_message_t state)
1118 mptscsih_shutdown(pdev);
1119 return mpt_suspend(pdev,state);
1122 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1124 * mptscsih_resume - Fusion MPT scsi driver resume routine.
1129 mptscsih_resume(struct pci_dev *pdev)
1131 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1132 struct Scsi_Host *host = ioc->sh;
1140 hd = (MPT_SCSI_HOST *)host->hostdata;
1149 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1151 * mptscsih_info - Return information about MPT adapter
1152 * @SChost: Pointer to Scsi_Host structure
1154 * (linux scsi_host_template.info routine)
1156 * Returns pointer to buffer where information was written.
1159 mptscsih_info(struct Scsi_Host *SChost)
1164 h = (MPT_SCSI_HOST *)SChost->hostdata;
1167 if (h->info_kbuf == NULL)
1168 if ((h->info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)
1169 return h->info_kbuf;
1170 h->info_kbuf[0] = '\0';
1172 mpt_print_ioc_summary(h->ioc, h->info_kbuf, &size, 0, 0);
1173 h->info_kbuf[size-1] = '\0';
1176 return h->info_kbuf;
1187 mptscsih_copy_mem_info(struct info_str *info, char *data, int len)
1189 if (info->pos + len > info->length)
1190 len = info->length - info->pos;
1192 if (info->pos + len < info->offset) {
1197 if (info->pos < info->offset) {
1198 data += (info->offset - info->pos);
1199 len -= (info->offset - info->pos);
1203 memcpy(info->buffer + info->pos, data, len);
1209 mptscsih_copy_info(struct info_str *info, char *fmt, ...)
1215 va_start(args, fmt);
1216 len = vsprintf(buf, fmt, args);
1219 mptscsih_copy_mem_info(info, buf, len);
1224 mptscsih_host_info(MPT_ADAPTER *ioc, char *pbuf, off_t offset, int len)
1226 struct info_str info;
1230 info.offset = offset;
1233 mptscsih_copy_info(&info, "%s: %s, ", ioc->name, ioc->prod_name);
1234 mptscsih_copy_info(&info, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING, ioc->facts.FWVersion.Word);
1235 mptscsih_copy_info(&info, "Ports=%d, ", ioc->facts.NumberOfPorts);
1236 mptscsih_copy_info(&info, "MaxQ=%d\n", ioc->req_depth);
1238 return ((info.pos > info.offset) ? info.pos - info.offset : 0);
1241 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1243 * mptscsih_proc_info - Return information about MPT adapter
1244 * @host: scsi host struct
1245 * @buffer: if write, user data; if read, buffer for user
1246 * @start: returns the buffer address
1247 * @offset: if write, 0; if read, the current offset into the buffer from
1248 * the previous read.
1249 * @length: if write, return length;
1250 * @func: write = 1; read = 0
1252 * (linux scsi_host_template.info routine)
1255 mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
1256 int length, int func)
1258 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
1259 MPT_ADAPTER *ioc = hd->ioc;
1264 * write is not supported
1270 size = mptscsih_host_info(ioc, buffer, offset, length);
1276 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1277 #define ADD_INDEX_LOG(req_ent) do { } while(0)
1279 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1281 * mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine.
1282 * @SCpnt: Pointer to scsi_cmnd structure
1283 * @done: Pointer SCSI mid-layer IO completion function
1285 * (linux scsi_host_template.queuecommand routine)
1286 * This is the primary SCSI IO start routine. Create a MPI SCSIIORequest
1287 * from a linux scsi_cmnd request and send it to the IOC.
1289 * Returns 0. (rtn value discarded by linux scsi mid-layer)
1292 mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1296 SCSIIORequest_t *pScsiReq;
1297 VirtDevice *vdev = SCpnt->device->hostdata;
1306 hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata;
1307 lun = SCpnt->device->lun;
1308 SCpnt->scsi_done = done;
1310 dmfprintk((MYIOC_s_INFO_FMT "qcmd: SCpnt=%p, done()=%p\n",
1311 (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt, done));
1313 if (hd->resetPending) {
1314 dtmprintk((MYIOC_s_WARN_FMT "qcmd: SCpnt=%p timeout + 60HZ\n",
1315 (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt));
1316 return SCSI_MLQUEUE_HOST_BUSY;
1319 if ((hd->ioc->bus_type == SPI) &&
1320 vdev->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT &&
1321 mptscsih_raid_id_to_num(hd, SCpnt->device->id) < 0) {
1322 SCpnt->result = DID_NO_CONNECT << 16;
1328 * Put together a MPT SCSI request...
1330 if ((mf = mpt_get_msg_frame(hd->ioc->DoneCtx, hd->ioc)) == NULL) {
1331 dprintk((MYIOC_s_WARN_FMT "QueueCmd, no msg frames!!\n",
1333 return SCSI_MLQUEUE_HOST_BUSY;
1336 pScsiReq = (SCSIIORequest_t *) mf;
1338 my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
1340 ADD_INDEX_LOG(my_idx);
1342 /* TUR's being issued with scsictl=0x02000000 (DATA_IN)!
1343 * Seems we may receive a buffer (datalen>0) even when there
1344 * will be no data transfer! GRRRRR...
1346 if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
1347 datalen = SCpnt->request_bufflen;
1348 scsidir = MPI_SCSIIO_CONTROL_READ; /* DATA IN (host<--ioc<--dev) */
1349 } else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
1350 datalen = SCpnt->request_bufflen;
1351 scsidir = MPI_SCSIIO_CONTROL_WRITE; /* DATA OUT (host-->ioc-->dev) */
1354 scsidir = MPI_SCSIIO_CONTROL_NODATATRANSFER;
1357 /* Default to untagged. Once a target structure has been allocated,
1358 * use the Inquiry data to determine if device supports tagged.
1361 && (vdev->vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)
1362 && (SCpnt->device->tagged_supported)) {
1363 scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
1365 scsictl = scsidir | MPI_SCSIIO_CONTROL_UNTAGGED;
1368 /* Use the above information to set up the message frame
1370 pScsiReq->TargetID = (u8) vdev->vtarget->target_id;
1371 pScsiReq->Bus = vdev->vtarget->bus_id;
1372 pScsiReq->ChainOffset = 0;
1373 if (vdev->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
1374 pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
1376 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
1377 pScsiReq->CDBLength = SCpnt->cmd_len;
1378 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
1379 pScsiReq->Reserved = 0;
1380 pScsiReq->MsgFlags = mpt_msg_flags();
1381 pScsiReq->LUN[0] = 0;
1382 pScsiReq->LUN[1] = lun;
1383 pScsiReq->LUN[2] = 0;
1384 pScsiReq->LUN[3] = 0;
1385 pScsiReq->LUN[4] = 0;
1386 pScsiReq->LUN[5] = 0;
1387 pScsiReq->LUN[6] = 0;
1388 pScsiReq->LUN[7] = 0;
1389 pScsiReq->Control = cpu_to_le32(scsictl);
1392 * Write SCSI CDB into the message
1394 cmd_len = SCpnt->cmd_len;
1395 for (ii=0; ii < cmd_len; ii++)
1396 pScsiReq->CDB[ii] = SCpnt->cmnd[ii];
1398 for (ii=cmd_len; ii < 16; ii++)
1399 pScsiReq->CDB[ii] = 0;
1402 pScsiReq->DataLength = cpu_to_le32(datalen);
1404 /* SenseBuffer low address */
1405 pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
1406 + (my_idx * MPT_SENSE_BUFFER_ALLOC));
1408 /* Now add the SG list
1409 * Always have a SGE even if null length.
1412 /* Add a NULL SGE */
1413 mptscsih_add_sge((char *)&pScsiReq->SGL, MPT_SGE_FLAGS_SSIMPLE_READ | 0,
1416 /* Add a 32 or 64 bit SGE */
1417 if (mptscsih_AddSGE(hd->ioc, SCpnt, pScsiReq, my_idx) != SUCCESS)
1421 SCpnt->host_scribble = (unsigned char *)mf;
1422 hd->ScsiLookup[my_idx] = SCpnt;
1424 mpt_put_msg_frame(hd->ioc->DoneCtx, hd->ioc, mf);
1425 dmfprintk((MYIOC_s_INFO_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n",
1426 hd->ioc->name, SCpnt, mf, my_idx));
1427 DBG_DUMP_REQUEST_FRAME(mf)
1431 hd->ScsiLookup[my_idx] = NULL;
1432 mptscsih_freeChainBuffers(hd->ioc, my_idx);
1433 mpt_free_msg_frame(hd->ioc, mf);
1434 return SCSI_MLQUEUE_HOST_BUSY;
1437 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1439 * mptscsih_freeChainBuffers - Function to free chain buffers associated
1440 * with a SCSI IO request
1441 * @hd: Pointer to the MPT_SCSI_HOST instance
1442 * @req_idx: Index of the SCSI IO request frame.
1444 * Called if SG chain buffer allocation fails and mptscsih callbacks.
1448 mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
1450 MPT_FRAME_HDR *chain;
1451 unsigned long flags;
1455 /* Get the first chain index and reset
1458 chain_idx = ioc->ReqToChain[req_idx];
1459 ioc->ReqToChain[req_idx] = MPT_HOST_NO_CHAIN;
1461 while (chain_idx != MPT_HOST_NO_CHAIN) {
1463 /* Save the next chain buffer index */
1464 next = ioc->ChainToChain[chain_idx];
1466 /* Free this chain buffer and reset
1469 ioc->ChainToChain[chain_idx] = MPT_HOST_NO_CHAIN;
1471 chain = (MPT_FRAME_HDR *) (ioc->ChainBuffer
1472 + (chain_idx * ioc->req_sz));
1474 spin_lock_irqsave(&ioc->FreeQlock, flags);
1475 list_add_tail(&chain->u.frame.linkage.list, &ioc->FreeChainQ);
1476 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1478 dmfprintk((MYIOC_s_INFO_FMT "FreeChainBuffers (index %d)\n",
1479 ioc->name, chain_idx));
1487 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1492 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1494 * mptscsih_TMHandler - Generic handler for SCSI Task Management.
1495 * Fall through to mpt_HardResetHandler if: not operational, too many
1496 * failed TM requests or handshake failure.
1498 * @ioc: Pointer to MPT_ADAPTER structure
1499 * @type: Task Management type
1500 * @target: Logical Target ID for reset (if appropriate)
1501 * @lun: Logical Unit for reset (if appropriate)
1502 * @ctx2abort: Context for the task to be aborted (if appropriate)
1504 * Remark: Currently invoked from a non-interrupt thread (_bh).
1506 * Remark: With old EH code, at most 1 SCSI TaskMgmt function per IOC
1509 * Returns 0 for SUCCESS or -1 if FAILED.
1512 mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout)
1518 unsigned long flags;
1520 /* If FW is being reloaded currently, return success to
1521 * the calling function.
1528 printk(KERN_ERR MYNAM " TMHandler" " NULL ioc!\n");
1531 dtmprintk((MYIOC_s_INFO_FMT "TMHandler Entered!\n", ioc->name));
1533 // SJR - CHECKME - Can we avoid this here?
1534 // (mpt_HardResetHandler has this check...)
1535 spin_lock_irqsave(&ioc->diagLock, flags);
1536 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)) {
1537 spin_unlock_irqrestore(&ioc->diagLock, flags);
1540 spin_unlock_irqrestore(&ioc->diagLock, flags);
1542 /* Wait a fixed amount of time for the TM pending flag to be cleared.
1543 * If we time out and not bus reset, then we return a FAILED status to the caller.
1544 * The call to mptscsih_tm_pending_wait() will set the pending flag if we are
1545 * successful. Otherwise, reload the FW.
1547 if (mptscsih_tm_pending_wait(hd) == FAILED) {
1548 if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
1549 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler abort: "
1550 "Timed out waiting for last TM (%d) to complete! \n",
1551 hd->ioc->name, hd->tmPending));
1553 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) {
1554 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler target reset: "
1555 "Timed out waiting for last TM (%d) to complete! \n",
1556 hd->ioc->name, hd->tmPending));
1558 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
1559 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler bus reset: "
1560 "Timed out waiting for last TM (%d) to complete! \n",
1561 hd->ioc->name, hd->tmPending));
1562 if (hd->tmPending & (1 << MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS))
1568 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
1569 hd->tmPending |= (1 << type);
1570 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1575 ioc_raw_state = mpt_GetIocState(hd->ioc, 0);
1577 #ifdef MPT_DEBUG_RESET
1578 if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) {
1579 printk(MYIOC_s_WARN_FMT
1580 "TM Handler: IOC Not operational(0x%x)!\n",
1581 hd->ioc->name, ioc_raw_state);
1585 if (doTask && ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL)
1586 && !(ioc_raw_state & MPI_DOORBELL_ACTIVE)) {
1588 /* Isse the Task Mgmt request.
1590 if (hd->hard_resets < -1)
1592 rc = mptscsih_IssueTaskMgmt(hd, type, channel, target, lun, ctx2abort, timeout);
1594 printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n", hd->ioc->name);
1596 dtmprintk((MYIOC_s_INFO_FMT "Issue of TaskMgmt Successful!\n", hd->ioc->name));
1600 /* Only fall through to the HRH if this is a bus reset
1602 if ((type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) && (rc ||
1603 ioc->reload_fw || (ioc->alt_ioc && ioc->alt_ioc->reload_fw))) {
1604 dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
1606 rc = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
1610 * Check IOCStatus from TM reply message
1612 if (hd->tm_iocstatus != MPI_IOCSTATUS_SUCCESS)
1615 dtmprintk((MYIOC_s_INFO_FMT "TMHandler rc = %d!\n", hd->ioc->name, rc));
1621 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1623 * mptscsih_IssueTaskMgmt - Generic send Task Management function.
1624 * @hd: Pointer to MPT_SCSI_HOST structure
1625 * @type: Task Management type
1626 * @target: Logical Target ID for reset (if appropriate)
1627 * @lun: Logical Unit for reset (if appropriate)
1628 * @ctx2abort: Context for the task to be aborted (if appropriate)
1630 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
1631 * or a non-interrupt thread. In the former, must not call schedule().
1633 * Not all fields are meaningfull for all task types.
1635 * Returns 0 for SUCCESS, -999 for "no msg frames",
1636 * else other non-zero value returned.
1639 mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout)
1642 SCSITaskMgmt_t *pScsiTm;
1646 /* Return Fail to calling function if no message frames available.
1648 if ((mf = mpt_get_msg_frame(hd->ioc->TaskCtx, hd->ioc)) == NULL) {
1649 dfailprintk((MYIOC_s_ERR_FMT "IssueTaskMgmt, no msg frames!!\n",
1653 dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt request @ %p\n",
1654 hd->ioc->name, mf));
1656 /* Format the Request
1658 pScsiTm = (SCSITaskMgmt_t *) mf;
1659 pScsiTm->TargetID = target;
1660 pScsiTm->Bus = channel;
1661 pScsiTm->ChainOffset = 0;
1662 pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
1664 pScsiTm->Reserved = 0;
1665 pScsiTm->TaskType = type;
1666 pScsiTm->Reserved1 = 0;
1667 pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)
1668 ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0;
1670 for (ii= 0; ii < 8; ii++) {
1671 pScsiTm->LUN[ii] = 0;
1673 pScsiTm->LUN[1] = lun;
1675 for (ii=0; ii < 7; ii++)
1676 pScsiTm->Reserved2[ii] = 0;
1678 pScsiTm->TaskMsgContext = ctx2abort;
1680 dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt: ctx2abort (0x%08x) type=%d\n",
1681 hd->ioc->name, ctx2abort, type));
1683 DBG_DUMP_TM_REQUEST_FRAME((u32 *)pScsiTm);
1685 if ((retval = mpt_send_handshake_request(hd->ioc->TaskCtx, hd->ioc,
1686 sizeof(SCSITaskMgmt_t), (u32*)pScsiTm,
1688 dfailprintk((MYIOC_s_ERR_FMT "_send_handshake FAILED!"
1689 " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
1691 mpt_free_msg_frame(hd->ioc, mf);
1695 if(mptscsih_tm_wait_for_completion(hd, timeout) == FAILED) {
1696 dfailprintk((MYIOC_s_ERR_FMT "_wait_for_completion FAILED!"
1697 " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
1699 mpt_free_msg_frame(hd->ioc, mf);
1700 dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
1702 retval = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
1709 mptscsih_get_tm_timeout(MPT_ADAPTER *ioc)
1711 switch (ioc->bus_type) {
1722 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1724 * mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant
1725 * @SCpnt: Pointer to scsi_cmnd structure, IO to be aborted
1727 * (linux scsi_host_template.eh_abort_handler routine)
1729 * Returns SUCCESS or FAILED.
1732 mptscsih_abort(struct scsi_cmnd * SCpnt)
1740 ulong sn = SCpnt->serial_number;
1742 /* If we can't locate our host adapter structure, return FAILED status.
1744 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL) {
1745 SCpnt->result = DID_RESET << 16;
1746 SCpnt->scsi_done(SCpnt);
1747 dfailprintk((KERN_INFO MYNAM ": mptscsih_abort: "
1748 "Can't locate host! (sc=%p)\n",
1753 /* Find this command
1755 if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) {
1756 /* Cmd not found in ScsiLookup.
1759 SCpnt->result = DID_RESET << 16;
1760 dtmprintk((KERN_INFO MYNAM ": %s: mptscsih_abort: "
1761 "Command not in the active list! (sc=%p)\n",
1762 hd->ioc->name, SCpnt));
1766 if (hd->resetPending) {
1770 if (hd->timeouts < -1)
1773 printk(KERN_WARNING MYNAM ": %s: attempting task abort! (sc=%p)\n",
1774 hd->ioc->name, SCpnt);
1775 scsi_print_command(SCpnt);
1777 /* Most important! Set TaskMsgContext to SCpnt's MsgContext!
1778 * (the IO to be ABORT'd)
1780 * NOTE: Since we do not byteswap MsgContext, we do not
1781 * swap it here either. It is an opaque cookie to
1782 * the controller, so it does not matter. -DaveM
1784 mf = MPT_INDEX_2_MFPTR(hd->ioc, scpnt_idx);
1785 ctx2abort = mf->u.frame.hwhdr.msgctxu.MsgContext;
1787 hd->abortSCpnt = SCpnt;
1789 vdev = SCpnt->device->hostdata;
1790 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
1791 vdev->vtarget->bus_id, vdev->vtarget->target_id, vdev->lun,
1792 ctx2abort, mptscsih_get_tm_timeout(hd->ioc));
1794 if (SCPNT_TO_LOOKUP_IDX(SCpnt) == scpnt_idx &&
1795 SCpnt->serial_number == sn) {
1799 printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n",
1801 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1806 if(retval != FAILED ) {
1808 hd->tmState = TM_STATE_NONE;
1813 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1815 * mptscsih_dev_reset - Perform a SCSI TARGET_RESET! new_eh variant
1816 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1818 * (linux scsi_host_template.eh_dev_reset_handler routine)
1820 * Returns SUCCESS or FAILED.
1823 mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
1829 /* If we can't locate our host adapter structure, return FAILED status.
1831 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1832 dtmprintk((KERN_INFO MYNAM ": mptscsih_dev_reset: "
1833 "Can't locate host! (sc=%p)\n",
1838 if (hd->resetPending)
1841 printk(KERN_WARNING MYNAM ": %s: attempting target reset! (sc=%p)\n",
1842 hd->ioc->name, SCpnt);
1843 scsi_print_command(SCpnt);
1845 vdev = SCpnt->device->hostdata;
1846 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
1847 vdev->vtarget->bus_id, vdev->vtarget->target_id,
1848 0, 0, mptscsih_get_tm_timeout(hd->ioc));
1850 printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n",
1852 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1857 if(retval != FAILED ) {
1859 hd->tmState = TM_STATE_NONE;
1864 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1866 * mptscsih_bus_reset - Perform a SCSI BUS_RESET! new_eh variant
1867 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1869 * (linux scsi_host_template.eh_bus_reset_handler routine)
1871 * Returns SUCCESS or FAILED.
1874 mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
1880 /* If we can't locate our host adapter structure, return FAILED status.
1882 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1883 dtmprintk((KERN_INFO MYNAM ": mptscsih_bus_reset: "
1884 "Can't locate host! (sc=%p)\n",
1889 printk(KERN_WARNING MYNAM ": %s: attempting bus reset! (sc=%p)\n",
1890 hd->ioc->name, SCpnt);
1891 scsi_print_command(SCpnt);
1893 if (hd->timeouts < -1)
1896 vdev = SCpnt->device->hostdata;
1897 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
1898 vdev->vtarget->bus_id, 0, 0, 0, mptscsih_get_tm_timeout(hd->ioc));
1900 printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n",
1902 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1907 if(retval != FAILED ) {
1909 hd->tmState = TM_STATE_NONE;
1914 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1916 * mptscsih_host_reset - Perform a SCSI host adapter RESET (new_eh variant)
1917 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1919 * (linux scsi_host_template.eh_host_reset_handler routine)
1921 * Returns SUCCESS or FAILED.
1924 mptscsih_host_reset(struct scsi_cmnd *SCpnt)
1927 int status = SUCCESS;
1929 /* If we can't locate the host to reset, then we failed. */
1930 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1931 dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
1932 "Can't locate host! (sc=%p)\n",
1937 printk(KERN_WARNING MYNAM ": %s: Attempting host reset! (sc=%p)\n",
1938 hd->ioc->name, SCpnt);
1940 /* If our attempts to reset the host failed, then return a failed
1941 * status. The host will be taken off line by the SCSI mid-layer.
1943 if (mpt_HardResetHandler(hd->ioc, CAN_SLEEP) < 0){
1946 /* Make sure TM pending is cleared and TM state is set to
1950 hd->tmState = TM_STATE_NONE;
1953 dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
1955 (status == SUCCESS) ? "SUCCESS" : "FAILED" ) );
1960 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1962 * mptscsih_tm_pending_wait - wait for pending task management request to complete
1963 * @hd: Pointer to MPT host structure.
1965 * Returns {SUCCESS,FAILED}.
1968 mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd)
1970 unsigned long flags;
1971 int loop_count = 4 * 10; /* Wait 10 seconds */
1972 int status = FAILED;
1975 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
1976 if (hd->tmState == TM_STATE_NONE) {
1977 hd->tmState = TM_STATE_IN_PROGRESS;
1979 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1983 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1985 } while (--loop_count);
1990 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1992 * mptscsih_tm_wait_for_completion - wait for completion of TM task
1993 * @hd: Pointer to MPT host structure.
1994 * @timeout: timeout in seconds
1996 * Returns {SUCCESS,FAILED}.
1999 mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout )
2001 unsigned long flags;
2002 int loop_count = 4 * timeout;
2003 int status = FAILED;
2006 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
2007 if(hd->tmPending == 0) {
2009 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2012 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2014 } while (--loop_count);
2019 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2021 mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code)
2025 switch (response_code) {
2026 case MPI_SCSITASKMGMT_RSP_TM_COMPLETE:
2027 desc = "The task completed.";
2029 case MPI_SCSITASKMGMT_RSP_INVALID_FRAME:
2030 desc = "The IOC received an invalid frame status.";
2032 case MPI_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED:
2033 desc = "The task type is not supported.";
2035 case MPI_SCSITASKMGMT_RSP_TM_FAILED:
2036 desc = "The requested task failed.";
2038 case MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED:
2039 desc = "The task completed successfully.";
2041 case MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN:
2042 desc = "The LUN request is invalid.";
2044 case MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC:
2045 desc = "The task is in the IOC queue and has not been sent to target.";
2051 printk(MYIOC_s_INFO_FMT "Response Code(0x%08x): F/W: %s\n",
2052 ioc->name, response_code, desc);
2055 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2057 * mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
2058 * @ioc: Pointer to MPT_ADAPTER structure
2059 * @mf: Pointer to SCSI task mgmt request frame
2060 * @mr: Pointer to SCSI task mgmt reply frame
2062 * This routine is called from mptbase.c::mpt_interrupt() at the completion
2063 * of any SCSI task management request.
2064 * This routine is registered with the MPT (base) driver at driver
2065 * load/init time via the mpt_register() API call.
2067 * Returns 1 indicating alloc'd request frame ptr should be freed.
2070 mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
2072 SCSITaskMgmtReply_t *pScsiTmReply;
2073 SCSITaskMgmt_t *pScsiTmReq;
2075 unsigned long flags;
2079 dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt completed (mf=%p,mr=%p)\n",
2080 ioc->name, mf, mr));
2082 /* Depending on the thread, a timer is activated for
2083 * the TM request. Delete this timer on completion of TM.
2084 * Decrement count of outstanding TM requests.
2086 hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
2088 dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt Complete: NULL Scsi Host Ptr\n",
2094 dtmprintk((MYIOC_s_WARN_FMT "ERROR! TaskMgmt Reply: NULL Request %p\n",
2098 pScsiTmReply = (SCSITaskMgmtReply_t*)mr;
2099 pScsiTmReq = (SCSITaskMgmt_t*)mf;
2101 /* Figure out if this was ABORT_TASK, TARGET_RESET, or BUS_RESET! */
2102 tmType = pScsiTmReq->TaskType;
2104 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05 &&
2105 pScsiTmReply->ResponseCode)
2106 mptscsih_taskmgmt_response_code(ioc,
2107 pScsiTmReply->ResponseCode);
2109 dtmprintk((MYIOC_s_WARN_FMT " TaskType = %d, TerminationCount=%d\n",
2110 ioc->name, tmType, le32_to_cpu(pScsiTmReply->TerminationCount)));
2111 DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply);
2113 iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2114 hd->tm_iocstatus = iocstatus;
2115 dtmprintk((MYIOC_s_WARN_FMT " SCSI TaskMgmt (%d) IOCStatus=%04x IOCLogInfo=%08x\n",
2116 ioc->name, tmType, iocstatus, le32_to_cpu(pScsiTmReply->IOCLogInfo)));
2117 /* Error? (anything non-zero?) */
2120 /* clear flags and continue.
2122 if (tmType == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK)
2123 hd->abortSCpnt = NULL;
2125 /* If an internal command is present
2126 * or the TM failed - reload the FW.
2127 * FC FW may respond FAILED to an ABORT
2129 if (tmType == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
2131 (iocstatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED)) {
2132 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0) {
2133 printk((KERN_WARNING
2134 " Firmware Reload FAILED!!\n"));
2139 dtmprintk((MYIOC_s_WARN_FMT " TaskMgmt SUCCESS\n", ioc->name));
2141 hd->abortSCpnt = NULL;
2146 spin_lock_irqsave(&ioc->FreeQlock, flags);
2148 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2149 hd->tmState = TM_STATE_NONE;
2154 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2156 * This is anyones guess quite frankly.
2159 mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
2160 sector_t capacity, int geom[])
2170 dummy = heads * sectors;
2171 cylinders = capacity;
2172 sector_div(cylinders,dummy);
2175 * Handle extended translation size for logical drives
2178 if ((ulong)capacity >= 0x200000) {
2181 dummy = heads * sectors;
2182 cylinders = capacity;
2183 sector_div(cylinders,dummy);
2189 geom[2] = cylinders;
2191 dprintk((KERN_NOTICE
2192 ": bios_param: Id=%i Lun=%i Channel=%i CHS=%i/%i/%i\n",
2193 sdev->id, sdev->lun,sdev->channel,(int)cylinders,heads,sectors));
2198 /* Search IOC page 3 to determine if this is hidden physical disk
2202 mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id)
2206 if (!ioc->raid_data.isRaid || !ioc->raid_data.pIocPg3)
2208 for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2209 if (id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID)
2214 EXPORT_SYMBOL(mptscsih_is_phys_disk);
2217 mptscsih_raid_id_to_num(MPT_SCSI_HOST *hd, uint physdiskid)
2221 if (!hd->ioc->raid_data.isRaid || !hd->ioc->raid_data.pIocPg3)
2224 for (i = 0; i < hd->ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2226 hd->ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID)
2227 return hd->ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum;
2232 EXPORT_SYMBOL(mptscsih_raid_id_to_num);
2234 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2236 * OS entry point to allow host driver to alloc memory
2237 * for each scsi target. Called once per device the bus scan.
2238 * Return non-zero if allocation fails.
2241 mptscsih_target_alloc(struct scsi_target *starget)
2243 VirtTarget *vtarget;
2245 vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
2248 starget->hostdata = vtarget;
2249 vtarget->starget = starget;
2253 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2255 * OS entry point to allow host driver to alloc memory
2256 * for each scsi device. Called once per device the bus scan.
2257 * Return non-zero if allocation fails.
2260 mptscsih_slave_alloc(struct scsi_device *sdev)
2262 struct Scsi_Host *host = sdev->host;
2263 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
2264 VirtTarget *vtarget;
2266 struct scsi_target *starget;
2268 vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
2270 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
2271 hd->ioc->name, sizeof(VirtDevice));
2275 vdev->lun = sdev->lun;
2276 sdev->hostdata = vdev;
2278 starget = scsi_target(sdev);
2279 vtarget = starget->hostdata;
2281 vdev->vtarget = vtarget;
2283 if (vtarget->num_luns == 0) {
2284 hd->Targets[sdev->id] = vtarget;
2285 vtarget->ioc_id = hd->ioc->id;
2286 vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
2287 vtarget->target_id = sdev->id;
2288 vtarget->bus_id = sdev->channel;
2289 if (hd->ioc->bus_type == SPI && sdev->channel == 0 &&
2290 hd->ioc->raid_data.isRaid & (1 << sdev->id)) {
2291 vtarget->raidVolume = 1;
2292 ddvtprintk((KERN_INFO
2293 "RAID Volume @ id %d\n", sdev->id));
2296 vtarget->num_luns++;
2301 * OS entry point to allow for host driver to free allocated memory
2302 * Called if no device present or device being unloaded
2305 mptscsih_target_destroy(struct scsi_target *starget)
2307 if (starget->hostdata)
2308 kfree(starget->hostdata);
2309 starget->hostdata = NULL;
2313 * OS entry point to allow for host driver to free allocated memory
2314 * Called if no device present or device being unloaded
2317 mptscsih_slave_destroy(struct scsi_device *sdev)
2319 struct Scsi_Host *host = sdev->host;
2320 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
2321 VirtTarget *vtarget;
2322 VirtDevice *vdevice;
2323 struct scsi_target *starget;
2325 starget = scsi_target(sdev);
2326 vtarget = starget->hostdata;
2327 vdevice = sdev->hostdata;
2329 mptscsih_search_running_cmds(hd, vdevice);
2330 vtarget->luns[0] &= ~(1 << vdevice->lun);
2331 vtarget->num_luns--;
2332 if (vtarget->num_luns == 0) {
2333 hd->Targets[sdev->id] = NULL;
2335 mptscsih_synchronize_cache(hd, vdevice);
2337 sdev->hostdata = NULL;
2340 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2342 * mptscsih_change_queue_depth - This function will set a devices queue depth
2343 * @sdev: per scsi_device pointer
2344 * @qdepth: requested queue depth
2346 * Adding support for new 'change_queue_depth' api.
2349 mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
2351 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sdev->host->hostdata;
2352 VirtTarget *vtarget;
2353 struct scsi_target *starget;
2357 starget = scsi_target(sdev);
2358 vtarget = starget->hostdata;
2360 if (hd->ioc->bus_type == SPI) {
2361 if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
2363 else if (sdev->type == TYPE_DISK &&
2364 vtarget->minSyncFactor <= MPT_ULTRA160)
2365 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2367 max_depth = MPT_SCSI_CMD_PER_DEV_LOW;
2369 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2371 if (qdepth > max_depth)
2376 tagged = MSG_SIMPLE_TAG;
2378 scsi_adjust_queue_depth(sdev, tagged, qdepth);
2379 return sdev->queue_depth;
2383 * OS entry point to adjust the queue_depths on a per-device basis.
2384 * Called once per device the bus scan. Use it to force the queue_depth
2385 * member to 1 if a device does not support Q tags.
2386 * Return non-zero if fails.
2389 mptscsih_slave_configure(struct scsi_device *sdev)
2391 struct Scsi_Host *sh = sdev->host;
2392 VirtTarget *vtarget;
2393 VirtDevice *vdevice;
2394 struct scsi_target *starget;
2395 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sh->hostdata;
2396 int indexed_lun, lun_index;
2398 starget = scsi_target(sdev);
2399 vtarget = starget->hostdata;
2400 vdevice = sdev->hostdata;
2402 dsprintk((MYIOC_s_INFO_FMT
2403 "device @ %p, id=%d, LUN=%d, channel=%d\n",
2404 hd->ioc->name, sdev, sdev->id, sdev->lun, sdev->channel));
2405 if (hd->ioc->bus_type == SPI)
2406 dsprintk((MYIOC_s_INFO_FMT
2407 "sdtr %d wdtr %d ppr %d inq length=%d\n",
2408 hd->ioc->name, sdev->sdtr, sdev->wdtr,
2409 sdev->ppr, sdev->inquiry_len));
2411 if (sdev->id > sh->max_id) {
2412 /* error case, should never happen */
2413 scsi_adjust_queue_depth(sdev, 0, 1);
2414 goto slave_configure_exit;
2417 vdevice->configured_lun=1;
2418 lun_index = (vdevice->lun >> 5); /* 32 luns per lun_index */
2419 indexed_lun = (vdevice->lun % 32);
2420 vtarget->luns[lun_index] |= (1 << indexed_lun);
2421 mptscsih_initTarget(hd, vtarget, sdev);
2422 mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH);
2424 dsprintk((MYIOC_s_INFO_FMT
2425 "Queue depth=%d, tflags=%x\n",
2426 hd->ioc->name, sdev->queue_depth, vtarget->tflags));
2428 if (hd->ioc->bus_type == SPI)
2429 dsprintk((MYIOC_s_INFO_FMT
2430 "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
2431 hd->ioc->name, vtarget->negoFlags, vtarget->maxOffset,
2432 vtarget->minSyncFactor));
2434 slave_configure_exit:
2436 dsprintk((MYIOC_s_INFO_FMT
2437 "tagged %d, simple %d, ordered %d\n",
2438 hd->ioc->name,sdev->tagged_supported, sdev->simple_tags,
2439 sdev->ordered_tags));
2444 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2446 * Private routines...
2449 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2450 /* Utility function to copy sense data from the scsi_cmnd buffer
2451 * to the FC and SCSI target structures.
2455 mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
2458 SCSIIORequest_t *pReq;
2459 u32 sense_count = le32_to_cpu(pScsiReply->SenseCount);
2461 /* Get target structure
2463 pReq = (SCSIIORequest_t *) mf;
2464 vdev = sc->device->hostdata;
2470 /* Copy the sense received into the scsi command block. */
2471 req_index = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2472 sense_data = ((u8 *)hd->ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC));
2473 memcpy(sc->sense_buffer, sense_data, SNS_LEN(sc));
2475 /* Log SMART data (asc = 0x5D, non-IM case only) if required.
2477 if ((hd->ioc->events) && (hd->ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) {
2478 if ((sense_data[12] == 0x5D) && (vdev->vtarget->raidVolume == 0)) {
2480 MPT_ADAPTER *ioc = hd->ioc;
2482 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
2483 ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
2484 ioc->events[idx].eventContext = ioc->eventContext;
2486 ioc->events[idx].data[0] = (pReq->LUN[1] << 24) ||
2487 (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) ||
2488 (sc->device->channel << 8) || sc->device->id;
2490 ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12];
2492 ioc->eventContext++;
2493 if (hd->ioc->pcidev->vendor ==
2494 PCI_VENDOR_ID_IBM) {
2495 mptscsih_issue_sep_command(hd->ioc,
2496 vdev->vtarget, MPI_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT);
2497 vdev->vtarget->tflags |=
2498 MPT_TARGET_FLAGS_LED_ON;
2503 dprintk((MYIOC_s_INFO_FMT "Hmmm... SenseData len=0! (?)\n",
2509 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc)
2514 hd = (MPT_SCSI_HOST *) sc->device->host->hostdata;
2516 for (i = 0; i < hd->ioc->req_depth; i++) {
2517 if (hd->ScsiLookup[i] == sc) {
2525 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2527 mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2530 unsigned long flags;
2533 dtmprintk((KERN_WARNING MYNAM
2534 ": IOC %s_reset routed to SCSI host driver!\n",
2535 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
2536 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
2538 /* If a FW reload request arrives after base installed but
2539 * before all scsi hosts have been attached, then an alt_ioc
2540 * may have a NULL sh pointer.
2542 if ((ioc->sh == NULL) || (ioc->sh->hostdata == NULL))
2545 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2547 if (reset_phase == MPT_IOC_SETUP_RESET) {
2548 dtmprintk((MYIOC_s_WARN_FMT "Setup-Diag Reset\n", ioc->name));
2551 * 1. Set Hard Reset Pending Flag
2552 * All new commands go to doneQ
2554 hd->resetPending = 1;
2556 } else if (reset_phase == MPT_IOC_PRE_RESET) {
2557 dtmprintk((MYIOC_s_WARN_FMT "Pre-Diag Reset\n", ioc->name));
2559 /* 2. Flush running commands
2560 * Clean ScsiLookup (and associated memory)
2564 /* 2b. Reply to OS all known outstanding I/O commands.
2566 mptscsih_flush_running_cmds(hd);
2568 /* 2c. If there was an internal command that
2569 * has not completed, configuration or io request,
2570 * free these resources.
2573 del_timer(&hd->timer);
2574 mpt_free_msg_frame(ioc, hd->cmdPtr);
2577 dtmprintk((MYIOC_s_WARN_FMT "Pre-Reset complete.\n", ioc->name));
2580 dtmprintk((MYIOC_s_WARN_FMT "Post-Diag Reset\n", ioc->name));
2582 /* Once a FW reload begins, all new OS commands are
2583 * redirected to the doneQ w/ a reset status.
2584 * Init all control structures.
2587 /* ScsiLookup initialization
2589 for (ii=0; ii < hd->ioc->req_depth; ii++)
2590 hd->ScsiLookup[ii] = NULL;
2592 /* 2. Chain Buffer initialization
2595 /* 4. Renegotiate to all devices, if SPI
2598 /* 5. Enable new commands to be posted
2600 spin_lock_irqsave(&ioc->FreeQlock, flags);
2602 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2603 hd->resetPending = 0;
2604 hd->tmState = TM_STATE_NONE;
2606 /* 6. If there was an internal command,
2607 * wake this process up.
2611 * Wake up the original calling thread
2613 hd->pLocal = &hd->localReply;
2614 hd->pLocal->completion = MPT_SCANDV_DID_RESET;
2615 hd->scandv_wait_done = 1;
2616 wake_up(&hd->scandv_waitq);
2620 dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name));
2624 return 1; /* currently means nothing really */
2627 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2629 mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2632 u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
2634 devtverboseprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
2637 if (ioc->sh == NULL ||
2638 ((hd = (MPT_SCSI_HOST *)ioc->sh->hostdata) == NULL))
2642 case MPI_EVENT_UNIT_ATTENTION: /* 03 */
2645 case MPI_EVENT_IOC_BUS_RESET: /* 04 */
2646 case MPI_EVENT_EXT_BUS_RESET: /* 05 */
2647 if (hd && (ioc->bus_type == SPI) && (hd->soft_resets < -1))
2650 case MPI_EVENT_LOGOUT: /* 09 */
2654 case MPI_EVENT_RESCAN: /* 06 */
2658 * CHECKME! Don't think we need to do
2659 * anything for these, but...
2661 case MPI_EVENT_LINK_STATUS_CHANGE: /* 07 */
2662 case MPI_EVENT_LOOP_STATE_CHANGE: /* 08 */
2664 * CHECKME! Falling thru...
2668 case MPI_EVENT_INTEGRATED_RAID: /* 0B */
2671 case MPI_EVENT_NONE: /* 00 */
2672 case MPI_EVENT_LOG_DATA: /* 01 */
2673 case MPI_EVENT_STATE_CHANGE: /* 02 */
2674 case MPI_EVENT_EVENT_CHANGE: /* 0A */
2676 dprintk((KERN_INFO " Ignoring event (=%02Xh)\n", event));
2680 return 1; /* currently means nothing really */
2683 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2685 * mptscsih_initTarget - Target, LUN alloc/free functionality.
2686 * @hd: Pointer to MPT_SCSI_HOST structure
2687 * @vtarget: per target private data
2688 * @sdev: SCSI device
2690 * NOTE: It's only SAFE to call this routine if data points to
2691 * sane & valid STANDARD INQUIRY data!
2693 * Allocate and initialize memory for this target.
2694 * Save inquiry data.
2698 mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget,
2699 struct scsi_device *sdev)
2701 dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n",
2702 hd->ioc->name, vtarget->bus_id, vtarget->target_id,
2705 /* Is LUN supported? If so, upper 2 bits will be 0
2706 * in first byte of inquiry data.
2708 if (sdev->inq_periph_qual != 0)
2711 if (vtarget == NULL)
2714 vtarget->type = sdev->type;
2716 if (hd->ioc->bus_type != SPI)
2719 if ((sdev->type == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) {
2720 /* Treat all Processors as SAF-TE if
2721 * command line option is set */
2722 vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
2723 mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id);
2724 }else if ((sdev->type == TYPE_PROCESSOR) &&
2725 !(vtarget->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) {
2726 if (sdev->inquiry_len > 49 ) {
2727 if (sdev->inquiry[44] == 'S' &&
2728 sdev->inquiry[45] == 'A' &&
2729 sdev->inquiry[46] == 'F' &&
2730 sdev->inquiry[47] == '-' &&
2731 sdev->inquiry[48] == 'T' &&
2732 sdev->inquiry[49] == 'E' ) {
2733 vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
2734 mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id);
2738 mptscsih_setTargetNegoParms(hd, vtarget, sdev);
2741 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2743 * Update the target negotiation parameters based on the
2744 * the Inquiry data, adapter capabilities, and NVRAM settings.
2748 mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target,
2749 struct scsi_device *sdev)
2751 SpiCfgData *pspi_data = &hd->ioc->spi_data;
2752 int id = (int) target->target_id;
2754 u8 width = MPT_NARROW;
2755 u8 factor = MPT_ASYNC;
2760 target->negoFlags = pspi_data->noQas;
2762 /* noQas == 0 => device supports QAS. */
2764 if (sdev->scsi_level < SCSI_2) {
2766 factor = MPT_ULTRA2;
2767 offset = pspi_data->maxSyncOffset;
2768 target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
2770 if (scsi_device_wide(sdev)) {
2774 if (scsi_device_sync(sdev)) {
2775 factor = pspi_data->minSyncFactor;
2776 if (!scsi_device_dt(sdev))
2777 factor = MPT_ULTRA2;
2779 if (!scsi_device_ius(sdev) &&
2780 !scsi_device_qas(sdev))
2781 factor = MPT_ULTRA160;
2783 factor = MPT_ULTRA320;
2784 if (scsi_device_qas(sdev)) {
2785 ddvtprintk((KERN_INFO "Enabling QAS due to byte56=%02x on id=%d!\n", scsi_device_qas(sdev), id));
2788 if (sdev->type == TYPE_TAPE &&
2789 scsi_device_ius(sdev))
2790 target->negoFlags |= MPT_TAPE_NEGO_IDP;
2793 offset = pspi_data->maxSyncOffset;
2795 /* If RAID, never disable QAS
2796 * else if non RAID, do not disable
2797 * QAS if bit 1 is set
2798 * bit 1 QAS support, non-raid only
2801 if (target->raidVolume == 1) {
2810 if (!sdev->tagged_supported) {
2811 target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
2814 /* Update tflags based on NVRAM settings. (SCSI only)
2816 if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
2817 nvram = pspi_data->nvram[id];
2818 nfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
2821 width = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
2824 /* Ensure factor is set to the
2825 * maximum of: adapter, nvram, inquiry
2828 if (nfactor < pspi_data->minSyncFactor )
2829 nfactor = pspi_data->minSyncFactor;
2831 factor = max(factor, nfactor);
2832 if (factor == MPT_ASYNC)
2843 /* Make sure data is consistent
2845 if ((!width) && (factor < MPT_ULTRA2)) {
2846 factor = MPT_ULTRA2;
2849 /* Save the data to the target structure.
2851 target->minSyncFactor = factor;
2852 target->maxOffset = offset;
2853 target->maxWidth = width;
2855 target->tflags |= MPT_TARGET_FLAGS_VALID_NEGO;
2857 /* Disable unused features.
2860 target->negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
2863 target->negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
2865 if ( factor > MPT_ULTRA320 )
2868 if (noQas && (pspi_data->noQas == 0)) {
2869 pspi_data->noQas |= MPT_TARGET_NO_NEGO_QAS;
2870 target->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
2872 /* Disable QAS in a mixed configuration case
2875 ddvtprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id));
2879 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2881 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2883 * SCSI Config Page functionality ...
2886 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2887 /* mptscsih_writeIOCPage4 - write IOC Page 4
2888 * @hd: Pointer to a SCSI Host Structure
2889 * @target_id: write IOC Page4 for this ID & Bus
2891 * Return: -EAGAIN if unable to obtain a Message Frame
2894 * Remark: We do not wait for a return, write pages sequentially.
2897 mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus)
2899 MPT_ADAPTER *ioc = hd->ioc;
2901 IOCPage4_t *IOCPage4Ptr;
2909 /* Get a MF for this command.
2911 if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
2912 dfailprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n",
2917 /* Set the request and the data pointers.
2918 * Place data at end of MF.
2920 pReq = (Config_t *)mf;
2922 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2923 frameOffset = ioc->req_sz - sizeof(IOCPage4_t);
2925 /* Complete the request frame (same for all requests).
2927 pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
2929 pReq->ChainOffset = 0;
2930 pReq->Function = MPI_FUNCTION_CONFIG;
2931 pReq->ExtPageLength = 0;
2932 pReq->ExtPageType = 0;
2934 for (ii=0; ii < 8; ii++) {
2935 pReq->Reserved2[ii] = 0;
2938 IOCPage4Ptr = ioc->spi_data.pIocPg4;
2939 dataDma = ioc->spi_data.IocPg4_dma;
2940 ii = IOCPage4Ptr->ActiveSEP++;
2941 IOCPage4Ptr->SEP[ii].SEPTargetID = target_id;
2942 IOCPage4Ptr->SEP[ii].SEPBus = bus;
2943 pReq->Header = IOCPage4Ptr->Header;
2944 pReq->PageAddress = cpu_to_le32(target_id | (bus << 8 ));
2946 /* Add a SGE to the config request.
2948 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE |
2949 (IOCPage4Ptr->Header.PageLength + ii) * 4;
2951 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma);
2953 dinitprintk((MYIOC_s_INFO_FMT
2954 "writeIOCPage4: MaxSEP=%d ActiveSEP=%d id=%d bus=%d\n",
2955 ioc->name, IOCPage4Ptr->MaxSEP, IOCPage4Ptr->ActiveSEP, target_id, bus));
2957 mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
2962 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2964 * Bus Scan and Domain Validation functionality ...
2967 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2969 * mptscsih_scandv_complete - Scan and DV callback routine registered
2970 * to Fustion MPT (base) driver.
2972 * @ioc: Pointer to MPT_ADAPTER structure
2973 * @mf: Pointer to original MPT request frame
2974 * @mr: Pointer to MPT reply frame (NULL if TurboReply)
2976 * This routine is called from mpt.c::mpt_interrupt() at the completion
2977 * of any SCSI IO request.
2978 * This routine is registered with the Fusion MPT (base) driver at driver
2979 * load/init time via the mpt_register() API call.
2981 * Returns 1 indicating alloc'd request frame ptr should be freed.
2983 * Remark: Sets a completion code and (possibly) saves sense data
2984 * in the IOC member localReply structure.
2985 * Used ONLY for DV and other internal commands.
2988 mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
2991 SCSIIORequest_t *pReq;
2995 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2998 (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) {
2999 printk(MYIOC_s_ERR_FMT
3000 "ScanDvComplete, %s req frame ptr! (=%p)\n",
3001 ioc->name, mf?"BAD":"NULL", (void *) mf);
3005 del_timer(&hd->timer);
3006 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3007 hd->ScsiLookup[req_idx] = NULL;
3008 pReq = (SCSIIORequest_t *) mf;
3010 if (mf != hd->cmdPtr) {
3011 printk(MYIOC_s_WARN_FMT "ScanDvComplete (mf=%p, cmdPtr=%p, idx=%d)\n",
3012 hd->ioc->name, (void *)mf, (void *) hd->cmdPtr, req_idx);
3016 ddvprintk((MYIOC_s_INFO_FMT "ScanDvComplete (mf=%p,mr=%p,idx=%d)\n",
3017 hd->ioc->name, mf, mr, req_idx));
3019 hd->pLocal = &hd->localReply;
3020 hd->pLocal->scsiStatus = 0;
3022 /* If target struct exists, clear sense valid flag.
3025 completionCode = MPT_SCANDV_GOOD;
3027 SCSIIOReply_t *pReply;
3031 pReply = (SCSIIOReply_t *) mr;
3033 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
3034 scsi_status = pReply->SCSIStatus;
3036 ddvtprintk((KERN_NOTICE " IOCStatus=%04xh, SCSIState=%02xh, SCSIStatus=%02xh, IOCLogInfo=%08xh\n",
3037 status, pReply->SCSIState, scsi_status,
3038 le32_to_cpu(pReply->IOCLogInfo)));
3042 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
3043 completionCode = MPT_SCANDV_SELECTION_TIMEOUT;
3046 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
3047 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
3048 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
3049 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
3050 completionCode = MPT_SCANDV_DID_RESET;
3053 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
3054 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
3055 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
3056 if (pReply->Function == MPI_FUNCTION_CONFIG) {
3057 ConfigReply_t *pr = (ConfigReply_t *)mr;
3058 completionCode = MPT_SCANDV_GOOD;
3059 hd->pLocal->header.PageVersion = pr->Header.PageVersion;
3060 hd->pLocal->header.PageLength = pr->Header.PageLength;
3061 hd->pLocal->header.PageNumber = pr->Header.PageNumber;
3062 hd->pLocal->header.PageType = pr->Header.PageType;
3064 } else if (pReply->Function == MPI_FUNCTION_RAID_ACTION) {
3065 /* If the RAID Volume request is successful,
3066 * return GOOD, else indicate that
3067 * some type of error occurred.
3069 MpiRaidActionReply_t *pr = (MpiRaidActionReply_t *)mr;
3070 if (le16_to_cpu(pr->ActionStatus) == MPI_RAID_ACTION_ASTATUS_SUCCESS)
3071 completionCode = MPT_SCANDV_GOOD;
3073 completionCode = MPT_SCANDV_SOME_ERROR;
3074 memcpy(hd->pLocal->sense, pr, sizeof(hd->pLocal->sense));
3076 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID) {
3080 /* save sense data in global structure
3082 completionCode = MPT_SCANDV_SENSE;
3083 hd->pLocal->scsiStatus = scsi_status;
3084 sense_data = ((u8 *)hd->ioc->sense_buf_pool +
3085 (req_idx * MPT_SENSE_BUFFER_ALLOC));
3087 sz = min_t(int, pReq->SenseBufferLength,
3088 SCSI_STD_SENSE_BYTES);
3089 memcpy(hd->pLocal->sense, sense_data, sz);
3091 ddvprintk((KERN_NOTICE " Check Condition, sense ptr %p\n",
3093 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_FAILED) {
3094 if (pReq->CDB[0] == INQUIRY)
3095 completionCode = MPT_SCANDV_ISSUE_SENSE;
3097 completionCode = MPT_SCANDV_DID_RESET;
3099 else if (pReply->SCSIState & MPI_SCSI_STATE_NO_SCSI_STATUS)
3100 completionCode = MPT_SCANDV_DID_RESET;
3101 else if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
3102 completionCode = MPT_SCANDV_DID_RESET;
3104 completionCode = MPT_SCANDV_GOOD;
3105 hd->pLocal->scsiStatus = scsi_status;
3109 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
3110 if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
3111 completionCode = MPT_SCANDV_DID_RESET;
3113 completionCode = MPT_SCANDV_SOME_ERROR;
3117 completionCode = MPT_SCANDV_SOME_ERROR;
3120 } /* switch(status) */
3122 ddvtprintk((KERN_NOTICE " completionCode set to %08xh\n",
3124 } /* end of address reply case */
3126 hd->pLocal->completion = completionCode;
3128 /* MF and RF are freed in mpt_interrupt
3131 /* Free Chain buffers (will never chain) in scan or dv */
3132 //mptscsih_freeChainBuffers(ioc, req_idx);
3135 * Wake up the original calling thread
3137 hd->scandv_wait_done = 1;
3138 wake_up(&hd->scandv_waitq);
3143 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3144 /* mptscsih_timer_expired - Call back for timer process.
3145 * Used only for dv functionality.
3146 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
3150 mptscsih_timer_expired(unsigned long data)
3152 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) data;
3154 ddvprintk((MYIOC_s_WARN_FMT "Timer Expired! Cmd %p\n", hd->ioc->name, hd->cmdPtr));
3157 MPIHeader_t *cmd = (MPIHeader_t *)hd->cmdPtr;
3159 if (cmd->Function == MPI_FUNCTION_SCSI_IO_REQUEST) {
3160 /* Desire to issue a task management request here.
3161 * TM requests MUST be single threaded.
3162 * If old eh code and no TM current, issue request.
3163 * If new eh code, do nothing. Wait for OS cmd timeout
3166 ddvtprintk((MYIOC_s_NOTE_FMT "DV Cmd Timeout: NoOp\n", hd->ioc->name));
3168 /* Perform a FW reload */
3169 if (mpt_HardResetHandler(hd->ioc, NO_SLEEP) < 0) {
3170 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", hd->ioc->name);
3174 /* This should NEVER happen */
3175 printk(MYIOC_s_WARN_FMT "Null cmdPtr!!!!\n", hd->ioc->name);
3178 /* No more processing.
3179 * TM call will generate an interrupt for SCSI TM Management.
3180 * The FW will reply to all outstanding commands, callback will finish cleanup.
3181 * Hard reset clean-up will free all resources.
3183 ddvprintk((MYIOC_s_WARN_FMT "Timer Expired Complete!\n", hd->ioc->name));
3189 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3191 * mptscsih_do_cmd - Do internal command.
3192 * @hd: MPT_SCSI_HOST pointer
3193 * @io: INTERNAL_CMD pointer.
3195 * Issue the specified internally generated command and do command
3196 * specific cleanup. For bus scan / DV only.
3197 * NOTES: If command is Inquiry and status is good,
3198 * initialize a target structure, save the data
3200 * Remark: Single threaded access only.
3203 * < 0 if an illegal command or no resources
3207 * > 0 if command complete but some type of completion error.
3210 mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
3213 SCSIIORequest_t *pScsiReq;
3214 SCSIIORequest_t ReqCopy;
3215 int my_idx, ii, dir;
3219 char CDB[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
3222 in_isr = in_interrupt();
3224 dprintk((MYIOC_s_WARN_FMT "Internal SCSI IO request not allowed in ISR context!\n",
3230 /* Set command specific information
3235 dir = MPI_SCSIIO_CONTROL_READ;
3241 case TEST_UNIT_READY:
3243 dir = MPI_SCSIIO_CONTROL_READ;
3249 dir = MPI_SCSIIO_CONTROL_READ;
3251 CDB[4] = 1; /*Spin up the disk */
3259 dir = MPI_SCSIIO_CONTROL_READ;
3265 dir = MPI_SCSIIO_CONTROL_READ;
3267 if (io->flags & MPT_ICFLAG_ECHO) {
3273 if (io->flags & MPT_ICFLAG_BUF_CAP) {
3276 CDB[6] = (io->size >> 16) & 0xFF;
3277 CDB[7] = (io->size >> 8) & 0xFF;
3278 CDB[8] = io->size & 0xFF;
3284 dir = MPI_SCSIIO_CONTROL_WRITE;
3286 if (io->flags & MPT_ICFLAG_ECHO) {
3291 CDB[6] = (io->size >> 16) & 0xFF;
3292 CDB[7] = (io->size >> 8) & 0xFF;
3293 CDB[8] = io->size & 0xFF;
3299 dir = MPI_SCSIIO_CONTROL_READ;
3306 dir = MPI_SCSIIO_CONTROL_READ;
3311 case SYNCHRONIZE_CACHE:
3313 dir = MPI_SCSIIO_CONTROL_READ;
3315 // CDB[1] = 0x02; /* set immediate bit */
3324 /* Get and Populate a free Frame
3326 if ((mf = mpt_get_msg_frame(hd->ioc->InternalCtx, hd->ioc)) == NULL) {
3327 ddvprintk((MYIOC_s_WARN_FMT "No msg frames!\n",
3332 pScsiReq = (SCSIIORequest_t *) mf;
3334 /* Get the request index */
3335 my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3336 ADD_INDEX_LOG(my_idx); /* for debug */
3338 if (io->flags & MPT_ICFLAG_PHYS_DISK) {
3339 pScsiReq->TargetID = io->physDiskNum;
3341 pScsiReq->ChainOffset = 0;
3342 pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
3344 pScsiReq->TargetID = io->id;
3345 pScsiReq->Bus = io->bus;
3346 pScsiReq->ChainOffset = 0;
3347 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
3350 pScsiReq->CDBLength = cmdLen;
3351 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
3353 pScsiReq->Reserved = 0;
3355 pScsiReq->MsgFlags = mpt_msg_flags();
3356 /* MsgContext set in mpt_get_msg_fram call */
3358 for (ii=0; ii < 8; ii++)
3359 pScsiReq->LUN[ii] = 0;
3360 pScsiReq->LUN[1] = io->lun;
3362 if (io->flags & MPT_ICFLAG_TAGGED_CMD)
3363 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ);
3365 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3367 if (cmd == REQUEST_SENSE) {
3368 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3369 ddvprintk((MYIOC_s_INFO_FMT "Untagged! 0x%2x\n",
3370 hd->ioc->name, cmd));
3373 for (ii=0; ii < 16; ii++)
3374 pScsiReq->CDB[ii] = CDB[ii];
3376 pScsiReq->DataLength = cpu_to_le32(io->size);
3377 pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
3378 + (my_idx * MPT_SENSE_BUFFER_ALLOC));
3380 ddvprintk((MYIOC_s_INFO_FMT "Sending Command 0x%x for (%d:%d:%d)\n",
3381 hd->ioc->name, cmd, io->bus, io->id, io->lun));
3383 if (dir == MPI_SCSIIO_CONTROL_READ) {
3384 mpt_add_sge((char *) &pScsiReq->SGL,
3385 MPT_SGE_FLAGS_SSIMPLE_READ | io->size,
3388 mpt_add_sge((char *) &pScsiReq->SGL,
3389 MPT_SGE_FLAGS_SSIMPLE_WRITE | io->size,
3393 /* The ISR will free the request frame, but we need
3394 * the information to initialize the target. Duplicate.
3396 memcpy(&ReqCopy, pScsiReq, sizeof(SCSIIORequest_t));
3398 /* Issue this command after:
3401 * Wait until the reply has been received
3402 * ScsiScanDvCtx callback function will
3404 * set scandv_wait_done and call wake_up
3407 hd->timer.expires = jiffies + HZ*cmdTimeout;
3408 hd->scandv_wait_done = 0;
3410 /* Save cmd pointer, for resource free if timeout or
3415 add_timer(&hd->timer);
3416 mpt_put_msg_frame(hd->ioc->InternalCtx, hd->ioc, mf);
3417 wait_event(hd->scandv_waitq, hd->scandv_wait_done);
3420 rc = hd->pLocal->completion;
3421 hd->pLocal->skip = 0;
3423 /* Always set fatal error codes in some cases.
3425 if (rc == MPT_SCANDV_SELECTION_TIMEOUT)
3427 else if (rc == MPT_SCANDV_SOME_ERROR)
3431 /* This should never happen. */
3432 ddvprintk((MYIOC_s_INFO_FMT "_do_cmd: Null pLocal!!!\n",
3439 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3441 * mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
3442 * @hd: Pointer to a SCSI HOST structure
3443 * @vdevice: virtual target device
3445 * Uses the ISR, but with special processing.
3446 * MUST be single-threaded.
3450 mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
3454 /* Following parameters will not change
3457 iocmd.cmd = SYNCHRONIZE_CACHE;
3459 iocmd.physDiskNum = -1;
3461 iocmd.data_dma = -1;
3463 iocmd.rsvd = iocmd.rsvd2 = 0;
3464 iocmd.bus = vdevice->vtarget->bus_id;
3465 iocmd.id = vdevice->vtarget->target_id;
3466 iocmd.lun = (u8)vdevice->lun;
3468 if ((vdevice->vtarget->type == TYPE_DISK) &&
3469 (vdevice->configured_lun))
3470 mptscsih_do_cmd(hd, &iocmd);
3473 EXPORT_SYMBOL(mptscsih_remove);
3474 EXPORT_SYMBOL(mptscsih_shutdown);
3476 EXPORT_SYMBOL(mptscsih_suspend);
3477 EXPORT_SYMBOL(mptscsih_resume);
3479 EXPORT_SYMBOL(mptscsih_proc_info);
3480 EXPORT_SYMBOL(mptscsih_info);
3481 EXPORT_SYMBOL(mptscsih_qcmd);
3482 EXPORT_SYMBOL(mptscsih_target_alloc);
3483 EXPORT_SYMBOL(mptscsih_slave_alloc);
3484 EXPORT_SYMBOL(mptscsih_target_destroy);
3485 EXPORT_SYMBOL(mptscsih_slave_destroy);
3486 EXPORT_SYMBOL(mptscsih_slave_configure);
3487 EXPORT_SYMBOL(mptscsih_abort);
3488 EXPORT_SYMBOL(mptscsih_dev_reset);
3489 EXPORT_SYMBOL(mptscsih_bus_reset);
3490 EXPORT_SYMBOL(mptscsih_host_reset);
3491 EXPORT_SYMBOL(mptscsih_bios_param);
3492 EXPORT_SYMBOL(mptscsih_io_done);
3493 EXPORT_SYMBOL(mptscsih_taskmgmt_complete);
3494 EXPORT_SYMBOL(mptscsih_scandv_complete);
3495 EXPORT_SYMBOL(mptscsih_event_process);
3496 EXPORT_SYMBOL(mptscsih_ioc_reset);
3497 EXPORT_SYMBOL(mptscsih_change_queue_depth);
3498 EXPORT_SYMBOL(mptscsih_timer_expired);
3499 EXPORT_SYMBOL(mptscsih_TMHandler);
3501 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/