2 * linux/drivers/message/fusion/mptscsih.c
3 * For use with LSI Logic PCI chip/adapter(s)
4 * running LSI Logic Fusion MPT (Message Passing Technology) firmware.
6 * Copyright (c) 1999-2007 LSI Logic Corporation
7 * (mailto:mpt_linux_developer@lsil.com)
10 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; version 2 of the License.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
22 THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
23 CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
24 LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
25 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
26 solely responsible for determining the appropriateness of using and
27 distributing the Program and assumes all risks associated with its
28 exercise of rights under this Agreement, including but not limited to
29 the risks and costs of program errors, damage to or loss of data,
30 programs or equipment, and unavailability or interruption of operations.
32 DISCLAIMER OF LIABILITY
33 NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
34 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
35 DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
36 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
37 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
38 USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
39 HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
41 You should have received a copy of the GNU General Public License
42 along with this program; if not, write to the Free Software
43 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
45 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
47 #include "linux_compat.h" /* linux-2.6 tweaks */
48 #include <linux/module.h>
49 #include <linux/kernel.h>
50 #include <linux/init.h>
51 #include <linux/errno.h>
52 #include <linux/kdev_t.h>
53 #include <linux/blkdev.h>
54 #include <linux/delay.h> /* for mdelay */
55 #include <linux/interrupt.h> /* needed for in_interrupt() proto */
56 #include <linux/reboot.h> /* notifier code */
57 #include <linux/sched.h>
58 #include <linux/workqueue.h>
60 #include <scsi/scsi.h>
61 #include <scsi/scsi_cmnd.h>
62 #include <scsi/scsi_device.h>
63 #include <scsi/scsi_host.h>
64 #include <scsi/scsi_tcq.h>
65 #include <scsi/scsi_dbg.h>
69 #include "lsi/mpi_log_sas.h"
71 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
72 #define my_NAME "Fusion MPT SCSI Host driver"
73 #define my_VERSION MPT_LINUX_VERSION_COMMON
74 #define MYNAM "mptscsih"
76 MODULE_AUTHOR(MODULEAUTHOR);
77 MODULE_DESCRIPTION(my_NAME);
78 MODULE_LICENSE("GPL");
79 MODULE_VERSION(my_VERSION);
81 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
83 typedef struct _BIG_SENSE_BUF {
84 u8 data[MPT_SENSE_BUFFER_ALLOC];
87 #define MPT_SCANDV_GOOD (0x00000000) /* must be 0 */
88 #define MPT_SCANDV_DID_RESET (0x00000001)
89 #define MPT_SCANDV_SENSE (0x00000002)
90 #define MPT_SCANDV_SOME_ERROR (0x00000004)
91 #define MPT_SCANDV_SELECTION_TIMEOUT (0x00000008)
92 #define MPT_SCANDV_ISSUE_SENSE (0x00000010)
93 #define MPT_SCANDV_FALLBACK (0x00000020)
95 #define MPT_SCANDV_MAX_RETRIES (10)
97 #define MPT_ICFLAG_BUF_CAP 0x01 /* ReadBuffer Read Capacity format */
98 #define MPT_ICFLAG_ECHO 0x02 /* ReadBuffer Echo buffer format */
99 #define MPT_ICFLAG_EBOS 0x04 /* ReadBuffer Echo buffer has EBOS */
100 #define MPT_ICFLAG_PHYS_DISK 0x08 /* Any SCSI IO but do Phys Disk Format */
101 #define MPT_ICFLAG_TAGGED_CMD 0x10 /* Do tagged IO */
102 #define MPT_ICFLAG_DID_RESET 0x20 /* Bus Reset occurred with this command */
103 #define MPT_ICFLAG_RESERVED 0x40 /* Reserved has been issued */
105 typedef struct _internal_cmd {
106 char *data; /* data pointer */
107 dma_addr_t data_dma; /* data dma address */
108 int size; /* transfer size */
109 u8 cmd; /* SCSI Op Code */
110 u8 bus; /* bus number */
111 u8 id; /* SCSI ID (virtual) */
113 u8 flags; /* Bit Field - See above */
114 u8 physDiskNum; /* Phys disk number, -1 else */
120 * Other private/forward protos...
122 int mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
123 static void mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq);
124 int mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
126 static int mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
127 SCSIIORequest_t *pReq, int req_idx);
128 static void mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx);
129 static void mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply);
130 static int mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd);
131 static int mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout );
132 static int SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc);
134 static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout);
136 int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
137 int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
139 static void mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, struct scsi_device *sdev);
140 static void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *vtarget, struct scsi_device *sdev);
141 static int mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus);
142 int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
143 static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
144 static void mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice);
146 void mptscsih_remove(struct pci_dev *);
147 void mptscsih_shutdown(struct pci_dev *);
149 int mptscsih_suspend(struct pci_dev *pdev, pm_message_t state);
150 int mptscsih_resume(struct pci_dev *pdev);
153 #define SNS_LEN(scp) sizeof((scp)->sense_buffer)
155 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
157 * mptscsih_add_sge - Place a simple SGE at address pAddr.
158 * @pAddr: virtual address for SGE
159 * @flagslength: SGE flags and data transfer length
160 * @dma_addr: Physical address
162 * This routine places a MPT request frame back on the MPT adapter's
166 mptscsih_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
168 if (sizeof(dma_addr_t) == sizeof(u64)) {
169 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
170 u32 tmp = dma_addr & 0xFFFFFFFF;
172 pSge->FlagsLength = cpu_to_le32(flagslength);
173 pSge->Address.Low = cpu_to_le32(tmp);
174 tmp = (u32) ((u64)dma_addr >> 32);
175 pSge->Address.High = cpu_to_le32(tmp);
178 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
179 pSge->FlagsLength = cpu_to_le32(flagslength);
180 pSge->Address = cpu_to_le32(dma_addr);
182 } /* mptscsih_add_sge() */
184 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
186 * mptscsih_add_chain - Place a chain SGE at address pAddr.
187 * @pAddr: virtual address for SGE
188 * @next: nextChainOffset value (u32's)
189 * @length: length of next SGL segment
190 * @dma_addr: Physical address
192 * This routine places a MPT request frame back on the MPT adapter's
196 mptscsih_add_chain(char *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
198 if (sizeof(dma_addr_t) == sizeof(u64)) {
199 SGEChain64_t *pChain = (SGEChain64_t *) pAddr;
200 u32 tmp = dma_addr & 0xFFFFFFFF;
202 pChain->Length = cpu_to_le16(length);
203 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size();
205 pChain->NextChainOffset = next;
207 pChain->Address.Low = cpu_to_le32(tmp);
208 tmp = (u32) ((u64)dma_addr >> 32);
209 pChain->Address.High = cpu_to_le32(tmp);
211 SGEChain32_t *pChain = (SGEChain32_t *) pAddr;
212 pChain->Length = cpu_to_le16(length);
213 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size();
214 pChain->NextChainOffset = next;
215 pChain->Address = cpu_to_le32(dma_addr);
217 } /* mptscsih_add_chain() */
219 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
221 * mptscsih_getFreeChainBuffer - Function to get a free chain
222 * from the MPT_SCSI_HOST FreeChainQ.
223 * @ioc: Pointer to MPT_ADAPTER structure
224 * @req_idx: Index of the SCSI IO request frame. (output)
226 * return SUCCESS or FAILED
229 mptscsih_getFreeChainBuffer(MPT_ADAPTER *ioc, int *retIndex)
231 MPT_FRAME_HDR *chainBuf;
236 dsgprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer called\n",
238 spin_lock_irqsave(&ioc->FreeQlock, flags);
239 if (!list_empty(&ioc->FreeChainQ)) {
242 chainBuf = list_entry(ioc->FreeChainQ.next, MPT_FRAME_HDR,
243 u.frame.linkage.list);
244 list_del(&chainBuf->u.frame.linkage.list);
245 offset = (u8 *)chainBuf - (u8 *)ioc->ChainBuffer;
246 chain_idx = offset / ioc->req_sz;
248 dsgprintk((MYIOC_s_ERR_FMT "getFreeChainBuffer chainBuf=%p ChainBuffer=%p offset=%d chain_idx=%d\n",
249 ioc->name, chainBuf, ioc->ChainBuffer, offset, chain_idx));
252 chain_idx = MPT_HOST_NO_CHAIN;
253 dfailprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer failed\n",
256 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
258 *retIndex = chain_idx;
260 } /* mptscsih_getFreeChainBuffer() */
262 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
264 * mptscsih_AddSGE - Add a SGE (plus chain buffers) to the
265 * SCSIIORequest_t Message Frame.
266 * @ioc: Pointer to MPT_ADAPTER structure
267 * @SCpnt: Pointer to scsi_cmnd structure
268 * @pReq: Pointer to SCSIIORequest_t structure
273 mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
274 SCSIIORequest_t *pReq, int req_idx)
278 struct scatterlist *sg;
280 int sges_left, sg_done;
281 int chain_idx = MPT_HOST_NO_CHAIN;
283 int numSgeSlots, numSgeThisFrame;
284 u32 sgflags, sgdir, thisxfer = 0;
285 int chain_dma_off = 0;
291 sgdir = le32_to_cpu(pReq->Control) & MPI_SCSIIO_CONTROL_DATADIRECTION_MASK;
292 if (sgdir == MPI_SCSIIO_CONTROL_WRITE) {
293 sgdir = MPT_TRANSFER_HOST_TO_IOC;
295 sgdir = MPT_TRANSFER_IOC_TO_HOST;
298 psge = (char *) &pReq->SGL;
299 frm_sz = ioc->req_sz;
301 /* Map the data portion, if any.
302 * sges_left = 0 if no data transfer.
304 if ( (sges_left = SCpnt->use_sg) ) {
305 sges_left = pci_map_sg(ioc->pcidev,
306 (struct scatterlist *) SCpnt->request_buffer,
308 SCpnt->sc_data_direction);
311 } else if (SCpnt->request_bufflen) {
312 SCpnt->SCp.dma_handle = pci_map_single(ioc->pcidev,
313 SCpnt->request_buffer,
314 SCpnt->request_bufflen,
315 SCpnt->sc_data_direction);
316 dsgprintk((MYIOC_s_INFO_FMT "SG: non-SG for %p, len=%d\n",
317 ioc->name, SCpnt, SCpnt->request_bufflen));
318 mptscsih_add_sge((char *) &pReq->SGL,
319 0xD1000000|MPT_SGE_FLAGS_ADDRESSING|sgdir|SCpnt->request_bufflen,
320 SCpnt->SCp.dma_handle);
325 /* Handle the SG case.
327 sg = (struct scatterlist *) SCpnt->request_buffer;
329 sgeOffset = sizeof(SCSIIORequest_t) - sizeof(SGE_IO_UNION);
332 /* Prior to entering this loop - the following must be set
333 * current MF: sgeOffset (bytes)
334 * chainSge (Null if original MF is not a chain buffer)
335 * sg_done (num SGE done for this MF)
339 numSgeSlots = ((frm_sz - sgeOffset) / (sizeof(u32) + sizeof(dma_addr_t)) );
340 numSgeThisFrame = (sges_left < numSgeSlots) ? sges_left : numSgeSlots;
342 sgflags = MPT_SGE_FLAGS_SIMPLE_ELEMENT | MPT_SGE_FLAGS_ADDRESSING | sgdir;
344 /* Get first (num - 1) SG elements
345 * Skip any SG entries with a length of 0
346 * NOTE: at finish, sg and psge pointed to NEXT data/location positions
348 for (ii=0; ii < (numSgeThisFrame-1); ii++) {
349 thisxfer = sg_dma_len(sg);
351 sg ++; /* Get next SG element from the OS */
356 v2 = sg_dma_address(sg);
357 mptscsih_add_sge(psge, sgflags | thisxfer, v2);
359 sg++; /* Get next SG element from the OS */
360 psge += (sizeof(u32) + sizeof(dma_addr_t));
361 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
365 if (numSgeThisFrame == sges_left) {
366 /* Add last element, end of buffer and end of list flags.
368 sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT |
369 MPT_SGE_FLAGS_END_OF_BUFFER |
370 MPT_SGE_FLAGS_END_OF_LIST;
372 /* Add last SGE and set termination flags.
373 * Note: Last SGE may have a length of 0 - which should be ok.
375 thisxfer = sg_dma_len(sg);
377 v2 = sg_dma_address(sg);
378 mptscsih_add_sge(psge, sgflags | thisxfer, v2);
381 psge += (sizeof(u32) + sizeof(dma_addr_t));
383 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
387 /* The current buffer is a chain buffer,
388 * but there is not another one.
389 * Update the chain element
390 * Offset and Length fields.
392 mptscsih_add_chain((char *)chainSge, 0, sgeOffset, ioc->ChainBufferDMA + chain_dma_off);
394 /* The current buffer is the original MF
395 * and there is no Chain buffer.
397 pReq->ChainOffset = 0;
398 RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor) + 1) & 0x03;
399 dsgprintk((MYIOC_s_INFO_FMT
400 "Single Buffer RequestNB=%x, sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
401 ioc->RequestNB[req_idx] = RequestNB;
404 /* At least one chain buffer is needed.
405 * Complete the first MF
406 * - last SGE element, set the LastElement bit
407 * - set ChainOffset (words) for orig MF
408 * (OR finish previous MF chain buffer)
409 * - update MFStructPtr ChainIndex
410 * - Populate chain element
415 dsgprintk((MYIOC_s_INFO_FMT "SG: Chain Required! sg done %d\n",
416 ioc->name, sg_done));
418 /* Set LAST_ELEMENT flag for last non-chain element
419 * in the buffer. Since psge points at the NEXT
420 * SGE element, go back one SGE element, update the flags
421 * and reset the pointer. (Note: sgflags & thisxfer are already
425 u32 *ptmp = (u32 *) (psge - (sizeof(u32) + sizeof(dma_addr_t)));
426 sgflags = le32_to_cpu(*ptmp);
427 sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT;
428 *ptmp = cpu_to_le32(sgflags);
432 /* The current buffer is a chain buffer.
433 * chainSge points to the previous Chain Element.
434 * Update its chain element Offset and Length (must
435 * include chain element size) fields.
436 * Old chain element is now complete.
438 u8 nextChain = (u8) (sgeOffset >> 2);
439 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
440 mptscsih_add_chain((char *)chainSge, nextChain, sgeOffset, ioc->ChainBufferDMA + chain_dma_off);
442 /* The original MF buffer requires a chain buffer -
444 * Last element in this MF is a chain element.
446 pReq->ChainOffset = (u8) (sgeOffset >> 2);
447 RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor) + 1) & 0x03;
448 dsgprintk((MYIOC_s_ERR_FMT "Chain Buffer Needed, RequestNB=%x sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
449 ioc->RequestNB[req_idx] = RequestNB;
452 sges_left -= sg_done;
455 /* NOTE: psge points to the beginning of the chain element
456 * in current buffer. Get a chain buffer.
458 if ((mptscsih_getFreeChainBuffer(ioc, &newIndex)) == FAILED) {
459 dfailprintk((MYIOC_s_INFO_FMT
460 "getFreeChainBuffer FAILED SCSI cmd=%02x (%p)\n",
461 ioc->name, pReq->CDB[0], SCpnt));
465 /* Update the tracking arrays.
466 * If chainSge == NULL, update ReqToChain, else ChainToChain
469 ioc->ChainToChain[chain_idx] = newIndex;
471 ioc->ReqToChain[req_idx] = newIndex;
473 chain_idx = newIndex;
474 chain_dma_off = ioc->req_sz * chain_idx;
476 /* Populate the chainSGE for the current buffer.
477 * - Set chain buffer pointer to psge and fill
478 * out the Address and Flags fields.
480 chainSge = (char *) psge;
481 dsgprintk((KERN_INFO " Current buff @ %p (index 0x%x)",
484 /* Start the SGE for the next buffer
486 psge = (char *) (ioc->ChainBuffer + chain_dma_off);
490 dsgprintk((KERN_INFO " Chain buff @ %p (index 0x%x)\n",
493 /* Start the SGE for the next buffer
500 } /* mptscsih_AddSGE() */
503 mptscsih_issue_sep_command(MPT_ADAPTER *ioc, VirtTarget *vtarget,
507 SEPRequest_t *SEPMsg;
509 if (ioc->bus_type == FC)
512 if ((mf = mpt_get_msg_frame(ioc->InternalCtx, ioc)) == NULL) {
513 dfailprintk((MYIOC_s_WARN_FMT "%s: no msg frames!!\n",
514 ioc->name,__FUNCTION__));
518 SEPMsg = (SEPRequest_t *)mf;
519 SEPMsg->Function = MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR;
520 SEPMsg->Bus = vtarget->bus_id;
521 SEPMsg->TargetID = vtarget->target_id;
522 SEPMsg->Action = MPI_SEP_REQ_ACTION_WRITE_STATUS;
523 SEPMsg->SlotStatus = SlotStatus;
524 devtverboseprintk((MYIOC_s_WARN_FMT
525 "Sending SEP cmd=%x id=%d bus=%d\n",
526 ioc->name, SlotStatus, SEPMsg->TargetID, SEPMsg->Bus));
527 mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
530 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
532 * mptscsih_io_done - Main SCSI IO callback routine registered to
533 * Fusion MPT (base) driver
534 * @ioc: Pointer to MPT_ADAPTER structure
535 * @mf: Pointer to original MPT request frame
536 * @r: Pointer to MPT reply frame (NULL if TurboReply)
538 * This routine is called from mpt.c::mpt_interrupt() at the completion
539 * of any SCSI IO request.
540 * This routine is registered with the Fusion MPT (base) driver at driver
541 * load/init time via the mpt_register() API call.
543 * Returns 1 indicating alloc'd request frame ptr should be freed.
546 mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
548 struct scsi_cmnd *sc;
550 SCSIIORequest_t *pScsiReq;
551 SCSIIOReply_t *pScsiReply;
552 u16 req_idx, req_idx_MR;
556 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
558 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
559 req_idx_MR = (mr != NULL) ?
560 le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx) : req_idx;
561 if ((req_idx != req_idx_MR) ||
562 (mf->u.frame.linkage.arg1 == 0xdeadbeaf)) {
563 printk(MYIOC_s_ERR_FMT "Received a mf that was already freed\n",
565 printk (MYIOC_s_ERR_FMT
566 "req_idx=%x req_idx_MR=%x mf=%p mr=%p sc=%p\n",
567 ioc->name, req_idx, req_idx_MR, mf, mr,
568 hd->ScsiLookup[req_idx_MR]);
572 sc = hd->ScsiLookup[req_idx];
573 hd->ScsiLookup[req_idx] = NULL;
575 MPIHeader_t *hdr = (MPIHeader_t *)mf;
577 /* Remark: writeSDP1 will use the ScsiDoneCtx
578 * If a SCSI I/O cmd, device disabled by OS and
579 * completion done. Cannot touch sc struct. Just free mem.
581 if (hdr->Function == MPI_FUNCTION_SCSI_IO_REQUEST)
582 printk(MYIOC_s_ERR_FMT "NULL ScsiCmd ptr!\n",
585 mptscsih_freeChainBuffers(ioc, req_idx);
589 if ((unsigned char *)mf != sc->host_scribble) {
590 mptscsih_freeChainBuffers(ioc, req_idx);
594 sc->host_scribble = NULL;
595 sc->result = DID_OK << 16; /* Set default reply as OK */
596 pScsiReq = (SCSIIORequest_t *) mf;
597 pScsiReply = (SCSIIOReply_t *) mr;
599 if((ioc->facts.MsgVersion >= MPI_VERSION_01_05) && pScsiReply){
600 dmfprintk((MYIOC_s_INFO_FMT
601 "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d,task-tag=%d)\n",
602 ioc->name, mf, mr, sc, req_idx, pScsiReply->TaskTag));
604 dmfprintk((MYIOC_s_INFO_FMT
605 "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n",
606 ioc->name, mf, mr, sc, req_idx));
609 if (pScsiReply == NULL) {
610 /* special context reply handling */
615 u8 scsi_state, scsi_status;
617 status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK;
618 scsi_state = pScsiReply->SCSIState;
619 scsi_status = pScsiReply->SCSIStatus;
620 xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
621 sc->resid = sc->request_bufflen - xfer_cnt;
624 * if we get a data underrun indication, yet no data was
625 * transferred and the SCSI status indicates that the
626 * command was never started, change the data underrun
629 if (status == MPI_IOCSTATUS_SCSI_DATA_UNDERRUN && xfer_cnt == 0 &&
630 (scsi_status == MPI_SCSI_STATUS_BUSY ||
631 scsi_status == MPI_SCSI_STATUS_RESERVATION_CONFLICT ||
632 scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)) {
633 status = MPI_IOCSTATUS_SUCCESS;
636 dreplyprintk((KERN_NOTICE "Reply ha=%d id=%d lun=%d:\n"
637 "IOCStatus=%04xh SCSIState=%02xh SCSIStatus=%02xh\n"
638 "resid=%d bufflen=%d xfer_cnt=%d\n",
639 ioc->id, sc->device->id, sc->device->lun,
640 status, scsi_state, scsi_status, sc->resid,
641 sc->request_bufflen, xfer_cnt));
643 if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)
644 mptscsih_copy_sense_data(sc, hd, mf, pScsiReply);
647 * Look for + dump FCP ResponseInfo[]!
649 if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID &&
650 pScsiReply->ResponseInfo) {
651 printk(KERN_NOTICE "ha=%d id=%d lun=%d: "
652 "FCP_ResponseInfo=%08xh\n",
653 ioc->id, sc->device->id, sc->device->lun,
654 le32_to_cpu(pScsiReply->ResponseInfo));
658 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
660 * Maybe: DRIVER_BUSY | SUGGEST_RETRY | DID_SOFT_ERROR (retry)
661 * But not: DID_BUS_BUSY lest one risk
662 * killing interrupt handler:-(
664 sc->result = SAM_STAT_BUSY;
667 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
668 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
669 sc->result = DID_BAD_TARGET << 16;
672 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
673 /* Spoof to SCSI Selection Timeout! */
674 if (ioc->bus_type != FC)
675 sc->result = DID_NO_CONNECT << 16;
676 /* else fibre, just stall until rescan event */
678 sc->result = DID_REQUEUE << 16;
680 if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF)
681 hd->sel_timeout[pScsiReq->TargetID]++;
683 vdev = sc->device->hostdata;
686 vtarget = vdev->vtarget;
687 if (vtarget->tflags & MPT_TARGET_FLAGS_LED_ON) {
688 mptscsih_issue_sep_command(ioc, vtarget,
689 MPI_SEP_REQ_SLOTSTATUS_UNCONFIGURED);
690 vtarget->tflags &= ~MPT_TARGET_FLAGS_LED_ON;
694 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
695 if ( ioc->bus_type == SAS ) {
696 u16 ioc_status = le16_to_cpu(pScsiReply->IOCStatus);
697 if (ioc_status & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
698 u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
699 log_info &=SAS_LOGINFO_MASK;
700 if (log_info == SAS_LOGINFO_NEXUS_LOSS) {
701 sc->result = (DID_BUS_BUSY << 16);
705 } else if (ioc->bus_type == FC) {
707 * The FC IOC may kill a request for variety of
708 * reasons, some of which may be recovered by a
709 * retry, some which are unlikely to be
710 * recovered. Return DID_ERROR instead of
711 * DID_RESET to permit retry of the command,
712 * just not an infinite number of them
714 sc->result = DID_ERROR << 16;
719 * Allow non-SAS & non-NEXUS_LOSS to drop into below code
722 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
723 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
724 /* Linux handles an unsolicited DID_RESET better
725 * than an unsolicited DID_ABORT.
727 sc->result = DID_RESET << 16;
731 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
732 sc->resid = sc->request_bufflen - xfer_cnt;
733 if((xfer_cnt==0)||(sc->underflow > xfer_cnt))
734 sc->result=DID_SOFT_ERROR << 16;
735 else /* Sufficient data transfer occurred */
736 sc->result = (DID_OK << 16) | scsi_status;
737 dreplyprintk((KERN_NOTICE
738 "RESIDUAL_MISMATCH: result=%x on id=%d\n", sc->result, sc->device->id));
741 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
743 * Do upfront check for valid SenseData and give it
746 sc->result = (DID_OK << 16) | scsi_status;
747 if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
748 /* Have already saved the status and sense data
752 if (xfer_cnt < sc->underflow) {
753 if (scsi_status == SAM_STAT_BUSY)
754 sc->result = SAM_STAT_BUSY;
756 sc->result = DID_SOFT_ERROR << 16;
758 if (scsi_state & (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)) {
761 sc->result = DID_SOFT_ERROR << 16;
763 else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
764 /* Not real sure here either... */
765 sc->result = DID_RESET << 16;
769 dreplyprintk((KERN_NOTICE " sc->underflow={report ERR if < %02xh bytes xfer'd}\n",
771 dreplyprintk((KERN_NOTICE " ActBytesXferd=%02xh\n", xfer_cnt));
774 if (scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)
775 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
779 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
781 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
782 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
783 if (scsi_status == MPI_SCSI_STATUS_BUSY)
784 sc->result = (DID_BUS_BUSY << 16) | scsi_status;
786 sc->result = (DID_OK << 16) | scsi_status;
787 if (scsi_state == 0) {
789 } else if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
791 * If running against circa 200003dd 909 MPT f/w,
792 * may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL
793 * (QUEUE_FULL) returned from device! --> get 0x0000?128
794 * and with SenseBytes set to 0.
796 if (pScsiReply->SCSIStatus == MPI_SCSI_STATUS_TASK_SET_FULL)
797 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
800 else if (scsi_state &
801 (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)
806 sc->result = DID_SOFT_ERROR << 16;
808 else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
809 /* Not real sure here either... */
810 sc->result = DID_RESET << 16;
812 else if (scsi_state & MPI_SCSI_STATE_QUEUE_TAG_REJECTED) {
813 /* Device Inq. data indicates that it supports
814 * QTags, but rejects QTag messages.
815 * This command completed OK.
817 * Not real sure here either so do nothing... */
820 if (sc->result == MPI_SCSI_STATUS_TASK_SET_FULL)
821 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
824 * Reservation Conflict, Busy,
825 * Command Terminated, CHECK
829 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
830 sc->result = DID_SOFT_ERROR << 16;
833 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
834 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
835 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
836 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
837 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
838 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
839 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
840 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
841 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
846 sc->result = DID_SOFT_ERROR << 16;
849 } /* switch(status) */
851 dreplyprintk((KERN_NOTICE " sc->result is %08xh\n", sc->result));
852 } /* end of address reply case */
854 /* Unmap the DMA buffers, if any. */
856 pci_unmap_sg(ioc->pcidev, (struct scatterlist *) sc->request_buffer,
857 sc->use_sg, sc->sc_data_direction);
858 } else if (sc->request_bufflen) {
859 pci_unmap_single(ioc->pcidev, sc->SCp.dma_handle,
860 sc->request_bufflen, sc->sc_data_direction);
863 sc->scsi_done(sc); /* Issue the command callback */
865 /* Free Chain buffers */
866 mptscsih_freeChainBuffers(ioc, req_idx);
871 * mptscsih_flush_running_cmds - For each command found, search
872 * Scsi_Host instance taskQ and reply to OS.
873 * Called only if recovering from a FW reload.
874 * @hd: Pointer to a SCSI HOST structure
878 * Must be called while new I/Os are being queued.
881 mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
883 MPT_ADAPTER *ioc = hd->ioc;
884 struct scsi_cmnd *SCpnt;
887 int max = ioc->req_depth;
889 dprintk((KERN_INFO MYNAM ": flush_ScsiLookup called\n"));
890 for (ii= 0; ii < max; ii++) {
891 if ((SCpnt = hd->ScsiLookup[ii]) != NULL) {
896 /* Null ScsiLookup index
898 hd->ScsiLookup[ii] = NULL;
900 mf = MPT_INDEX_2_MFPTR(ioc, ii);
901 dmfprintk(( "flush: ScsiDone (mf=%p,sc=%p)\n",
904 /* Free Chain buffers */
905 mptscsih_freeChainBuffers(ioc, ii);
907 /* Free Message frames */
908 mpt_free_msg_frame(ioc, mf);
910 if ((unsigned char *)mf != SCpnt->host_scribble)
913 /* Set status, free OS resources (SG DMA buffers)
917 pci_unmap_sg(ioc->pcidev,
918 (struct scatterlist *) SCpnt->request_buffer,
920 SCpnt->sc_data_direction);
921 } else if (SCpnt->request_bufflen) {
922 pci_unmap_single(ioc->pcidev,
923 SCpnt->SCp.dma_handle,
924 SCpnt->request_bufflen,
925 SCpnt->sc_data_direction);
927 SCpnt->result = DID_RESET << 16;
928 SCpnt->host_scribble = NULL;
930 SCpnt->scsi_done(SCpnt); /* Issue the command callback */
938 * mptscsih_search_running_cmds - Delete any commands associated
939 * with the specified target and lun. Function called only
940 * when a lun is disable by mid-layer.
941 * Do NOT access the referenced scsi_cmnd structure or
942 * members. Will cause either a paging or NULL ptr error.
943 * (BUT, BUT, BUT, the code does reference it! - mdr)
944 * @hd: Pointer to a SCSI HOST structure
945 * @vdevice: per device private data
949 * Called from slave_destroy.
952 mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
954 SCSIIORequest_t *mf = NULL;
956 int max = hd->ioc->req_depth;
957 struct scsi_cmnd *sc;
959 dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n",
960 vdevice->vtarget->target_id, vdevice->lun, max));
962 for (ii=0; ii < max; ii++) {
963 if ((sc = hd->ScsiLookup[ii]) != NULL) {
965 mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii);
968 dsprintk(( "search_running: found (sc=%p, mf = %p) target %d, lun %d \n",
969 hd->ScsiLookup[ii], mf, mf->TargetID, mf->LUN[1]));
970 if ((mf->TargetID != ((u8)vdevice->vtarget->target_id)) || (mf->LUN[1] != ((u8) vdevice->lun)))
975 hd->ScsiLookup[ii] = NULL;
976 mptscsih_freeChainBuffers(hd->ioc, ii);
977 mpt_free_msg_frame(hd->ioc, (MPT_FRAME_HDR *)mf);
978 if ((unsigned char *)mf != sc->host_scribble)
981 pci_unmap_sg(hd->ioc->pcidev,
982 (struct scatterlist *) sc->request_buffer,
984 sc->sc_data_direction);
985 } else if (sc->request_bufflen) {
986 pci_unmap_single(hd->ioc->pcidev,
989 sc->sc_data_direction);
991 sc->host_scribble = NULL;
992 sc->result = DID_NO_CONNECT << 16;
999 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1001 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1003 * mptscsih_report_queue_full - Report QUEUE_FULL status returned
1004 * from a SCSI target device.
1005 * @sc: Pointer to scsi_cmnd structure
1006 * @pScsiReply: Pointer to SCSIIOReply_t
1007 * @pScsiReq: Pointer to original SCSI request
1009 * This routine periodically reports QUEUE_FULL status returned from a
1010 * SCSI target device. It reports this to the console via kernel
1011 * printk() API call, not more than once every 10 seconds.
1014 mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq)
1016 long time = jiffies;
1019 if (sc->device == NULL)
1021 if (sc->device->host == NULL)
1023 if ((hd = (MPT_SCSI_HOST *)sc->device->host->hostdata) == NULL)
1026 if (time - hd->last_queue_full > 10 * HZ) {
1027 dprintk((MYIOC_s_WARN_FMT "Device (%d:%d:%d) reported QUEUE_FULL!\n",
1028 hd->ioc->name, 0, sc->device->id, sc->device->lun));
1029 hd->last_queue_full = time;
1033 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1035 * mptscsih_remove - Removed scsi devices
1036 * @pdev: Pointer to pci_dev structure
1041 mptscsih_remove(struct pci_dev *pdev)
1043 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1044 struct Scsi_Host *host = ioc->sh;
1053 scsi_remove_host(host);
1055 if((hd = (MPT_SCSI_HOST *)host->hostdata) == NULL)
1058 mptscsih_shutdown(pdev);
1062 if (hd->ScsiLookup != NULL) {
1063 sz1 = hd->ioc->req_depth * sizeof(void *);
1064 kfree(hd->ScsiLookup);
1065 hd->ScsiLookup = NULL;
1069 * Free pointer array.
1074 dprintk((MYIOC_s_INFO_FMT
1075 "Free'd ScsiLookup (%d) memory\n",
1076 hd->ioc->name, sz1));
1078 kfree(hd->info_kbuf);
1080 /* NULL the Scsi_Host pointer
1084 scsi_host_put(host);
1090 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1092 * mptscsih_shutdown - reboot notifier
1096 mptscsih_shutdown(struct pci_dev *pdev)
1098 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1099 struct Scsi_Host *host = ioc->sh;
1105 hd = (MPT_SCSI_HOST *)host->hostdata;
1110 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1112 * mptscsih_suspend - Fusion MPT scsi driver suspend routine.
1117 mptscsih_suspend(struct pci_dev *pdev, pm_message_t state)
1119 mptscsih_shutdown(pdev);
1120 return mpt_suspend(pdev,state);
1123 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1125 * mptscsih_resume - Fusion MPT scsi driver resume routine.
1130 mptscsih_resume(struct pci_dev *pdev)
1132 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1133 struct Scsi_Host *host = ioc->sh;
1141 hd = (MPT_SCSI_HOST *)host->hostdata;
1150 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1152 * mptscsih_info - Return information about MPT adapter
1153 * @SChost: Pointer to Scsi_Host structure
1155 * (linux scsi_host_template.info routine)
1157 * Returns pointer to buffer where information was written.
1160 mptscsih_info(struct Scsi_Host *SChost)
1165 h = (MPT_SCSI_HOST *)SChost->hostdata;
1168 if (h->info_kbuf == NULL)
1169 if ((h->info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)
1170 return h->info_kbuf;
1171 h->info_kbuf[0] = '\0';
1173 mpt_print_ioc_summary(h->ioc, h->info_kbuf, &size, 0, 0);
1174 h->info_kbuf[size-1] = '\0';
1177 return h->info_kbuf;
1188 mptscsih_copy_mem_info(struct info_str *info, char *data, int len)
1190 if (info->pos + len > info->length)
1191 len = info->length - info->pos;
1193 if (info->pos + len < info->offset) {
1198 if (info->pos < info->offset) {
1199 data += (info->offset - info->pos);
1200 len -= (info->offset - info->pos);
1204 memcpy(info->buffer + info->pos, data, len);
1210 mptscsih_copy_info(struct info_str *info, char *fmt, ...)
1216 va_start(args, fmt);
1217 len = vsprintf(buf, fmt, args);
1220 mptscsih_copy_mem_info(info, buf, len);
1225 mptscsih_host_info(MPT_ADAPTER *ioc, char *pbuf, off_t offset, int len)
1227 struct info_str info;
1231 info.offset = offset;
1234 mptscsih_copy_info(&info, "%s: %s, ", ioc->name, ioc->prod_name);
1235 mptscsih_copy_info(&info, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING, ioc->facts.FWVersion.Word);
1236 mptscsih_copy_info(&info, "Ports=%d, ", ioc->facts.NumberOfPorts);
1237 mptscsih_copy_info(&info, "MaxQ=%d\n", ioc->req_depth);
1239 return ((info.pos > info.offset) ? info.pos - info.offset : 0);
1242 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1244 * mptscsih_proc_info - Return information about MPT adapter
1245 * @host: scsi host struct
1246 * @buffer: if write, user data; if read, buffer for user
1247 * @start: returns the buffer address
1248 * @offset: if write, 0; if read, the current offset into the buffer from
1249 * the previous read.
1250 * @length: if write, return length;
1251 * @func: write = 1; read = 0
1253 * (linux scsi_host_template.info routine)
1256 mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
1257 int length, int func)
1259 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
1260 MPT_ADAPTER *ioc = hd->ioc;
1265 * write is not supported
1271 size = mptscsih_host_info(ioc, buffer, offset, length);
1277 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1278 #define ADD_INDEX_LOG(req_ent) do { } while(0)
1280 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1282 * mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine.
1283 * @SCpnt: Pointer to scsi_cmnd structure
1284 * @done: Pointer SCSI mid-layer IO completion function
1286 * (linux scsi_host_template.queuecommand routine)
1287 * This is the primary SCSI IO start routine. Create a MPI SCSIIORequest
1288 * from a linux scsi_cmnd request and send it to the IOC.
1290 * Returns 0. (rtn value discarded by linux scsi mid-layer)
1293 mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1297 SCSIIORequest_t *pScsiReq;
1298 VirtDevice *vdev = SCpnt->device->hostdata;
1307 hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata;
1308 lun = SCpnt->device->lun;
1309 SCpnt->scsi_done = done;
1311 dmfprintk((MYIOC_s_INFO_FMT "qcmd: SCpnt=%p, done()=%p\n",
1312 (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt, done));
1314 if (hd->resetPending) {
1315 dtmprintk((MYIOC_s_WARN_FMT "qcmd: SCpnt=%p timeout + 60HZ\n",
1316 (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt));
1317 return SCSI_MLQUEUE_HOST_BUSY;
1320 if ((hd->ioc->bus_type == SPI) &&
1321 vdev->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT &&
1322 mptscsih_raid_id_to_num(hd, SCpnt->device->id) < 0) {
1323 SCpnt->result = DID_NO_CONNECT << 16;
1329 * Put together a MPT SCSI request...
1331 if ((mf = mpt_get_msg_frame(hd->ioc->DoneCtx, hd->ioc)) == NULL) {
1332 dprintk((MYIOC_s_WARN_FMT "QueueCmd, no msg frames!!\n",
1334 return SCSI_MLQUEUE_HOST_BUSY;
1337 pScsiReq = (SCSIIORequest_t *) mf;
1339 my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
1341 ADD_INDEX_LOG(my_idx);
1343 /* TUR's being issued with scsictl=0x02000000 (DATA_IN)!
1344 * Seems we may receive a buffer (datalen>0) even when there
1345 * will be no data transfer! GRRRRR...
1347 if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
1348 datalen = SCpnt->request_bufflen;
1349 scsidir = MPI_SCSIIO_CONTROL_READ; /* DATA IN (host<--ioc<--dev) */
1350 } else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
1351 datalen = SCpnt->request_bufflen;
1352 scsidir = MPI_SCSIIO_CONTROL_WRITE; /* DATA OUT (host-->ioc-->dev) */
1355 scsidir = MPI_SCSIIO_CONTROL_NODATATRANSFER;
1358 /* Default to untagged. Once a target structure has been allocated,
1359 * use the Inquiry data to determine if device supports tagged.
1362 && (vdev->vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)
1363 && (SCpnt->device->tagged_supported)) {
1364 scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
1366 scsictl = scsidir | MPI_SCSIIO_CONTROL_UNTAGGED;
1369 /* Use the above information to set up the message frame
1371 pScsiReq->TargetID = (u8) vdev->vtarget->target_id;
1372 pScsiReq->Bus = vdev->vtarget->bus_id;
1373 pScsiReq->ChainOffset = 0;
1374 if (vdev->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
1375 pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
1377 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
1378 pScsiReq->CDBLength = SCpnt->cmd_len;
1379 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
1380 pScsiReq->Reserved = 0;
1381 pScsiReq->MsgFlags = mpt_msg_flags();
1382 pScsiReq->LUN[0] = 0;
1383 pScsiReq->LUN[1] = lun;
1384 pScsiReq->LUN[2] = 0;
1385 pScsiReq->LUN[3] = 0;
1386 pScsiReq->LUN[4] = 0;
1387 pScsiReq->LUN[5] = 0;
1388 pScsiReq->LUN[6] = 0;
1389 pScsiReq->LUN[7] = 0;
1390 pScsiReq->Control = cpu_to_le32(scsictl);
1393 * Write SCSI CDB into the message
1395 cmd_len = SCpnt->cmd_len;
1396 for (ii=0; ii < cmd_len; ii++)
1397 pScsiReq->CDB[ii] = SCpnt->cmnd[ii];
1399 for (ii=cmd_len; ii < 16; ii++)
1400 pScsiReq->CDB[ii] = 0;
1403 pScsiReq->DataLength = cpu_to_le32(datalen);
1405 /* SenseBuffer low address */
1406 pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
1407 + (my_idx * MPT_SENSE_BUFFER_ALLOC));
1409 /* Now add the SG list
1410 * Always have a SGE even if null length.
1413 /* Add a NULL SGE */
1414 mptscsih_add_sge((char *)&pScsiReq->SGL, MPT_SGE_FLAGS_SSIMPLE_READ | 0,
1417 /* Add a 32 or 64 bit SGE */
1418 if (mptscsih_AddSGE(hd->ioc, SCpnt, pScsiReq, my_idx) != SUCCESS)
1422 SCpnt->host_scribble = (unsigned char *)mf;
1423 hd->ScsiLookup[my_idx] = SCpnt;
1425 mpt_put_msg_frame(hd->ioc->DoneCtx, hd->ioc, mf);
1426 dmfprintk((MYIOC_s_INFO_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n",
1427 hd->ioc->name, SCpnt, mf, my_idx));
1428 DBG_DUMP_REQUEST_FRAME(mf)
1432 hd->ScsiLookup[my_idx] = NULL;
1433 mptscsih_freeChainBuffers(hd->ioc, my_idx);
1434 mpt_free_msg_frame(hd->ioc, mf);
1435 return SCSI_MLQUEUE_HOST_BUSY;
1438 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1440 * mptscsih_freeChainBuffers - Function to free chain buffers associated
1441 * with a SCSI IO request
1442 * @hd: Pointer to the MPT_SCSI_HOST instance
1443 * @req_idx: Index of the SCSI IO request frame.
1445 * Called if SG chain buffer allocation fails and mptscsih callbacks.
1449 mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
1451 MPT_FRAME_HDR *chain;
1452 unsigned long flags;
1456 /* Get the first chain index and reset
1459 chain_idx = ioc->ReqToChain[req_idx];
1460 ioc->ReqToChain[req_idx] = MPT_HOST_NO_CHAIN;
1462 while (chain_idx != MPT_HOST_NO_CHAIN) {
1464 /* Save the next chain buffer index */
1465 next = ioc->ChainToChain[chain_idx];
1467 /* Free this chain buffer and reset
1470 ioc->ChainToChain[chain_idx] = MPT_HOST_NO_CHAIN;
1472 chain = (MPT_FRAME_HDR *) (ioc->ChainBuffer
1473 + (chain_idx * ioc->req_sz));
1475 spin_lock_irqsave(&ioc->FreeQlock, flags);
1476 list_add_tail(&chain->u.frame.linkage.list, &ioc->FreeChainQ);
1477 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1479 dmfprintk((MYIOC_s_INFO_FMT "FreeChainBuffers (index %d)\n",
1480 ioc->name, chain_idx));
1488 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1493 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1495 * mptscsih_TMHandler - Generic handler for SCSI Task Management.
1496 * Fall through to mpt_HardResetHandler if: not operational, too many
1497 * failed TM requests or handshake failure.
1499 * @ioc: Pointer to MPT_ADAPTER structure
1500 * @type: Task Management type
1501 * @target: Logical Target ID for reset (if appropriate)
1502 * @lun: Logical Unit for reset (if appropriate)
1503 * @ctx2abort: Context for the task to be aborted (if appropriate)
1505 * Remark: Currently invoked from a non-interrupt thread (_bh).
1507 * Remark: With old EH code, at most 1 SCSI TaskMgmt function per IOC
1510 * Returns 0 for SUCCESS or -1 if FAILED.
1513 mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout)
1519 unsigned long flags;
1521 /* If FW is being reloaded currently, return success to
1522 * the calling function.
1529 printk(KERN_ERR MYNAM " TMHandler" " NULL ioc!\n");
1532 dtmprintk((MYIOC_s_INFO_FMT "TMHandler Entered!\n", ioc->name));
1534 // SJR - CHECKME - Can we avoid this here?
1535 // (mpt_HardResetHandler has this check...)
1536 spin_lock_irqsave(&ioc->diagLock, flags);
1537 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)) {
1538 spin_unlock_irqrestore(&ioc->diagLock, flags);
1541 spin_unlock_irqrestore(&ioc->diagLock, flags);
1543 /* Wait a fixed amount of time for the TM pending flag to be cleared.
1544 * If we time out and not bus reset, then we return a FAILED status to the caller.
1545 * The call to mptscsih_tm_pending_wait() will set the pending flag if we are
1546 * successful. Otherwise, reload the FW.
1548 if (mptscsih_tm_pending_wait(hd) == FAILED) {
1549 if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
1550 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler abort: "
1551 "Timed out waiting for last TM (%d) to complete! \n",
1552 hd->ioc->name, hd->tmPending));
1554 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) {
1555 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler target reset: "
1556 "Timed out waiting for last TM (%d) to complete! \n",
1557 hd->ioc->name, hd->tmPending));
1559 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
1560 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler bus reset: "
1561 "Timed out waiting for last TM (%d) to complete! \n",
1562 hd->ioc->name, hd->tmPending));
1563 if (hd->tmPending & (1 << MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS))
1569 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
1570 hd->tmPending |= (1 << type);
1571 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1576 ioc_raw_state = mpt_GetIocState(hd->ioc, 0);
1578 #ifdef MPT_DEBUG_RESET
1579 if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) {
1580 printk(MYIOC_s_WARN_FMT
1581 "TM Handler: IOC Not operational(0x%x)!\n",
1582 hd->ioc->name, ioc_raw_state);
1586 if (doTask && ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL)
1587 && !(ioc_raw_state & MPI_DOORBELL_ACTIVE)) {
1589 /* Isse the Task Mgmt request.
1591 if (hd->hard_resets < -1)
1593 rc = mptscsih_IssueTaskMgmt(hd, type, channel, target, lun, ctx2abort, timeout);
1595 printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n", hd->ioc->name);
1597 dtmprintk((MYIOC_s_INFO_FMT "Issue of TaskMgmt Successful!\n", hd->ioc->name));
1601 /* Only fall through to the HRH if this is a bus reset
1603 if ((type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) && (rc ||
1604 ioc->reload_fw || (ioc->alt_ioc && ioc->alt_ioc->reload_fw))) {
1605 dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
1607 rc = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
1611 * Check IOCStatus from TM reply message
1613 if (hd->tm_iocstatus != MPI_IOCSTATUS_SUCCESS)
1616 dtmprintk((MYIOC_s_INFO_FMT "TMHandler rc = %d!\n", hd->ioc->name, rc));
1622 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1624 * mptscsih_IssueTaskMgmt - Generic send Task Management function.
1625 * @hd: Pointer to MPT_SCSI_HOST structure
1626 * @type: Task Management type
1627 * @target: Logical Target ID for reset (if appropriate)
1628 * @lun: Logical Unit for reset (if appropriate)
1629 * @ctx2abort: Context for the task to be aborted (if appropriate)
1631 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
1632 * or a non-interrupt thread. In the former, must not call schedule().
1634 * Not all fields are meaningfull for all task types.
1636 * Returns 0 for SUCCESS, -999 for "no msg frames",
1637 * else other non-zero value returned.
1640 mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout)
1643 SCSITaskMgmt_t *pScsiTm;
1647 /* Return Fail to calling function if no message frames available.
1649 if ((mf = mpt_get_msg_frame(hd->ioc->TaskCtx, hd->ioc)) == NULL) {
1650 dfailprintk((MYIOC_s_ERR_FMT "IssueTaskMgmt, no msg frames!!\n",
1654 dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt request @ %p\n",
1655 hd->ioc->name, mf));
1657 /* Format the Request
1659 pScsiTm = (SCSITaskMgmt_t *) mf;
1660 pScsiTm->TargetID = target;
1661 pScsiTm->Bus = channel;
1662 pScsiTm->ChainOffset = 0;
1663 pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
1665 pScsiTm->Reserved = 0;
1666 pScsiTm->TaskType = type;
1667 pScsiTm->Reserved1 = 0;
1668 pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)
1669 ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0;
1671 for (ii= 0; ii < 8; ii++) {
1672 pScsiTm->LUN[ii] = 0;
1674 pScsiTm->LUN[1] = lun;
1676 for (ii=0; ii < 7; ii++)
1677 pScsiTm->Reserved2[ii] = 0;
1679 pScsiTm->TaskMsgContext = ctx2abort;
1681 dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt: ctx2abort (0x%08x) type=%d\n",
1682 hd->ioc->name, ctx2abort, type));
1684 DBG_DUMP_TM_REQUEST_FRAME((u32 *)pScsiTm);
1686 if ((retval = mpt_send_handshake_request(hd->ioc->TaskCtx, hd->ioc,
1687 sizeof(SCSITaskMgmt_t), (u32*)pScsiTm,
1689 dfailprintk((MYIOC_s_ERR_FMT "_send_handshake FAILED!"
1690 " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
1692 mpt_free_msg_frame(hd->ioc, mf);
1696 if(mptscsih_tm_wait_for_completion(hd, timeout) == FAILED) {
1697 dfailprintk((MYIOC_s_ERR_FMT "_wait_for_completion FAILED!"
1698 " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
1700 mpt_free_msg_frame(hd->ioc, mf);
1701 dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
1703 retval = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
1710 mptscsih_get_tm_timeout(MPT_ADAPTER *ioc)
1712 switch (ioc->bus_type) {
1723 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1725 * mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant
1726 * @SCpnt: Pointer to scsi_cmnd structure, IO to be aborted
1728 * (linux scsi_host_template.eh_abort_handler routine)
1730 * Returns SUCCESS or FAILED.
1733 mptscsih_abort(struct scsi_cmnd * SCpnt)
1741 ulong sn = SCpnt->serial_number;
1743 /* If we can't locate our host adapter structure, return FAILED status.
1745 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL) {
1746 SCpnt->result = DID_RESET << 16;
1747 SCpnt->scsi_done(SCpnt);
1748 dfailprintk((KERN_INFO MYNAM ": mptscsih_abort: "
1749 "Can't locate host! (sc=%p)\n",
1754 /* Find this command
1756 if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) {
1757 /* Cmd not found in ScsiLookup.
1760 SCpnt->result = DID_RESET << 16;
1761 dtmprintk((KERN_INFO MYNAM ": %s: mptscsih_abort: "
1762 "Command not in the active list! (sc=%p)\n",
1763 hd->ioc->name, SCpnt));
1767 if (hd->resetPending) {
1771 if (hd->timeouts < -1)
1774 printk(KERN_WARNING MYNAM ": %s: attempting task abort! (sc=%p)\n",
1775 hd->ioc->name, SCpnt);
1776 scsi_print_command(SCpnt);
1778 /* Most important! Set TaskMsgContext to SCpnt's MsgContext!
1779 * (the IO to be ABORT'd)
1781 * NOTE: Since we do not byteswap MsgContext, we do not
1782 * swap it here either. It is an opaque cookie to
1783 * the controller, so it does not matter. -DaveM
1785 mf = MPT_INDEX_2_MFPTR(hd->ioc, scpnt_idx);
1786 ctx2abort = mf->u.frame.hwhdr.msgctxu.MsgContext;
1788 hd->abortSCpnt = SCpnt;
1790 vdev = SCpnt->device->hostdata;
1791 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
1792 vdev->vtarget->bus_id, vdev->vtarget->target_id, vdev->lun,
1793 ctx2abort, mptscsih_get_tm_timeout(hd->ioc));
1795 if (SCPNT_TO_LOOKUP_IDX(SCpnt) == scpnt_idx &&
1796 SCpnt->serial_number == sn) {
1800 printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n",
1802 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1807 if(retval != FAILED ) {
1809 hd->tmState = TM_STATE_NONE;
1814 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1816 * mptscsih_dev_reset - Perform a SCSI TARGET_RESET! new_eh variant
1817 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1819 * (linux scsi_host_template.eh_dev_reset_handler routine)
1821 * Returns SUCCESS or FAILED.
1824 mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
1830 /* If we can't locate our host adapter structure, return FAILED status.
1832 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1833 dtmprintk((KERN_INFO MYNAM ": mptscsih_dev_reset: "
1834 "Can't locate host! (sc=%p)\n",
1839 if (hd->resetPending)
1842 printk(KERN_WARNING MYNAM ": %s: attempting target reset! (sc=%p)\n",
1843 hd->ioc->name, SCpnt);
1844 scsi_print_command(SCpnt);
1846 vdev = SCpnt->device->hostdata;
1847 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
1848 vdev->vtarget->bus_id, vdev->vtarget->target_id,
1849 0, 0, mptscsih_get_tm_timeout(hd->ioc));
1851 printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n",
1853 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1858 if(retval != FAILED ) {
1860 hd->tmState = TM_STATE_NONE;
1865 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1867 * mptscsih_bus_reset - Perform a SCSI BUS_RESET! new_eh variant
1868 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1870 * (linux scsi_host_template.eh_bus_reset_handler routine)
1872 * Returns SUCCESS or FAILED.
1875 mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
1881 /* If we can't locate our host adapter structure, return FAILED status.
1883 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1884 dtmprintk((KERN_INFO MYNAM ": mptscsih_bus_reset: "
1885 "Can't locate host! (sc=%p)\n",
1890 printk(KERN_WARNING MYNAM ": %s: attempting bus reset! (sc=%p)\n",
1891 hd->ioc->name, SCpnt);
1892 scsi_print_command(SCpnt);
1894 if (hd->timeouts < -1)
1897 vdev = SCpnt->device->hostdata;
1898 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
1899 vdev->vtarget->bus_id, 0, 0, 0, mptscsih_get_tm_timeout(hd->ioc));
1901 printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n",
1903 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1908 if(retval != FAILED ) {
1910 hd->tmState = TM_STATE_NONE;
1915 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1917 * mptscsih_host_reset - Perform a SCSI host adapter RESET (new_eh variant)
1918 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1920 * (linux scsi_host_template.eh_host_reset_handler routine)
1922 * Returns SUCCESS or FAILED.
1925 mptscsih_host_reset(struct scsi_cmnd *SCpnt)
1928 int status = SUCCESS;
1930 /* If we can't locate the host to reset, then we failed. */
1931 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1932 dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
1933 "Can't locate host! (sc=%p)\n",
1938 printk(KERN_WARNING MYNAM ": %s: Attempting host reset! (sc=%p)\n",
1939 hd->ioc->name, SCpnt);
1941 /* If our attempts to reset the host failed, then return a failed
1942 * status. The host will be taken off line by the SCSI mid-layer.
1944 if (mpt_HardResetHandler(hd->ioc, CAN_SLEEP) < 0){
1947 /* Make sure TM pending is cleared and TM state is set to
1951 hd->tmState = TM_STATE_NONE;
1954 dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
1956 (status == SUCCESS) ? "SUCCESS" : "FAILED" ) );
1961 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1963 * mptscsih_tm_pending_wait - wait for pending task management request to complete
1964 * @hd: Pointer to MPT host structure.
1966 * Returns {SUCCESS,FAILED}.
1969 mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd)
1971 unsigned long flags;
1972 int loop_count = 4 * 10; /* Wait 10 seconds */
1973 int status = FAILED;
1976 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
1977 if (hd->tmState == TM_STATE_NONE) {
1978 hd->tmState = TM_STATE_IN_PROGRESS;
1980 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1984 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1986 } while (--loop_count);
1991 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1993 * mptscsih_tm_wait_for_completion - wait for completion of TM task
1994 * @hd: Pointer to MPT host structure.
1995 * @timeout: timeout in seconds
1997 * Returns {SUCCESS,FAILED}.
2000 mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout )
2002 unsigned long flags;
2003 int loop_count = 4 * timeout;
2004 int status = FAILED;
2007 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
2008 if(hd->tmPending == 0) {
2010 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2013 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2015 } while (--loop_count);
2020 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2022 mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code)
2026 switch (response_code) {
2027 case MPI_SCSITASKMGMT_RSP_TM_COMPLETE:
2028 desc = "The task completed.";
2030 case MPI_SCSITASKMGMT_RSP_INVALID_FRAME:
2031 desc = "The IOC received an invalid frame status.";
2033 case MPI_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED:
2034 desc = "The task type is not supported.";
2036 case MPI_SCSITASKMGMT_RSP_TM_FAILED:
2037 desc = "The requested task failed.";
2039 case MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED:
2040 desc = "The task completed successfully.";
2042 case MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN:
2043 desc = "The LUN request is invalid.";
2045 case MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC:
2046 desc = "The task is in the IOC queue and has not been sent to target.";
2052 printk(MYIOC_s_INFO_FMT "Response Code(0x%08x): F/W: %s\n",
2053 ioc->name, response_code, desc);
2056 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2058 * mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
2059 * @ioc: Pointer to MPT_ADAPTER structure
2060 * @mf: Pointer to SCSI task mgmt request frame
2061 * @mr: Pointer to SCSI task mgmt reply frame
2063 * This routine is called from mptbase.c::mpt_interrupt() at the completion
2064 * of any SCSI task management request.
2065 * This routine is registered with the MPT (base) driver at driver
2066 * load/init time via the mpt_register() API call.
2068 * Returns 1 indicating alloc'd request frame ptr should be freed.
2071 mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
2073 SCSITaskMgmtReply_t *pScsiTmReply;
2074 SCSITaskMgmt_t *pScsiTmReq;
2076 unsigned long flags;
2080 dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt completed (mf=%p,mr=%p)\n",
2081 ioc->name, mf, mr));
2083 /* Depending on the thread, a timer is activated for
2084 * the TM request. Delete this timer on completion of TM.
2085 * Decrement count of outstanding TM requests.
2087 hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
2089 dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt Complete: NULL Scsi Host Ptr\n",
2095 dtmprintk((MYIOC_s_WARN_FMT "ERROR! TaskMgmt Reply: NULL Request %p\n",
2099 pScsiTmReply = (SCSITaskMgmtReply_t*)mr;
2100 pScsiTmReq = (SCSITaskMgmt_t*)mf;
2102 /* Figure out if this was ABORT_TASK, TARGET_RESET, or BUS_RESET! */
2103 tmType = pScsiTmReq->TaskType;
2105 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05 &&
2106 pScsiTmReply->ResponseCode)
2107 mptscsih_taskmgmt_response_code(ioc,
2108 pScsiTmReply->ResponseCode);
2110 dtmprintk((MYIOC_s_WARN_FMT " TaskType = %d, TerminationCount=%d\n",
2111 ioc->name, tmType, le32_to_cpu(pScsiTmReply->TerminationCount)));
2112 DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply);
2114 iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2115 hd->tm_iocstatus = iocstatus;
2116 dtmprintk((MYIOC_s_WARN_FMT " SCSI TaskMgmt (%d) IOCStatus=%04x IOCLogInfo=%08x\n",
2117 ioc->name, tmType, iocstatus, le32_to_cpu(pScsiTmReply->IOCLogInfo)));
2118 /* Error? (anything non-zero?) */
2121 /* clear flags and continue.
2123 if (tmType == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK)
2124 hd->abortSCpnt = NULL;
2126 /* If an internal command is present
2127 * or the TM failed - reload the FW.
2128 * FC FW may respond FAILED to an ABORT
2130 if (tmType == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
2132 (iocstatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED)) {
2133 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0) {
2134 printk((KERN_WARNING
2135 " Firmware Reload FAILED!!\n"));
2140 dtmprintk((MYIOC_s_WARN_FMT " TaskMgmt SUCCESS\n", ioc->name));
2142 hd->abortSCpnt = NULL;
2147 spin_lock_irqsave(&ioc->FreeQlock, flags);
2149 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2150 hd->tmState = TM_STATE_NONE;
2155 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2157 * This is anyones guess quite frankly.
2160 mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
2161 sector_t capacity, int geom[])
2171 dummy = heads * sectors;
2172 cylinders = capacity;
2173 sector_div(cylinders,dummy);
2176 * Handle extended translation size for logical drives
2179 if ((ulong)capacity >= 0x200000) {
2182 dummy = heads * sectors;
2183 cylinders = capacity;
2184 sector_div(cylinders,dummy);
2190 geom[2] = cylinders;
2192 dprintk((KERN_NOTICE
2193 ": bios_param: Id=%i Lun=%i Channel=%i CHS=%i/%i/%i\n",
2194 sdev->id, sdev->lun,sdev->channel,(int)cylinders,heads,sectors));
2199 /* Search IOC page 3 to determine if this is hidden physical disk
2203 mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id)
2207 if (!ioc->raid_data.isRaid || !ioc->raid_data.pIocPg3)
2209 for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2210 if (id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID)
2215 EXPORT_SYMBOL(mptscsih_is_phys_disk);
2218 mptscsih_raid_id_to_num(MPT_SCSI_HOST *hd, uint physdiskid)
2222 if (!hd->ioc->raid_data.isRaid || !hd->ioc->raid_data.pIocPg3)
2225 for (i = 0; i < hd->ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2227 hd->ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID)
2228 return hd->ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum;
2233 EXPORT_SYMBOL(mptscsih_raid_id_to_num);
2235 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2237 * OS entry point to allow host driver to alloc memory
2238 * for each scsi target. Called once per device the bus scan.
2239 * Return non-zero if allocation fails.
2242 mptscsih_target_alloc(struct scsi_target *starget)
2244 VirtTarget *vtarget;
2246 vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
2249 starget->hostdata = vtarget;
2250 vtarget->starget = starget;
2254 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2256 * OS entry point to allow host driver to alloc memory
2257 * for each scsi device. Called once per device the bus scan.
2258 * Return non-zero if allocation fails.
2261 mptscsih_slave_alloc(struct scsi_device *sdev)
2263 struct Scsi_Host *host = sdev->host;
2264 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
2265 VirtTarget *vtarget;
2267 struct scsi_target *starget;
2269 vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
2271 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
2272 hd->ioc->name, sizeof(VirtDevice));
2276 vdev->lun = sdev->lun;
2277 sdev->hostdata = vdev;
2279 starget = scsi_target(sdev);
2280 vtarget = starget->hostdata;
2282 vdev->vtarget = vtarget;
2284 if (vtarget->num_luns == 0) {
2285 hd->Targets[sdev->id] = vtarget;
2286 vtarget->ioc_id = hd->ioc->id;
2287 vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
2288 vtarget->target_id = sdev->id;
2289 vtarget->bus_id = sdev->channel;
2290 if (hd->ioc->bus_type == SPI && sdev->channel == 0 &&
2291 hd->ioc->raid_data.isRaid & (1 << sdev->id)) {
2292 vtarget->raidVolume = 1;
2293 ddvtprintk((KERN_INFO
2294 "RAID Volume @ id %d\n", sdev->id));
2297 vtarget->num_luns++;
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_target_destroy(struct scsi_target *starget)
2308 if (starget->hostdata)
2309 kfree(starget->hostdata);
2310 starget->hostdata = NULL;
2314 * OS entry point to allow for host driver to free allocated memory
2315 * Called if no device present or device being unloaded
2318 mptscsih_slave_destroy(struct scsi_device *sdev)
2320 struct Scsi_Host *host = sdev->host;
2321 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
2322 VirtTarget *vtarget;
2323 VirtDevice *vdevice;
2324 struct scsi_target *starget;
2326 starget = scsi_target(sdev);
2327 vtarget = starget->hostdata;
2328 vdevice = sdev->hostdata;
2330 mptscsih_search_running_cmds(hd, vdevice);
2331 vtarget->luns[0] &= ~(1 << vdevice->lun);
2332 vtarget->num_luns--;
2333 if (vtarget->num_luns == 0) {
2334 hd->Targets[sdev->id] = NULL;
2336 mptscsih_synchronize_cache(hd, vdevice);
2338 sdev->hostdata = NULL;
2341 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2343 * mptscsih_change_queue_depth - This function will set a devices queue depth
2344 * @sdev: per scsi_device pointer
2345 * @qdepth: requested queue depth
2347 * Adding support for new 'change_queue_depth' api.
2350 mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
2352 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sdev->host->hostdata;
2353 VirtTarget *vtarget;
2354 struct scsi_target *starget;
2358 starget = scsi_target(sdev);
2359 vtarget = starget->hostdata;
2361 if (hd->ioc->bus_type == SPI) {
2362 if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
2364 else if (sdev->type == TYPE_DISK &&
2365 vtarget->minSyncFactor <= MPT_ULTRA160)
2366 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2368 max_depth = MPT_SCSI_CMD_PER_DEV_LOW;
2370 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2372 if (qdepth > max_depth)
2377 tagged = MSG_SIMPLE_TAG;
2379 scsi_adjust_queue_depth(sdev, tagged, qdepth);
2380 return sdev->queue_depth;
2384 * OS entry point to adjust the queue_depths on a per-device basis.
2385 * Called once per device the bus scan. Use it to force the queue_depth
2386 * member to 1 if a device does not support Q tags.
2387 * Return non-zero if fails.
2390 mptscsih_slave_configure(struct scsi_device *sdev)
2392 struct Scsi_Host *sh = sdev->host;
2393 VirtTarget *vtarget;
2394 VirtDevice *vdevice;
2395 struct scsi_target *starget;
2396 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sh->hostdata;
2397 int indexed_lun, lun_index;
2399 starget = scsi_target(sdev);
2400 vtarget = starget->hostdata;
2401 vdevice = sdev->hostdata;
2403 dsprintk((MYIOC_s_INFO_FMT
2404 "device @ %p, id=%d, LUN=%d, channel=%d\n",
2405 hd->ioc->name, sdev, sdev->id, sdev->lun, sdev->channel));
2406 if (hd->ioc->bus_type == SPI)
2407 dsprintk((MYIOC_s_INFO_FMT
2408 "sdtr %d wdtr %d ppr %d inq length=%d\n",
2409 hd->ioc->name, sdev->sdtr, sdev->wdtr,
2410 sdev->ppr, sdev->inquiry_len));
2412 if (sdev->id > sh->max_id) {
2413 /* error case, should never happen */
2414 scsi_adjust_queue_depth(sdev, 0, 1);
2415 goto slave_configure_exit;
2418 vdevice->configured_lun=1;
2419 lun_index = (vdevice->lun >> 5); /* 32 luns per lun_index */
2420 indexed_lun = (vdevice->lun % 32);
2421 vtarget->luns[lun_index] |= (1 << indexed_lun);
2422 mptscsih_initTarget(hd, vtarget, sdev);
2423 mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH);
2425 dsprintk((MYIOC_s_INFO_FMT
2426 "Queue depth=%d, tflags=%x\n",
2427 hd->ioc->name, sdev->queue_depth, vtarget->tflags));
2429 if (hd->ioc->bus_type == SPI)
2430 dsprintk((MYIOC_s_INFO_FMT
2431 "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
2432 hd->ioc->name, vtarget->negoFlags, vtarget->maxOffset,
2433 vtarget->minSyncFactor));
2435 slave_configure_exit:
2437 dsprintk((MYIOC_s_INFO_FMT
2438 "tagged %d, simple %d, ordered %d\n",
2439 hd->ioc->name,sdev->tagged_supported, sdev->simple_tags,
2440 sdev->ordered_tags));
2445 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2447 * Private routines...
2450 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2451 /* Utility function to copy sense data from the scsi_cmnd buffer
2452 * to the FC and SCSI target structures.
2456 mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
2459 SCSIIORequest_t *pReq;
2460 u32 sense_count = le32_to_cpu(pScsiReply->SenseCount);
2462 /* Get target structure
2464 pReq = (SCSIIORequest_t *) mf;
2465 vdev = sc->device->hostdata;
2471 /* Copy the sense received into the scsi command block. */
2472 req_index = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2473 sense_data = ((u8 *)hd->ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC));
2474 memcpy(sc->sense_buffer, sense_data, SNS_LEN(sc));
2476 /* Log SMART data (asc = 0x5D, non-IM case only) if required.
2478 if ((hd->ioc->events) && (hd->ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) {
2479 if ((sense_data[12] == 0x5D) && (vdev->vtarget->raidVolume == 0)) {
2481 MPT_ADAPTER *ioc = hd->ioc;
2483 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
2484 ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
2485 ioc->events[idx].eventContext = ioc->eventContext;
2487 ioc->events[idx].data[0] = (pReq->LUN[1] << 24) ||
2488 (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) ||
2489 (sc->device->channel << 8) || sc->device->id;
2491 ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12];
2493 ioc->eventContext++;
2494 if (hd->ioc->pcidev->vendor ==
2495 PCI_VENDOR_ID_IBM) {
2496 mptscsih_issue_sep_command(hd->ioc,
2497 vdev->vtarget, MPI_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT);
2498 vdev->vtarget->tflags |=
2499 MPT_TARGET_FLAGS_LED_ON;
2504 dprintk((MYIOC_s_INFO_FMT "Hmmm... SenseData len=0! (?)\n",
2510 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc)
2515 hd = (MPT_SCSI_HOST *) sc->device->host->hostdata;
2517 for (i = 0; i < hd->ioc->req_depth; i++) {
2518 if (hd->ScsiLookup[i] == sc) {
2526 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2528 mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2531 unsigned long flags;
2534 dtmprintk((KERN_WARNING MYNAM
2535 ": IOC %s_reset routed to SCSI host driver!\n",
2536 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
2537 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
2539 /* If a FW reload request arrives after base installed but
2540 * before all scsi hosts have been attached, then an alt_ioc
2541 * may have a NULL sh pointer.
2543 if ((ioc->sh == NULL) || (ioc->sh->hostdata == NULL))
2546 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2548 if (reset_phase == MPT_IOC_SETUP_RESET) {
2549 dtmprintk((MYIOC_s_WARN_FMT "Setup-Diag Reset\n", ioc->name));
2552 * 1. Set Hard Reset Pending Flag
2553 * All new commands go to doneQ
2555 hd->resetPending = 1;
2557 } else if (reset_phase == MPT_IOC_PRE_RESET) {
2558 dtmprintk((MYIOC_s_WARN_FMT "Pre-Diag Reset\n", ioc->name));
2560 /* 2. Flush running commands
2561 * Clean ScsiLookup (and associated memory)
2565 /* 2b. Reply to OS all known outstanding I/O commands.
2567 mptscsih_flush_running_cmds(hd);
2569 /* 2c. If there was an internal command that
2570 * has not completed, configuration or io request,
2571 * free these resources.
2574 del_timer(&hd->timer);
2575 mpt_free_msg_frame(ioc, hd->cmdPtr);
2578 dtmprintk((MYIOC_s_WARN_FMT "Pre-Reset complete.\n", ioc->name));
2581 dtmprintk((MYIOC_s_WARN_FMT "Post-Diag Reset\n", ioc->name));
2583 /* Once a FW reload begins, all new OS commands are
2584 * redirected to the doneQ w/ a reset status.
2585 * Init all control structures.
2588 /* ScsiLookup initialization
2590 for (ii=0; ii < hd->ioc->req_depth; ii++)
2591 hd->ScsiLookup[ii] = NULL;
2593 /* 2. Chain Buffer initialization
2596 /* 4. Renegotiate to all devices, if SPI
2599 /* 5. Enable new commands to be posted
2601 spin_lock_irqsave(&ioc->FreeQlock, flags);
2603 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2604 hd->resetPending = 0;
2605 hd->tmState = TM_STATE_NONE;
2607 /* 6. If there was an internal command,
2608 * wake this process up.
2612 * Wake up the original calling thread
2614 hd->pLocal = &hd->localReply;
2615 hd->pLocal->completion = MPT_SCANDV_DID_RESET;
2616 hd->scandv_wait_done = 1;
2617 wake_up(&hd->scandv_waitq);
2621 dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name));
2625 return 1; /* currently means nothing really */
2628 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2630 mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2633 u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
2635 devtverboseprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
2638 if (ioc->sh == NULL ||
2639 ((hd = (MPT_SCSI_HOST *)ioc->sh->hostdata) == NULL))
2643 case MPI_EVENT_UNIT_ATTENTION: /* 03 */
2646 case MPI_EVENT_IOC_BUS_RESET: /* 04 */
2647 case MPI_EVENT_EXT_BUS_RESET: /* 05 */
2648 if (hd && (ioc->bus_type == SPI) && (hd->soft_resets < -1))
2651 case MPI_EVENT_LOGOUT: /* 09 */
2655 case MPI_EVENT_RESCAN: /* 06 */
2659 * CHECKME! Don't think we need to do
2660 * anything for these, but...
2662 case MPI_EVENT_LINK_STATUS_CHANGE: /* 07 */
2663 case MPI_EVENT_LOOP_STATE_CHANGE: /* 08 */
2665 * CHECKME! Falling thru...
2669 case MPI_EVENT_INTEGRATED_RAID: /* 0B */
2672 case MPI_EVENT_NONE: /* 00 */
2673 case MPI_EVENT_LOG_DATA: /* 01 */
2674 case MPI_EVENT_STATE_CHANGE: /* 02 */
2675 case MPI_EVENT_EVENT_CHANGE: /* 0A */
2677 dprintk((KERN_INFO " Ignoring event (=%02Xh)\n", event));
2681 return 1; /* currently means nothing really */
2684 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2686 * mptscsih_initTarget - Target, LUN alloc/free functionality.
2687 * @hd: Pointer to MPT_SCSI_HOST structure
2688 * @vtarget: per target private data
2689 * @sdev: SCSI device
2691 * NOTE: It's only SAFE to call this routine if data points to
2692 * sane & valid STANDARD INQUIRY data!
2694 * Allocate and initialize memory for this target.
2695 * Save inquiry data.
2699 mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget,
2700 struct scsi_device *sdev)
2702 dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n",
2703 hd->ioc->name, vtarget->bus_id, vtarget->target_id,
2706 /* Is LUN supported? If so, upper 2 bits will be 0
2707 * in first byte of inquiry data.
2709 if (sdev->inq_periph_qual != 0)
2712 if (vtarget == NULL)
2715 vtarget->type = sdev->type;
2717 if (hd->ioc->bus_type != SPI)
2720 if ((sdev->type == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) {
2721 /* Treat all Processors as SAF-TE if
2722 * command line option is set */
2723 vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
2724 mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id);
2725 }else if ((sdev->type == TYPE_PROCESSOR) &&
2726 !(vtarget->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) {
2727 if (sdev->inquiry_len > 49 ) {
2728 if (sdev->inquiry[44] == 'S' &&
2729 sdev->inquiry[45] == 'A' &&
2730 sdev->inquiry[46] == 'F' &&
2731 sdev->inquiry[47] == '-' &&
2732 sdev->inquiry[48] == 'T' &&
2733 sdev->inquiry[49] == 'E' ) {
2734 vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
2735 mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id);
2739 mptscsih_setTargetNegoParms(hd, vtarget, sdev);
2742 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2744 * Update the target negotiation parameters based on the
2745 * the Inquiry data, adapter capabilities, and NVRAM settings.
2749 mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target,
2750 struct scsi_device *sdev)
2752 SpiCfgData *pspi_data = &hd->ioc->spi_data;
2753 int id = (int) target->target_id;
2755 u8 width = MPT_NARROW;
2756 u8 factor = MPT_ASYNC;
2761 target->negoFlags = pspi_data->noQas;
2763 /* noQas == 0 => device supports QAS. */
2765 if (sdev->scsi_level < SCSI_2) {
2767 factor = MPT_ULTRA2;
2768 offset = pspi_data->maxSyncOffset;
2769 target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
2771 if (scsi_device_wide(sdev)) {
2775 if (scsi_device_sync(sdev)) {
2776 factor = pspi_data->minSyncFactor;
2777 if (!scsi_device_dt(sdev))
2778 factor = MPT_ULTRA2;
2780 if (!scsi_device_ius(sdev) &&
2781 !scsi_device_qas(sdev))
2782 factor = MPT_ULTRA160;
2784 factor = MPT_ULTRA320;
2785 if (scsi_device_qas(sdev)) {
2786 ddvtprintk((KERN_INFO "Enabling QAS due to byte56=%02x on id=%d!\n", scsi_device_qas(sdev), id));
2789 if (sdev->type == TYPE_TAPE &&
2790 scsi_device_ius(sdev))
2791 target->negoFlags |= MPT_TAPE_NEGO_IDP;
2794 offset = pspi_data->maxSyncOffset;
2796 /* If RAID, never disable QAS
2797 * else if non RAID, do not disable
2798 * QAS if bit 1 is set
2799 * bit 1 QAS support, non-raid only
2802 if (target->raidVolume == 1) {
2811 if (!sdev->tagged_supported) {
2812 target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
2815 /* Update tflags based on NVRAM settings. (SCSI only)
2817 if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
2818 nvram = pspi_data->nvram[id];
2819 nfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
2822 width = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
2825 /* Ensure factor is set to the
2826 * maximum of: adapter, nvram, inquiry
2829 if (nfactor < pspi_data->minSyncFactor )
2830 nfactor = pspi_data->minSyncFactor;
2832 factor = max(factor, nfactor);
2833 if (factor == MPT_ASYNC)
2844 /* Make sure data is consistent
2846 if ((!width) && (factor < MPT_ULTRA2)) {
2847 factor = MPT_ULTRA2;
2850 /* Save the data to the target structure.
2852 target->minSyncFactor = factor;
2853 target->maxOffset = offset;
2854 target->maxWidth = width;
2856 target->tflags |= MPT_TARGET_FLAGS_VALID_NEGO;
2858 /* Disable unused features.
2861 target->negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
2864 target->negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
2866 if ( factor > MPT_ULTRA320 )
2869 if (noQas && (pspi_data->noQas == 0)) {
2870 pspi_data->noQas |= MPT_TARGET_NO_NEGO_QAS;
2871 target->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
2873 /* Disable QAS in a mixed configuration case
2876 ddvtprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id));
2880 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2882 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2884 * SCSI Config Page functionality ...
2887 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2888 /* mptscsih_writeIOCPage4 - write IOC Page 4
2889 * @hd: Pointer to a SCSI Host Structure
2890 * @target_id: write IOC Page4 for this ID & Bus
2892 * Return: -EAGAIN if unable to obtain a Message Frame
2895 * Remark: We do not wait for a return, write pages sequentially.
2898 mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus)
2900 MPT_ADAPTER *ioc = hd->ioc;
2902 IOCPage4_t *IOCPage4Ptr;
2910 /* Get a MF for this command.
2912 if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
2913 dfailprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n",
2918 /* Set the request and the data pointers.
2919 * Place data at end of MF.
2921 pReq = (Config_t *)mf;
2923 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2924 frameOffset = ioc->req_sz - sizeof(IOCPage4_t);
2926 /* Complete the request frame (same for all requests).
2928 pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
2930 pReq->ChainOffset = 0;
2931 pReq->Function = MPI_FUNCTION_CONFIG;
2932 pReq->ExtPageLength = 0;
2933 pReq->ExtPageType = 0;
2935 for (ii=0; ii < 8; ii++) {
2936 pReq->Reserved2[ii] = 0;
2939 IOCPage4Ptr = ioc->spi_data.pIocPg4;
2940 dataDma = ioc->spi_data.IocPg4_dma;
2941 ii = IOCPage4Ptr->ActiveSEP++;
2942 IOCPage4Ptr->SEP[ii].SEPTargetID = target_id;
2943 IOCPage4Ptr->SEP[ii].SEPBus = bus;
2944 pReq->Header = IOCPage4Ptr->Header;
2945 pReq->PageAddress = cpu_to_le32(target_id | (bus << 8 ));
2947 /* Add a SGE to the config request.
2949 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE |
2950 (IOCPage4Ptr->Header.PageLength + ii) * 4;
2952 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma);
2954 dinitprintk((MYIOC_s_INFO_FMT
2955 "writeIOCPage4: MaxSEP=%d ActiveSEP=%d id=%d bus=%d\n",
2956 ioc->name, IOCPage4Ptr->MaxSEP, IOCPage4Ptr->ActiveSEP, target_id, bus));
2958 mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
2963 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2965 * Bus Scan and Domain Validation functionality ...
2968 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2970 * mptscsih_scandv_complete - Scan and DV callback routine registered
2971 * to Fustion MPT (base) driver.
2973 * @ioc: Pointer to MPT_ADAPTER structure
2974 * @mf: Pointer to original MPT request frame
2975 * @mr: Pointer to MPT reply frame (NULL if TurboReply)
2977 * This routine is called from mpt.c::mpt_interrupt() at the completion
2978 * of any SCSI IO request.
2979 * This routine is registered with the Fusion MPT (base) driver at driver
2980 * load/init time via the mpt_register() API call.
2982 * Returns 1 indicating alloc'd request frame ptr should be freed.
2984 * Remark: Sets a completion code and (possibly) saves sense data
2985 * in the IOC member localReply structure.
2986 * Used ONLY for DV and other internal commands.
2989 mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
2992 SCSIIORequest_t *pReq;
2996 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2999 (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) {
3000 printk(MYIOC_s_ERR_FMT
3001 "ScanDvComplete, %s req frame ptr! (=%p)\n",
3002 ioc->name, mf?"BAD":"NULL", (void *) mf);
3006 del_timer(&hd->timer);
3007 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3008 hd->ScsiLookup[req_idx] = NULL;
3009 pReq = (SCSIIORequest_t *) mf;
3011 if (mf != hd->cmdPtr) {
3012 printk(MYIOC_s_WARN_FMT "ScanDvComplete (mf=%p, cmdPtr=%p, idx=%d)\n",
3013 hd->ioc->name, (void *)mf, (void *) hd->cmdPtr, req_idx);
3017 ddvprintk((MYIOC_s_INFO_FMT "ScanDvComplete (mf=%p,mr=%p,idx=%d)\n",
3018 hd->ioc->name, mf, mr, req_idx));
3020 hd->pLocal = &hd->localReply;
3021 hd->pLocal->scsiStatus = 0;
3023 /* If target struct exists, clear sense valid flag.
3026 completionCode = MPT_SCANDV_GOOD;
3028 SCSIIOReply_t *pReply;
3032 pReply = (SCSIIOReply_t *) mr;
3034 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
3035 scsi_status = pReply->SCSIStatus;
3037 ddvtprintk((KERN_NOTICE " IOCStatus=%04xh, SCSIState=%02xh, SCSIStatus=%02xh, IOCLogInfo=%08xh\n",
3038 status, pReply->SCSIState, scsi_status,
3039 le32_to_cpu(pReply->IOCLogInfo)));
3043 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
3044 completionCode = MPT_SCANDV_SELECTION_TIMEOUT;
3047 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
3048 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
3049 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
3050 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
3051 completionCode = MPT_SCANDV_DID_RESET;
3054 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
3055 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
3056 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
3057 if (pReply->Function == MPI_FUNCTION_CONFIG) {
3058 ConfigReply_t *pr = (ConfigReply_t *)mr;
3059 completionCode = MPT_SCANDV_GOOD;
3060 hd->pLocal->header.PageVersion = pr->Header.PageVersion;
3061 hd->pLocal->header.PageLength = pr->Header.PageLength;
3062 hd->pLocal->header.PageNumber = pr->Header.PageNumber;
3063 hd->pLocal->header.PageType = pr->Header.PageType;
3065 } else if (pReply->Function == MPI_FUNCTION_RAID_ACTION) {
3066 /* If the RAID Volume request is successful,
3067 * return GOOD, else indicate that
3068 * some type of error occurred.
3070 MpiRaidActionReply_t *pr = (MpiRaidActionReply_t *)mr;
3071 if (le16_to_cpu(pr->ActionStatus) == MPI_RAID_ACTION_ASTATUS_SUCCESS)
3072 completionCode = MPT_SCANDV_GOOD;
3074 completionCode = MPT_SCANDV_SOME_ERROR;
3075 memcpy(hd->pLocal->sense, pr, sizeof(hd->pLocal->sense));
3077 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID) {
3081 /* save sense data in global structure
3083 completionCode = MPT_SCANDV_SENSE;
3084 hd->pLocal->scsiStatus = scsi_status;
3085 sense_data = ((u8 *)hd->ioc->sense_buf_pool +
3086 (req_idx * MPT_SENSE_BUFFER_ALLOC));
3088 sz = min_t(int, pReq->SenseBufferLength,
3089 SCSI_STD_SENSE_BYTES);
3090 memcpy(hd->pLocal->sense, sense_data, sz);
3092 ddvprintk((KERN_NOTICE " Check Condition, sense ptr %p\n",
3094 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_FAILED) {
3095 if (pReq->CDB[0] == INQUIRY)
3096 completionCode = MPT_SCANDV_ISSUE_SENSE;
3098 completionCode = MPT_SCANDV_DID_RESET;
3100 else if (pReply->SCSIState & MPI_SCSI_STATE_NO_SCSI_STATUS)
3101 completionCode = MPT_SCANDV_DID_RESET;
3102 else if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
3103 completionCode = MPT_SCANDV_DID_RESET;
3105 completionCode = MPT_SCANDV_GOOD;
3106 hd->pLocal->scsiStatus = scsi_status;
3110 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
3111 if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
3112 completionCode = MPT_SCANDV_DID_RESET;
3114 completionCode = MPT_SCANDV_SOME_ERROR;
3118 completionCode = MPT_SCANDV_SOME_ERROR;
3121 } /* switch(status) */
3123 ddvtprintk((KERN_NOTICE " completionCode set to %08xh\n",
3125 } /* end of address reply case */
3127 hd->pLocal->completion = completionCode;
3129 /* MF and RF are freed in mpt_interrupt
3132 /* Free Chain buffers (will never chain) in scan or dv */
3133 //mptscsih_freeChainBuffers(ioc, req_idx);
3136 * Wake up the original calling thread
3138 hd->scandv_wait_done = 1;
3139 wake_up(&hd->scandv_waitq);
3144 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3145 /* mptscsih_timer_expired - Call back for timer process.
3146 * Used only for dv functionality.
3147 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
3151 mptscsih_timer_expired(unsigned long data)
3153 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) data;
3155 ddvprintk((MYIOC_s_WARN_FMT "Timer Expired! Cmd %p\n", hd->ioc->name, hd->cmdPtr));
3158 MPIHeader_t *cmd = (MPIHeader_t *)hd->cmdPtr;
3160 if (cmd->Function == MPI_FUNCTION_SCSI_IO_REQUEST) {
3161 /* Desire to issue a task management request here.
3162 * TM requests MUST be single threaded.
3163 * If old eh code and no TM current, issue request.
3164 * If new eh code, do nothing. Wait for OS cmd timeout
3167 ddvtprintk((MYIOC_s_NOTE_FMT "DV Cmd Timeout: NoOp\n", hd->ioc->name));
3169 /* Perform a FW reload */
3170 if (mpt_HardResetHandler(hd->ioc, NO_SLEEP) < 0) {
3171 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", hd->ioc->name);
3175 /* This should NEVER happen */
3176 printk(MYIOC_s_WARN_FMT "Null cmdPtr!!!!\n", hd->ioc->name);
3179 /* No more processing.
3180 * TM call will generate an interrupt for SCSI TM Management.
3181 * The FW will reply to all outstanding commands, callback will finish cleanup.
3182 * Hard reset clean-up will free all resources.
3184 ddvprintk((MYIOC_s_WARN_FMT "Timer Expired Complete!\n", hd->ioc->name));
3190 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3192 * mptscsih_do_cmd - Do internal command.
3193 * @hd: MPT_SCSI_HOST pointer
3194 * @io: INTERNAL_CMD pointer.
3196 * Issue the specified internally generated command and do command
3197 * specific cleanup. For bus scan / DV only.
3198 * NOTES: If command is Inquiry and status is good,
3199 * initialize a target structure, save the data
3201 * Remark: Single threaded access only.
3204 * < 0 if an illegal command or no resources
3208 * > 0 if command complete but some type of completion error.
3211 mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
3214 SCSIIORequest_t *pScsiReq;
3215 SCSIIORequest_t ReqCopy;
3216 int my_idx, ii, dir;
3220 char CDB[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
3223 in_isr = in_interrupt();
3225 dprintk((MYIOC_s_WARN_FMT "Internal SCSI IO request not allowed in ISR context!\n",
3231 /* Set command specific information
3236 dir = MPI_SCSIIO_CONTROL_READ;
3242 case TEST_UNIT_READY:
3244 dir = MPI_SCSIIO_CONTROL_READ;
3250 dir = MPI_SCSIIO_CONTROL_READ;
3252 CDB[4] = 1; /*Spin up the disk */
3260 dir = MPI_SCSIIO_CONTROL_READ;
3266 dir = MPI_SCSIIO_CONTROL_READ;
3268 if (io->flags & MPT_ICFLAG_ECHO) {
3274 if (io->flags & MPT_ICFLAG_BUF_CAP) {
3277 CDB[6] = (io->size >> 16) & 0xFF;
3278 CDB[7] = (io->size >> 8) & 0xFF;
3279 CDB[8] = io->size & 0xFF;
3285 dir = MPI_SCSIIO_CONTROL_WRITE;
3287 if (io->flags & MPT_ICFLAG_ECHO) {
3292 CDB[6] = (io->size >> 16) & 0xFF;
3293 CDB[7] = (io->size >> 8) & 0xFF;
3294 CDB[8] = io->size & 0xFF;
3300 dir = MPI_SCSIIO_CONTROL_READ;
3307 dir = MPI_SCSIIO_CONTROL_READ;
3312 case SYNCHRONIZE_CACHE:
3314 dir = MPI_SCSIIO_CONTROL_READ;
3316 // CDB[1] = 0x02; /* set immediate bit */
3325 /* Get and Populate a free Frame
3327 if ((mf = mpt_get_msg_frame(hd->ioc->InternalCtx, hd->ioc)) == NULL) {
3328 ddvprintk((MYIOC_s_WARN_FMT "No msg frames!\n",
3333 pScsiReq = (SCSIIORequest_t *) mf;
3335 /* Get the request index */
3336 my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3337 ADD_INDEX_LOG(my_idx); /* for debug */
3339 if (io->flags & MPT_ICFLAG_PHYS_DISK) {
3340 pScsiReq->TargetID = io->physDiskNum;
3342 pScsiReq->ChainOffset = 0;
3343 pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
3345 pScsiReq->TargetID = io->id;
3346 pScsiReq->Bus = io->bus;
3347 pScsiReq->ChainOffset = 0;
3348 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
3351 pScsiReq->CDBLength = cmdLen;
3352 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
3354 pScsiReq->Reserved = 0;
3356 pScsiReq->MsgFlags = mpt_msg_flags();
3357 /* MsgContext set in mpt_get_msg_fram call */
3359 for (ii=0; ii < 8; ii++)
3360 pScsiReq->LUN[ii] = 0;
3361 pScsiReq->LUN[1] = io->lun;
3363 if (io->flags & MPT_ICFLAG_TAGGED_CMD)
3364 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ);
3366 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3368 if (cmd == REQUEST_SENSE) {
3369 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3370 ddvprintk((MYIOC_s_INFO_FMT "Untagged! 0x%2x\n",
3371 hd->ioc->name, cmd));
3374 for (ii=0; ii < 16; ii++)
3375 pScsiReq->CDB[ii] = CDB[ii];
3377 pScsiReq->DataLength = cpu_to_le32(io->size);
3378 pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
3379 + (my_idx * MPT_SENSE_BUFFER_ALLOC));
3381 ddvprintk((MYIOC_s_INFO_FMT "Sending Command 0x%x for (%d:%d:%d)\n",
3382 hd->ioc->name, cmd, io->bus, io->id, io->lun));
3384 if (dir == MPI_SCSIIO_CONTROL_READ) {
3385 mpt_add_sge((char *) &pScsiReq->SGL,
3386 MPT_SGE_FLAGS_SSIMPLE_READ | io->size,
3389 mpt_add_sge((char *) &pScsiReq->SGL,
3390 MPT_SGE_FLAGS_SSIMPLE_WRITE | io->size,
3394 /* The ISR will free the request frame, but we need
3395 * the information to initialize the target. Duplicate.
3397 memcpy(&ReqCopy, pScsiReq, sizeof(SCSIIORequest_t));
3399 /* Issue this command after:
3402 * Wait until the reply has been received
3403 * ScsiScanDvCtx callback function will
3405 * set scandv_wait_done and call wake_up
3408 hd->timer.expires = jiffies + HZ*cmdTimeout;
3409 hd->scandv_wait_done = 0;
3411 /* Save cmd pointer, for resource free if timeout or
3416 add_timer(&hd->timer);
3417 mpt_put_msg_frame(hd->ioc->InternalCtx, hd->ioc, mf);
3418 wait_event(hd->scandv_waitq, hd->scandv_wait_done);
3421 rc = hd->pLocal->completion;
3422 hd->pLocal->skip = 0;
3424 /* Always set fatal error codes in some cases.
3426 if (rc == MPT_SCANDV_SELECTION_TIMEOUT)
3428 else if (rc == MPT_SCANDV_SOME_ERROR)
3432 /* This should never happen. */
3433 ddvprintk((MYIOC_s_INFO_FMT "_do_cmd: Null pLocal!!!\n",
3440 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3442 * mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
3443 * @hd: Pointer to a SCSI HOST structure
3444 * @vdevice: virtual target device
3446 * Uses the ISR, but with special processing.
3447 * MUST be single-threaded.
3451 mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
3455 /* Following parameters will not change
3458 iocmd.cmd = SYNCHRONIZE_CACHE;
3460 iocmd.physDiskNum = -1;
3462 iocmd.data_dma = -1;
3464 iocmd.rsvd = iocmd.rsvd2 = 0;
3465 iocmd.bus = vdevice->vtarget->bus_id;
3466 iocmd.id = vdevice->vtarget->target_id;
3467 iocmd.lun = (u8)vdevice->lun;
3469 if ((vdevice->vtarget->type == TYPE_DISK) &&
3470 (vdevice->configured_lun))
3471 mptscsih_do_cmd(hd, &iocmd);
3474 EXPORT_SYMBOL(mptscsih_remove);
3475 EXPORT_SYMBOL(mptscsih_shutdown);
3477 EXPORT_SYMBOL(mptscsih_suspend);
3478 EXPORT_SYMBOL(mptscsih_resume);
3480 EXPORT_SYMBOL(mptscsih_proc_info);
3481 EXPORT_SYMBOL(mptscsih_info);
3482 EXPORT_SYMBOL(mptscsih_qcmd);
3483 EXPORT_SYMBOL(mptscsih_target_alloc);
3484 EXPORT_SYMBOL(mptscsih_slave_alloc);
3485 EXPORT_SYMBOL(mptscsih_target_destroy);
3486 EXPORT_SYMBOL(mptscsih_slave_destroy);
3487 EXPORT_SYMBOL(mptscsih_slave_configure);
3488 EXPORT_SYMBOL(mptscsih_abort);
3489 EXPORT_SYMBOL(mptscsih_dev_reset);
3490 EXPORT_SYMBOL(mptscsih_bus_reset);
3491 EXPORT_SYMBOL(mptscsih_host_reset);
3492 EXPORT_SYMBOL(mptscsih_bios_param);
3493 EXPORT_SYMBOL(mptscsih_io_done);
3494 EXPORT_SYMBOL(mptscsih_taskmgmt_complete);
3495 EXPORT_SYMBOL(mptscsih_scandv_complete);
3496 EXPORT_SYMBOL(mptscsih_event_process);
3497 EXPORT_SYMBOL(mptscsih_ioc_reset);
3498 EXPORT_SYMBOL(mptscsih_change_queue_depth);
3499 EXPORT_SYMBOL(mptscsih_timer_expired);
3500 EXPORT_SYMBOL(mptscsih_TMHandler);
3502 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/