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
1233 * @host: scsi host struct
1234 * @buffer: if write, user data; if read, buffer for user
1235 * @start: returns the buffer address
1236 * @offset: if write, 0; if read, the current offset into the buffer from
1237 * the previous read.
1238 * @length: if write, return length;
1239 * @func: write = 1; read = 0
1241 * (linux scsi_host_template.info routine)
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 (new_eh variant)
1906 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1908 * (linux scsi_host_template.eh_host_reset_handler routine)
1910 * Returns SUCCESS or FAILED.
1913 mptscsih_host_reset(struct scsi_cmnd *SCpnt)
1916 int status = SUCCESS;
1918 /* If we can't locate the host to reset, then we failed. */
1919 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1920 dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
1921 "Can't locate host! (sc=%p)\n",
1926 printk(KERN_WARNING MYNAM ": %s: Attempting host reset! (sc=%p)\n",
1927 hd->ioc->name, SCpnt);
1929 /* If our attempts to reset the host failed, then return a failed
1930 * status. The host will be taken off line by the SCSI mid-layer.
1932 if (mpt_HardResetHandler(hd->ioc, CAN_SLEEP) < 0){
1935 /* Make sure TM pending is cleared and TM state is set to
1939 hd->tmState = TM_STATE_NONE;
1942 dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
1944 (status == SUCCESS) ? "SUCCESS" : "FAILED" ) );
1949 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1951 * mptscsih_tm_pending_wait - wait for pending task management request to complete
1952 * @hd: Pointer to MPT host structure.
1954 * Returns {SUCCESS,FAILED}.
1957 mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd)
1959 unsigned long flags;
1960 int loop_count = 4 * 10; /* Wait 10 seconds */
1961 int status = FAILED;
1964 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
1965 if (hd->tmState == TM_STATE_NONE) {
1966 hd->tmState = TM_STATE_IN_PROGRESS;
1968 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1972 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1974 } while (--loop_count);
1979 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1981 * mptscsih_tm_wait_for_completion - wait for completion of TM task
1982 * @hd: Pointer to MPT host structure.
1983 * @timeout: timeout in seconds
1985 * Returns {SUCCESS,FAILED}.
1988 mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout )
1990 unsigned long flags;
1991 int loop_count = 4 * timeout;
1992 int status = FAILED;
1995 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
1996 if(hd->tmPending == 0) {
1998 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2001 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2003 } while (--loop_count);
2008 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2010 mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code)
2014 switch (response_code) {
2015 case MPI_SCSITASKMGMT_RSP_TM_COMPLETE:
2016 desc = "The task completed.";
2018 case MPI_SCSITASKMGMT_RSP_INVALID_FRAME:
2019 desc = "The IOC received an invalid frame status.";
2021 case MPI_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED:
2022 desc = "The task type is not supported.";
2024 case MPI_SCSITASKMGMT_RSP_TM_FAILED:
2025 desc = "The requested task failed.";
2027 case MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED:
2028 desc = "The task completed successfully.";
2030 case MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN:
2031 desc = "The LUN request is invalid.";
2033 case MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC:
2034 desc = "The task is in the IOC queue and has not been sent to target.";
2040 printk(MYIOC_s_INFO_FMT "Response Code(0x%08x): F/W: %s\n",
2041 ioc->name, response_code, desc);
2044 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2046 * mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
2047 * @ioc: Pointer to MPT_ADAPTER structure
2048 * @mf: Pointer to SCSI task mgmt request frame
2049 * @mr: Pointer to SCSI task mgmt reply frame
2051 * This routine is called from mptbase.c::mpt_interrupt() at the completion
2052 * of any SCSI task management request.
2053 * This routine is registered with the MPT (base) driver at driver
2054 * load/init time via the mpt_register() API call.
2056 * Returns 1 indicating alloc'd request frame ptr should be freed.
2059 mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
2061 SCSITaskMgmtReply_t *pScsiTmReply;
2062 SCSITaskMgmt_t *pScsiTmReq;
2064 unsigned long flags;
2068 dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt completed (mf=%p,mr=%p)\n",
2069 ioc->name, mf, mr));
2071 /* Depending on the thread, a timer is activated for
2072 * the TM request. Delete this timer on completion of TM.
2073 * Decrement count of outstanding TM requests.
2075 hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
2077 dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt Complete: NULL Scsi Host Ptr\n",
2083 dtmprintk((MYIOC_s_WARN_FMT "ERROR! TaskMgmt Reply: NULL Request %p\n",
2087 pScsiTmReply = (SCSITaskMgmtReply_t*)mr;
2088 pScsiTmReq = (SCSITaskMgmt_t*)mf;
2090 /* Figure out if this was ABORT_TASK, TARGET_RESET, or BUS_RESET! */
2091 tmType = pScsiTmReq->TaskType;
2093 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05 &&
2094 pScsiTmReply->ResponseCode)
2095 mptscsih_taskmgmt_response_code(ioc,
2096 pScsiTmReply->ResponseCode);
2098 dtmprintk((MYIOC_s_WARN_FMT " TaskType = %d, TerminationCount=%d\n",
2099 ioc->name, tmType, le32_to_cpu(pScsiTmReply->TerminationCount)));
2100 DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply);
2102 iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2103 hd->tm_iocstatus = iocstatus;
2104 dtmprintk((MYIOC_s_WARN_FMT " SCSI TaskMgmt (%d) IOCStatus=%04x IOCLogInfo=%08x\n",
2105 ioc->name, tmType, iocstatus, le32_to_cpu(pScsiTmReply->IOCLogInfo)));
2106 /* Error? (anything non-zero?) */
2109 /* clear flags and continue.
2111 if (tmType == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK)
2112 hd->abortSCpnt = NULL;
2114 /* If an internal command is present
2115 * or the TM failed - reload the FW.
2116 * FC FW may respond FAILED to an ABORT
2118 if (tmType == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
2120 (iocstatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED)) {
2121 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0) {
2122 printk((KERN_WARNING
2123 " Firmware Reload FAILED!!\n"));
2128 dtmprintk((MYIOC_s_WARN_FMT " TaskMgmt SUCCESS\n", ioc->name));
2130 hd->abortSCpnt = NULL;
2135 spin_lock_irqsave(&ioc->FreeQlock, flags);
2137 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2138 hd->tmState = TM_STATE_NONE;
2143 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2145 * This is anyones guess quite frankly.
2148 mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
2149 sector_t capacity, int geom[])
2159 dummy = heads * sectors;
2160 cylinders = capacity;
2161 sector_div(cylinders,dummy);
2164 * Handle extended translation size for logical drives
2167 if ((ulong)capacity >= 0x200000) {
2170 dummy = heads * sectors;
2171 cylinders = capacity;
2172 sector_div(cylinders,dummy);
2178 geom[2] = cylinders;
2180 dprintk((KERN_NOTICE
2181 ": bios_param: Id=%i Lun=%i Channel=%i CHS=%i/%i/%i\n",
2182 sdev->id, sdev->lun,sdev->channel,(int)cylinders,heads,sectors));
2187 /* Search IOC page 3 to determine if this is hidden physical disk
2191 mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id)
2195 if (!ioc->raid_data.isRaid || !ioc->raid_data.pIocPg3)
2197 for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2198 if (id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID)
2203 EXPORT_SYMBOL(mptscsih_is_phys_disk);
2206 mptscsih_raid_id_to_num(MPT_SCSI_HOST *hd, uint physdiskid)
2210 if (!hd->ioc->raid_data.isRaid || !hd->ioc->raid_data.pIocPg3)
2213 for (i = 0; i < hd->ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2215 hd->ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID)
2216 return hd->ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum;
2221 EXPORT_SYMBOL(mptscsih_raid_id_to_num);
2223 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2225 * OS entry point to allow host driver to alloc memory
2226 * for each scsi target. Called once per device the bus scan.
2227 * Return non-zero if allocation fails.
2230 mptscsih_target_alloc(struct scsi_target *starget)
2232 VirtTarget *vtarget;
2234 vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
2237 starget->hostdata = vtarget;
2238 vtarget->starget = starget;
2242 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2244 * OS entry point to allow host driver to alloc memory
2245 * for each scsi device. Called once per device the bus scan.
2246 * Return non-zero if allocation fails.
2249 mptscsih_slave_alloc(struct scsi_device *sdev)
2251 struct Scsi_Host *host = sdev->host;
2252 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
2253 VirtTarget *vtarget;
2255 struct scsi_target *starget;
2257 vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
2259 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
2260 hd->ioc->name, sizeof(VirtDevice));
2264 vdev->lun = sdev->lun;
2265 sdev->hostdata = vdev;
2267 starget = scsi_target(sdev);
2268 vtarget = starget->hostdata;
2270 vdev->vtarget = vtarget;
2272 if (vtarget->num_luns == 0) {
2273 hd->Targets[sdev->id] = vtarget;
2274 vtarget->ioc_id = hd->ioc->id;
2275 vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
2276 vtarget->target_id = sdev->id;
2277 vtarget->bus_id = sdev->channel;
2278 if (hd->ioc->bus_type == SPI && sdev->channel == 0 &&
2279 hd->ioc->raid_data.isRaid & (1 << sdev->id)) {
2280 vtarget->raidVolume = 1;
2281 ddvtprintk((KERN_INFO
2282 "RAID Volume @ id %d\n", sdev->id));
2285 vtarget->num_luns++;
2290 * OS entry point to allow for host driver to free allocated memory
2291 * Called if no device present or device being unloaded
2294 mptscsih_target_destroy(struct scsi_target *starget)
2296 if (starget->hostdata)
2297 kfree(starget->hostdata);
2298 starget->hostdata = NULL;
2302 * OS entry point to allow for host driver to free allocated memory
2303 * Called if no device present or device being unloaded
2306 mptscsih_slave_destroy(struct scsi_device *sdev)
2308 struct Scsi_Host *host = sdev->host;
2309 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
2310 VirtTarget *vtarget;
2311 VirtDevice *vdevice;
2312 struct scsi_target *starget;
2314 starget = scsi_target(sdev);
2315 vtarget = starget->hostdata;
2316 vdevice = sdev->hostdata;
2318 mptscsih_search_running_cmds(hd, vdevice);
2319 vtarget->luns[0] &= ~(1 << vdevice->lun);
2320 vtarget->num_luns--;
2321 if (vtarget->num_luns == 0) {
2322 hd->Targets[sdev->id] = NULL;
2324 mptscsih_synchronize_cache(hd, vdevice);
2326 sdev->hostdata = NULL;
2329 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2331 * mptscsih_change_queue_depth - This function will set a devices queue depth
2332 * @sdev: per scsi_device pointer
2333 * @qdepth: requested queue depth
2335 * Adding support for new 'change_queue_depth' api.
2338 mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
2340 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sdev->host->hostdata;
2341 VirtTarget *vtarget;
2342 struct scsi_target *starget;
2346 starget = scsi_target(sdev);
2347 vtarget = starget->hostdata;
2349 if (hd->ioc->bus_type == SPI) {
2350 if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
2352 else if (sdev->type == TYPE_DISK &&
2353 vtarget->minSyncFactor <= MPT_ULTRA160)
2354 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2356 max_depth = MPT_SCSI_CMD_PER_DEV_LOW;
2358 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2360 if (qdepth > max_depth)
2365 tagged = MSG_SIMPLE_TAG;
2367 scsi_adjust_queue_depth(sdev, tagged, qdepth);
2368 return sdev->queue_depth;
2372 * OS entry point to adjust the queue_depths on a per-device basis.
2373 * Called once per device the bus scan. Use it to force the queue_depth
2374 * member to 1 if a device does not support Q tags.
2375 * Return non-zero if fails.
2378 mptscsih_slave_configure(struct scsi_device *sdev)
2380 struct Scsi_Host *sh = sdev->host;
2381 VirtTarget *vtarget;
2382 VirtDevice *vdevice;
2383 struct scsi_target *starget;
2384 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sh->hostdata;
2385 int indexed_lun, lun_index;
2387 starget = scsi_target(sdev);
2388 vtarget = starget->hostdata;
2389 vdevice = sdev->hostdata;
2391 dsprintk((MYIOC_s_INFO_FMT
2392 "device @ %p, id=%d, LUN=%d, channel=%d\n",
2393 hd->ioc->name, sdev, sdev->id, sdev->lun, sdev->channel));
2394 if (hd->ioc->bus_type == SPI)
2395 dsprintk((MYIOC_s_INFO_FMT
2396 "sdtr %d wdtr %d ppr %d inq length=%d\n",
2397 hd->ioc->name, sdev->sdtr, sdev->wdtr,
2398 sdev->ppr, sdev->inquiry_len));
2400 if (sdev->id > sh->max_id) {
2401 /* error case, should never happen */
2402 scsi_adjust_queue_depth(sdev, 0, 1);
2403 goto slave_configure_exit;
2406 vdevice->configured_lun=1;
2407 lun_index = (vdevice->lun >> 5); /* 32 luns per lun_index */
2408 indexed_lun = (vdevice->lun % 32);
2409 vtarget->luns[lun_index] |= (1 << indexed_lun);
2410 mptscsih_initTarget(hd, vtarget, sdev);
2411 mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH);
2413 dsprintk((MYIOC_s_INFO_FMT
2414 "Queue depth=%d, tflags=%x\n",
2415 hd->ioc->name, sdev->queue_depth, vtarget->tflags));
2417 if (hd->ioc->bus_type == SPI)
2418 dsprintk((MYIOC_s_INFO_FMT
2419 "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
2420 hd->ioc->name, vtarget->negoFlags, vtarget->maxOffset,
2421 vtarget->minSyncFactor));
2423 slave_configure_exit:
2425 dsprintk((MYIOC_s_INFO_FMT
2426 "tagged %d, simple %d, ordered %d\n",
2427 hd->ioc->name,sdev->tagged_supported, sdev->simple_tags,
2428 sdev->ordered_tags));
2433 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2435 * Private routines...
2438 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2439 /* Utility function to copy sense data from the scsi_cmnd buffer
2440 * to the FC and SCSI target structures.
2444 mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
2447 SCSIIORequest_t *pReq;
2448 u32 sense_count = le32_to_cpu(pScsiReply->SenseCount);
2450 /* Get target structure
2452 pReq = (SCSIIORequest_t *) mf;
2453 vdev = sc->device->hostdata;
2459 /* Copy the sense received into the scsi command block. */
2460 req_index = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2461 sense_data = ((u8 *)hd->ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC));
2462 memcpy(sc->sense_buffer, sense_data, SNS_LEN(sc));
2464 /* Log SMART data (asc = 0x5D, non-IM case only) if required.
2466 if ((hd->ioc->events) && (hd->ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) {
2467 if ((sense_data[12] == 0x5D) && (vdev->vtarget->raidVolume == 0)) {
2469 MPT_ADAPTER *ioc = hd->ioc;
2471 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
2472 ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
2473 ioc->events[idx].eventContext = ioc->eventContext;
2475 ioc->events[idx].data[0] = (pReq->LUN[1] << 24) ||
2476 (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) ||
2477 (sc->device->channel << 8) || sc->device->id;
2479 ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12];
2481 ioc->eventContext++;
2482 if (hd->ioc->pcidev->vendor ==
2483 PCI_VENDOR_ID_IBM) {
2484 mptscsih_issue_sep_command(hd->ioc,
2485 vdev->vtarget, MPI_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT);
2486 vdev->vtarget->tflags |=
2487 MPT_TARGET_FLAGS_LED_ON;
2492 dprintk((MYIOC_s_INFO_FMT "Hmmm... SenseData len=0! (?)\n",
2498 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc)
2503 hd = (MPT_SCSI_HOST *) sc->device->host->hostdata;
2505 for (i = 0; i < hd->ioc->req_depth; i++) {
2506 if (hd->ScsiLookup[i] == sc) {
2514 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2516 mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2519 unsigned long flags;
2522 dtmprintk((KERN_WARNING MYNAM
2523 ": IOC %s_reset routed to SCSI host driver!\n",
2524 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
2525 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
2527 /* If a FW reload request arrives after base installed but
2528 * before all scsi hosts have been attached, then an alt_ioc
2529 * may have a NULL sh pointer.
2531 if ((ioc->sh == NULL) || (ioc->sh->hostdata == NULL))
2534 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2536 if (reset_phase == MPT_IOC_SETUP_RESET) {
2537 dtmprintk((MYIOC_s_WARN_FMT "Setup-Diag Reset\n", ioc->name));
2540 * 1. Set Hard Reset Pending Flag
2541 * All new commands go to doneQ
2543 hd->resetPending = 1;
2545 } else if (reset_phase == MPT_IOC_PRE_RESET) {
2546 dtmprintk((MYIOC_s_WARN_FMT "Pre-Diag Reset\n", ioc->name));
2548 /* 2. Flush running commands
2549 * Clean ScsiLookup (and associated memory)
2553 /* 2b. Reply to OS all known outstanding I/O commands.
2555 mptscsih_flush_running_cmds(hd);
2557 /* 2c. If there was an internal command that
2558 * has not completed, configuration or io request,
2559 * free these resources.
2562 del_timer(&hd->timer);
2563 mpt_free_msg_frame(ioc, hd->cmdPtr);
2566 dtmprintk((MYIOC_s_WARN_FMT "Pre-Reset complete.\n", ioc->name));
2569 dtmprintk((MYIOC_s_WARN_FMT "Post-Diag Reset\n", ioc->name));
2571 /* Once a FW reload begins, all new OS commands are
2572 * redirected to the doneQ w/ a reset status.
2573 * Init all control structures.
2576 /* ScsiLookup initialization
2578 for (ii=0; ii < hd->ioc->req_depth; ii++)
2579 hd->ScsiLookup[ii] = NULL;
2581 /* 2. Chain Buffer initialization
2584 /* 4. Renegotiate to all devices, if SPI
2587 /* 5. Enable new commands to be posted
2589 spin_lock_irqsave(&ioc->FreeQlock, flags);
2591 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2592 hd->resetPending = 0;
2593 hd->tmState = TM_STATE_NONE;
2595 /* 6. If there was an internal command,
2596 * wake this process up.
2600 * Wake up the original calling thread
2602 hd->pLocal = &hd->localReply;
2603 hd->pLocal->completion = MPT_SCANDV_DID_RESET;
2604 hd->scandv_wait_done = 1;
2605 wake_up(&hd->scandv_waitq);
2609 dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name));
2613 return 1; /* currently means nothing really */
2616 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2618 mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2621 u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
2623 devtverboseprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
2626 if (ioc->sh == NULL ||
2627 ((hd = (MPT_SCSI_HOST *)ioc->sh->hostdata) == NULL))
2631 case MPI_EVENT_UNIT_ATTENTION: /* 03 */
2634 case MPI_EVENT_IOC_BUS_RESET: /* 04 */
2635 case MPI_EVENT_EXT_BUS_RESET: /* 05 */
2636 if (hd && (ioc->bus_type == SPI) && (hd->soft_resets < -1))
2639 case MPI_EVENT_LOGOUT: /* 09 */
2643 case MPI_EVENT_RESCAN: /* 06 */
2647 * CHECKME! Don't think we need to do
2648 * anything for these, but...
2650 case MPI_EVENT_LINK_STATUS_CHANGE: /* 07 */
2651 case MPI_EVENT_LOOP_STATE_CHANGE: /* 08 */
2653 * CHECKME! Falling thru...
2657 case MPI_EVENT_INTEGRATED_RAID: /* 0B */
2660 case MPI_EVENT_NONE: /* 00 */
2661 case MPI_EVENT_LOG_DATA: /* 01 */
2662 case MPI_EVENT_STATE_CHANGE: /* 02 */
2663 case MPI_EVENT_EVENT_CHANGE: /* 0A */
2665 dprintk((KERN_INFO " Ignoring event (=%02Xh)\n", event));
2669 return 1; /* currently means nothing really */
2672 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2674 * mptscsih_initTarget - Target, LUN alloc/free functionality.
2675 * @hd: Pointer to MPT_SCSI_HOST structure
2676 * @vtarget: per target private data
2677 * @sdev: SCSI device
2679 * NOTE: It's only SAFE to call this routine if data points to
2680 * sane & valid STANDARD INQUIRY data!
2682 * Allocate and initialize memory for this target.
2683 * Save inquiry data.
2687 mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget,
2688 struct scsi_device *sdev)
2690 dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n",
2691 hd->ioc->name, vtarget->bus_id, vtarget->target_id, lun, hd));
2693 /* Is LUN supported? If so, upper 2 bits will be 0
2694 * in first byte of inquiry data.
2696 if (sdev->inq_periph_qual != 0)
2699 if (vtarget == NULL)
2702 vtarget->type = sdev->type;
2704 if (hd->ioc->bus_type != SPI)
2707 if ((sdev->type == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) {
2708 /* Treat all Processors as SAF-TE if
2709 * command line option is set */
2710 vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
2711 mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id);
2712 }else if ((sdev->type == TYPE_PROCESSOR) &&
2713 !(vtarget->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) {
2714 if (sdev->inquiry_len > 49 ) {
2715 if (sdev->inquiry[44] == 'S' &&
2716 sdev->inquiry[45] == 'A' &&
2717 sdev->inquiry[46] == 'F' &&
2718 sdev->inquiry[47] == '-' &&
2719 sdev->inquiry[48] == 'T' &&
2720 sdev->inquiry[49] == 'E' ) {
2721 vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
2722 mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id);
2726 mptscsih_setTargetNegoParms(hd, vtarget, sdev);
2729 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2731 * Update the target negotiation parameters based on the
2732 * the Inquiry data, adapter capabilities, and NVRAM settings.
2736 mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target,
2737 struct scsi_device *sdev)
2739 SpiCfgData *pspi_data = &hd->ioc->spi_data;
2740 int id = (int) target->target_id;
2742 u8 width = MPT_NARROW;
2743 u8 factor = MPT_ASYNC;
2748 target->negoFlags = pspi_data->noQas;
2750 /* noQas == 0 => device supports QAS. */
2752 if (sdev->scsi_level < SCSI_2) {
2754 factor = MPT_ULTRA2;
2755 offset = pspi_data->maxSyncOffset;
2756 target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
2758 if (scsi_device_wide(sdev)) {
2762 if (scsi_device_sync(sdev)) {
2763 factor = pspi_data->minSyncFactor;
2764 if (!scsi_device_dt(sdev))
2765 factor = MPT_ULTRA2;
2767 if (!scsi_device_ius(sdev) &&
2768 !scsi_device_qas(sdev))
2769 factor = MPT_ULTRA160;
2771 factor = MPT_ULTRA320;
2772 if (scsi_device_qas(sdev)) {
2773 ddvtprintk((KERN_INFO "Enabling QAS due to byte56=%02x on id=%d!\n", byte56, id));
2776 if (sdev->type == TYPE_TAPE &&
2777 scsi_device_ius(sdev))
2778 target->negoFlags |= MPT_TAPE_NEGO_IDP;
2781 offset = pspi_data->maxSyncOffset;
2783 /* If RAID, never disable QAS
2784 * else if non RAID, do not disable
2785 * QAS if bit 1 is set
2786 * bit 1 QAS support, non-raid only
2789 if (target->raidVolume == 1) {
2798 if (!sdev->tagged_supported) {
2799 target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
2802 /* Update tflags based on NVRAM settings. (SCSI only)
2804 if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
2805 nvram = pspi_data->nvram[id];
2806 nfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
2809 width = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
2812 /* Ensure factor is set to the
2813 * maximum of: adapter, nvram, inquiry
2816 if (nfactor < pspi_data->minSyncFactor )
2817 nfactor = pspi_data->minSyncFactor;
2819 factor = max(factor, nfactor);
2820 if (factor == MPT_ASYNC)
2831 /* Make sure data is consistent
2833 if ((!width) && (factor < MPT_ULTRA2)) {
2834 factor = MPT_ULTRA2;
2837 /* Save the data to the target structure.
2839 target->minSyncFactor = factor;
2840 target->maxOffset = offset;
2841 target->maxWidth = width;
2843 target->tflags |= MPT_TARGET_FLAGS_VALID_NEGO;
2845 /* Disable unused features.
2848 target->negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
2851 target->negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
2853 if ( factor > MPT_ULTRA320 )
2856 if (noQas && (pspi_data->noQas == 0)) {
2857 pspi_data->noQas |= MPT_TARGET_NO_NEGO_QAS;
2858 target->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
2860 /* Disable QAS in a mixed configuration case
2863 ddvtprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id));
2867 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2869 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2871 * SCSI Config Page functionality ...
2874 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2875 /* mptscsih_writeIOCPage4 - write IOC Page 4
2876 * @hd: Pointer to a SCSI Host Structure
2877 * @target_id: write IOC Page4 for this ID & Bus
2879 * Return: -EAGAIN if unable to obtain a Message Frame
2882 * Remark: We do not wait for a return, write pages sequentially.
2885 mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus)
2887 MPT_ADAPTER *ioc = hd->ioc;
2889 IOCPage4_t *IOCPage4Ptr;
2897 /* Get a MF for this command.
2899 if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
2900 dfailprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n",
2905 /* Set the request and the data pointers.
2906 * Place data at end of MF.
2908 pReq = (Config_t *)mf;
2910 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2911 frameOffset = ioc->req_sz - sizeof(IOCPage4_t);
2913 /* Complete the request frame (same for all requests).
2915 pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
2917 pReq->ChainOffset = 0;
2918 pReq->Function = MPI_FUNCTION_CONFIG;
2919 pReq->ExtPageLength = 0;
2920 pReq->ExtPageType = 0;
2922 for (ii=0; ii < 8; ii++) {
2923 pReq->Reserved2[ii] = 0;
2926 IOCPage4Ptr = ioc->spi_data.pIocPg4;
2927 dataDma = ioc->spi_data.IocPg4_dma;
2928 ii = IOCPage4Ptr->ActiveSEP++;
2929 IOCPage4Ptr->SEP[ii].SEPTargetID = target_id;
2930 IOCPage4Ptr->SEP[ii].SEPBus = bus;
2931 pReq->Header = IOCPage4Ptr->Header;
2932 pReq->PageAddress = cpu_to_le32(target_id | (bus << 8 ));
2934 /* Add a SGE to the config request.
2936 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE |
2937 (IOCPage4Ptr->Header.PageLength + ii) * 4;
2939 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma);
2941 dinitprintk((MYIOC_s_INFO_FMT
2942 "writeIOCPage4: MaxSEP=%d ActiveSEP=%d id=%d bus=%d\n",
2943 ioc->name, IOCPage4Ptr->MaxSEP, IOCPage4Ptr->ActiveSEP, target_id, bus));
2945 mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
2950 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2952 * Bus Scan and Domain Validation functionality ...
2955 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2957 * mptscsih_scandv_complete - Scan and DV callback routine registered
2958 * to Fustion MPT (base) driver.
2960 * @ioc: Pointer to MPT_ADAPTER structure
2961 * @mf: Pointer to original MPT request frame
2962 * @mr: Pointer to MPT reply frame (NULL if TurboReply)
2964 * This routine is called from mpt.c::mpt_interrupt() at the completion
2965 * of any SCSI IO request.
2966 * This routine is registered with the Fusion MPT (base) driver at driver
2967 * load/init time via the mpt_register() API call.
2969 * Returns 1 indicating alloc'd request frame ptr should be freed.
2971 * Remark: Sets a completion code and (possibly) saves sense data
2972 * in the IOC member localReply structure.
2973 * Used ONLY for DV and other internal commands.
2976 mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
2979 SCSIIORequest_t *pReq;
2983 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2986 (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) {
2987 printk(MYIOC_s_ERR_FMT
2988 "ScanDvComplete, %s req frame ptr! (=%p)\n",
2989 ioc->name, mf?"BAD":"NULL", (void *) mf);
2993 del_timer(&hd->timer);
2994 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2995 hd->ScsiLookup[req_idx] = NULL;
2996 pReq = (SCSIIORequest_t *) mf;
2998 if (mf != hd->cmdPtr) {
2999 printk(MYIOC_s_WARN_FMT "ScanDvComplete (mf=%p, cmdPtr=%p, idx=%d)\n",
3000 hd->ioc->name, (void *)mf, (void *) hd->cmdPtr, req_idx);
3004 ddvprintk((MYIOC_s_INFO_FMT "ScanDvComplete (mf=%p,mr=%p,idx=%d)\n",
3005 hd->ioc->name, mf, mr, req_idx));
3007 hd->pLocal = &hd->localReply;
3008 hd->pLocal->scsiStatus = 0;
3010 /* If target struct exists, clear sense valid flag.
3013 completionCode = MPT_SCANDV_GOOD;
3015 SCSIIOReply_t *pReply;
3019 pReply = (SCSIIOReply_t *) mr;
3021 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
3022 scsi_status = pReply->SCSIStatus;
3024 ddvtprintk((KERN_NOTICE " IOCStatus=%04xh, SCSIState=%02xh, SCSIStatus=%02xh, IOCLogInfo=%08xh\n",
3025 status, pReply->SCSIState, scsi_status,
3026 le32_to_cpu(pReply->IOCLogInfo)));
3030 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
3031 completionCode = MPT_SCANDV_SELECTION_TIMEOUT;
3034 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
3035 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
3036 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
3037 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
3038 completionCode = MPT_SCANDV_DID_RESET;
3041 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
3042 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
3043 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
3044 if (pReply->Function == MPI_FUNCTION_CONFIG) {
3045 ConfigReply_t *pr = (ConfigReply_t *)mr;
3046 completionCode = MPT_SCANDV_GOOD;
3047 hd->pLocal->header.PageVersion = pr->Header.PageVersion;
3048 hd->pLocal->header.PageLength = pr->Header.PageLength;
3049 hd->pLocal->header.PageNumber = pr->Header.PageNumber;
3050 hd->pLocal->header.PageType = pr->Header.PageType;
3052 } else if (pReply->Function == MPI_FUNCTION_RAID_ACTION) {
3053 /* If the RAID Volume request is successful,
3054 * return GOOD, else indicate that
3055 * some type of error occurred.
3057 MpiRaidActionReply_t *pr = (MpiRaidActionReply_t *)mr;
3058 if (le16_to_cpu(pr->ActionStatus) == MPI_RAID_ACTION_ASTATUS_SUCCESS)
3059 completionCode = MPT_SCANDV_GOOD;
3061 completionCode = MPT_SCANDV_SOME_ERROR;
3062 memcpy(hd->pLocal->sense, pr, sizeof(hd->pLocal->sense));
3064 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID) {
3068 /* save sense data in global structure
3070 completionCode = MPT_SCANDV_SENSE;
3071 hd->pLocal->scsiStatus = scsi_status;
3072 sense_data = ((u8 *)hd->ioc->sense_buf_pool +
3073 (req_idx * MPT_SENSE_BUFFER_ALLOC));
3075 sz = min_t(int, pReq->SenseBufferLength,
3076 SCSI_STD_SENSE_BYTES);
3077 memcpy(hd->pLocal->sense, sense_data, sz);
3079 ddvprintk((KERN_NOTICE " Check Condition, sense ptr %p\n",
3081 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_FAILED) {
3082 if (pReq->CDB[0] == INQUIRY)
3083 completionCode = MPT_SCANDV_ISSUE_SENSE;
3085 completionCode = MPT_SCANDV_DID_RESET;
3087 else if (pReply->SCSIState & MPI_SCSI_STATE_NO_SCSI_STATUS)
3088 completionCode = MPT_SCANDV_DID_RESET;
3089 else if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
3090 completionCode = MPT_SCANDV_DID_RESET;
3092 completionCode = MPT_SCANDV_GOOD;
3093 hd->pLocal->scsiStatus = scsi_status;
3097 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
3098 if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
3099 completionCode = MPT_SCANDV_DID_RESET;
3101 completionCode = MPT_SCANDV_SOME_ERROR;
3105 completionCode = MPT_SCANDV_SOME_ERROR;
3108 } /* switch(status) */
3110 ddvtprintk((KERN_NOTICE " completionCode set to %08xh\n",
3112 } /* end of address reply case */
3114 hd->pLocal->completion = completionCode;
3116 /* MF and RF are freed in mpt_interrupt
3119 /* Free Chain buffers (will never chain) in scan or dv */
3120 //mptscsih_freeChainBuffers(ioc, req_idx);
3123 * Wake up the original calling thread
3125 hd->scandv_wait_done = 1;
3126 wake_up(&hd->scandv_waitq);
3131 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3132 /* mptscsih_timer_expired - Call back for timer process.
3133 * Used only for dv functionality.
3134 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
3138 mptscsih_timer_expired(unsigned long data)
3140 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) data;
3142 ddvprintk((MYIOC_s_WARN_FMT "Timer Expired! Cmd %p\n", hd->ioc->name, hd->cmdPtr));
3145 MPIHeader_t *cmd = (MPIHeader_t *)hd->cmdPtr;
3147 if (cmd->Function == MPI_FUNCTION_SCSI_IO_REQUEST) {
3148 /* Desire to issue a task management request here.
3149 * TM requests MUST be single threaded.
3150 * If old eh code and no TM current, issue request.
3151 * If new eh code, do nothing. Wait for OS cmd timeout
3154 ddvtprintk((MYIOC_s_NOTE_FMT "DV Cmd Timeout: NoOp\n", hd->ioc->name));
3156 /* Perform a FW reload */
3157 if (mpt_HardResetHandler(hd->ioc, NO_SLEEP) < 0) {
3158 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", hd->ioc->name);
3162 /* This should NEVER happen */
3163 printk(MYIOC_s_WARN_FMT "Null cmdPtr!!!!\n", hd->ioc->name);
3166 /* No more processing.
3167 * TM call will generate an interrupt for SCSI TM Management.
3168 * The FW will reply to all outstanding commands, callback will finish cleanup.
3169 * Hard reset clean-up will free all resources.
3171 ddvprintk((MYIOC_s_WARN_FMT "Timer Expired Complete!\n", hd->ioc->name));
3177 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3179 * mptscsih_do_cmd - Do internal command.
3180 * @hd: MPT_SCSI_HOST pointer
3181 * @io: INTERNAL_CMD pointer.
3183 * Issue the specified internally generated command and do command
3184 * specific cleanup. For bus scan / DV only.
3185 * NOTES: If command is Inquiry and status is good,
3186 * initialize a target structure, save the data
3188 * Remark: Single threaded access only.
3191 * < 0 if an illegal command or no resources
3195 * > 0 if command complete but some type of completion error.
3198 mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
3201 SCSIIORequest_t *pScsiReq;
3202 SCSIIORequest_t ReqCopy;
3203 int my_idx, ii, dir;
3207 char CDB[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
3210 in_isr = in_interrupt();
3212 dprintk((MYIOC_s_WARN_FMT "Internal SCSI IO request not allowed in ISR context!\n",
3218 /* Set command specific information
3223 dir = MPI_SCSIIO_CONTROL_READ;
3229 case TEST_UNIT_READY:
3231 dir = MPI_SCSIIO_CONTROL_READ;
3237 dir = MPI_SCSIIO_CONTROL_READ;
3239 CDB[4] = 1; /*Spin up the disk */
3247 dir = MPI_SCSIIO_CONTROL_READ;
3253 dir = MPI_SCSIIO_CONTROL_READ;
3255 if (io->flags & MPT_ICFLAG_ECHO) {
3261 if (io->flags & MPT_ICFLAG_BUF_CAP) {
3264 CDB[6] = (io->size >> 16) & 0xFF;
3265 CDB[7] = (io->size >> 8) & 0xFF;
3266 CDB[8] = io->size & 0xFF;
3272 dir = MPI_SCSIIO_CONTROL_WRITE;
3274 if (io->flags & MPT_ICFLAG_ECHO) {
3279 CDB[6] = (io->size >> 16) & 0xFF;
3280 CDB[7] = (io->size >> 8) & 0xFF;
3281 CDB[8] = io->size & 0xFF;
3287 dir = MPI_SCSIIO_CONTROL_READ;
3294 dir = MPI_SCSIIO_CONTROL_READ;
3299 case SYNCHRONIZE_CACHE:
3301 dir = MPI_SCSIIO_CONTROL_READ;
3303 // CDB[1] = 0x02; /* set immediate bit */
3312 /* Get and Populate a free Frame
3314 if ((mf = mpt_get_msg_frame(hd->ioc->InternalCtx, hd->ioc)) == NULL) {
3315 ddvprintk((MYIOC_s_WARN_FMT "No msg frames!\n",
3320 pScsiReq = (SCSIIORequest_t *) mf;
3322 /* Get the request index */
3323 my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3324 ADD_INDEX_LOG(my_idx); /* for debug */
3326 if (io->flags & MPT_ICFLAG_PHYS_DISK) {
3327 pScsiReq->TargetID = io->physDiskNum;
3329 pScsiReq->ChainOffset = 0;
3330 pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
3332 pScsiReq->TargetID = io->id;
3333 pScsiReq->Bus = io->bus;
3334 pScsiReq->ChainOffset = 0;
3335 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
3338 pScsiReq->CDBLength = cmdLen;
3339 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
3341 pScsiReq->Reserved = 0;
3343 pScsiReq->MsgFlags = mpt_msg_flags();
3344 /* MsgContext set in mpt_get_msg_fram call */
3346 for (ii=0; ii < 8; ii++)
3347 pScsiReq->LUN[ii] = 0;
3348 pScsiReq->LUN[1] = io->lun;
3350 if (io->flags & MPT_ICFLAG_TAGGED_CMD)
3351 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ);
3353 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3355 if (cmd == REQUEST_SENSE) {
3356 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3357 ddvprintk((MYIOC_s_INFO_FMT "Untagged! 0x%2x\n",
3358 hd->ioc->name, cmd));
3361 for (ii=0; ii < 16; ii++)
3362 pScsiReq->CDB[ii] = CDB[ii];
3364 pScsiReq->DataLength = cpu_to_le32(io->size);
3365 pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
3366 + (my_idx * MPT_SENSE_BUFFER_ALLOC));
3368 ddvprintk((MYIOC_s_INFO_FMT "Sending Command 0x%x for (%d:%d:%d)\n",
3369 hd->ioc->name, cmd, io->bus, io->id, io->lun));
3371 if (dir == MPI_SCSIIO_CONTROL_READ) {
3372 mpt_add_sge((char *) &pScsiReq->SGL,
3373 MPT_SGE_FLAGS_SSIMPLE_READ | io->size,
3376 mpt_add_sge((char *) &pScsiReq->SGL,
3377 MPT_SGE_FLAGS_SSIMPLE_WRITE | io->size,
3381 /* The ISR will free the request frame, but we need
3382 * the information to initialize the target. Duplicate.
3384 memcpy(&ReqCopy, pScsiReq, sizeof(SCSIIORequest_t));
3386 /* Issue this command after:
3389 * Wait until the reply has been received
3390 * ScsiScanDvCtx callback function will
3392 * set scandv_wait_done and call wake_up
3395 hd->timer.expires = jiffies + HZ*cmdTimeout;
3396 hd->scandv_wait_done = 0;
3398 /* Save cmd pointer, for resource free if timeout or
3403 add_timer(&hd->timer);
3404 mpt_put_msg_frame(hd->ioc->InternalCtx, hd->ioc, mf);
3405 wait_event(hd->scandv_waitq, hd->scandv_wait_done);
3408 rc = hd->pLocal->completion;
3409 hd->pLocal->skip = 0;
3411 /* Always set fatal error codes in some cases.
3413 if (rc == MPT_SCANDV_SELECTION_TIMEOUT)
3415 else if (rc == MPT_SCANDV_SOME_ERROR)
3419 /* This should never happen. */
3420 ddvprintk((MYIOC_s_INFO_FMT "_do_cmd: Null pLocal!!!\n",
3427 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3429 * mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
3430 * @hd: Pointer to a SCSI HOST structure
3431 * @vdevice: virtual target device
3433 * Uses the ISR, but with special processing.
3434 * MUST be single-threaded.
3438 mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
3442 /* Following parameters will not change
3445 iocmd.cmd = SYNCHRONIZE_CACHE;
3447 iocmd.physDiskNum = -1;
3449 iocmd.data_dma = -1;
3451 iocmd.rsvd = iocmd.rsvd2 = 0;
3452 iocmd.bus = vdevice->vtarget->bus_id;
3453 iocmd.id = vdevice->vtarget->target_id;
3454 iocmd.lun = (u8)vdevice->lun;
3456 if ((vdevice->vtarget->type == TYPE_DISK) &&
3457 (vdevice->configured_lun))
3458 mptscsih_do_cmd(hd, &iocmd);
3461 EXPORT_SYMBOL(mptscsih_remove);
3462 EXPORT_SYMBOL(mptscsih_shutdown);
3464 EXPORT_SYMBOL(mptscsih_suspend);
3465 EXPORT_SYMBOL(mptscsih_resume);
3467 EXPORT_SYMBOL(mptscsih_proc_info);
3468 EXPORT_SYMBOL(mptscsih_info);
3469 EXPORT_SYMBOL(mptscsih_qcmd);
3470 EXPORT_SYMBOL(mptscsih_target_alloc);
3471 EXPORT_SYMBOL(mptscsih_slave_alloc);
3472 EXPORT_SYMBOL(mptscsih_target_destroy);
3473 EXPORT_SYMBOL(mptscsih_slave_destroy);
3474 EXPORT_SYMBOL(mptscsih_slave_configure);
3475 EXPORT_SYMBOL(mptscsih_abort);
3476 EXPORT_SYMBOL(mptscsih_dev_reset);
3477 EXPORT_SYMBOL(mptscsih_bus_reset);
3478 EXPORT_SYMBOL(mptscsih_host_reset);
3479 EXPORT_SYMBOL(mptscsih_bios_param);
3480 EXPORT_SYMBOL(mptscsih_io_done);
3481 EXPORT_SYMBOL(mptscsih_taskmgmt_complete);
3482 EXPORT_SYMBOL(mptscsih_scandv_complete);
3483 EXPORT_SYMBOL(mptscsih_event_process);
3484 EXPORT_SYMBOL(mptscsih_ioc_reset);
3485 EXPORT_SYMBOL(mptscsih_change_queue_depth);
3486 EXPORT_SYMBOL(mptscsih_timer_expired);
3487 EXPORT_SYMBOL(mptscsih_TMHandler);
3489 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/