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>
70 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
71 #define my_NAME "Fusion MPT SCSI Host driver"
72 #define my_VERSION MPT_LINUX_VERSION_COMMON
73 #define MYNAM "mptscsih"
75 MODULE_AUTHOR(MODULEAUTHOR);
76 MODULE_DESCRIPTION(my_NAME);
77 MODULE_LICENSE("GPL");
79 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
81 typedef struct _BIG_SENSE_BUF {
82 u8 data[MPT_SENSE_BUFFER_ALLOC];
85 #define MPT_SCANDV_GOOD (0x00000000) /* must be 0 */
86 #define MPT_SCANDV_DID_RESET (0x00000001)
87 #define MPT_SCANDV_SENSE (0x00000002)
88 #define MPT_SCANDV_SOME_ERROR (0x00000004)
89 #define MPT_SCANDV_SELECTION_TIMEOUT (0x00000008)
90 #define MPT_SCANDV_ISSUE_SENSE (0x00000010)
91 #define MPT_SCANDV_FALLBACK (0x00000020)
93 #define MPT_SCANDV_MAX_RETRIES (10)
95 #define MPT_ICFLAG_BUF_CAP 0x01 /* ReadBuffer Read Capacity format */
96 #define MPT_ICFLAG_ECHO 0x02 /* ReadBuffer Echo buffer format */
97 #define MPT_ICFLAG_EBOS 0x04 /* ReadBuffer Echo buffer has EBOS */
98 #define MPT_ICFLAG_PHYS_DISK 0x08 /* Any SCSI IO but do Phys Disk Format */
99 #define MPT_ICFLAG_TAGGED_CMD 0x10 /* Do tagged IO */
100 #define MPT_ICFLAG_DID_RESET 0x20 /* Bus Reset occurred with this command */
101 #define MPT_ICFLAG_RESERVED 0x40 /* Reserved has been issued */
103 typedef struct _internal_cmd {
104 char *data; /* data pointer */
105 dma_addr_t data_dma; /* data dma address */
106 int size; /* transfer size */
107 u8 cmd; /* SCSI Op Code */
108 u8 bus; /* bus number */
109 u8 id; /* SCSI ID (virtual) */
111 u8 flags; /* Bit Field - See above */
112 u8 physDiskNum; /* Phys disk number, -1 else */
118 * Other private/forward protos...
120 int mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
121 static void mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq);
122 int mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
124 static int mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
125 SCSIIORequest_t *pReq, int req_idx);
126 static void mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx);
127 static void mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply);
128 static int mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd);
129 static int mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout );
130 static u32 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc);
132 static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout);
134 int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
135 int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
137 static void mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, struct scsi_device *sdev);
138 static void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *vtarget, struct scsi_device *sdev);
139 static int mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus);
140 int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
141 static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
142 static void mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice);
144 void mptscsih_remove(struct pci_dev *);
145 void mptscsih_shutdown(struct pci_dev *);
147 int mptscsih_suspend(struct pci_dev *pdev, pm_message_t state);
148 int mptscsih_resume(struct pci_dev *pdev);
151 #define SNS_LEN(scp) sizeof((scp)->sense_buffer)
153 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
155 * mptscsih_add_sge - Place a simple SGE at address pAddr.
156 * @pAddr: virtual address for SGE
157 * @flagslength: SGE flags and data transfer length
158 * @dma_addr: Physical address
160 * This routine places a MPT request frame back on the MPT adapter's
164 mptscsih_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
166 if (sizeof(dma_addr_t) == sizeof(u64)) {
167 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
168 u32 tmp = dma_addr & 0xFFFFFFFF;
170 pSge->FlagsLength = cpu_to_le32(flagslength);
171 pSge->Address.Low = cpu_to_le32(tmp);
172 tmp = (u32) ((u64)dma_addr >> 32);
173 pSge->Address.High = cpu_to_le32(tmp);
176 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
177 pSge->FlagsLength = cpu_to_le32(flagslength);
178 pSge->Address = cpu_to_le32(dma_addr);
180 } /* mptscsih_add_sge() */
182 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
184 * mptscsih_add_chain - Place a chain SGE at address pAddr.
185 * @pAddr: virtual address for SGE
186 * @next: nextChainOffset value (u32's)
187 * @length: length of next SGL segment
188 * @dma_addr: Physical address
190 * This routine places a MPT request frame back on the MPT adapter's
194 mptscsih_add_chain(char *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
196 if (sizeof(dma_addr_t) == sizeof(u64)) {
197 SGEChain64_t *pChain = (SGEChain64_t *) pAddr;
198 u32 tmp = dma_addr & 0xFFFFFFFF;
200 pChain->Length = cpu_to_le16(length);
201 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size();
203 pChain->NextChainOffset = next;
205 pChain->Address.Low = cpu_to_le32(tmp);
206 tmp = (u32) ((u64)dma_addr >> 32);
207 pChain->Address.High = cpu_to_le32(tmp);
209 SGEChain32_t *pChain = (SGEChain32_t *) pAddr;
210 pChain->Length = cpu_to_le16(length);
211 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size();
212 pChain->NextChainOffset = next;
213 pChain->Address = cpu_to_le32(dma_addr);
215 } /* mptscsih_add_chain() */
217 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
219 * mptscsih_getFreeChainBuffer - Function to get a free chain
220 * from the MPT_SCSI_HOST FreeChainQ.
221 * @ioc: Pointer to MPT_ADAPTER structure
222 * @req_idx: Index of the SCSI IO request frame. (output)
224 * return SUCCESS or FAILED
227 mptscsih_getFreeChainBuffer(MPT_ADAPTER *ioc, int *retIndex)
229 MPT_FRAME_HDR *chainBuf;
234 dsgprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer called\n",
236 spin_lock_irqsave(&ioc->FreeQlock, flags);
237 if (!list_empty(&ioc->FreeChainQ)) {
240 chainBuf = list_entry(ioc->FreeChainQ.next, MPT_FRAME_HDR,
241 u.frame.linkage.list);
242 list_del(&chainBuf->u.frame.linkage.list);
243 offset = (u8 *)chainBuf - (u8 *)ioc->ChainBuffer;
244 chain_idx = offset / ioc->req_sz;
246 dsgprintk((MYIOC_s_ERR_FMT "getFreeChainBuffer chainBuf=%p ChainBuffer=%p offset=%d chain_idx=%d\n",
247 ioc->name, chainBuf, ioc->ChainBuffer, offset, chain_idx));
250 chain_idx = MPT_HOST_NO_CHAIN;
251 dfailprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer failed\n",
254 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
256 *retIndex = chain_idx;
258 } /* mptscsih_getFreeChainBuffer() */
260 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
262 * mptscsih_AddSGE - Add a SGE (plus chain buffers) to the
263 * SCSIIORequest_t Message Frame.
264 * @ioc: Pointer to MPT_ADAPTER structure
265 * @SCpnt: Pointer to scsi_cmnd structure
266 * @pReq: Pointer to SCSIIORequest_t structure
271 mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
272 SCSIIORequest_t *pReq, int req_idx)
276 struct scatterlist *sg;
278 int sges_left, sg_done;
279 int chain_idx = MPT_HOST_NO_CHAIN;
281 int numSgeSlots, numSgeThisFrame;
282 u32 sgflags, sgdir, thisxfer = 0;
283 int chain_dma_off = 0;
289 sgdir = le32_to_cpu(pReq->Control) & MPI_SCSIIO_CONTROL_DATADIRECTION_MASK;
290 if (sgdir == MPI_SCSIIO_CONTROL_WRITE) {
291 sgdir = MPT_TRANSFER_HOST_TO_IOC;
293 sgdir = MPT_TRANSFER_IOC_TO_HOST;
296 psge = (char *) &pReq->SGL;
297 frm_sz = ioc->req_sz;
299 /* Map the data portion, if any.
300 * sges_left = 0 if no data transfer.
302 if ( (sges_left = SCpnt->use_sg) ) {
303 sges_left = pci_map_sg(ioc->pcidev,
304 (struct scatterlist *) SCpnt->request_buffer,
306 SCpnt->sc_data_direction);
309 } else if (SCpnt->request_bufflen) {
310 SCpnt->SCp.dma_handle = pci_map_single(ioc->pcidev,
311 SCpnt->request_buffer,
312 SCpnt->request_bufflen,
313 SCpnt->sc_data_direction);
314 dsgprintk((MYIOC_s_INFO_FMT "SG: non-SG for %p, len=%d\n",
315 ioc->name, SCpnt, SCpnt->request_bufflen));
316 mptscsih_add_sge((char *) &pReq->SGL,
317 0xD1000000|MPT_SGE_FLAGS_ADDRESSING|sgdir|SCpnt->request_bufflen,
318 SCpnt->SCp.dma_handle);
323 /* Handle the SG case.
325 sg = (struct scatterlist *) SCpnt->request_buffer;
327 sgeOffset = sizeof(SCSIIORequest_t) - sizeof(SGE_IO_UNION);
330 /* Prior to entering this loop - the following must be set
331 * current MF: sgeOffset (bytes)
332 * chainSge (Null if original MF is not a chain buffer)
333 * sg_done (num SGE done for this MF)
337 numSgeSlots = ((frm_sz - sgeOffset) / (sizeof(u32) + sizeof(dma_addr_t)) );
338 numSgeThisFrame = (sges_left < numSgeSlots) ? sges_left : numSgeSlots;
340 sgflags = MPT_SGE_FLAGS_SIMPLE_ELEMENT | MPT_SGE_FLAGS_ADDRESSING | sgdir;
342 /* Get first (num - 1) SG elements
343 * Skip any SG entries with a length of 0
344 * NOTE: at finish, sg and psge pointed to NEXT data/location positions
346 for (ii=0; ii < (numSgeThisFrame-1); ii++) {
347 thisxfer = sg_dma_len(sg);
349 sg ++; /* Get next SG element from the OS */
354 v2 = sg_dma_address(sg);
355 mptscsih_add_sge(psge, sgflags | thisxfer, v2);
357 sg++; /* Get next SG element from the OS */
358 psge += (sizeof(u32) + sizeof(dma_addr_t));
359 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
363 if (numSgeThisFrame == sges_left) {
364 /* Add last element, end of buffer and end of list flags.
366 sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT |
367 MPT_SGE_FLAGS_END_OF_BUFFER |
368 MPT_SGE_FLAGS_END_OF_LIST;
370 /* Add last SGE and set termination flags.
371 * Note: Last SGE may have a length of 0 - which should be ok.
373 thisxfer = sg_dma_len(sg);
375 v2 = sg_dma_address(sg);
376 mptscsih_add_sge(psge, sgflags | thisxfer, v2);
379 psge += (sizeof(u32) + sizeof(dma_addr_t));
381 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
385 /* The current buffer is a chain buffer,
386 * but there is not another one.
387 * Update the chain element
388 * Offset and Length fields.
390 mptscsih_add_chain((char *)chainSge, 0, sgeOffset, ioc->ChainBufferDMA + chain_dma_off);
392 /* The current buffer is the original MF
393 * and there is no Chain buffer.
395 pReq->ChainOffset = 0;
396 RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor) + 1) & 0x03;
397 dsgprintk((MYIOC_s_INFO_FMT
398 "Single Buffer RequestNB=%x, sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
399 ioc->RequestNB[req_idx] = RequestNB;
402 /* At least one chain buffer is needed.
403 * Complete the first MF
404 * - last SGE element, set the LastElement bit
405 * - set ChainOffset (words) for orig MF
406 * (OR finish previous MF chain buffer)
407 * - update MFStructPtr ChainIndex
408 * - Populate chain element
413 dsgprintk((MYIOC_s_INFO_FMT "SG: Chain Required! sg done %d\n",
414 ioc->name, sg_done));
416 /* Set LAST_ELEMENT flag for last non-chain element
417 * in the buffer. Since psge points at the NEXT
418 * SGE element, go back one SGE element, update the flags
419 * and reset the pointer. (Note: sgflags & thisxfer are already
423 u32 *ptmp = (u32 *) (psge - (sizeof(u32) + sizeof(dma_addr_t)));
424 sgflags = le32_to_cpu(*ptmp);
425 sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT;
426 *ptmp = cpu_to_le32(sgflags);
430 /* The current buffer is a chain buffer.
431 * chainSge points to the previous Chain Element.
432 * Update its chain element Offset and Length (must
433 * include chain element size) fields.
434 * Old chain element is now complete.
436 u8 nextChain = (u8) (sgeOffset >> 2);
437 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
438 mptscsih_add_chain((char *)chainSge, nextChain, sgeOffset, ioc->ChainBufferDMA + chain_dma_off);
440 /* The original MF buffer requires a chain buffer -
442 * Last element in this MF is a chain element.
444 pReq->ChainOffset = (u8) (sgeOffset >> 2);
445 RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor) + 1) & 0x03;
446 dsgprintk((MYIOC_s_ERR_FMT "Chain Buffer Needed, RequestNB=%x sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
447 ioc->RequestNB[req_idx] = RequestNB;
450 sges_left -= sg_done;
453 /* NOTE: psge points to the beginning of the chain element
454 * in current buffer. Get a chain buffer.
456 if ((mptscsih_getFreeChainBuffer(ioc, &newIndex)) == FAILED) {
457 dfailprintk((MYIOC_s_INFO_FMT
458 "getFreeChainBuffer FAILED SCSI cmd=%02x (%p)\n",
459 ioc->name, pReq->CDB[0], SCpnt));
463 /* Update the tracking arrays.
464 * If chainSge == NULL, update ReqToChain, else ChainToChain
467 ioc->ChainToChain[chain_idx] = newIndex;
469 ioc->ReqToChain[req_idx] = newIndex;
471 chain_idx = newIndex;
472 chain_dma_off = ioc->req_sz * chain_idx;
474 /* Populate the chainSGE for the current buffer.
475 * - Set chain buffer pointer to psge and fill
476 * out the Address and Flags fields.
478 chainSge = (char *) psge;
479 dsgprintk((KERN_INFO " Current buff @ %p (index 0x%x)",
482 /* Start the SGE for the next buffer
484 psge = (char *) (ioc->ChainBuffer + chain_dma_off);
488 dsgprintk((KERN_INFO " Chain buff @ %p (index 0x%x)\n",
491 /* Start the SGE for the next buffer
498 } /* mptscsih_AddSGE() */
500 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
502 * mptscsih_io_done - Main SCSI IO callback routine registered to
503 * Fusion MPT (base) driver
504 * @ioc: Pointer to MPT_ADAPTER structure
505 * @mf: Pointer to original MPT request frame
506 * @r: Pointer to MPT reply frame (NULL if TurboReply)
508 * This routine is called from mpt.c::mpt_interrupt() at the completion
509 * of any SCSI IO request.
510 * This routine is registered with the Fusion MPT (base) driver at driver
511 * load/init time via the mpt_register() API call.
513 * Returns 1 indicating alloc'd request frame ptr should be freed.
516 mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
518 struct scsi_cmnd *sc;
520 SCSIIORequest_t *pScsiReq;
521 SCSIIOReply_t *pScsiReply;
522 u16 req_idx, req_idx_MR;
524 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
526 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
527 req_idx_MR = (mr != NULL) ?
528 le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx) : req_idx;
529 if ((req_idx != req_idx_MR) ||
530 (mf->u.frame.linkage.arg1 == 0xdeadbeaf)) {
531 printk(MYIOC_s_ERR_FMT "Received a mf that was already freed\n",
533 printk (MYIOC_s_ERR_FMT
534 "req_idx=%x req_idx_MR=%x mf=%p mr=%p sc=%p\n",
535 ioc->name, req_idx, req_idx_MR, mf, mr,
536 hd->ScsiLookup[req_idx_MR]);
540 sc = hd->ScsiLookup[req_idx];
542 MPIHeader_t *hdr = (MPIHeader_t *)mf;
544 /* Remark: writeSDP1 will use the ScsiDoneCtx
545 * If a SCSI I/O cmd, device disabled by OS and
546 * completion done. Cannot touch sc struct. Just free mem.
548 if (hdr->Function == MPI_FUNCTION_SCSI_IO_REQUEST)
549 printk(MYIOC_s_ERR_FMT "NULL ScsiCmd ptr!\n",
552 mptscsih_freeChainBuffers(ioc, req_idx);
556 sc->result = DID_OK << 16; /* Set default reply as OK */
557 pScsiReq = (SCSIIORequest_t *) mf;
558 pScsiReply = (SCSIIOReply_t *) mr;
560 if((ioc->facts.MsgVersion >= MPI_VERSION_01_05) && pScsiReply){
561 dmfprintk((MYIOC_s_INFO_FMT
562 "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d,task-tag=%d)\n",
563 ioc->name, mf, mr, sc, req_idx, pScsiReply->TaskTag));
565 dmfprintk((MYIOC_s_INFO_FMT
566 "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n",
567 ioc->name, mf, mr, sc, req_idx));
570 if (pScsiReply == NULL) {
571 /* special context reply handling */
576 u8 scsi_state, scsi_status;
578 status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK;
579 scsi_state = pScsiReply->SCSIState;
580 scsi_status = pScsiReply->SCSIStatus;
581 xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
582 sc->resid = sc->request_bufflen - xfer_cnt;
585 * if we get a data underrun indication, yet no data was
586 * transferred and the SCSI status indicates that the
587 * command was never started, change the data underrun
590 if (status == MPI_IOCSTATUS_SCSI_DATA_UNDERRUN && xfer_cnt == 0 &&
591 (scsi_status == MPI_SCSI_STATUS_BUSY ||
592 scsi_status == MPI_SCSI_STATUS_RESERVATION_CONFLICT ||
593 scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)) {
594 status = MPI_IOCSTATUS_SUCCESS;
597 dreplyprintk((KERN_NOTICE "Reply ha=%d id=%d lun=%d:\n"
598 "IOCStatus=%04xh SCSIState=%02xh SCSIStatus=%02xh\n"
599 "resid=%d bufflen=%d xfer_cnt=%d\n",
600 ioc->id, sc->device->id, sc->device->lun,
601 status, scsi_state, scsi_status, sc->resid,
602 sc->request_bufflen, xfer_cnt));
604 if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)
605 mptscsih_copy_sense_data(sc, hd, mf, pScsiReply);
608 * Look for + dump FCP ResponseInfo[]!
610 if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID &&
611 pScsiReply->ResponseInfo) {
612 printk(KERN_NOTICE "ha=%d id=%d lun=%d: "
613 "FCP_ResponseInfo=%08xh\n",
614 ioc->id, sc->device->id, sc->device->lun,
615 le32_to_cpu(pScsiReply->ResponseInfo));
619 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
621 * Maybe: DRIVER_BUSY | SUGGEST_RETRY | DID_SOFT_ERROR (retry)
622 * But not: DID_BUS_BUSY lest one risk
623 * killing interrupt handler:-(
625 sc->result = SAM_STAT_BUSY;
628 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
629 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
630 sc->result = DID_BAD_TARGET << 16;
633 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
634 /* Spoof to SCSI Selection Timeout! */
635 sc->result = DID_NO_CONNECT << 16;
637 if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF)
638 hd->sel_timeout[pScsiReq->TargetID]++;
641 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
642 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
643 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
644 /* Linux handles an unsolicited DID_RESET better
645 * than an unsolicited DID_ABORT.
647 sc->result = DID_RESET << 16;
651 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
652 sc->resid = sc->request_bufflen - xfer_cnt;
653 if((xfer_cnt==0)||(sc->underflow > xfer_cnt))
654 sc->result=DID_SOFT_ERROR << 16;
655 else /* Sufficient data transfer occurred */
656 sc->result = (DID_OK << 16) | scsi_status;
657 dreplyprintk((KERN_NOTICE
658 "RESIDUAL_MISMATCH: result=%x on id=%d\n", sc->result, sc->device->id));
661 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
663 * Do upfront check for valid SenseData and give it
666 sc->result = (DID_OK << 16) | scsi_status;
667 if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
668 /* Have already saved the status and sense data
672 if (xfer_cnt < sc->underflow) {
673 if (scsi_status == SAM_STAT_BUSY)
674 sc->result = SAM_STAT_BUSY;
676 sc->result = DID_SOFT_ERROR << 16;
678 if (scsi_state & (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)) {
681 sc->result = DID_SOFT_ERROR << 16;
683 else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
684 /* Not real sure here either... */
685 sc->result = DID_RESET << 16;
689 dreplyprintk((KERN_NOTICE " sc->underflow={report ERR if < %02xh bytes xfer'd}\n",
691 dreplyprintk((KERN_NOTICE " ActBytesXferd=%02xh\n", xfer_cnt));
694 if (scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)
695 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
699 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
701 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
702 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
703 if (scsi_status == MPI_SCSI_STATUS_BUSY)
704 sc->result = (DID_BUS_BUSY << 16) | scsi_status;
706 sc->result = (DID_OK << 16) | scsi_status;
707 if (scsi_state == 0) {
709 } else if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
711 * If running against circa 200003dd 909 MPT f/w,
712 * may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL
713 * (QUEUE_FULL) returned from device! --> get 0x0000?128
714 * and with SenseBytes set to 0.
716 if (pScsiReply->SCSIStatus == MPI_SCSI_STATUS_TASK_SET_FULL)
717 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
720 else if (scsi_state &
721 (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)
726 sc->result = DID_SOFT_ERROR << 16;
728 else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
729 /* Not real sure here either... */
730 sc->result = DID_RESET << 16;
732 else if (scsi_state & MPI_SCSI_STATE_QUEUE_TAG_REJECTED) {
733 /* Device Inq. data indicates that it supports
734 * QTags, but rejects QTag messages.
735 * This command completed OK.
737 * Not real sure here either so do nothing... */
740 if (sc->result == MPI_SCSI_STATUS_TASK_SET_FULL)
741 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
744 * Reservation Conflict, Busy,
745 * Command Terminated, CHECK
749 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
750 sc->result = DID_SOFT_ERROR << 16;
753 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
754 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
755 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
756 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
757 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
758 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
759 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
760 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
761 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
766 sc->result = DID_SOFT_ERROR << 16;
769 } /* switch(status) */
771 dreplyprintk((KERN_NOTICE " sc->result is %08xh\n", sc->result));
772 } /* end of address reply case */
774 /* Unmap the DMA buffers, if any. */
776 pci_unmap_sg(ioc->pcidev, (struct scatterlist *) sc->request_buffer,
777 sc->use_sg, sc->sc_data_direction);
778 } else if (sc->request_bufflen) {
779 pci_unmap_single(ioc->pcidev, sc->SCp.dma_handle,
780 sc->request_bufflen, sc->sc_data_direction);
783 hd->ScsiLookup[req_idx] = NULL;
785 sc->scsi_done(sc); /* Issue the command callback */
787 /* Free Chain buffers */
788 mptscsih_freeChainBuffers(ioc, req_idx);
793 * mptscsih_flush_running_cmds - For each command found, search
794 * Scsi_Host instance taskQ and reply to OS.
795 * Called only if recovering from a FW reload.
796 * @hd: Pointer to a SCSI HOST structure
800 * Must be called while new I/Os are being queued.
803 mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
805 MPT_ADAPTER *ioc = hd->ioc;
806 struct scsi_cmnd *SCpnt;
809 int max = ioc->req_depth;
811 dprintk((KERN_INFO MYNAM ": flush_ScsiLookup called\n"));
812 for (ii= 0; ii < max; ii++) {
813 if ((SCpnt = hd->ScsiLookup[ii]) != NULL) {
818 /* Null ScsiLookup index
820 hd->ScsiLookup[ii] = NULL;
822 mf = MPT_INDEX_2_MFPTR(ioc, ii);
823 dmfprintk(( "flush: ScsiDone (mf=%p,sc=%p)\n",
826 /* Set status, free OS resources (SG DMA buffers)
828 * Free driver resources (chain, msg buffers)
831 pci_unmap_sg(ioc->pcidev,
832 (struct scatterlist *) SCpnt->request_buffer,
834 SCpnt->sc_data_direction);
835 } else if (SCpnt->request_bufflen) {
836 pci_unmap_single(ioc->pcidev,
837 SCpnt->SCp.dma_handle,
838 SCpnt->request_bufflen,
839 SCpnt->sc_data_direction);
841 SCpnt->result = DID_RESET << 16;
842 SCpnt->host_scribble = NULL;
844 /* Free Chain buffers */
845 mptscsih_freeChainBuffers(ioc, ii);
847 /* Free Message frames */
848 mpt_free_msg_frame(ioc, mf);
850 SCpnt->scsi_done(SCpnt); /* Issue the command callback */
858 * mptscsih_search_running_cmds - Delete any commands associated
859 * with the specified target and lun. Function called only
860 * when a lun is disable by mid-layer.
861 * Do NOT access the referenced scsi_cmnd structure or
862 * members. Will cause either a paging or NULL ptr error.
863 * (BUT, BUT, BUT, the code does reference it! - mdr)
864 * @hd: Pointer to a SCSI HOST structure
865 * @vdevice: per device private data
869 * Called from slave_destroy.
872 mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
874 SCSIIORequest_t *mf = NULL;
876 int max = hd->ioc->req_depth;
877 struct scsi_cmnd *sc;
879 dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n",
880 vdevice->target_id, vdevice->lun, max));
882 for (ii=0; ii < max; ii++) {
883 if ((sc = hd->ScsiLookup[ii]) != NULL) {
885 mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii);
887 dsprintk(( "search_running: found (sc=%p, mf = %p) target %d, lun %d \n",
888 hd->ScsiLookup[ii], mf, mf->TargetID, mf->LUN[1]));
890 if ((mf->TargetID != ((u8)vdevice->target_id)) || (mf->LUN[1] != ((u8) vdevice->lun)))
895 hd->ScsiLookup[ii] = NULL;
896 mptscsih_freeChainBuffers(hd->ioc, ii);
897 mpt_free_msg_frame(hd->ioc, (MPT_FRAME_HDR *)mf);
899 pci_unmap_sg(hd->ioc->pcidev,
900 (struct scatterlist *) sc->request_buffer,
902 sc->sc_data_direction);
903 } else if (sc->request_bufflen) {
904 pci_unmap_single(hd->ioc->pcidev,
907 sc->sc_data_direction);
909 sc->host_scribble = NULL;
910 sc->result = DID_NO_CONNECT << 16;
917 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
919 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
921 * mptscsih_report_queue_full - Report QUEUE_FULL status returned
922 * from a SCSI target device.
923 * @sc: Pointer to scsi_cmnd structure
924 * @pScsiReply: Pointer to SCSIIOReply_t
925 * @pScsiReq: Pointer to original SCSI request
927 * This routine periodically reports QUEUE_FULL status returned from a
928 * SCSI target device. It reports this to the console via kernel
929 * printk() API call, not more than once every 10 seconds.
932 mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq)
937 if (sc->device == NULL)
939 if (sc->device->host == NULL)
941 if ((hd = (MPT_SCSI_HOST *)sc->device->host->hostdata) == NULL)
944 if (time - hd->last_queue_full > 10 * HZ) {
945 dprintk((MYIOC_s_WARN_FMT "Device (%d:%d:%d) reported QUEUE_FULL!\n",
946 hd->ioc->name, 0, sc->device->id, sc->device->lun));
947 hd->last_queue_full = time;
951 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
953 * mptscsih_remove - Removed scsi devices
954 * @pdev: Pointer to pci_dev structure
959 mptscsih_remove(struct pci_dev *pdev)
961 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
962 struct Scsi_Host *host = ioc->sh;
971 scsi_remove_host(host);
973 if((hd = (MPT_SCSI_HOST *)host->hostdata) == NULL)
976 mptscsih_shutdown(pdev);
980 if (hd->ScsiLookup != NULL) {
981 sz1 = hd->ioc->req_depth * sizeof(void *);
982 kfree(hd->ScsiLookup);
983 hd->ScsiLookup = NULL;
987 * Free pointer array.
992 dprintk((MYIOC_s_INFO_FMT
993 "Free'd ScsiLookup (%d) memory\n",
994 hd->ioc->name, sz1));
996 kfree(hd->info_kbuf);
998 /* NULL the Scsi_Host pointer
1002 scsi_host_put(host);
1008 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1010 * mptscsih_shutdown - reboot notifier
1014 mptscsih_shutdown(struct pci_dev *pdev)
1016 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1017 struct Scsi_Host *host = ioc->sh;
1023 hd = (MPT_SCSI_HOST *)host->hostdata;
1028 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1030 * mptscsih_suspend - Fusion MPT scsi driver suspend routine.
1035 mptscsih_suspend(struct pci_dev *pdev, pm_message_t state)
1037 mptscsih_shutdown(pdev);
1038 return mpt_suspend(pdev,state);
1041 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1043 * mptscsih_resume - Fusion MPT scsi driver resume routine.
1048 mptscsih_resume(struct pci_dev *pdev)
1050 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1051 struct Scsi_Host *host = ioc->sh;
1059 hd = (MPT_SCSI_HOST *)host->hostdata;
1068 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1070 * mptscsih_info - Return information about MPT adapter
1071 * @SChost: Pointer to Scsi_Host structure
1073 * (linux scsi_host_template.info routine)
1075 * Returns pointer to buffer where information was written.
1078 mptscsih_info(struct Scsi_Host *SChost)
1083 h = (MPT_SCSI_HOST *)SChost->hostdata;
1086 if (h->info_kbuf == NULL)
1087 if ((h->info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)
1088 return h->info_kbuf;
1089 h->info_kbuf[0] = '\0';
1091 mpt_print_ioc_summary(h->ioc, h->info_kbuf, &size, 0, 0);
1092 h->info_kbuf[size-1] = '\0';
1095 return h->info_kbuf;
1106 mptscsih_copy_mem_info(struct info_str *info, char *data, int len)
1108 if (info->pos + len > info->length)
1109 len = info->length - info->pos;
1111 if (info->pos + len < info->offset) {
1116 if (info->pos < info->offset) {
1117 data += (info->offset - info->pos);
1118 len -= (info->offset - info->pos);
1122 memcpy(info->buffer + info->pos, data, len);
1128 mptscsih_copy_info(struct info_str *info, char *fmt, ...)
1134 va_start(args, fmt);
1135 len = vsprintf(buf, fmt, args);
1138 mptscsih_copy_mem_info(info, buf, len);
1143 mptscsih_host_info(MPT_ADAPTER *ioc, char *pbuf, off_t offset, int len)
1145 struct info_str info;
1149 info.offset = offset;
1152 mptscsih_copy_info(&info, "%s: %s, ", ioc->name, ioc->prod_name);
1153 mptscsih_copy_info(&info, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING, ioc->facts.FWVersion.Word);
1154 mptscsih_copy_info(&info, "Ports=%d, ", ioc->facts.NumberOfPorts);
1155 mptscsih_copy_info(&info, "MaxQ=%d\n", ioc->req_depth);
1157 return ((info.pos > info.offset) ? info.pos - info.offset : 0);
1160 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1162 * mptscsih_proc_info - Return information about MPT adapter
1164 * (linux scsi_host_template.info routine)
1166 * buffer: if write, user data; if read, buffer for user
1167 * length: if write, return length;
1168 * offset: if write, 0; if read, the current offset into the buffer from
1169 * the previous read.
1170 * hostno: scsi host number
1171 * func: if write = 1; if read = 0
1174 mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
1175 int length, int func)
1177 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
1178 MPT_ADAPTER *ioc = hd->ioc;
1183 * write is not supported
1189 size = mptscsih_host_info(ioc, buffer, offset, length);
1195 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1196 #define ADD_INDEX_LOG(req_ent) do { } while(0)
1198 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1200 * mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine.
1201 * @SCpnt: Pointer to scsi_cmnd structure
1202 * @done: Pointer SCSI mid-layer IO completion function
1204 * (linux scsi_host_template.queuecommand routine)
1205 * This is the primary SCSI IO start routine. Create a MPI SCSIIORequest
1206 * from a linux scsi_cmnd request and send it to the IOC.
1208 * Returns 0. (rtn value discarded by linux scsi mid-layer)
1211 mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1215 SCSIIORequest_t *pScsiReq;
1216 VirtDevice *vdev = SCpnt->device->hostdata;
1225 hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata;
1226 lun = SCpnt->device->lun;
1227 SCpnt->scsi_done = done;
1229 dmfprintk((MYIOC_s_INFO_FMT "qcmd: SCpnt=%p, done()=%p\n",
1230 (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt, done));
1232 if (hd->resetPending) {
1233 dtmprintk((MYIOC_s_WARN_FMT "qcmd: SCpnt=%p timeout + 60HZ\n",
1234 (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt));
1235 return SCSI_MLQUEUE_HOST_BUSY;
1238 if (vdev->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT &&
1239 mptscsih_raid_id_to_num(hd, SCpnt->device->id) < 0) {
1240 SCpnt->result = DID_NO_CONNECT << 16;
1246 * Put together a MPT SCSI request...
1248 if ((mf = mpt_get_msg_frame(hd->ioc->DoneCtx, hd->ioc)) == NULL) {
1249 dprintk((MYIOC_s_WARN_FMT "QueueCmd, no msg frames!!\n",
1251 return SCSI_MLQUEUE_HOST_BUSY;
1254 pScsiReq = (SCSIIORequest_t *) mf;
1256 my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
1258 ADD_INDEX_LOG(my_idx);
1260 /* TUR's being issued with scsictl=0x02000000 (DATA_IN)!
1261 * Seems we may receive a buffer (datalen>0) even when there
1262 * will be no data transfer! GRRRRR...
1264 if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
1265 datalen = SCpnt->request_bufflen;
1266 scsidir = MPI_SCSIIO_CONTROL_READ; /* DATA IN (host<--ioc<--dev) */
1267 } else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
1268 datalen = SCpnt->request_bufflen;
1269 scsidir = MPI_SCSIIO_CONTROL_WRITE; /* DATA OUT (host-->ioc-->dev) */
1272 scsidir = MPI_SCSIIO_CONTROL_NODATATRANSFER;
1275 /* Default to untagged. Once a target structure has been allocated,
1276 * use the Inquiry data to determine if device supports tagged.
1279 && (vdev->vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)
1280 && (SCpnt->device->tagged_supported)) {
1281 scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
1283 scsictl = scsidir | MPI_SCSIIO_CONTROL_UNTAGGED;
1286 /* Use the above information to set up the message frame
1288 pScsiReq->TargetID = (u8) vdev->target_id;
1289 pScsiReq->Bus = vdev->bus_id;
1290 pScsiReq->ChainOffset = 0;
1291 if (vdev->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
1292 pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
1294 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
1295 pScsiReq->CDBLength = SCpnt->cmd_len;
1296 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
1297 pScsiReq->Reserved = 0;
1298 pScsiReq->MsgFlags = mpt_msg_flags();
1299 pScsiReq->LUN[0] = 0;
1300 pScsiReq->LUN[1] = lun;
1301 pScsiReq->LUN[2] = 0;
1302 pScsiReq->LUN[3] = 0;
1303 pScsiReq->LUN[4] = 0;
1304 pScsiReq->LUN[5] = 0;
1305 pScsiReq->LUN[6] = 0;
1306 pScsiReq->LUN[7] = 0;
1307 pScsiReq->Control = cpu_to_le32(scsictl);
1310 * Write SCSI CDB into the message
1312 cmd_len = SCpnt->cmd_len;
1313 for (ii=0; ii < cmd_len; ii++)
1314 pScsiReq->CDB[ii] = SCpnt->cmnd[ii];
1316 for (ii=cmd_len; ii < 16; ii++)
1317 pScsiReq->CDB[ii] = 0;
1320 pScsiReq->DataLength = cpu_to_le32(datalen);
1322 /* SenseBuffer low address */
1323 pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
1324 + (my_idx * MPT_SENSE_BUFFER_ALLOC));
1326 /* Now add the SG list
1327 * Always have a SGE even if null length.
1330 /* Add a NULL SGE */
1331 mptscsih_add_sge((char *)&pScsiReq->SGL, MPT_SGE_FLAGS_SSIMPLE_READ | 0,
1334 /* Add a 32 or 64 bit SGE */
1335 if (mptscsih_AddSGE(hd->ioc, SCpnt, pScsiReq, my_idx) != SUCCESS)
1339 hd->ScsiLookup[my_idx] = SCpnt;
1340 SCpnt->host_scribble = NULL;
1342 mpt_put_msg_frame(hd->ioc->DoneCtx, hd->ioc, mf);
1343 dmfprintk((MYIOC_s_INFO_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n",
1344 hd->ioc->name, SCpnt, mf, my_idx));
1345 DBG_DUMP_REQUEST_FRAME(mf)
1349 hd->ScsiLookup[my_idx] = NULL;
1350 mptscsih_freeChainBuffers(hd->ioc, my_idx);
1351 mpt_free_msg_frame(hd->ioc, mf);
1352 return SCSI_MLQUEUE_HOST_BUSY;
1355 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1357 * mptscsih_freeChainBuffers - Function to free chain buffers associated
1358 * with a SCSI IO request
1359 * @hd: Pointer to the MPT_SCSI_HOST instance
1360 * @req_idx: Index of the SCSI IO request frame.
1362 * Called if SG chain buffer allocation fails and mptscsih callbacks.
1366 mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
1368 MPT_FRAME_HDR *chain;
1369 unsigned long flags;
1373 /* Get the first chain index and reset
1376 chain_idx = ioc->ReqToChain[req_idx];
1377 ioc->ReqToChain[req_idx] = MPT_HOST_NO_CHAIN;
1379 while (chain_idx != MPT_HOST_NO_CHAIN) {
1381 /* Save the next chain buffer index */
1382 next = ioc->ChainToChain[chain_idx];
1384 /* Free this chain buffer and reset
1387 ioc->ChainToChain[chain_idx] = MPT_HOST_NO_CHAIN;
1389 chain = (MPT_FRAME_HDR *) (ioc->ChainBuffer
1390 + (chain_idx * ioc->req_sz));
1392 spin_lock_irqsave(&ioc->FreeQlock, flags);
1393 list_add_tail(&chain->u.frame.linkage.list, &ioc->FreeChainQ);
1394 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1396 dmfprintk((MYIOC_s_INFO_FMT "FreeChainBuffers (index %d)\n",
1397 ioc->name, chain_idx));
1405 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1410 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1412 * mptscsih_TMHandler - Generic handler for SCSI Task Management.
1413 * Fall through to mpt_HardResetHandler if: not operational, too many
1414 * failed TM requests or handshake failure.
1416 * @ioc: Pointer to MPT_ADAPTER structure
1417 * @type: Task Management type
1418 * @target: Logical Target ID for reset (if appropriate)
1419 * @lun: Logical Unit for reset (if appropriate)
1420 * @ctx2abort: Context for the task to be aborted (if appropriate)
1422 * Remark: Currently invoked from a non-interrupt thread (_bh).
1424 * Remark: With old EH code, at most 1 SCSI TaskMgmt function per IOC
1427 * Returns 0 for SUCCESS or -1 if FAILED.
1430 mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout)
1436 unsigned long flags;
1438 /* If FW is being reloaded currently, return success to
1439 * the calling function.
1446 printk(KERN_ERR MYNAM " TMHandler" " NULL ioc!\n");
1449 dtmprintk((MYIOC_s_INFO_FMT "TMHandler Entered!\n", ioc->name));
1451 // SJR - CHECKME - Can we avoid this here?
1452 // (mpt_HardResetHandler has this check...)
1453 spin_lock_irqsave(&ioc->diagLock, flags);
1454 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)) {
1455 spin_unlock_irqrestore(&ioc->diagLock, flags);
1458 spin_unlock_irqrestore(&ioc->diagLock, flags);
1460 /* Wait a fixed amount of time for the TM pending flag to be cleared.
1461 * If we time out and not bus reset, then we return a FAILED status to the caller.
1462 * The call to mptscsih_tm_pending_wait() will set the pending flag if we are
1463 * successful. Otherwise, reload the FW.
1465 if (mptscsih_tm_pending_wait(hd) == FAILED) {
1466 if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
1467 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler abort: "
1468 "Timed out waiting for last TM (%d) to complete! \n",
1469 hd->ioc->name, hd->tmPending));
1471 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) {
1472 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler target reset: "
1473 "Timed out waiting for last TM (%d) to complete! \n",
1474 hd->ioc->name, hd->tmPending));
1476 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
1477 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler bus reset: "
1478 "Timed out waiting for last TM (%d) to complete! \n",
1479 hd->ioc->name, hd->tmPending));
1480 if (hd->tmPending & (1 << MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS))
1486 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
1487 hd->tmPending |= (1 << type);
1488 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1493 ioc_raw_state = mpt_GetIocState(hd->ioc, 0);
1495 #ifdef MPT_DEBUG_RESET
1496 if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) {
1497 printk(MYIOC_s_WARN_FMT
1498 "TM Handler: IOC Not operational(0x%x)!\n",
1499 hd->ioc->name, ioc_raw_state);
1503 if (doTask && ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL)
1504 && !(ioc_raw_state & MPI_DOORBELL_ACTIVE)) {
1506 /* Isse the Task Mgmt request.
1508 if (hd->hard_resets < -1)
1510 rc = mptscsih_IssueTaskMgmt(hd, type, channel, target, lun, ctx2abort, timeout);
1512 printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n", hd->ioc->name);
1514 dtmprintk((MYIOC_s_INFO_FMT "Issue of TaskMgmt Successful!\n", hd->ioc->name));
1518 /* Only fall through to the HRH if this is a bus reset
1520 if ((type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) && (rc ||
1521 ioc->reload_fw || (ioc->alt_ioc && ioc->alt_ioc->reload_fw))) {
1522 dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
1524 rc = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
1527 dtmprintk((MYIOC_s_INFO_FMT "TMHandler rc = %d!\n", hd->ioc->name, rc));
1533 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1535 * mptscsih_IssueTaskMgmt - Generic send Task Management function.
1536 * @hd: Pointer to MPT_SCSI_HOST structure
1537 * @type: Task Management type
1538 * @target: Logical Target ID for reset (if appropriate)
1539 * @lun: Logical Unit for reset (if appropriate)
1540 * @ctx2abort: Context for the task to be aborted (if appropriate)
1542 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
1543 * or a non-interrupt thread. In the former, must not call schedule().
1545 * Not all fields are meaningfull for all task types.
1547 * Returns 0 for SUCCESS, -999 for "no msg frames",
1548 * else other non-zero value returned.
1551 mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout)
1554 SCSITaskMgmt_t *pScsiTm;
1558 /* Return Fail to calling function if no message frames available.
1560 if ((mf = mpt_get_msg_frame(hd->ioc->TaskCtx, hd->ioc)) == NULL) {
1561 dfailprintk((MYIOC_s_ERR_FMT "IssueTaskMgmt, no msg frames!!\n",
1565 dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt request @ %p\n",
1566 hd->ioc->name, mf));
1568 /* Format the Request
1570 pScsiTm = (SCSITaskMgmt_t *) mf;
1571 pScsiTm->TargetID = target;
1572 pScsiTm->Bus = channel;
1573 pScsiTm->ChainOffset = 0;
1574 pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
1576 pScsiTm->Reserved = 0;
1577 pScsiTm->TaskType = type;
1578 pScsiTm->Reserved1 = 0;
1579 pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)
1580 ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0;
1582 for (ii= 0; ii < 8; ii++) {
1583 pScsiTm->LUN[ii] = 0;
1585 pScsiTm->LUN[1] = lun;
1587 for (ii=0; ii < 7; ii++)
1588 pScsiTm->Reserved2[ii] = 0;
1590 pScsiTm->TaskMsgContext = ctx2abort;
1592 dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt: ctx2abort (0x%08x) type=%d\n",
1593 hd->ioc->name, ctx2abort, type));
1595 DBG_DUMP_TM_REQUEST_FRAME((u32 *)pScsiTm);
1597 if ((retval = mpt_send_handshake_request(hd->ioc->TaskCtx, hd->ioc,
1598 sizeof(SCSITaskMgmt_t), (u32*)pScsiTm,
1600 dfailprintk((MYIOC_s_ERR_FMT "_send_handshake FAILED!"
1601 " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
1603 mpt_free_msg_frame(hd->ioc, mf);
1607 if(mptscsih_tm_wait_for_completion(hd, timeout) == FAILED) {
1608 dfailprintk((MYIOC_s_ERR_FMT "_wait_for_completion FAILED!"
1609 " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
1611 mpt_free_msg_frame(hd->ioc, mf);
1612 dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
1614 retval = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
1621 mptscsih_get_tm_timeout(MPT_ADAPTER *ioc)
1623 switch (ioc->bus_type) {
1634 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1636 * mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant
1637 * @SCpnt: Pointer to scsi_cmnd structure, IO to be aborted
1639 * (linux scsi_host_template.eh_abort_handler routine)
1641 * Returns SUCCESS or FAILED.
1644 mptscsih_abort(struct scsi_cmnd * SCpnt)
1654 /* If we can't locate our host adapter structure, return FAILED status.
1656 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL) {
1657 SCpnt->result = DID_RESET << 16;
1658 SCpnt->scsi_done(SCpnt);
1659 dfailprintk((KERN_INFO MYNAM ": mptscsih_abort: "
1660 "Can't locate host! (sc=%p)\n",
1666 if (hd->resetPending) {
1670 if (hd->timeouts < -1)
1673 /* Find this command
1675 if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) {
1676 /* Cmd not found in ScsiLookup.
1679 SCpnt->result = DID_RESET << 16;
1680 dtmprintk((KERN_INFO MYNAM ": %s: mptscsih_abort: "
1681 "Command not in the active list! (sc=%p)\n",
1682 hd->ioc->name, SCpnt));
1686 printk(KERN_WARNING MYNAM ": %s: attempting task abort! (sc=%p)\n",
1687 hd->ioc->name, SCpnt);
1688 scsi_print_command(SCpnt);
1690 /* Most important! Set TaskMsgContext to SCpnt's MsgContext!
1691 * (the IO to be ABORT'd)
1693 * NOTE: Since we do not byteswap MsgContext, we do not
1694 * swap it here either. It is an opaque cookie to
1695 * the controller, so it does not matter. -DaveM
1697 mf = MPT_INDEX_2_MFPTR(hd->ioc, scpnt_idx);
1698 ctx2abort = mf->u.frame.hwhdr.msgctxu.MsgContext;
1700 hd->abortSCpnt = SCpnt;
1702 vdev = SCpnt->device->hostdata;
1703 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
1704 vdev->bus_id, vdev->target_id, vdev->lun,
1705 ctx2abort, mptscsih_get_tm_timeout(ioc));
1707 printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n",
1709 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1714 if(retval != FAILED ) {
1716 hd->tmState = TM_STATE_NONE;
1721 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1723 * mptscsih_dev_reset - Perform a SCSI TARGET_RESET! new_eh variant
1724 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1726 * (linux scsi_host_template.eh_dev_reset_handler routine)
1728 * Returns SUCCESS or FAILED.
1731 mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
1737 /* If we can't locate our host adapter structure, return FAILED status.
1739 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1740 dtmprintk((KERN_INFO MYNAM ": mptscsih_dev_reset: "
1741 "Can't locate host! (sc=%p)\n",
1746 if (hd->resetPending)
1749 printk(KERN_WARNING MYNAM ": %s: attempting target reset! (sc=%p)\n",
1750 hd->ioc->name, SCpnt);
1751 scsi_print_command(SCpnt);
1753 vdev = SCpnt->device->hostdata;
1754 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
1755 vdev->bus_id, vdev->target_id,
1756 0, 0, mptscsih_get_tm_timeout(hd->ioc));
1758 printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n",
1760 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1765 if(retval != FAILED ) {
1767 hd->tmState = TM_STATE_NONE;
1772 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1774 * mptscsih_bus_reset - Perform a SCSI BUS_RESET! new_eh variant
1775 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1777 * (linux scsi_host_template.eh_bus_reset_handler routine)
1779 * Returns SUCCESS or FAILED.
1782 mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
1788 /* If we can't locate our host adapter structure, return FAILED status.
1790 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1791 dtmprintk((KERN_INFO MYNAM ": mptscsih_bus_reset: "
1792 "Can't locate host! (sc=%p)\n",
1797 printk(KERN_WARNING MYNAM ": %s: attempting bus reset! (sc=%p)\n",
1798 hd->ioc->name, SCpnt);
1799 scsi_print_command(SCpnt);
1801 if (hd->timeouts < -1)
1804 vdev = SCpnt->device->hostdata;
1805 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
1806 vdev->bus_id, 0, 0, 0, mptscsih_get_tm_timeout(hd->ioc));
1808 printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n",
1810 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1815 if(retval != FAILED ) {
1817 hd->tmState = TM_STATE_NONE;
1822 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1824 * mptscsih_host_reset - Perform a SCSI host adapter RESET!
1826 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1828 * (linux scsi_host_template.eh_host_reset_handler routine)
1830 * Returns SUCCESS or FAILED.
1833 mptscsih_host_reset(struct scsi_cmnd *SCpnt)
1836 int status = SUCCESS;
1838 /* If we can't locate the host to reset, then we failed. */
1839 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1840 dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
1841 "Can't locate host! (sc=%p)\n",
1846 printk(KERN_WARNING MYNAM ": %s: Attempting host reset! (sc=%p)\n",
1847 hd->ioc->name, SCpnt);
1849 /* If our attempts to reset the host failed, then return a failed
1850 * status. The host will be taken off line by the SCSI mid-layer.
1852 if (mpt_HardResetHandler(hd->ioc, CAN_SLEEP) < 0){
1855 /* Make sure TM pending is cleared and TM state is set to
1859 hd->tmState = TM_STATE_NONE;
1862 dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
1864 (status == SUCCESS) ? "SUCCESS" : "FAILED" ) );
1869 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1871 * mptscsih_tm_pending_wait - wait for pending task management request to
1873 * @hd: Pointer to MPT host structure.
1875 * Returns {SUCCESS,FAILED}.
1878 mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd)
1880 unsigned long flags;
1881 int loop_count = 4 * 10; /* Wait 10 seconds */
1882 int status = FAILED;
1885 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
1886 if (hd->tmState == TM_STATE_NONE) {
1887 hd->tmState = TM_STATE_IN_PROGRESS;
1889 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1893 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1895 } while (--loop_count);
1900 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1902 * mptscsih_tm_wait_for_completion - wait for completion of TM task
1903 * @hd: Pointer to MPT host structure.
1905 * Returns {SUCCESS,FAILED}.
1908 mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout )
1910 unsigned long flags;
1911 int loop_count = 4 * timeout;
1912 int status = FAILED;
1915 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
1916 if(hd->tmPending == 0) {
1918 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1921 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1922 msleep_interruptible(250);
1923 } while (--loop_count);
1928 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1930 mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code)
1934 switch (response_code) {
1935 case MPI_SCSITASKMGMT_RSP_TM_COMPLETE:
1936 desc = "The task completed.";
1938 case MPI_SCSITASKMGMT_RSP_INVALID_FRAME:
1939 desc = "The IOC received an invalid frame status.";
1941 case MPI_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED:
1942 desc = "The task type is not supported.";
1944 case MPI_SCSITASKMGMT_RSP_TM_FAILED:
1945 desc = "The requested task failed.";
1947 case MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED:
1948 desc = "The task completed successfully.";
1950 case MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN:
1951 desc = "The LUN request is invalid.";
1953 case MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC:
1954 desc = "The task is in the IOC queue and has not been sent to target.";
1960 printk(MYIOC_s_INFO_FMT "Response Code(0x%08x): F/W: %s\n",
1961 ioc->name, response_code, desc);
1964 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1966 * mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
1967 * @ioc: Pointer to MPT_ADAPTER structure
1968 * @mf: Pointer to SCSI task mgmt request frame
1969 * @mr: Pointer to SCSI task mgmt reply frame
1971 * This routine is called from mptbase.c::mpt_interrupt() at the completion
1972 * of any SCSI task management request.
1973 * This routine is registered with the MPT (base) driver at driver
1974 * load/init time via the mpt_register() API call.
1976 * Returns 1 indicating alloc'd request frame ptr should be freed.
1979 mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
1981 SCSITaskMgmtReply_t *pScsiTmReply;
1982 SCSITaskMgmt_t *pScsiTmReq;
1984 unsigned long flags;
1988 dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt completed (mf=%p,mr=%p)\n",
1989 ioc->name, mf, mr));
1991 /* Depending on the thread, a timer is activated for
1992 * the TM request. Delete this timer on completion of TM.
1993 * Decrement count of outstanding TM requests.
1995 hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
1997 dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt Complete: NULL Scsi Host Ptr\n",
2003 dtmprintk((MYIOC_s_WARN_FMT "ERROR! TaskMgmt Reply: NULL Request %p\n",
2007 pScsiTmReply = (SCSITaskMgmtReply_t*)mr;
2008 pScsiTmReq = (SCSITaskMgmt_t*)mf;
2010 /* Figure out if this was ABORT_TASK, TARGET_RESET, or BUS_RESET! */
2011 tmType = pScsiTmReq->TaskType;
2013 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05 &&
2014 pScsiTmReply->ResponseCode)
2015 mptscsih_taskmgmt_response_code(ioc,
2016 pScsiTmReply->ResponseCode);
2018 dtmprintk((MYIOC_s_WARN_FMT " TaskType = %d, TerminationCount=%d\n",
2019 ioc->name, tmType, le32_to_cpu(pScsiTmReply->TerminationCount)));
2020 DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply);
2022 iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2023 dtmprintk((MYIOC_s_WARN_FMT " SCSI TaskMgmt (%d) IOCStatus=%04x IOCLogInfo=%08x\n",
2024 ioc->name, tmType, iocstatus, le32_to_cpu(pScsiTmReply->IOCLogInfo)));
2025 /* Error? (anything non-zero?) */
2028 /* clear flags and continue.
2030 if (tmType == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK)
2031 hd->abortSCpnt = NULL;
2033 /* If an internal command is present
2034 * or the TM failed - reload the FW.
2035 * FC FW may respond FAILED to an ABORT
2037 if (tmType == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
2039 (iocstatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED)) {
2040 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0) {
2041 printk((KERN_WARNING
2042 " Firmware Reload FAILED!!\n"));
2047 dtmprintk((MYIOC_s_WARN_FMT " TaskMgmt SUCCESS\n", ioc->name));
2049 hd->abortSCpnt = NULL;
2054 spin_lock_irqsave(&ioc->FreeQlock, flags);
2056 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2057 hd->tmState = TM_STATE_NONE;
2062 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2064 * This is anyones guess quite frankly.
2067 mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
2068 sector_t capacity, int geom[])
2078 dummy = heads * sectors;
2079 cylinders = capacity;
2080 sector_div(cylinders,dummy);
2083 * Handle extended translation size for logical drives
2086 if ((ulong)capacity >= 0x200000) {
2089 dummy = heads * sectors;
2090 cylinders = capacity;
2091 sector_div(cylinders,dummy);
2097 geom[2] = cylinders;
2099 dprintk((KERN_NOTICE
2100 ": bios_param: Id=%i Lun=%i Channel=%i CHS=%i/%i/%i\n",
2101 sdev->id, sdev->lun,sdev->channel,(int)cylinders,heads,sectors));
2107 mptscsih_raid_id_to_num(MPT_SCSI_HOST *hd, uint physdiskid)
2111 if (!hd->ioc->raid_data.isRaid || !hd->ioc->raid_data.pIocPg3)
2114 for (i = 0; i < hd->ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2116 hd->ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID)
2117 return hd->ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum;
2122 EXPORT_SYMBOL(mptscsih_raid_id_to_num);
2124 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2126 * OS entry point to allow host driver to alloc memory
2127 * for each scsi target. Called once per device the bus scan.
2128 * Return non-zero if allocation fails.
2131 mptscsih_target_alloc(struct scsi_target *starget)
2133 VirtTarget *vtarget;
2135 vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
2138 starget->hostdata = vtarget;
2139 vtarget->starget = starget;
2143 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2145 * OS entry point to allow host driver to alloc memory
2146 * for each scsi device. Called once per device the bus scan.
2147 * Return non-zero if allocation fails.
2150 mptscsih_slave_alloc(struct scsi_device *sdev)
2152 struct Scsi_Host *host = sdev->host;
2153 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
2154 VirtTarget *vtarget;
2156 struct scsi_target *starget;
2158 vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
2160 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
2161 hd->ioc->name, sizeof(VirtDevice));
2165 vdev->ioc_id = hd->ioc->id;
2166 vdev->target_id = sdev->id;
2167 vdev->bus_id = sdev->channel;
2168 vdev->lun = sdev->lun;
2169 sdev->hostdata = vdev;
2171 starget = scsi_target(sdev);
2172 vtarget = starget->hostdata;
2174 vdev->vtarget = vtarget;
2176 if (vtarget->num_luns == 0) {
2177 hd->Targets[sdev->id] = vtarget;
2178 vtarget->ioc_id = hd->ioc->id;
2179 vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
2180 vtarget->target_id = sdev->id;
2181 vtarget->bus_id = sdev->channel;
2182 if (hd->ioc->bus_type == SPI && sdev->channel == 0 &&
2183 hd->ioc->raid_data.isRaid & (1 << sdev->id)) {
2184 vtarget->raidVolume = 1;
2185 ddvtprintk((KERN_INFO
2186 "RAID Volume @ id %d\n", sdev->id));
2189 vtarget->num_luns++;
2194 * OS entry point to allow for host driver to free allocated memory
2195 * Called if no device present or device being unloaded
2198 mptscsih_target_destroy(struct scsi_target *starget)
2200 if (starget->hostdata)
2201 kfree(starget->hostdata);
2202 starget->hostdata = NULL;
2206 * OS entry point to allow for host driver to free allocated memory
2207 * Called if no device present or device being unloaded
2210 mptscsih_slave_destroy(struct scsi_device *sdev)
2212 struct Scsi_Host *host = sdev->host;
2213 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
2214 VirtTarget *vtarget;
2215 VirtDevice *vdevice;
2216 struct scsi_target *starget;
2218 starget = scsi_target(sdev);
2219 vtarget = starget->hostdata;
2220 vdevice = sdev->hostdata;
2222 mptscsih_search_running_cmds(hd, vdevice);
2223 vtarget->luns[0] &= ~(1 << vdevice->lun);
2224 vtarget->num_luns--;
2225 if (vtarget->num_luns == 0) {
2226 hd->Targets[sdev->id] = NULL;
2228 mptscsih_synchronize_cache(hd, vdevice);
2230 sdev->hostdata = NULL;
2233 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2235 * mptscsih_change_queue_depth - This function will set a devices queue depth
2236 * @sdev: per scsi_device pointer
2237 * @qdepth: requested queue depth
2239 * Adding support for new 'change_queue_depth' api.
2242 mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
2244 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sdev->host->hostdata;
2245 VirtTarget *vtarget;
2246 struct scsi_target *starget;
2250 starget = scsi_target(sdev);
2251 vtarget = starget->hostdata;
2253 if (hd->ioc->bus_type == SPI) {
2254 if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
2256 else if (sdev->type == TYPE_DISK &&
2257 vtarget->minSyncFactor <= MPT_ULTRA160)
2258 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2260 max_depth = MPT_SCSI_CMD_PER_DEV_LOW;
2262 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2264 if (qdepth > max_depth)
2269 tagged = MSG_SIMPLE_TAG;
2271 scsi_adjust_queue_depth(sdev, tagged, qdepth);
2272 return sdev->queue_depth;
2276 * OS entry point to adjust the queue_depths on a per-device basis.
2277 * Called once per device the bus scan. Use it to force the queue_depth
2278 * member to 1 if a device does not support Q tags.
2279 * Return non-zero if fails.
2282 mptscsih_slave_configure(struct scsi_device *sdev)
2284 struct Scsi_Host *sh = sdev->host;
2285 VirtTarget *vtarget;
2286 VirtDevice *vdevice;
2287 struct scsi_target *starget;
2288 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sh->hostdata;
2289 int indexed_lun, lun_index;
2291 starget = scsi_target(sdev);
2292 vtarget = starget->hostdata;
2293 vdevice = sdev->hostdata;
2295 dsprintk((MYIOC_s_INFO_FMT
2296 "device @ %p, id=%d, LUN=%d, channel=%d\n",
2297 hd->ioc->name, sdev, sdev->id, sdev->lun, sdev->channel));
2298 if (hd->ioc->bus_type == SPI)
2299 dsprintk((MYIOC_s_INFO_FMT
2300 "sdtr %d wdtr %d ppr %d inq length=%d\n",
2301 hd->ioc->name, sdev->sdtr, sdev->wdtr,
2302 sdev->ppr, sdev->inquiry_len));
2304 if (sdev->id > sh->max_id) {
2305 /* error case, should never happen */
2306 scsi_adjust_queue_depth(sdev, 0, 1);
2307 goto slave_configure_exit;
2310 vdevice->configured_lun=1;
2311 lun_index = (vdevice->lun >> 5); /* 32 luns per lun_index */
2312 indexed_lun = (vdevice->lun % 32);
2313 vtarget->luns[lun_index] |= (1 << indexed_lun);
2314 mptscsih_initTarget(hd, vtarget, sdev);
2315 mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH);
2317 dsprintk((MYIOC_s_INFO_FMT
2318 "Queue depth=%d, tflags=%x\n",
2319 hd->ioc->name, sdev->queue_depth, vtarget->tflags));
2321 if (hd->ioc->bus_type == SPI)
2322 dsprintk((MYIOC_s_INFO_FMT
2323 "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
2324 hd->ioc->name, vtarget->negoFlags, vtarget->maxOffset,
2325 vtarget->minSyncFactor));
2327 slave_configure_exit:
2329 dsprintk((MYIOC_s_INFO_FMT
2330 "tagged %d, simple %d, ordered %d\n",
2331 hd->ioc->name,sdev->tagged_supported, sdev->simple_tags,
2332 sdev->ordered_tags));
2337 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2339 * Private routines...
2342 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2343 /* Utility function to copy sense data from the scsi_cmnd buffer
2344 * to the FC and SCSI target structures.
2348 mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
2351 SCSIIORequest_t *pReq;
2352 u32 sense_count = le32_to_cpu(pScsiReply->SenseCount);
2354 /* Get target structure
2356 pReq = (SCSIIORequest_t *) mf;
2357 vdev = sc->device->hostdata;
2363 /* Copy the sense received into the scsi command block. */
2364 req_index = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2365 sense_data = ((u8 *)hd->ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC));
2366 memcpy(sc->sense_buffer, sense_data, SNS_LEN(sc));
2368 /* Log SMART data (asc = 0x5D, non-IM case only) if required.
2370 if ((hd->ioc->events) && (hd->ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) {
2371 if ((sense_data[12] == 0x5D) && (vdev->vtarget->raidVolume == 0)) {
2373 MPT_ADAPTER *ioc = hd->ioc;
2375 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
2376 ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
2377 ioc->events[idx].eventContext = ioc->eventContext;
2379 ioc->events[idx].data[0] = (pReq->LUN[1] << 24) ||
2380 (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) ||
2381 (sc->device->channel << 8) || sc->device->id;
2383 ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12];
2385 ioc->eventContext++;
2389 dprintk((MYIOC_s_INFO_FMT "Hmmm... SenseData len=0! (?)\n",
2395 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc)
2400 hd = (MPT_SCSI_HOST *) sc->device->host->hostdata;
2402 for (i = 0; i < hd->ioc->req_depth; i++) {
2403 if (hd->ScsiLookup[i] == sc) {
2411 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2413 mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2416 unsigned long flags;
2419 dtmprintk((KERN_WARNING MYNAM
2420 ": IOC %s_reset routed to SCSI host driver!\n",
2421 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
2422 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
2424 /* If a FW reload request arrives after base installed but
2425 * before all scsi hosts have been attached, then an alt_ioc
2426 * may have a NULL sh pointer.
2428 if ((ioc->sh == NULL) || (ioc->sh->hostdata == NULL))
2431 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2433 if (reset_phase == MPT_IOC_SETUP_RESET) {
2434 dtmprintk((MYIOC_s_WARN_FMT "Setup-Diag Reset\n", ioc->name));
2437 * 1. Set Hard Reset Pending Flag
2438 * All new commands go to doneQ
2440 hd->resetPending = 1;
2442 } else if (reset_phase == MPT_IOC_PRE_RESET) {
2443 dtmprintk((MYIOC_s_WARN_FMT "Pre-Diag Reset\n", ioc->name));
2445 /* 2. Flush running commands
2446 * Clean ScsiLookup (and associated memory)
2450 /* 2b. Reply to OS all known outstanding I/O commands.
2452 mptscsih_flush_running_cmds(hd);
2454 /* 2c. If there was an internal command that
2455 * has not completed, configuration or io request,
2456 * free these resources.
2459 del_timer(&hd->timer);
2460 mpt_free_msg_frame(ioc, hd->cmdPtr);
2463 dtmprintk((MYIOC_s_WARN_FMT "Pre-Reset complete.\n", ioc->name));
2466 dtmprintk((MYIOC_s_WARN_FMT "Post-Diag Reset\n", ioc->name));
2468 /* Once a FW reload begins, all new OS commands are
2469 * redirected to the doneQ w/ a reset status.
2470 * Init all control structures.
2473 /* ScsiLookup initialization
2475 for (ii=0; ii < hd->ioc->req_depth; ii++)
2476 hd->ScsiLookup[ii] = NULL;
2478 /* 2. Chain Buffer initialization
2481 /* 4. Renegotiate to all devices, if SPI
2484 /* 5. Enable new commands to be posted
2486 spin_lock_irqsave(&ioc->FreeQlock, flags);
2488 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2489 hd->resetPending = 0;
2490 hd->tmState = TM_STATE_NONE;
2492 /* 6. If there was an internal command,
2493 * wake this process up.
2497 * Wake up the original calling thread
2499 hd->pLocal = &hd->localReply;
2500 hd->pLocal->completion = MPT_SCANDV_DID_RESET;
2501 hd->scandv_wait_done = 1;
2502 wake_up(&hd->scandv_waitq);
2506 /* 7. FC: Rescan for blocked rports which might have returned.
2508 else if (ioc->bus_type == FC) {
2510 unsigned long flags;
2512 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
2513 work_count = ++ioc->fc_rescan_work_count;
2514 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
2515 if (work_count == 1)
2516 schedule_work(&ioc->fc_rescan_work);
2518 dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name));
2522 return 1; /* currently means nothing really */
2525 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2527 mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2530 u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
2532 unsigned long flags;
2534 devtprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
2537 if (ioc->sh == NULL ||
2538 ((hd = (MPT_SCSI_HOST *)ioc->sh->hostdata) == NULL))
2542 case MPI_EVENT_UNIT_ATTENTION: /* 03 */
2545 case MPI_EVENT_IOC_BUS_RESET: /* 04 */
2546 case MPI_EVENT_EXT_BUS_RESET: /* 05 */
2547 if (hd && (ioc->bus_type == SPI) && (hd->soft_resets < -1))
2550 case MPI_EVENT_LOGOUT: /* 09 */
2554 case MPI_EVENT_RESCAN: /* 06 */
2555 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
2556 work_count = ++ioc->fc_rescan_work_count;
2557 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
2558 if (work_count == 1)
2559 schedule_work(&ioc->fc_rescan_work);
2563 * CHECKME! Don't think we need to do
2564 * anything for these, but...
2566 case MPI_EVENT_LINK_STATUS_CHANGE: /* 07 */
2567 case MPI_EVENT_LOOP_STATE_CHANGE: /* 08 */
2569 * CHECKME! Falling thru...
2573 case MPI_EVENT_INTEGRATED_RAID: /* 0B */
2576 case MPI_EVENT_NONE: /* 00 */
2577 case MPI_EVENT_LOG_DATA: /* 01 */
2578 case MPI_EVENT_STATE_CHANGE: /* 02 */
2579 case MPI_EVENT_EVENT_CHANGE: /* 0A */
2581 dprintk((KERN_INFO " Ignoring event (=%02Xh)\n", event));
2585 return 1; /* currently means nothing really */
2588 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2590 * mptscsih_initTarget - Target, LUN alloc/free functionality.
2591 * @hd: Pointer to MPT_SCSI_HOST structure
2592 * @vtarget: per target private data
2593 * @sdev: SCSI device
2595 * NOTE: It's only SAFE to call this routine if data points to
2596 * sane & valid STANDARD INQUIRY data!
2598 * Allocate and initialize memory for this target.
2599 * Save inquiry data.
2603 mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget,
2604 struct scsi_device *sdev)
2606 dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n",
2607 hd->ioc->name, vtarget->bus_id, vtarget->target_id, lun, hd));
2609 /* Is LUN supported? If so, upper 2 bits will be 0
2610 * in first byte of inquiry data.
2612 if (sdev->inq_periph_qual != 0)
2615 if (vtarget == NULL)
2618 vtarget->type = sdev->type;
2620 if (hd->ioc->bus_type != SPI)
2623 if ((sdev->type == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) {
2624 /* Treat all Processors as SAF-TE if
2625 * command line option is set */
2626 vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
2627 mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id);
2628 }else if ((sdev->type == TYPE_PROCESSOR) &&
2629 !(vtarget->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) {
2630 if (sdev->inquiry_len > 49 ) {
2631 if (sdev->inquiry[44] == 'S' &&
2632 sdev->inquiry[45] == 'A' &&
2633 sdev->inquiry[46] == 'F' &&
2634 sdev->inquiry[47] == '-' &&
2635 sdev->inquiry[48] == 'T' &&
2636 sdev->inquiry[49] == 'E' ) {
2637 vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
2638 mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id);
2642 mptscsih_setTargetNegoParms(hd, vtarget, sdev);
2645 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2647 * Update the target negotiation parameters based on the
2648 * the Inquiry data, adapter capabilities, and NVRAM settings.
2652 mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target,
2653 struct scsi_device *sdev)
2655 SpiCfgData *pspi_data = &hd->ioc->spi_data;
2656 int id = (int) target->target_id;
2658 u8 width = MPT_NARROW;
2659 u8 factor = MPT_ASYNC;
2664 target->negoFlags = pspi_data->noQas;
2666 /* noQas == 0 => device supports QAS. */
2668 if (sdev->scsi_level < SCSI_2) {
2670 factor = MPT_ULTRA2;
2671 offset = pspi_data->maxSyncOffset;
2672 target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
2674 if (scsi_device_wide(sdev)) {
2678 if (scsi_device_sync(sdev)) {
2679 factor = pspi_data->minSyncFactor;
2680 if (!scsi_device_dt(sdev))
2681 factor = MPT_ULTRA2;
2683 if (!scsi_device_ius(sdev) &&
2684 !scsi_device_qas(sdev))
2685 factor = MPT_ULTRA160;
2687 factor = MPT_ULTRA320;
2688 if (scsi_device_qas(sdev)) {
2689 ddvtprintk((KERN_INFO "Enabling QAS due to byte56=%02x on id=%d!\n", byte56, id));
2692 if (sdev->type == TYPE_TAPE &&
2693 scsi_device_ius(sdev))
2694 target->negoFlags |= MPT_TAPE_NEGO_IDP;
2697 offset = pspi_data->maxSyncOffset;
2699 /* If RAID, never disable QAS
2700 * else if non RAID, do not disable
2701 * QAS if bit 1 is set
2702 * bit 1 QAS support, non-raid only
2705 if (target->raidVolume == 1) {
2714 if (!sdev->tagged_supported) {
2715 target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
2718 /* Update tflags based on NVRAM settings. (SCSI only)
2720 if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
2721 nvram = pspi_data->nvram[id];
2722 nfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
2725 width = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
2728 /* Ensure factor is set to the
2729 * maximum of: adapter, nvram, inquiry
2732 if (nfactor < pspi_data->minSyncFactor )
2733 nfactor = pspi_data->minSyncFactor;
2735 factor = max(factor, nfactor);
2736 if (factor == MPT_ASYNC)
2747 /* Make sure data is consistent
2749 if ((!width) && (factor < MPT_ULTRA2)) {
2750 factor = MPT_ULTRA2;
2753 /* Save the data to the target structure.
2755 target->minSyncFactor = factor;
2756 target->maxOffset = offset;
2757 target->maxWidth = width;
2759 target->tflags |= MPT_TARGET_FLAGS_VALID_NEGO;
2761 /* Disable unused features.
2764 target->negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
2767 target->negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
2769 if ( factor > MPT_ULTRA320 )
2772 if (noQas && (pspi_data->noQas == 0)) {
2773 pspi_data->noQas |= MPT_TARGET_NO_NEGO_QAS;
2774 target->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
2776 /* Disable QAS in a mixed configuration case
2779 ddvtprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id));
2783 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2785 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2787 * SCSI Config Page functionality ...
2790 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2791 /* mptscsih_writeIOCPage4 - write IOC Page 4
2792 * @hd: Pointer to a SCSI Host Structure
2793 * @target_id: write IOC Page4 for this ID & Bus
2795 * Return: -EAGAIN if unable to obtain a Message Frame
2798 * Remark: We do not wait for a return, write pages sequentially.
2801 mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus)
2803 MPT_ADAPTER *ioc = hd->ioc;
2805 IOCPage4_t *IOCPage4Ptr;
2813 /* Get a MF for this command.
2815 if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
2816 dfailprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n",
2821 /* Set the request and the data pointers.
2822 * Place data at end of MF.
2824 pReq = (Config_t *)mf;
2826 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2827 frameOffset = ioc->req_sz - sizeof(IOCPage4_t);
2829 /* Complete the request frame (same for all requests).
2831 pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
2833 pReq->ChainOffset = 0;
2834 pReq->Function = MPI_FUNCTION_CONFIG;
2835 pReq->ExtPageLength = 0;
2836 pReq->ExtPageType = 0;
2838 for (ii=0; ii < 8; ii++) {
2839 pReq->Reserved2[ii] = 0;
2842 IOCPage4Ptr = ioc->spi_data.pIocPg4;
2843 dataDma = ioc->spi_data.IocPg4_dma;
2844 ii = IOCPage4Ptr->ActiveSEP++;
2845 IOCPage4Ptr->SEP[ii].SEPTargetID = target_id;
2846 IOCPage4Ptr->SEP[ii].SEPBus = bus;
2847 pReq->Header = IOCPage4Ptr->Header;
2848 pReq->PageAddress = cpu_to_le32(target_id | (bus << 8 ));
2850 /* Add a SGE to the config request.
2852 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE |
2853 (IOCPage4Ptr->Header.PageLength + ii) * 4;
2855 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma);
2857 dinitprintk((MYIOC_s_INFO_FMT
2858 "writeIOCPage4: MaxSEP=%d ActiveSEP=%d id=%d bus=%d\n",
2859 ioc->name, IOCPage4Ptr->MaxSEP, IOCPage4Ptr->ActiveSEP, target_id, bus));
2861 mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
2866 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2868 * Bus Scan and Domain Validation functionality ...
2871 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2873 * mptscsih_scandv_complete - Scan and DV callback routine registered
2874 * to Fustion MPT (base) driver.
2876 * @ioc: Pointer to MPT_ADAPTER structure
2877 * @mf: Pointer to original MPT request frame
2878 * @mr: Pointer to MPT reply frame (NULL if TurboReply)
2880 * This routine is called from mpt.c::mpt_interrupt() at the completion
2881 * of any SCSI IO request.
2882 * This routine is registered with the Fusion MPT (base) driver at driver
2883 * load/init time via the mpt_register() API call.
2885 * Returns 1 indicating alloc'd request frame ptr should be freed.
2887 * Remark: Sets a completion code and (possibly) saves sense data
2888 * in the IOC member localReply structure.
2889 * Used ONLY for DV and other internal commands.
2892 mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
2895 SCSIIORequest_t *pReq;
2899 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2902 (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) {
2903 printk(MYIOC_s_ERR_FMT
2904 "ScanDvComplete, %s req frame ptr! (=%p)\n",
2905 ioc->name, mf?"BAD":"NULL", (void *) mf);
2909 del_timer(&hd->timer);
2910 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2911 hd->ScsiLookup[req_idx] = NULL;
2912 pReq = (SCSIIORequest_t *) mf;
2914 if (mf != hd->cmdPtr) {
2915 printk(MYIOC_s_WARN_FMT "ScanDvComplete (mf=%p, cmdPtr=%p, idx=%d)\n",
2916 hd->ioc->name, (void *)mf, (void *) hd->cmdPtr, req_idx);
2920 ddvprintk((MYIOC_s_INFO_FMT "ScanDvComplete (mf=%p,mr=%p,idx=%d)\n",
2921 hd->ioc->name, mf, mr, req_idx));
2923 hd->pLocal = &hd->localReply;
2924 hd->pLocal->scsiStatus = 0;
2926 /* If target struct exists, clear sense valid flag.
2929 completionCode = MPT_SCANDV_GOOD;
2931 SCSIIOReply_t *pReply;
2935 pReply = (SCSIIOReply_t *) mr;
2937 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2938 scsi_status = pReply->SCSIStatus;
2940 ddvtprintk((KERN_NOTICE " IOCStatus=%04xh, SCSIState=%02xh, SCSIStatus=%02xh, IOCLogInfo=%08xh\n",
2941 status, pReply->SCSIState, scsi_status,
2942 le32_to_cpu(pReply->IOCLogInfo)));
2946 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
2947 completionCode = MPT_SCANDV_SELECTION_TIMEOUT;
2950 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
2951 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
2952 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
2953 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
2954 completionCode = MPT_SCANDV_DID_RESET;
2957 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
2958 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
2959 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
2960 if (pReply->Function == MPI_FUNCTION_CONFIG) {
2961 ConfigReply_t *pr = (ConfigReply_t *)mr;
2962 completionCode = MPT_SCANDV_GOOD;
2963 hd->pLocal->header.PageVersion = pr->Header.PageVersion;
2964 hd->pLocal->header.PageLength = pr->Header.PageLength;
2965 hd->pLocal->header.PageNumber = pr->Header.PageNumber;
2966 hd->pLocal->header.PageType = pr->Header.PageType;
2968 } else if (pReply->Function == MPI_FUNCTION_RAID_ACTION) {
2969 /* If the RAID Volume request is successful,
2970 * return GOOD, else indicate that
2971 * some type of error occurred.
2973 MpiRaidActionReply_t *pr = (MpiRaidActionReply_t *)mr;
2974 if (le16_to_cpu(pr->ActionStatus) == MPI_RAID_ACTION_ASTATUS_SUCCESS)
2975 completionCode = MPT_SCANDV_GOOD;
2977 completionCode = MPT_SCANDV_SOME_ERROR;
2978 memcpy(hd->pLocal->sense, pr, sizeof(hd->pLocal->sense));
2980 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID) {
2984 /* save sense data in global structure
2986 completionCode = MPT_SCANDV_SENSE;
2987 hd->pLocal->scsiStatus = scsi_status;
2988 sense_data = ((u8 *)hd->ioc->sense_buf_pool +
2989 (req_idx * MPT_SENSE_BUFFER_ALLOC));
2991 sz = min_t(int, pReq->SenseBufferLength,
2992 SCSI_STD_SENSE_BYTES);
2993 memcpy(hd->pLocal->sense, sense_data, sz);
2995 ddvprintk((KERN_NOTICE " Check Condition, sense ptr %p\n",
2997 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_FAILED) {
2998 if (pReq->CDB[0] == INQUIRY)
2999 completionCode = MPT_SCANDV_ISSUE_SENSE;
3001 completionCode = MPT_SCANDV_DID_RESET;
3003 else if (pReply->SCSIState & MPI_SCSI_STATE_NO_SCSI_STATUS)
3004 completionCode = MPT_SCANDV_DID_RESET;
3005 else if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
3006 completionCode = MPT_SCANDV_DID_RESET;
3008 completionCode = MPT_SCANDV_GOOD;
3009 hd->pLocal->scsiStatus = scsi_status;
3013 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
3014 if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
3015 completionCode = MPT_SCANDV_DID_RESET;
3017 completionCode = MPT_SCANDV_SOME_ERROR;
3021 completionCode = MPT_SCANDV_SOME_ERROR;
3024 } /* switch(status) */
3026 ddvtprintk((KERN_NOTICE " completionCode set to %08xh\n",
3028 } /* end of address reply case */
3030 hd->pLocal->completion = completionCode;
3032 /* MF and RF are freed in mpt_interrupt
3035 /* Free Chain buffers (will never chain) in scan or dv */
3036 //mptscsih_freeChainBuffers(ioc, req_idx);
3039 * Wake up the original calling thread
3041 hd->scandv_wait_done = 1;
3042 wake_up(&hd->scandv_waitq);
3047 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3048 /* mptscsih_timer_expired - Call back for timer process.
3049 * Used only for dv functionality.
3050 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
3054 mptscsih_timer_expired(unsigned long data)
3056 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) data;
3058 ddvprintk((MYIOC_s_WARN_FMT "Timer Expired! Cmd %p\n", hd->ioc->name, hd->cmdPtr));
3061 MPIHeader_t *cmd = (MPIHeader_t *)hd->cmdPtr;
3063 if (cmd->Function == MPI_FUNCTION_SCSI_IO_REQUEST) {
3064 /* Desire to issue a task management request here.
3065 * TM requests MUST be single threaded.
3066 * If old eh code and no TM current, issue request.
3067 * If new eh code, do nothing. Wait for OS cmd timeout
3070 ddvtprintk((MYIOC_s_NOTE_FMT "DV Cmd Timeout: NoOp\n", hd->ioc->name));
3072 /* Perform a FW reload */
3073 if (mpt_HardResetHandler(hd->ioc, NO_SLEEP) < 0) {
3074 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", hd->ioc->name);
3078 /* This should NEVER happen */
3079 printk(MYIOC_s_WARN_FMT "Null cmdPtr!!!!\n", hd->ioc->name);
3082 /* No more processing.
3083 * TM call will generate an interrupt for SCSI TM Management.
3084 * The FW will reply to all outstanding commands, callback will finish cleanup.
3085 * Hard reset clean-up will free all resources.
3087 ddvprintk((MYIOC_s_WARN_FMT "Timer Expired Complete!\n", hd->ioc->name));
3093 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3095 * mptscsih_do_cmd - Do internal command.
3096 * @hd: MPT_SCSI_HOST pointer
3097 * @io: INTERNAL_CMD pointer.
3099 * Issue the specified internally generated command and do command
3100 * specific cleanup. For bus scan / DV only.
3101 * NOTES: If command is Inquiry and status is good,
3102 * initialize a target structure, save the data
3104 * Remark: Single threaded access only.
3107 * < 0 if an illegal command or no resources
3111 * > 0 if command complete but some type of completion error.
3114 mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
3117 SCSIIORequest_t *pScsiReq;
3118 SCSIIORequest_t ReqCopy;
3119 int my_idx, ii, dir;
3123 char CDB[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
3126 in_isr = in_interrupt();
3128 dprintk((MYIOC_s_WARN_FMT "Internal SCSI IO request not allowed in ISR context!\n",
3134 /* Set command specific information
3139 dir = MPI_SCSIIO_CONTROL_READ;
3145 case TEST_UNIT_READY:
3147 dir = MPI_SCSIIO_CONTROL_READ;
3153 dir = MPI_SCSIIO_CONTROL_READ;
3155 CDB[4] = 1; /*Spin up the disk */
3163 dir = MPI_SCSIIO_CONTROL_READ;
3169 dir = MPI_SCSIIO_CONTROL_READ;
3171 if (io->flags & MPT_ICFLAG_ECHO) {
3177 if (io->flags & MPT_ICFLAG_BUF_CAP) {
3180 CDB[6] = (io->size >> 16) & 0xFF;
3181 CDB[7] = (io->size >> 8) & 0xFF;
3182 CDB[8] = io->size & 0xFF;
3188 dir = MPI_SCSIIO_CONTROL_WRITE;
3190 if (io->flags & MPT_ICFLAG_ECHO) {
3195 CDB[6] = (io->size >> 16) & 0xFF;
3196 CDB[7] = (io->size >> 8) & 0xFF;
3197 CDB[8] = io->size & 0xFF;
3203 dir = MPI_SCSIIO_CONTROL_READ;
3210 dir = MPI_SCSIIO_CONTROL_READ;
3215 case SYNCHRONIZE_CACHE:
3217 dir = MPI_SCSIIO_CONTROL_READ;
3219 // CDB[1] = 0x02; /* set immediate bit */
3228 /* Get and Populate a free Frame
3230 if ((mf = mpt_get_msg_frame(hd->ioc->InternalCtx, hd->ioc)) == NULL) {
3231 ddvprintk((MYIOC_s_WARN_FMT "No msg frames!\n",
3236 pScsiReq = (SCSIIORequest_t *) mf;
3238 /* Get the request index */
3239 my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3240 ADD_INDEX_LOG(my_idx); /* for debug */
3242 if (io->flags & MPT_ICFLAG_PHYS_DISK) {
3243 pScsiReq->TargetID = io->physDiskNum;
3245 pScsiReq->ChainOffset = 0;
3246 pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
3248 pScsiReq->TargetID = io->id;
3249 pScsiReq->Bus = io->bus;
3250 pScsiReq->ChainOffset = 0;
3251 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
3254 pScsiReq->CDBLength = cmdLen;
3255 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
3257 pScsiReq->Reserved = 0;
3259 pScsiReq->MsgFlags = mpt_msg_flags();
3260 /* MsgContext set in mpt_get_msg_fram call */
3262 for (ii=0; ii < 8; ii++)
3263 pScsiReq->LUN[ii] = 0;
3264 pScsiReq->LUN[1] = io->lun;
3266 if (io->flags & MPT_ICFLAG_TAGGED_CMD)
3267 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ);
3269 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3271 if (cmd == REQUEST_SENSE) {
3272 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3273 ddvprintk((MYIOC_s_INFO_FMT "Untagged! 0x%2x\n",
3274 hd->ioc->name, cmd));
3277 for (ii=0; ii < 16; ii++)
3278 pScsiReq->CDB[ii] = CDB[ii];
3280 pScsiReq->DataLength = cpu_to_le32(io->size);
3281 pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
3282 + (my_idx * MPT_SENSE_BUFFER_ALLOC));
3284 ddvprintk((MYIOC_s_INFO_FMT "Sending Command 0x%x for (%d:%d:%d)\n",
3285 hd->ioc->name, cmd, io->bus, io->id, io->lun));
3287 if (dir == MPI_SCSIIO_CONTROL_READ) {
3288 mpt_add_sge((char *) &pScsiReq->SGL,
3289 MPT_SGE_FLAGS_SSIMPLE_READ | io->size,
3292 mpt_add_sge((char *) &pScsiReq->SGL,
3293 MPT_SGE_FLAGS_SSIMPLE_WRITE | io->size,
3297 /* The ISR will free the request frame, but we need
3298 * the information to initialize the target. Duplicate.
3300 memcpy(&ReqCopy, pScsiReq, sizeof(SCSIIORequest_t));
3302 /* Issue this command after:
3305 * Wait until the reply has been received
3306 * ScsiScanDvCtx callback function will
3308 * set scandv_wait_done and call wake_up
3311 hd->timer.expires = jiffies + HZ*cmdTimeout;
3312 hd->scandv_wait_done = 0;
3314 /* Save cmd pointer, for resource free if timeout or
3319 add_timer(&hd->timer);
3320 mpt_put_msg_frame(hd->ioc->InternalCtx, hd->ioc, mf);
3321 wait_event(hd->scandv_waitq, hd->scandv_wait_done);
3324 rc = hd->pLocal->completion;
3325 hd->pLocal->skip = 0;
3327 /* Always set fatal error codes in some cases.
3329 if (rc == MPT_SCANDV_SELECTION_TIMEOUT)
3331 else if (rc == MPT_SCANDV_SOME_ERROR)
3335 /* This should never happen. */
3336 ddvprintk((MYIOC_s_INFO_FMT "_do_cmd: Null pLocal!!!\n",
3343 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3345 * mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
3346 * @hd: Pointer to a SCSI HOST structure
3347 * @vtarget: per device private data
3350 * Uses the ISR, but with special processing.
3351 * MUST be single-threaded.
3355 mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
3359 /* Following parameters will not change
3362 iocmd.cmd = SYNCHRONIZE_CACHE;
3364 iocmd.physDiskNum = -1;
3366 iocmd.data_dma = -1;
3368 iocmd.rsvd = iocmd.rsvd2 = 0;
3369 iocmd.bus = vdevice->bus_id;
3370 iocmd.id = vdevice->target_id;
3371 iocmd.lun = (u8)vdevice->lun;
3373 if ((vdevice->vtarget->type == TYPE_DISK) &&
3374 (vdevice->configured_lun))
3375 mptscsih_do_cmd(hd, &iocmd);
3378 EXPORT_SYMBOL(mptscsih_remove);
3379 EXPORT_SYMBOL(mptscsih_shutdown);
3381 EXPORT_SYMBOL(mptscsih_suspend);
3382 EXPORT_SYMBOL(mptscsih_resume);
3384 EXPORT_SYMBOL(mptscsih_proc_info);
3385 EXPORT_SYMBOL(mptscsih_info);
3386 EXPORT_SYMBOL(mptscsih_qcmd);
3387 EXPORT_SYMBOL(mptscsih_target_alloc);
3388 EXPORT_SYMBOL(mptscsih_slave_alloc);
3389 EXPORT_SYMBOL(mptscsih_target_destroy);
3390 EXPORT_SYMBOL(mptscsih_slave_destroy);
3391 EXPORT_SYMBOL(mptscsih_slave_configure);
3392 EXPORT_SYMBOL(mptscsih_abort);
3393 EXPORT_SYMBOL(mptscsih_dev_reset);
3394 EXPORT_SYMBOL(mptscsih_bus_reset);
3395 EXPORT_SYMBOL(mptscsih_host_reset);
3396 EXPORT_SYMBOL(mptscsih_bios_param);
3397 EXPORT_SYMBOL(mptscsih_io_done);
3398 EXPORT_SYMBOL(mptscsih_taskmgmt_complete);
3399 EXPORT_SYMBOL(mptscsih_scandv_complete);
3400 EXPORT_SYMBOL(mptscsih_event_process);
3401 EXPORT_SYMBOL(mptscsih_ioc_reset);
3402 EXPORT_SYMBOL(mptscsih_change_queue_depth);
3403 EXPORT_SYMBOL(mptscsih_timer_expired);
3404 EXPORT_SYMBOL(mptscsih_TMHandler);
3406 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/