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);
707 * Allow non-SAS & non-NEXUS_LOSS to drop into below code
710 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
711 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
712 /* Linux handles an unsolicited DID_RESET better
713 * than an unsolicited DID_ABORT.
715 sc->result = DID_RESET << 16;
719 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
720 sc->resid = sc->request_bufflen - xfer_cnt;
721 if((xfer_cnt==0)||(sc->underflow > xfer_cnt))
722 sc->result=DID_SOFT_ERROR << 16;
723 else /* Sufficient data transfer occurred */
724 sc->result = (DID_OK << 16) | scsi_status;
725 dreplyprintk((KERN_NOTICE
726 "RESIDUAL_MISMATCH: result=%x on id=%d\n", sc->result, sc->device->id));
729 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
731 * Do upfront check for valid SenseData and give it
734 sc->result = (DID_OK << 16) | scsi_status;
735 if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
736 /* Have already saved the status and sense data
740 if (xfer_cnt < sc->underflow) {
741 if (scsi_status == SAM_STAT_BUSY)
742 sc->result = SAM_STAT_BUSY;
744 sc->result = DID_SOFT_ERROR << 16;
746 if (scsi_state & (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)) {
749 sc->result = DID_SOFT_ERROR << 16;
751 else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
752 /* Not real sure here either... */
753 sc->result = DID_RESET << 16;
757 dreplyprintk((KERN_NOTICE " sc->underflow={report ERR if < %02xh bytes xfer'd}\n",
759 dreplyprintk((KERN_NOTICE " ActBytesXferd=%02xh\n", xfer_cnt));
762 if (scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)
763 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
767 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
769 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
770 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
771 if (scsi_status == MPI_SCSI_STATUS_BUSY)
772 sc->result = (DID_BUS_BUSY << 16) | scsi_status;
774 sc->result = (DID_OK << 16) | scsi_status;
775 if (scsi_state == 0) {
777 } else if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
779 * If running against circa 200003dd 909 MPT f/w,
780 * may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL
781 * (QUEUE_FULL) returned from device! --> get 0x0000?128
782 * and with SenseBytes set to 0.
784 if (pScsiReply->SCSIStatus == MPI_SCSI_STATUS_TASK_SET_FULL)
785 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
788 else if (scsi_state &
789 (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)
794 sc->result = DID_SOFT_ERROR << 16;
796 else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
797 /* Not real sure here either... */
798 sc->result = DID_RESET << 16;
800 else if (scsi_state & MPI_SCSI_STATE_QUEUE_TAG_REJECTED) {
801 /* Device Inq. data indicates that it supports
802 * QTags, but rejects QTag messages.
803 * This command completed OK.
805 * Not real sure here either so do nothing... */
808 if (sc->result == MPI_SCSI_STATUS_TASK_SET_FULL)
809 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
812 * Reservation Conflict, Busy,
813 * Command Terminated, CHECK
817 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
818 sc->result = DID_SOFT_ERROR << 16;
821 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
822 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
823 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
824 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
825 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
826 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
827 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
828 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
829 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
834 sc->result = DID_SOFT_ERROR << 16;
837 } /* switch(status) */
839 dreplyprintk((KERN_NOTICE " sc->result is %08xh\n", sc->result));
840 } /* end of address reply case */
842 /* Unmap the DMA buffers, if any. */
844 pci_unmap_sg(ioc->pcidev, (struct scatterlist *) sc->request_buffer,
845 sc->use_sg, sc->sc_data_direction);
846 } else if (sc->request_bufflen) {
847 pci_unmap_single(ioc->pcidev, sc->SCp.dma_handle,
848 sc->request_bufflen, sc->sc_data_direction);
851 sc->scsi_done(sc); /* Issue the command callback */
853 /* Free Chain buffers */
854 mptscsih_freeChainBuffers(ioc, req_idx);
859 * mptscsih_flush_running_cmds - For each command found, search
860 * Scsi_Host instance taskQ and reply to OS.
861 * Called only if recovering from a FW reload.
862 * @hd: Pointer to a SCSI HOST structure
866 * Must be called while new I/Os are being queued.
869 mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
871 MPT_ADAPTER *ioc = hd->ioc;
872 struct scsi_cmnd *SCpnt;
875 int max = ioc->req_depth;
877 dprintk((KERN_INFO MYNAM ": flush_ScsiLookup called\n"));
878 for (ii= 0; ii < max; ii++) {
879 if ((SCpnt = hd->ScsiLookup[ii]) != NULL) {
884 /* Null ScsiLookup index
886 hd->ScsiLookup[ii] = NULL;
888 mf = MPT_INDEX_2_MFPTR(ioc, ii);
889 dmfprintk(( "flush: ScsiDone (mf=%p,sc=%p)\n",
892 /* Free Chain buffers */
893 mptscsih_freeChainBuffers(ioc, ii);
895 /* Free Message frames */
896 mpt_free_msg_frame(ioc, mf);
898 if ((unsigned char *)mf != SCpnt->host_scribble)
901 /* Set status, free OS resources (SG DMA buffers)
905 pci_unmap_sg(ioc->pcidev,
906 (struct scatterlist *) SCpnt->request_buffer,
908 SCpnt->sc_data_direction);
909 } else if (SCpnt->request_bufflen) {
910 pci_unmap_single(ioc->pcidev,
911 SCpnt->SCp.dma_handle,
912 SCpnt->request_bufflen,
913 SCpnt->sc_data_direction);
915 SCpnt->result = DID_RESET << 16;
916 SCpnt->host_scribble = NULL;
918 SCpnt->scsi_done(SCpnt); /* Issue the command callback */
926 * mptscsih_search_running_cmds - Delete any commands associated
927 * with the specified target and lun. Function called only
928 * when a lun is disable by mid-layer.
929 * Do NOT access the referenced scsi_cmnd structure or
930 * members. Will cause either a paging or NULL ptr error.
931 * (BUT, BUT, BUT, the code does reference it! - mdr)
932 * @hd: Pointer to a SCSI HOST structure
933 * @vdevice: per device private data
937 * Called from slave_destroy.
940 mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
942 SCSIIORequest_t *mf = NULL;
944 int max = hd->ioc->req_depth;
945 struct scsi_cmnd *sc;
947 dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n",
948 vdevice->vtarget->target_id, vdevice->lun, max));
950 for (ii=0; ii < max; ii++) {
951 if ((sc = hd->ScsiLookup[ii]) != NULL) {
953 mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii);
956 dsprintk(( "search_running: found (sc=%p, mf = %p) target %d, lun %d \n",
957 hd->ScsiLookup[ii], mf, mf->TargetID, mf->LUN[1]));
958 if ((mf->TargetID != ((u8)vdevice->vtarget->target_id)) || (mf->LUN[1] != ((u8) vdevice->lun)))
963 hd->ScsiLookup[ii] = NULL;
964 mptscsih_freeChainBuffers(hd->ioc, ii);
965 mpt_free_msg_frame(hd->ioc, (MPT_FRAME_HDR *)mf);
966 if ((unsigned char *)mf != sc->host_scribble)
969 pci_unmap_sg(hd->ioc->pcidev,
970 (struct scatterlist *) sc->request_buffer,
972 sc->sc_data_direction);
973 } else if (sc->request_bufflen) {
974 pci_unmap_single(hd->ioc->pcidev,
977 sc->sc_data_direction);
979 sc->host_scribble = NULL;
980 sc->result = DID_NO_CONNECT << 16;
987 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
989 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
991 * mptscsih_report_queue_full - Report QUEUE_FULL status returned
992 * from a SCSI target device.
993 * @sc: Pointer to scsi_cmnd structure
994 * @pScsiReply: Pointer to SCSIIOReply_t
995 * @pScsiReq: Pointer to original SCSI request
997 * This routine periodically reports QUEUE_FULL status returned from a
998 * SCSI target device. It reports this to the console via kernel
999 * printk() API call, not more than once every 10 seconds.
1002 mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq)
1004 long time = jiffies;
1007 if (sc->device == NULL)
1009 if (sc->device->host == NULL)
1011 if ((hd = (MPT_SCSI_HOST *)sc->device->host->hostdata) == NULL)
1014 if (time - hd->last_queue_full > 10 * HZ) {
1015 dprintk((MYIOC_s_WARN_FMT "Device (%d:%d:%d) reported QUEUE_FULL!\n",
1016 hd->ioc->name, 0, sc->device->id, sc->device->lun));
1017 hd->last_queue_full = time;
1021 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1023 * mptscsih_remove - Removed scsi devices
1024 * @pdev: Pointer to pci_dev structure
1029 mptscsih_remove(struct pci_dev *pdev)
1031 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1032 struct Scsi_Host *host = ioc->sh;
1041 scsi_remove_host(host);
1043 if((hd = (MPT_SCSI_HOST *)host->hostdata) == NULL)
1046 mptscsih_shutdown(pdev);
1050 if (hd->ScsiLookup != NULL) {
1051 sz1 = hd->ioc->req_depth * sizeof(void *);
1052 kfree(hd->ScsiLookup);
1053 hd->ScsiLookup = NULL;
1057 * Free pointer array.
1062 dprintk((MYIOC_s_INFO_FMT
1063 "Free'd ScsiLookup (%d) memory\n",
1064 hd->ioc->name, sz1));
1066 kfree(hd->info_kbuf);
1068 /* NULL the Scsi_Host pointer
1072 scsi_host_put(host);
1078 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1080 * mptscsih_shutdown - reboot notifier
1084 mptscsih_shutdown(struct pci_dev *pdev)
1086 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1087 struct Scsi_Host *host = ioc->sh;
1093 hd = (MPT_SCSI_HOST *)host->hostdata;
1098 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1100 * mptscsih_suspend - Fusion MPT scsi driver suspend routine.
1105 mptscsih_suspend(struct pci_dev *pdev, pm_message_t state)
1107 mptscsih_shutdown(pdev);
1108 return mpt_suspend(pdev,state);
1111 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1113 * mptscsih_resume - Fusion MPT scsi driver resume routine.
1118 mptscsih_resume(struct pci_dev *pdev)
1120 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1121 struct Scsi_Host *host = ioc->sh;
1129 hd = (MPT_SCSI_HOST *)host->hostdata;
1138 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1140 * mptscsih_info - Return information about MPT adapter
1141 * @SChost: Pointer to Scsi_Host structure
1143 * (linux scsi_host_template.info routine)
1145 * Returns pointer to buffer where information was written.
1148 mptscsih_info(struct Scsi_Host *SChost)
1153 h = (MPT_SCSI_HOST *)SChost->hostdata;
1156 if (h->info_kbuf == NULL)
1157 if ((h->info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)
1158 return h->info_kbuf;
1159 h->info_kbuf[0] = '\0';
1161 mpt_print_ioc_summary(h->ioc, h->info_kbuf, &size, 0, 0);
1162 h->info_kbuf[size-1] = '\0';
1165 return h->info_kbuf;
1176 mptscsih_copy_mem_info(struct info_str *info, char *data, int len)
1178 if (info->pos + len > info->length)
1179 len = info->length - info->pos;
1181 if (info->pos + len < info->offset) {
1186 if (info->pos < info->offset) {
1187 data += (info->offset - info->pos);
1188 len -= (info->offset - info->pos);
1192 memcpy(info->buffer + info->pos, data, len);
1198 mptscsih_copy_info(struct info_str *info, char *fmt, ...)
1204 va_start(args, fmt);
1205 len = vsprintf(buf, fmt, args);
1208 mptscsih_copy_mem_info(info, buf, len);
1213 mptscsih_host_info(MPT_ADAPTER *ioc, char *pbuf, off_t offset, int len)
1215 struct info_str info;
1219 info.offset = offset;
1222 mptscsih_copy_info(&info, "%s: %s, ", ioc->name, ioc->prod_name);
1223 mptscsih_copy_info(&info, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING, ioc->facts.FWVersion.Word);
1224 mptscsih_copy_info(&info, "Ports=%d, ", ioc->facts.NumberOfPorts);
1225 mptscsih_copy_info(&info, "MaxQ=%d\n", ioc->req_depth);
1227 return ((info.pos > info.offset) ? info.pos - info.offset : 0);
1230 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1232 * mptscsih_proc_info - Return information about MPT adapter
1234 * (linux scsi_host_template.info routine)
1236 * buffer: if write, user data; if read, buffer for user
1237 * length: if write, return length;
1238 * offset: if write, 0; if read, the current offset into the buffer from
1239 * the previous read.
1240 * hostno: scsi host number
1241 * func: if write = 1; if read = 0
1244 mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
1245 int length, int func)
1247 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
1248 MPT_ADAPTER *ioc = hd->ioc;
1253 * write is not supported
1259 size = mptscsih_host_info(ioc, buffer, offset, length);
1265 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1266 #define ADD_INDEX_LOG(req_ent) do { } while(0)
1268 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1270 * mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine.
1271 * @SCpnt: Pointer to scsi_cmnd structure
1272 * @done: Pointer SCSI mid-layer IO completion function
1274 * (linux scsi_host_template.queuecommand routine)
1275 * This is the primary SCSI IO start routine. Create a MPI SCSIIORequest
1276 * from a linux scsi_cmnd request and send it to the IOC.
1278 * Returns 0. (rtn value discarded by linux scsi mid-layer)
1281 mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1285 SCSIIORequest_t *pScsiReq;
1286 VirtDevice *vdev = SCpnt->device->hostdata;
1295 hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata;
1296 lun = SCpnt->device->lun;
1297 SCpnt->scsi_done = done;
1299 dmfprintk((MYIOC_s_INFO_FMT "qcmd: SCpnt=%p, done()=%p\n",
1300 (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt, done));
1302 if (hd->resetPending) {
1303 dtmprintk((MYIOC_s_WARN_FMT "qcmd: SCpnt=%p timeout + 60HZ\n",
1304 (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt));
1305 return SCSI_MLQUEUE_HOST_BUSY;
1308 if ((hd->ioc->bus_type == SPI) &&
1309 vdev->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT &&
1310 mptscsih_raid_id_to_num(hd, SCpnt->device->id) < 0) {
1311 SCpnt->result = DID_NO_CONNECT << 16;
1317 * Put together a MPT SCSI request...
1319 if ((mf = mpt_get_msg_frame(hd->ioc->DoneCtx, hd->ioc)) == NULL) {
1320 dprintk((MYIOC_s_WARN_FMT "QueueCmd, no msg frames!!\n",
1322 return SCSI_MLQUEUE_HOST_BUSY;
1325 pScsiReq = (SCSIIORequest_t *) mf;
1327 my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
1329 ADD_INDEX_LOG(my_idx);
1331 /* TUR's being issued with scsictl=0x02000000 (DATA_IN)!
1332 * Seems we may receive a buffer (datalen>0) even when there
1333 * will be no data transfer! GRRRRR...
1335 if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
1336 datalen = SCpnt->request_bufflen;
1337 scsidir = MPI_SCSIIO_CONTROL_READ; /* DATA IN (host<--ioc<--dev) */
1338 } else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
1339 datalen = SCpnt->request_bufflen;
1340 scsidir = MPI_SCSIIO_CONTROL_WRITE; /* DATA OUT (host-->ioc-->dev) */
1343 scsidir = MPI_SCSIIO_CONTROL_NODATATRANSFER;
1346 /* Default to untagged. Once a target structure has been allocated,
1347 * use the Inquiry data to determine if device supports tagged.
1350 && (vdev->vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)
1351 && (SCpnt->device->tagged_supported)) {
1352 scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
1354 scsictl = scsidir | MPI_SCSIIO_CONTROL_UNTAGGED;
1357 /* Use the above information to set up the message frame
1359 pScsiReq->TargetID = (u8) vdev->vtarget->target_id;
1360 pScsiReq->Bus = vdev->vtarget->bus_id;
1361 pScsiReq->ChainOffset = 0;
1362 if (vdev->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
1363 pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
1365 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
1366 pScsiReq->CDBLength = SCpnt->cmd_len;
1367 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
1368 pScsiReq->Reserved = 0;
1369 pScsiReq->MsgFlags = mpt_msg_flags();
1370 pScsiReq->LUN[0] = 0;
1371 pScsiReq->LUN[1] = lun;
1372 pScsiReq->LUN[2] = 0;
1373 pScsiReq->LUN[3] = 0;
1374 pScsiReq->LUN[4] = 0;
1375 pScsiReq->LUN[5] = 0;
1376 pScsiReq->LUN[6] = 0;
1377 pScsiReq->LUN[7] = 0;
1378 pScsiReq->Control = cpu_to_le32(scsictl);
1381 * Write SCSI CDB into the message
1383 cmd_len = SCpnt->cmd_len;
1384 for (ii=0; ii < cmd_len; ii++)
1385 pScsiReq->CDB[ii] = SCpnt->cmnd[ii];
1387 for (ii=cmd_len; ii < 16; ii++)
1388 pScsiReq->CDB[ii] = 0;
1391 pScsiReq->DataLength = cpu_to_le32(datalen);
1393 /* SenseBuffer low address */
1394 pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
1395 + (my_idx * MPT_SENSE_BUFFER_ALLOC));
1397 /* Now add the SG list
1398 * Always have a SGE even if null length.
1401 /* Add a NULL SGE */
1402 mptscsih_add_sge((char *)&pScsiReq->SGL, MPT_SGE_FLAGS_SSIMPLE_READ | 0,
1405 /* Add a 32 or 64 bit SGE */
1406 if (mptscsih_AddSGE(hd->ioc, SCpnt, pScsiReq, my_idx) != SUCCESS)
1410 SCpnt->host_scribble = (unsigned char *)mf;
1411 hd->ScsiLookup[my_idx] = SCpnt;
1413 mpt_put_msg_frame(hd->ioc->DoneCtx, hd->ioc, mf);
1414 dmfprintk((MYIOC_s_INFO_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n",
1415 hd->ioc->name, SCpnt, mf, my_idx));
1416 DBG_DUMP_REQUEST_FRAME(mf)
1420 hd->ScsiLookup[my_idx] = NULL;
1421 mptscsih_freeChainBuffers(hd->ioc, my_idx);
1422 mpt_free_msg_frame(hd->ioc, mf);
1423 return SCSI_MLQUEUE_HOST_BUSY;
1426 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1428 * mptscsih_freeChainBuffers - Function to free chain buffers associated
1429 * with a SCSI IO request
1430 * @hd: Pointer to the MPT_SCSI_HOST instance
1431 * @req_idx: Index of the SCSI IO request frame.
1433 * Called if SG chain buffer allocation fails and mptscsih callbacks.
1437 mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
1439 MPT_FRAME_HDR *chain;
1440 unsigned long flags;
1444 /* Get the first chain index and reset
1447 chain_idx = ioc->ReqToChain[req_idx];
1448 ioc->ReqToChain[req_idx] = MPT_HOST_NO_CHAIN;
1450 while (chain_idx != MPT_HOST_NO_CHAIN) {
1452 /* Save the next chain buffer index */
1453 next = ioc->ChainToChain[chain_idx];
1455 /* Free this chain buffer and reset
1458 ioc->ChainToChain[chain_idx] = MPT_HOST_NO_CHAIN;
1460 chain = (MPT_FRAME_HDR *) (ioc->ChainBuffer
1461 + (chain_idx * ioc->req_sz));
1463 spin_lock_irqsave(&ioc->FreeQlock, flags);
1464 list_add_tail(&chain->u.frame.linkage.list, &ioc->FreeChainQ);
1465 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1467 dmfprintk((MYIOC_s_INFO_FMT "FreeChainBuffers (index %d)\n",
1468 ioc->name, chain_idx));
1476 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1481 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1483 * mptscsih_TMHandler - Generic handler for SCSI Task Management.
1484 * Fall through to mpt_HardResetHandler if: not operational, too many
1485 * failed TM requests or handshake failure.
1487 * @ioc: Pointer to MPT_ADAPTER structure
1488 * @type: Task Management type
1489 * @target: Logical Target ID for reset (if appropriate)
1490 * @lun: Logical Unit for reset (if appropriate)
1491 * @ctx2abort: Context for the task to be aborted (if appropriate)
1493 * Remark: Currently invoked from a non-interrupt thread (_bh).
1495 * Remark: With old EH code, at most 1 SCSI TaskMgmt function per IOC
1498 * Returns 0 for SUCCESS or -1 if FAILED.
1501 mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout)
1507 unsigned long flags;
1509 /* If FW is being reloaded currently, return success to
1510 * the calling function.
1517 printk(KERN_ERR MYNAM " TMHandler" " NULL ioc!\n");
1520 dtmprintk((MYIOC_s_INFO_FMT "TMHandler Entered!\n", ioc->name));
1522 // SJR - CHECKME - Can we avoid this here?
1523 // (mpt_HardResetHandler has this check...)
1524 spin_lock_irqsave(&ioc->diagLock, flags);
1525 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)) {
1526 spin_unlock_irqrestore(&ioc->diagLock, flags);
1529 spin_unlock_irqrestore(&ioc->diagLock, flags);
1531 /* Wait a fixed amount of time for the TM pending flag to be cleared.
1532 * If we time out and not bus reset, then we return a FAILED status to the caller.
1533 * The call to mptscsih_tm_pending_wait() will set the pending flag if we are
1534 * successful. Otherwise, reload the FW.
1536 if (mptscsih_tm_pending_wait(hd) == FAILED) {
1537 if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
1538 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler abort: "
1539 "Timed out waiting for last TM (%d) to complete! \n",
1540 hd->ioc->name, hd->tmPending));
1542 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) {
1543 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler target reset: "
1544 "Timed out waiting for last TM (%d) to complete! \n",
1545 hd->ioc->name, hd->tmPending));
1547 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
1548 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler bus reset: "
1549 "Timed out waiting for last TM (%d) to complete! \n",
1550 hd->ioc->name, hd->tmPending));
1551 if (hd->tmPending & (1 << MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS))
1557 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
1558 hd->tmPending |= (1 << type);
1559 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1564 ioc_raw_state = mpt_GetIocState(hd->ioc, 0);
1566 #ifdef MPT_DEBUG_RESET
1567 if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) {
1568 printk(MYIOC_s_WARN_FMT
1569 "TM Handler: IOC Not operational(0x%x)!\n",
1570 hd->ioc->name, ioc_raw_state);
1574 if (doTask && ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL)
1575 && !(ioc_raw_state & MPI_DOORBELL_ACTIVE)) {
1577 /* Isse the Task Mgmt request.
1579 if (hd->hard_resets < -1)
1581 rc = mptscsih_IssueTaskMgmt(hd, type, channel, target, lun, ctx2abort, timeout);
1583 printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n", hd->ioc->name);
1585 dtmprintk((MYIOC_s_INFO_FMT "Issue of TaskMgmt Successful!\n", hd->ioc->name));
1589 /* Only fall through to the HRH if this is a bus reset
1591 if ((type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) && (rc ||
1592 ioc->reload_fw || (ioc->alt_ioc && ioc->alt_ioc->reload_fw))) {
1593 dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
1595 rc = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
1599 * Check IOCStatus from TM reply message
1601 if (hd->tm_iocstatus != MPI_IOCSTATUS_SUCCESS)
1604 dtmprintk((MYIOC_s_INFO_FMT "TMHandler rc = %d!\n", hd->ioc->name, rc));
1610 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1612 * mptscsih_IssueTaskMgmt - Generic send Task Management function.
1613 * @hd: Pointer to MPT_SCSI_HOST structure
1614 * @type: Task Management type
1615 * @target: Logical Target ID for reset (if appropriate)
1616 * @lun: Logical Unit for reset (if appropriate)
1617 * @ctx2abort: Context for the task to be aborted (if appropriate)
1619 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
1620 * or a non-interrupt thread. In the former, must not call schedule().
1622 * Not all fields are meaningfull for all task types.
1624 * Returns 0 for SUCCESS, -999 for "no msg frames",
1625 * else other non-zero value returned.
1628 mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout)
1631 SCSITaskMgmt_t *pScsiTm;
1635 /* Return Fail to calling function if no message frames available.
1637 if ((mf = mpt_get_msg_frame(hd->ioc->TaskCtx, hd->ioc)) == NULL) {
1638 dfailprintk((MYIOC_s_ERR_FMT "IssueTaskMgmt, no msg frames!!\n",
1642 dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt request @ %p\n",
1643 hd->ioc->name, mf));
1645 /* Format the Request
1647 pScsiTm = (SCSITaskMgmt_t *) mf;
1648 pScsiTm->TargetID = target;
1649 pScsiTm->Bus = channel;
1650 pScsiTm->ChainOffset = 0;
1651 pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
1653 pScsiTm->Reserved = 0;
1654 pScsiTm->TaskType = type;
1655 pScsiTm->Reserved1 = 0;
1656 pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)
1657 ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0;
1659 for (ii= 0; ii < 8; ii++) {
1660 pScsiTm->LUN[ii] = 0;
1662 pScsiTm->LUN[1] = lun;
1664 for (ii=0; ii < 7; ii++)
1665 pScsiTm->Reserved2[ii] = 0;
1667 pScsiTm->TaskMsgContext = ctx2abort;
1669 dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt: ctx2abort (0x%08x) type=%d\n",
1670 hd->ioc->name, ctx2abort, type));
1672 DBG_DUMP_TM_REQUEST_FRAME((u32 *)pScsiTm);
1674 if ((retval = mpt_send_handshake_request(hd->ioc->TaskCtx, hd->ioc,
1675 sizeof(SCSITaskMgmt_t), (u32*)pScsiTm,
1677 dfailprintk((MYIOC_s_ERR_FMT "_send_handshake FAILED!"
1678 " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
1680 mpt_free_msg_frame(hd->ioc, mf);
1684 if(mptscsih_tm_wait_for_completion(hd, timeout) == FAILED) {
1685 dfailprintk((MYIOC_s_ERR_FMT "_wait_for_completion FAILED!"
1686 " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
1688 mpt_free_msg_frame(hd->ioc, mf);
1689 dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
1691 retval = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
1698 mptscsih_get_tm_timeout(MPT_ADAPTER *ioc)
1700 switch (ioc->bus_type) {
1711 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1713 * mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant
1714 * @SCpnt: Pointer to scsi_cmnd structure, IO to be aborted
1716 * (linux scsi_host_template.eh_abort_handler routine)
1718 * Returns SUCCESS or FAILED.
1721 mptscsih_abort(struct scsi_cmnd * SCpnt)
1729 ulong sn = SCpnt->serial_number;
1731 /* If we can't locate our host adapter structure, return FAILED status.
1733 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL) {
1734 SCpnt->result = DID_RESET << 16;
1735 SCpnt->scsi_done(SCpnt);
1736 dfailprintk((KERN_INFO MYNAM ": mptscsih_abort: "
1737 "Can't locate host! (sc=%p)\n",
1742 /* Find this command
1744 if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) {
1745 /* Cmd not found in ScsiLookup.
1748 SCpnt->result = DID_RESET << 16;
1749 dtmprintk((KERN_INFO MYNAM ": %s: mptscsih_abort: "
1750 "Command not in the active list! (sc=%p)\n",
1751 hd->ioc->name, SCpnt));
1755 if (hd->resetPending) {
1759 if (hd->timeouts < -1)
1762 printk(KERN_WARNING MYNAM ": %s: attempting task abort! (sc=%p)\n",
1763 hd->ioc->name, SCpnt);
1764 scsi_print_command(SCpnt);
1766 /* Most important! Set TaskMsgContext to SCpnt's MsgContext!
1767 * (the IO to be ABORT'd)
1769 * NOTE: Since we do not byteswap MsgContext, we do not
1770 * swap it here either. It is an opaque cookie to
1771 * the controller, so it does not matter. -DaveM
1773 mf = MPT_INDEX_2_MFPTR(hd->ioc, scpnt_idx);
1774 ctx2abort = mf->u.frame.hwhdr.msgctxu.MsgContext;
1776 hd->abortSCpnt = SCpnt;
1778 vdev = SCpnt->device->hostdata;
1779 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
1780 vdev->vtarget->bus_id, vdev->vtarget->target_id, vdev->lun,
1781 ctx2abort, mptscsih_get_tm_timeout(hd->ioc));
1783 if (SCPNT_TO_LOOKUP_IDX(SCpnt) == scpnt_idx &&
1784 SCpnt->serial_number == sn) {
1788 printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n",
1790 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1795 if(retval != FAILED ) {
1797 hd->tmState = TM_STATE_NONE;
1802 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1804 * mptscsih_dev_reset - Perform a SCSI TARGET_RESET! new_eh variant
1805 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1807 * (linux scsi_host_template.eh_dev_reset_handler routine)
1809 * Returns SUCCESS or FAILED.
1812 mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
1818 /* If we can't locate our host adapter structure, return FAILED status.
1820 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1821 dtmprintk((KERN_INFO MYNAM ": mptscsih_dev_reset: "
1822 "Can't locate host! (sc=%p)\n",
1827 if (hd->resetPending)
1830 printk(KERN_WARNING MYNAM ": %s: attempting target reset! (sc=%p)\n",
1831 hd->ioc->name, SCpnt);
1832 scsi_print_command(SCpnt);
1834 vdev = SCpnt->device->hostdata;
1835 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
1836 vdev->vtarget->bus_id, vdev->vtarget->target_id,
1837 0, 0, mptscsih_get_tm_timeout(hd->ioc));
1839 printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n",
1841 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1846 if(retval != FAILED ) {
1848 hd->tmState = TM_STATE_NONE;
1853 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1855 * mptscsih_bus_reset - Perform a SCSI BUS_RESET! new_eh variant
1856 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1858 * (linux scsi_host_template.eh_bus_reset_handler routine)
1860 * Returns SUCCESS or FAILED.
1863 mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
1869 /* If we can't locate our host adapter structure, return FAILED status.
1871 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1872 dtmprintk((KERN_INFO MYNAM ": mptscsih_bus_reset: "
1873 "Can't locate host! (sc=%p)\n",
1878 printk(KERN_WARNING MYNAM ": %s: attempting bus reset! (sc=%p)\n",
1879 hd->ioc->name, SCpnt);
1880 scsi_print_command(SCpnt);
1882 if (hd->timeouts < -1)
1885 vdev = SCpnt->device->hostdata;
1886 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
1887 vdev->vtarget->bus_id, 0, 0, 0, mptscsih_get_tm_timeout(hd->ioc));
1889 printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n",
1891 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1896 if(retval != FAILED ) {
1898 hd->tmState = TM_STATE_NONE;
1903 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1905 * mptscsih_host_reset - Perform a SCSI host adapter RESET!
1907 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1909 * (linux scsi_host_template.eh_host_reset_handler routine)
1911 * Returns SUCCESS or FAILED.
1914 mptscsih_host_reset(struct scsi_cmnd *SCpnt)
1917 int status = SUCCESS;
1919 /* If we can't locate the host to reset, then we failed. */
1920 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1921 dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
1922 "Can't locate host! (sc=%p)\n",
1927 printk(KERN_WARNING MYNAM ": %s: Attempting host reset! (sc=%p)\n",
1928 hd->ioc->name, SCpnt);
1930 /* If our attempts to reset the host failed, then return a failed
1931 * status. The host will be taken off line by the SCSI mid-layer.
1933 if (mpt_HardResetHandler(hd->ioc, CAN_SLEEP) < 0){
1936 /* Make sure TM pending is cleared and TM state is set to
1940 hd->tmState = TM_STATE_NONE;
1943 dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
1945 (status == SUCCESS) ? "SUCCESS" : "FAILED" ) );
1950 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1952 * mptscsih_tm_pending_wait - wait for pending task management request to
1954 * @hd: Pointer to MPT host structure.
1956 * Returns {SUCCESS,FAILED}.
1959 mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd)
1961 unsigned long flags;
1962 int loop_count = 4 * 10; /* Wait 10 seconds */
1963 int status = FAILED;
1966 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
1967 if (hd->tmState == TM_STATE_NONE) {
1968 hd->tmState = TM_STATE_IN_PROGRESS;
1970 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1974 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1976 } while (--loop_count);
1981 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1983 * mptscsih_tm_wait_for_completion - wait for completion of TM task
1984 * @hd: Pointer to MPT host structure.
1986 * Returns {SUCCESS,FAILED}.
1989 mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout )
1991 unsigned long flags;
1992 int loop_count = 4 * timeout;
1993 int status = FAILED;
1996 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
1997 if(hd->tmPending == 0) {
1999 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2002 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2004 } while (--loop_count);
2009 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2011 mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code)
2015 switch (response_code) {
2016 case MPI_SCSITASKMGMT_RSP_TM_COMPLETE:
2017 desc = "The task completed.";
2019 case MPI_SCSITASKMGMT_RSP_INVALID_FRAME:
2020 desc = "The IOC received an invalid frame status.";
2022 case MPI_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED:
2023 desc = "The task type is not supported.";
2025 case MPI_SCSITASKMGMT_RSP_TM_FAILED:
2026 desc = "The requested task failed.";
2028 case MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED:
2029 desc = "The task completed successfully.";
2031 case MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN:
2032 desc = "The LUN request is invalid.";
2034 case MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC:
2035 desc = "The task is in the IOC queue and has not been sent to target.";
2041 printk(MYIOC_s_INFO_FMT "Response Code(0x%08x): F/W: %s\n",
2042 ioc->name, response_code, desc);
2045 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2047 * mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
2048 * @ioc: Pointer to MPT_ADAPTER structure
2049 * @mf: Pointer to SCSI task mgmt request frame
2050 * @mr: Pointer to SCSI task mgmt reply frame
2052 * This routine is called from mptbase.c::mpt_interrupt() at the completion
2053 * of any SCSI task management request.
2054 * This routine is registered with the MPT (base) driver at driver
2055 * load/init time via the mpt_register() API call.
2057 * Returns 1 indicating alloc'd request frame ptr should be freed.
2060 mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
2062 SCSITaskMgmtReply_t *pScsiTmReply;
2063 SCSITaskMgmt_t *pScsiTmReq;
2065 unsigned long flags;
2069 dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt completed (mf=%p,mr=%p)\n",
2070 ioc->name, mf, mr));
2072 /* Depending on the thread, a timer is activated for
2073 * the TM request. Delete this timer on completion of TM.
2074 * Decrement count of outstanding TM requests.
2076 hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
2078 dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt Complete: NULL Scsi Host Ptr\n",
2084 dtmprintk((MYIOC_s_WARN_FMT "ERROR! TaskMgmt Reply: NULL Request %p\n",
2088 pScsiTmReply = (SCSITaskMgmtReply_t*)mr;
2089 pScsiTmReq = (SCSITaskMgmt_t*)mf;
2091 /* Figure out if this was ABORT_TASK, TARGET_RESET, or BUS_RESET! */
2092 tmType = pScsiTmReq->TaskType;
2094 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05 &&
2095 pScsiTmReply->ResponseCode)
2096 mptscsih_taskmgmt_response_code(ioc,
2097 pScsiTmReply->ResponseCode);
2099 dtmprintk((MYIOC_s_WARN_FMT " TaskType = %d, TerminationCount=%d\n",
2100 ioc->name, tmType, le32_to_cpu(pScsiTmReply->TerminationCount)));
2101 DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply);
2103 iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2104 hd->tm_iocstatus = iocstatus;
2105 dtmprintk((MYIOC_s_WARN_FMT " SCSI TaskMgmt (%d) IOCStatus=%04x IOCLogInfo=%08x\n",
2106 ioc->name, tmType, iocstatus, le32_to_cpu(pScsiTmReply->IOCLogInfo)));
2107 /* Error? (anything non-zero?) */
2110 /* clear flags and continue.
2112 if (tmType == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK)
2113 hd->abortSCpnt = NULL;
2115 /* If an internal command is present
2116 * or the TM failed - reload the FW.
2117 * FC FW may respond FAILED to an ABORT
2119 if (tmType == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
2121 (iocstatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED)) {
2122 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0) {
2123 printk((KERN_WARNING
2124 " Firmware Reload FAILED!!\n"));
2129 dtmprintk((MYIOC_s_WARN_FMT " TaskMgmt SUCCESS\n", ioc->name));
2131 hd->abortSCpnt = NULL;
2136 spin_lock_irqsave(&ioc->FreeQlock, flags);
2138 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2139 hd->tmState = TM_STATE_NONE;
2144 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2146 * This is anyones guess quite frankly.
2149 mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
2150 sector_t capacity, int geom[])
2160 dummy = heads * sectors;
2161 cylinders = capacity;
2162 sector_div(cylinders,dummy);
2165 * Handle extended translation size for logical drives
2168 if ((ulong)capacity >= 0x200000) {
2171 dummy = heads * sectors;
2172 cylinders = capacity;
2173 sector_div(cylinders,dummy);
2179 geom[2] = cylinders;
2181 dprintk((KERN_NOTICE
2182 ": bios_param: Id=%i Lun=%i Channel=%i CHS=%i/%i/%i\n",
2183 sdev->id, sdev->lun,sdev->channel,(int)cylinders,heads,sectors));
2188 /* Search IOC page 3 to determine if this is hidden physical disk
2192 mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id)
2196 if (!ioc->raid_data.isRaid || !ioc->raid_data.pIocPg3)
2198 for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2199 if (id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID)
2204 EXPORT_SYMBOL(mptscsih_is_phys_disk);
2207 mptscsih_raid_id_to_num(MPT_SCSI_HOST *hd, uint physdiskid)
2211 if (!hd->ioc->raid_data.isRaid || !hd->ioc->raid_data.pIocPg3)
2214 for (i = 0; i < hd->ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2216 hd->ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID)
2217 return hd->ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum;
2222 EXPORT_SYMBOL(mptscsih_raid_id_to_num);
2224 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2226 * OS entry point to allow host driver to alloc memory
2227 * for each scsi target. Called once per device the bus scan.
2228 * Return non-zero if allocation fails.
2231 mptscsih_target_alloc(struct scsi_target *starget)
2233 VirtTarget *vtarget;
2235 vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
2238 starget->hostdata = vtarget;
2239 vtarget->starget = starget;
2243 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2245 * OS entry point to allow host driver to alloc memory
2246 * for each scsi device. Called once per device the bus scan.
2247 * Return non-zero if allocation fails.
2250 mptscsih_slave_alloc(struct scsi_device *sdev)
2252 struct Scsi_Host *host = sdev->host;
2253 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
2254 VirtTarget *vtarget;
2256 struct scsi_target *starget;
2258 vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
2260 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
2261 hd->ioc->name, sizeof(VirtDevice));
2265 vdev->lun = sdev->lun;
2266 sdev->hostdata = vdev;
2268 starget = scsi_target(sdev);
2269 vtarget = starget->hostdata;
2271 vdev->vtarget = vtarget;
2273 if (vtarget->num_luns == 0) {
2274 hd->Targets[sdev->id] = vtarget;
2275 vtarget->ioc_id = hd->ioc->id;
2276 vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
2277 vtarget->target_id = sdev->id;
2278 vtarget->bus_id = sdev->channel;
2279 if (hd->ioc->bus_type == SPI && sdev->channel == 0 &&
2280 hd->ioc->raid_data.isRaid & (1 << sdev->id)) {
2281 vtarget->raidVolume = 1;
2282 ddvtprintk((KERN_INFO
2283 "RAID Volume @ id %d\n", sdev->id));
2286 vtarget->num_luns++;
2291 * OS entry point to allow for host driver to free allocated memory
2292 * Called if no device present or device being unloaded
2295 mptscsih_target_destroy(struct scsi_target *starget)
2297 if (starget->hostdata)
2298 kfree(starget->hostdata);
2299 starget->hostdata = NULL;
2303 * OS entry point to allow for host driver to free allocated memory
2304 * Called if no device present or device being unloaded
2307 mptscsih_slave_destroy(struct scsi_device *sdev)
2309 struct Scsi_Host *host = sdev->host;
2310 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
2311 VirtTarget *vtarget;
2312 VirtDevice *vdevice;
2313 struct scsi_target *starget;
2315 starget = scsi_target(sdev);
2316 vtarget = starget->hostdata;
2317 vdevice = sdev->hostdata;
2319 mptscsih_search_running_cmds(hd, vdevice);
2320 vtarget->luns[0] &= ~(1 << vdevice->lun);
2321 vtarget->num_luns--;
2322 if (vtarget->num_luns == 0) {
2323 hd->Targets[sdev->id] = NULL;
2325 mptscsih_synchronize_cache(hd, vdevice);
2327 sdev->hostdata = NULL;
2330 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2332 * mptscsih_change_queue_depth - This function will set a devices queue depth
2333 * @sdev: per scsi_device pointer
2334 * @qdepth: requested queue depth
2336 * Adding support for new 'change_queue_depth' api.
2339 mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
2341 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sdev->host->hostdata;
2342 VirtTarget *vtarget;
2343 struct scsi_target *starget;
2347 starget = scsi_target(sdev);
2348 vtarget = starget->hostdata;
2350 if (hd->ioc->bus_type == SPI) {
2351 if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
2353 else if (sdev->type == TYPE_DISK &&
2354 vtarget->minSyncFactor <= MPT_ULTRA160)
2355 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2357 max_depth = MPT_SCSI_CMD_PER_DEV_LOW;
2359 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2361 if (qdepth > max_depth)
2366 tagged = MSG_SIMPLE_TAG;
2368 scsi_adjust_queue_depth(sdev, tagged, qdepth);
2369 return sdev->queue_depth;
2373 * OS entry point to adjust the queue_depths on a per-device basis.
2374 * Called once per device the bus scan. Use it to force the queue_depth
2375 * member to 1 if a device does not support Q tags.
2376 * Return non-zero if fails.
2379 mptscsih_slave_configure(struct scsi_device *sdev)
2381 struct Scsi_Host *sh = sdev->host;
2382 VirtTarget *vtarget;
2383 VirtDevice *vdevice;
2384 struct scsi_target *starget;
2385 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sh->hostdata;
2386 int indexed_lun, lun_index;
2388 starget = scsi_target(sdev);
2389 vtarget = starget->hostdata;
2390 vdevice = sdev->hostdata;
2392 dsprintk((MYIOC_s_INFO_FMT
2393 "device @ %p, id=%d, LUN=%d, channel=%d\n",
2394 hd->ioc->name, sdev, sdev->id, sdev->lun, sdev->channel));
2395 if (hd->ioc->bus_type == SPI)
2396 dsprintk((MYIOC_s_INFO_FMT
2397 "sdtr %d wdtr %d ppr %d inq length=%d\n",
2398 hd->ioc->name, sdev->sdtr, sdev->wdtr,
2399 sdev->ppr, sdev->inquiry_len));
2401 if (sdev->id > sh->max_id) {
2402 /* error case, should never happen */
2403 scsi_adjust_queue_depth(sdev, 0, 1);
2404 goto slave_configure_exit;
2407 vdevice->configured_lun=1;
2408 lun_index = (vdevice->lun >> 5); /* 32 luns per lun_index */
2409 indexed_lun = (vdevice->lun % 32);
2410 vtarget->luns[lun_index] |= (1 << indexed_lun);
2411 mptscsih_initTarget(hd, vtarget, sdev);
2412 mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH);
2414 dsprintk((MYIOC_s_INFO_FMT
2415 "Queue depth=%d, tflags=%x\n",
2416 hd->ioc->name, sdev->queue_depth, vtarget->tflags));
2418 if (hd->ioc->bus_type == SPI)
2419 dsprintk((MYIOC_s_INFO_FMT
2420 "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
2421 hd->ioc->name, vtarget->negoFlags, vtarget->maxOffset,
2422 vtarget->minSyncFactor));
2424 slave_configure_exit:
2426 dsprintk((MYIOC_s_INFO_FMT
2427 "tagged %d, simple %d, ordered %d\n",
2428 hd->ioc->name,sdev->tagged_supported, sdev->simple_tags,
2429 sdev->ordered_tags));
2434 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2436 * Private routines...
2439 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2440 /* Utility function to copy sense data from the scsi_cmnd buffer
2441 * to the FC and SCSI target structures.
2445 mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
2448 SCSIIORequest_t *pReq;
2449 u32 sense_count = le32_to_cpu(pScsiReply->SenseCount);
2451 /* Get target structure
2453 pReq = (SCSIIORequest_t *) mf;
2454 vdev = sc->device->hostdata;
2460 /* Copy the sense received into the scsi command block. */
2461 req_index = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2462 sense_data = ((u8 *)hd->ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC));
2463 memcpy(sc->sense_buffer, sense_data, SNS_LEN(sc));
2465 /* Log SMART data (asc = 0x5D, non-IM case only) if required.
2467 if ((hd->ioc->events) && (hd->ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) {
2468 if ((sense_data[12] == 0x5D) && (vdev->vtarget->raidVolume == 0)) {
2470 MPT_ADAPTER *ioc = hd->ioc;
2472 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
2473 ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
2474 ioc->events[idx].eventContext = ioc->eventContext;
2476 ioc->events[idx].data[0] = (pReq->LUN[1] << 24) ||
2477 (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) ||
2478 (sc->device->channel << 8) || sc->device->id;
2480 ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12];
2482 ioc->eventContext++;
2483 if (hd->ioc->pcidev->vendor ==
2484 PCI_VENDOR_ID_IBM) {
2485 mptscsih_issue_sep_command(hd->ioc,
2486 vdev->vtarget, MPI_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT);
2487 vdev->vtarget->tflags |=
2488 MPT_TARGET_FLAGS_LED_ON;
2493 dprintk((MYIOC_s_INFO_FMT "Hmmm... SenseData len=0! (?)\n",
2499 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc)
2504 hd = (MPT_SCSI_HOST *) sc->device->host->hostdata;
2506 for (i = 0; i < hd->ioc->req_depth; i++) {
2507 if (hd->ScsiLookup[i] == sc) {
2515 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2517 mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2520 unsigned long flags;
2523 dtmprintk((KERN_WARNING MYNAM
2524 ": IOC %s_reset routed to SCSI host driver!\n",
2525 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
2526 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
2528 /* If a FW reload request arrives after base installed but
2529 * before all scsi hosts have been attached, then an alt_ioc
2530 * may have a NULL sh pointer.
2532 if ((ioc->sh == NULL) || (ioc->sh->hostdata == NULL))
2535 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2537 if (reset_phase == MPT_IOC_SETUP_RESET) {
2538 dtmprintk((MYIOC_s_WARN_FMT "Setup-Diag Reset\n", ioc->name));
2541 * 1. Set Hard Reset Pending Flag
2542 * All new commands go to doneQ
2544 hd->resetPending = 1;
2546 } else if (reset_phase == MPT_IOC_PRE_RESET) {
2547 dtmprintk((MYIOC_s_WARN_FMT "Pre-Diag Reset\n", ioc->name));
2549 /* 2. Flush running commands
2550 * Clean ScsiLookup (and associated memory)
2554 /* 2b. Reply to OS all known outstanding I/O commands.
2556 mptscsih_flush_running_cmds(hd);
2558 /* 2c. If there was an internal command that
2559 * has not completed, configuration or io request,
2560 * free these resources.
2563 del_timer(&hd->timer);
2564 mpt_free_msg_frame(ioc, hd->cmdPtr);
2567 dtmprintk((MYIOC_s_WARN_FMT "Pre-Reset complete.\n", ioc->name));
2570 dtmprintk((MYIOC_s_WARN_FMT "Post-Diag Reset\n", ioc->name));
2572 /* Once a FW reload begins, all new OS commands are
2573 * redirected to the doneQ w/ a reset status.
2574 * Init all control structures.
2577 /* ScsiLookup initialization
2579 for (ii=0; ii < hd->ioc->req_depth; ii++)
2580 hd->ScsiLookup[ii] = NULL;
2582 /* 2. Chain Buffer initialization
2585 /* 4. Renegotiate to all devices, if SPI
2588 /* 5. Enable new commands to be posted
2590 spin_lock_irqsave(&ioc->FreeQlock, flags);
2592 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2593 hd->resetPending = 0;
2594 hd->tmState = TM_STATE_NONE;
2596 /* 6. If there was an internal command,
2597 * wake this process up.
2601 * Wake up the original calling thread
2603 hd->pLocal = &hd->localReply;
2604 hd->pLocal->completion = MPT_SCANDV_DID_RESET;
2605 hd->scandv_wait_done = 1;
2606 wake_up(&hd->scandv_waitq);
2610 dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name));
2614 return 1; /* currently means nothing really */
2617 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2619 mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2622 u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
2624 devtverboseprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
2627 if (ioc->sh == NULL ||
2628 ((hd = (MPT_SCSI_HOST *)ioc->sh->hostdata) == NULL))
2632 case MPI_EVENT_UNIT_ATTENTION: /* 03 */
2635 case MPI_EVENT_IOC_BUS_RESET: /* 04 */
2636 case MPI_EVENT_EXT_BUS_RESET: /* 05 */
2637 if (hd && (ioc->bus_type == SPI) && (hd->soft_resets < -1))
2640 case MPI_EVENT_LOGOUT: /* 09 */
2644 case MPI_EVENT_RESCAN: /* 06 */
2648 * CHECKME! Don't think we need to do
2649 * anything for these, but...
2651 case MPI_EVENT_LINK_STATUS_CHANGE: /* 07 */
2652 case MPI_EVENT_LOOP_STATE_CHANGE: /* 08 */
2654 * CHECKME! Falling thru...
2658 case MPI_EVENT_INTEGRATED_RAID: /* 0B */
2661 case MPI_EVENT_NONE: /* 00 */
2662 case MPI_EVENT_LOG_DATA: /* 01 */
2663 case MPI_EVENT_STATE_CHANGE: /* 02 */
2664 case MPI_EVENT_EVENT_CHANGE: /* 0A */
2666 dprintk((KERN_INFO " Ignoring event (=%02Xh)\n", event));
2670 return 1; /* currently means nothing really */
2673 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2675 * mptscsih_initTarget - Target, LUN alloc/free functionality.
2676 * @hd: Pointer to MPT_SCSI_HOST structure
2677 * @vtarget: per target private data
2678 * @sdev: SCSI device
2680 * NOTE: It's only SAFE to call this routine if data points to
2681 * sane & valid STANDARD INQUIRY data!
2683 * Allocate and initialize memory for this target.
2684 * Save inquiry data.
2688 mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget,
2689 struct scsi_device *sdev)
2691 dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n",
2692 hd->ioc->name, vtarget->bus_id, vtarget->target_id, lun, hd));
2694 /* Is LUN supported? If so, upper 2 bits will be 0
2695 * in first byte of inquiry data.
2697 if (sdev->inq_periph_qual != 0)
2700 if (vtarget == NULL)
2703 vtarget->type = sdev->type;
2705 if (hd->ioc->bus_type != SPI)
2708 if ((sdev->type == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) {
2709 /* Treat all Processors as SAF-TE if
2710 * command line option is set */
2711 vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
2712 mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id);
2713 }else if ((sdev->type == TYPE_PROCESSOR) &&
2714 !(vtarget->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) {
2715 if (sdev->inquiry_len > 49 ) {
2716 if (sdev->inquiry[44] == 'S' &&
2717 sdev->inquiry[45] == 'A' &&
2718 sdev->inquiry[46] == 'F' &&
2719 sdev->inquiry[47] == '-' &&
2720 sdev->inquiry[48] == 'T' &&
2721 sdev->inquiry[49] == 'E' ) {
2722 vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
2723 mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id);
2727 mptscsih_setTargetNegoParms(hd, vtarget, sdev);
2730 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2732 * Update the target negotiation parameters based on the
2733 * the Inquiry data, adapter capabilities, and NVRAM settings.
2737 mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target,
2738 struct scsi_device *sdev)
2740 SpiCfgData *pspi_data = &hd->ioc->spi_data;
2741 int id = (int) target->target_id;
2743 u8 width = MPT_NARROW;
2744 u8 factor = MPT_ASYNC;
2749 target->negoFlags = pspi_data->noQas;
2751 /* noQas == 0 => device supports QAS. */
2753 if (sdev->scsi_level < SCSI_2) {
2755 factor = MPT_ULTRA2;
2756 offset = pspi_data->maxSyncOffset;
2757 target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
2759 if (scsi_device_wide(sdev)) {
2763 if (scsi_device_sync(sdev)) {
2764 factor = pspi_data->minSyncFactor;
2765 if (!scsi_device_dt(sdev))
2766 factor = MPT_ULTRA2;
2768 if (!scsi_device_ius(sdev) &&
2769 !scsi_device_qas(sdev))
2770 factor = MPT_ULTRA160;
2772 factor = MPT_ULTRA320;
2773 if (scsi_device_qas(sdev)) {
2774 ddvtprintk((KERN_INFO "Enabling QAS due to byte56=%02x on id=%d!\n", byte56, id));
2777 if (sdev->type == TYPE_TAPE &&
2778 scsi_device_ius(sdev))
2779 target->negoFlags |= MPT_TAPE_NEGO_IDP;
2782 offset = pspi_data->maxSyncOffset;
2784 /* If RAID, never disable QAS
2785 * else if non RAID, do not disable
2786 * QAS if bit 1 is set
2787 * bit 1 QAS support, non-raid only
2790 if (target->raidVolume == 1) {
2799 if (!sdev->tagged_supported) {
2800 target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
2803 /* Update tflags based on NVRAM settings. (SCSI only)
2805 if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
2806 nvram = pspi_data->nvram[id];
2807 nfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
2810 width = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
2813 /* Ensure factor is set to the
2814 * maximum of: adapter, nvram, inquiry
2817 if (nfactor < pspi_data->minSyncFactor )
2818 nfactor = pspi_data->minSyncFactor;
2820 factor = max(factor, nfactor);
2821 if (factor == MPT_ASYNC)
2832 /* Make sure data is consistent
2834 if ((!width) && (factor < MPT_ULTRA2)) {
2835 factor = MPT_ULTRA2;
2838 /* Save the data to the target structure.
2840 target->minSyncFactor = factor;
2841 target->maxOffset = offset;
2842 target->maxWidth = width;
2844 target->tflags |= MPT_TARGET_FLAGS_VALID_NEGO;
2846 /* Disable unused features.
2849 target->negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
2852 target->negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
2854 if ( factor > MPT_ULTRA320 )
2857 if (noQas && (pspi_data->noQas == 0)) {
2858 pspi_data->noQas |= MPT_TARGET_NO_NEGO_QAS;
2859 target->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
2861 /* Disable QAS in a mixed configuration case
2864 ddvtprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id));
2868 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2870 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2872 * SCSI Config Page functionality ...
2875 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2876 /* mptscsih_writeIOCPage4 - write IOC Page 4
2877 * @hd: Pointer to a SCSI Host Structure
2878 * @target_id: write IOC Page4 for this ID & Bus
2880 * Return: -EAGAIN if unable to obtain a Message Frame
2883 * Remark: We do not wait for a return, write pages sequentially.
2886 mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus)
2888 MPT_ADAPTER *ioc = hd->ioc;
2890 IOCPage4_t *IOCPage4Ptr;
2898 /* Get a MF for this command.
2900 if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
2901 dfailprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n",
2906 /* Set the request and the data pointers.
2907 * Place data at end of MF.
2909 pReq = (Config_t *)mf;
2911 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2912 frameOffset = ioc->req_sz - sizeof(IOCPage4_t);
2914 /* Complete the request frame (same for all requests).
2916 pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
2918 pReq->ChainOffset = 0;
2919 pReq->Function = MPI_FUNCTION_CONFIG;
2920 pReq->ExtPageLength = 0;
2921 pReq->ExtPageType = 0;
2923 for (ii=0; ii < 8; ii++) {
2924 pReq->Reserved2[ii] = 0;
2927 IOCPage4Ptr = ioc->spi_data.pIocPg4;
2928 dataDma = ioc->spi_data.IocPg4_dma;
2929 ii = IOCPage4Ptr->ActiveSEP++;
2930 IOCPage4Ptr->SEP[ii].SEPTargetID = target_id;
2931 IOCPage4Ptr->SEP[ii].SEPBus = bus;
2932 pReq->Header = IOCPage4Ptr->Header;
2933 pReq->PageAddress = cpu_to_le32(target_id | (bus << 8 ));
2935 /* Add a SGE to the config request.
2937 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE |
2938 (IOCPage4Ptr->Header.PageLength + ii) * 4;
2940 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma);
2942 dinitprintk((MYIOC_s_INFO_FMT
2943 "writeIOCPage4: MaxSEP=%d ActiveSEP=%d id=%d bus=%d\n",
2944 ioc->name, IOCPage4Ptr->MaxSEP, IOCPage4Ptr->ActiveSEP, target_id, bus));
2946 mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
2951 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2953 * Bus Scan and Domain Validation functionality ...
2956 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2958 * mptscsih_scandv_complete - Scan and DV callback routine registered
2959 * to Fustion MPT (base) driver.
2961 * @ioc: Pointer to MPT_ADAPTER structure
2962 * @mf: Pointer to original MPT request frame
2963 * @mr: Pointer to MPT reply frame (NULL if TurboReply)
2965 * This routine is called from mpt.c::mpt_interrupt() at the completion
2966 * of any SCSI IO request.
2967 * This routine is registered with the Fusion MPT (base) driver at driver
2968 * load/init time via the mpt_register() API call.
2970 * Returns 1 indicating alloc'd request frame ptr should be freed.
2972 * Remark: Sets a completion code and (possibly) saves sense data
2973 * in the IOC member localReply structure.
2974 * Used ONLY for DV and other internal commands.
2977 mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
2980 SCSIIORequest_t *pReq;
2984 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2987 (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) {
2988 printk(MYIOC_s_ERR_FMT
2989 "ScanDvComplete, %s req frame ptr! (=%p)\n",
2990 ioc->name, mf?"BAD":"NULL", (void *) mf);
2994 del_timer(&hd->timer);
2995 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2996 hd->ScsiLookup[req_idx] = NULL;
2997 pReq = (SCSIIORequest_t *) mf;
2999 if (mf != hd->cmdPtr) {
3000 printk(MYIOC_s_WARN_FMT "ScanDvComplete (mf=%p, cmdPtr=%p, idx=%d)\n",
3001 hd->ioc->name, (void *)mf, (void *) hd->cmdPtr, req_idx);
3005 ddvprintk((MYIOC_s_INFO_FMT "ScanDvComplete (mf=%p,mr=%p,idx=%d)\n",
3006 hd->ioc->name, mf, mr, req_idx));
3008 hd->pLocal = &hd->localReply;
3009 hd->pLocal->scsiStatus = 0;
3011 /* If target struct exists, clear sense valid flag.
3014 completionCode = MPT_SCANDV_GOOD;
3016 SCSIIOReply_t *pReply;
3020 pReply = (SCSIIOReply_t *) mr;
3022 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
3023 scsi_status = pReply->SCSIStatus;
3025 ddvtprintk((KERN_NOTICE " IOCStatus=%04xh, SCSIState=%02xh, SCSIStatus=%02xh, IOCLogInfo=%08xh\n",
3026 status, pReply->SCSIState, scsi_status,
3027 le32_to_cpu(pReply->IOCLogInfo)));
3031 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
3032 completionCode = MPT_SCANDV_SELECTION_TIMEOUT;
3035 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
3036 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
3037 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
3038 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
3039 completionCode = MPT_SCANDV_DID_RESET;
3042 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
3043 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
3044 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
3045 if (pReply->Function == MPI_FUNCTION_CONFIG) {
3046 ConfigReply_t *pr = (ConfigReply_t *)mr;
3047 completionCode = MPT_SCANDV_GOOD;
3048 hd->pLocal->header.PageVersion = pr->Header.PageVersion;
3049 hd->pLocal->header.PageLength = pr->Header.PageLength;
3050 hd->pLocal->header.PageNumber = pr->Header.PageNumber;
3051 hd->pLocal->header.PageType = pr->Header.PageType;
3053 } else if (pReply->Function == MPI_FUNCTION_RAID_ACTION) {
3054 /* If the RAID Volume request is successful,
3055 * return GOOD, else indicate that
3056 * some type of error occurred.
3058 MpiRaidActionReply_t *pr = (MpiRaidActionReply_t *)mr;
3059 if (le16_to_cpu(pr->ActionStatus) == MPI_RAID_ACTION_ASTATUS_SUCCESS)
3060 completionCode = MPT_SCANDV_GOOD;
3062 completionCode = MPT_SCANDV_SOME_ERROR;
3063 memcpy(hd->pLocal->sense, pr, sizeof(hd->pLocal->sense));
3065 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID) {
3069 /* save sense data in global structure
3071 completionCode = MPT_SCANDV_SENSE;
3072 hd->pLocal->scsiStatus = scsi_status;
3073 sense_data = ((u8 *)hd->ioc->sense_buf_pool +
3074 (req_idx * MPT_SENSE_BUFFER_ALLOC));
3076 sz = min_t(int, pReq->SenseBufferLength,
3077 SCSI_STD_SENSE_BYTES);
3078 memcpy(hd->pLocal->sense, sense_data, sz);
3080 ddvprintk((KERN_NOTICE " Check Condition, sense ptr %p\n",
3082 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_FAILED) {
3083 if (pReq->CDB[0] == INQUIRY)
3084 completionCode = MPT_SCANDV_ISSUE_SENSE;
3086 completionCode = MPT_SCANDV_DID_RESET;
3088 else if (pReply->SCSIState & MPI_SCSI_STATE_NO_SCSI_STATUS)
3089 completionCode = MPT_SCANDV_DID_RESET;
3090 else if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
3091 completionCode = MPT_SCANDV_DID_RESET;
3093 completionCode = MPT_SCANDV_GOOD;
3094 hd->pLocal->scsiStatus = scsi_status;
3098 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
3099 if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
3100 completionCode = MPT_SCANDV_DID_RESET;
3102 completionCode = MPT_SCANDV_SOME_ERROR;
3106 completionCode = MPT_SCANDV_SOME_ERROR;
3109 } /* switch(status) */
3111 ddvtprintk((KERN_NOTICE " completionCode set to %08xh\n",
3113 } /* end of address reply case */
3115 hd->pLocal->completion = completionCode;
3117 /* MF and RF are freed in mpt_interrupt
3120 /* Free Chain buffers (will never chain) in scan or dv */
3121 //mptscsih_freeChainBuffers(ioc, req_idx);
3124 * Wake up the original calling thread
3126 hd->scandv_wait_done = 1;
3127 wake_up(&hd->scandv_waitq);
3132 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3133 /* mptscsih_timer_expired - Call back for timer process.
3134 * Used only for dv functionality.
3135 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
3139 mptscsih_timer_expired(unsigned long data)
3141 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) data;
3143 ddvprintk((MYIOC_s_WARN_FMT "Timer Expired! Cmd %p\n", hd->ioc->name, hd->cmdPtr));
3146 MPIHeader_t *cmd = (MPIHeader_t *)hd->cmdPtr;
3148 if (cmd->Function == MPI_FUNCTION_SCSI_IO_REQUEST) {
3149 /* Desire to issue a task management request here.
3150 * TM requests MUST be single threaded.
3151 * If old eh code and no TM current, issue request.
3152 * If new eh code, do nothing. Wait for OS cmd timeout
3155 ddvtprintk((MYIOC_s_NOTE_FMT "DV Cmd Timeout: NoOp\n", hd->ioc->name));
3157 /* Perform a FW reload */
3158 if (mpt_HardResetHandler(hd->ioc, NO_SLEEP) < 0) {
3159 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", hd->ioc->name);
3163 /* This should NEVER happen */
3164 printk(MYIOC_s_WARN_FMT "Null cmdPtr!!!!\n", hd->ioc->name);
3167 /* No more processing.
3168 * TM call will generate an interrupt for SCSI TM Management.
3169 * The FW will reply to all outstanding commands, callback will finish cleanup.
3170 * Hard reset clean-up will free all resources.
3172 ddvprintk((MYIOC_s_WARN_FMT "Timer Expired Complete!\n", hd->ioc->name));
3178 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3180 * mptscsih_do_cmd - Do internal command.
3181 * @hd: MPT_SCSI_HOST pointer
3182 * @io: INTERNAL_CMD pointer.
3184 * Issue the specified internally generated command and do command
3185 * specific cleanup. For bus scan / DV only.
3186 * NOTES: If command is Inquiry and status is good,
3187 * initialize a target structure, save the data
3189 * Remark: Single threaded access only.
3192 * < 0 if an illegal command or no resources
3196 * > 0 if command complete but some type of completion error.
3199 mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
3202 SCSIIORequest_t *pScsiReq;
3203 SCSIIORequest_t ReqCopy;
3204 int my_idx, ii, dir;
3208 char CDB[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
3211 in_isr = in_interrupt();
3213 dprintk((MYIOC_s_WARN_FMT "Internal SCSI IO request not allowed in ISR context!\n",
3219 /* Set command specific information
3224 dir = MPI_SCSIIO_CONTROL_READ;
3230 case TEST_UNIT_READY:
3232 dir = MPI_SCSIIO_CONTROL_READ;
3238 dir = MPI_SCSIIO_CONTROL_READ;
3240 CDB[4] = 1; /*Spin up the disk */
3248 dir = MPI_SCSIIO_CONTROL_READ;
3254 dir = MPI_SCSIIO_CONTROL_READ;
3256 if (io->flags & MPT_ICFLAG_ECHO) {
3262 if (io->flags & MPT_ICFLAG_BUF_CAP) {
3265 CDB[6] = (io->size >> 16) & 0xFF;
3266 CDB[7] = (io->size >> 8) & 0xFF;
3267 CDB[8] = io->size & 0xFF;
3273 dir = MPI_SCSIIO_CONTROL_WRITE;
3275 if (io->flags & MPT_ICFLAG_ECHO) {
3280 CDB[6] = (io->size >> 16) & 0xFF;
3281 CDB[7] = (io->size >> 8) & 0xFF;
3282 CDB[8] = io->size & 0xFF;
3288 dir = MPI_SCSIIO_CONTROL_READ;
3295 dir = MPI_SCSIIO_CONTROL_READ;
3300 case SYNCHRONIZE_CACHE:
3302 dir = MPI_SCSIIO_CONTROL_READ;
3304 // CDB[1] = 0x02; /* set immediate bit */
3313 /* Get and Populate a free Frame
3315 if ((mf = mpt_get_msg_frame(hd->ioc->InternalCtx, hd->ioc)) == NULL) {
3316 ddvprintk((MYIOC_s_WARN_FMT "No msg frames!\n",
3321 pScsiReq = (SCSIIORequest_t *) mf;
3323 /* Get the request index */
3324 my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3325 ADD_INDEX_LOG(my_idx); /* for debug */
3327 if (io->flags & MPT_ICFLAG_PHYS_DISK) {
3328 pScsiReq->TargetID = io->physDiskNum;
3330 pScsiReq->ChainOffset = 0;
3331 pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
3333 pScsiReq->TargetID = io->id;
3334 pScsiReq->Bus = io->bus;
3335 pScsiReq->ChainOffset = 0;
3336 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
3339 pScsiReq->CDBLength = cmdLen;
3340 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
3342 pScsiReq->Reserved = 0;
3344 pScsiReq->MsgFlags = mpt_msg_flags();
3345 /* MsgContext set in mpt_get_msg_fram call */
3347 for (ii=0; ii < 8; ii++)
3348 pScsiReq->LUN[ii] = 0;
3349 pScsiReq->LUN[1] = io->lun;
3351 if (io->flags & MPT_ICFLAG_TAGGED_CMD)
3352 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ);
3354 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3356 if (cmd == REQUEST_SENSE) {
3357 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3358 ddvprintk((MYIOC_s_INFO_FMT "Untagged! 0x%2x\n",
3359 hd->ioc->name, cmd));
3362 for (ii=0; ii < 16; ii++)
3363 pScsiReq->CDB[ii] = CDB[ii];
3365 pScsiReq->DataLength = cpu_to_le32(io->size);
3366 pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
3367 + (my_idx * MPT_SENSE_BUFFER_ALLOC));
3369 ddvprintk((MYIOC_s_INFO_FMT "Sending Command 0x%x for (%d:%d:%d)\n",
3370 hd->ioc->name, cmd, io->bus, io->id, io->lun));
3372 if (dir == MPI_SCSIIO_CONTROL_READ) {
3373 mpt_add_sge((char *) &pScsiReq->SGL,
3374 MPT_SGE_FLAGS_SSIMPLE_READ | io->size,
3377 mpt_add_sge((char *) &pScsiReq->SGL,
3378 MPT_SGE_FLAGS_SSIMPLE_WRITE | io->size,
3382 /* The ISR will free the request frame, but we need
3383 * the information to initialize the target. Duplicate.
3385 memcpy(&ReqCopy, pScsiReq, sizeof(SCSIIORequest_t));
3387 /* Issue this command after:
3390 * Wait until the reply has been received
3391 * ScsiScanDvCtx callback function will
3393 * set scandv_wait_done and call wake_up
3396 hd->timer.expires = jiffies + HZ*cmdTimeout;
3397 hd->scandv_wait_done = 0;
3399 /* Save cmd pointer, for resource free if timeout or
3404 add_timer(&hd->timer);
3405 mpt_put_msg_frame(hd->ioc->InternalCtx, hd->ioc, mf);
3406 wait_event(hd->scandv_waitq, hd->scandv_wait_done);
3409 rc = hd->pLocal->completion;
3410 hd->pLocal->skip = 0;
3412 /* Always set fatal error codes in some cases.
3414 if (rc == MPT_SCANDV_SELECTION_TIMEOUT)
3416 else if (rc == MPT_SCANDV_SOME_ERROR)
3420 /* This should never happen. */
3421 ddvprintk((MYIOC_s_INFO_FMT "_do_cmd: Null pLocal!!!\n",
3428 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3430 * mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
3431 * @hd: Pointer to a SCSI HOST structure
3432 * @vtarget: per device private data
3435 * Uses the ISR, but with special processing.
3436 * MUST be single-threaded.
3440 mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
3444 /* Following parameters will not change
3447 iocmd.cmd = SYNCHRONIZE_CACHE;
3449 iocmd.physDiskNum = -1;
3451 iocmd.data_dma = -1;
3453 iocmd.rsvd = iocmd.rsvd2 = 0;
3454 iocmd.bus = vdevice->vtarget->bus_id;
3455 iocmd.id = vdevice->vtarget->target_id;
3456 iocmd.lun = (u8)vdevice->lun;
3458 if ((vdevice->vtarget->type == TYPE_DISK) &&
3459 (vdevice->configured_lun))
3460 mptscsih_do_cmd(hd, &iocmd);
3463 EXPORT_SYMBOL(mptscsih_remove);
3464 EXPORT_SYMBOL(mptscsih_shutdown);
3466 EXPORT_SYMBOL(mptscsih_suspend);
3467 EXPORT_SYMBOL(mptscsih_resume);
3469 EXPORT_SYMBOL(mptscsih_proc_info);
3470 EXPORT_SYMBOL(mptscsih_info);
3471 EXPORT_SYMBOL(mptscsih_qcmd);
3472 EXPORT_SYMBOL(mptscsih_target_alloc);
3473 EXPORT_SYMBOL(mptscsih_slave_alloc);
3474 EXPORT_SYMBOL(mptscsih_target_destroy);
3475 EXPORT_SYMBOL(mptscsih_slave_destroy);
3476 EXPORT_SYMBOL(mptscsih_slave_configure);
3477 EXPORT_SYMBOL(mptscsih_abort);
3478 EXPORT_SYMBOL(mptscsih_dev_reset);
3479 EXPORT_SYMBOL(mptscsih_bus_reset);
3480 EXPORT_SYMBOL(mptscsih_host_reset);
3481 EXPORT_SYMBOL(mptscsih_bios_param);
3482 EXPORT_SYMBOL(mptscsih_io_done);
3483 EXPORT_SYMBOL(mptscsih_taskmgmt_complete);
3484 EXPORT_SYMBOL(mptscsih_scandv_complete);
3485 EXPORT_SYMBOL(mptscsih_event_process);
3486 EXPORT_SYMBOL(mptscsih_ioc_reset);
3487 EXPORT_SYMBOL(mptscsih_change_queue_depth);
3488 EXPORT_SYMBOL(mptscsih_timer_expired);
3489 EXPORT_SYMBOL(mptscsih_TMHandler);
3491 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/