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>
69 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
70 #define my_NAME "Fusion MPT SCSI Host driver"
71 #define my_VERSION MPT_LINUX_VERSION_COMMON
72 #define MYNAM "mptscsih"
74 MODULE_AUTHOR(MODULEAUTHOR);
75 MODULE_DESCRIPTION(my_NAME);
76 MODULE_LICENSE("GPL");
78 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
80 typedef struct _BIG_SENSE_BUF {
81 u8 data[MPT_SENSE_BUFFER_ALLOC];
84 #define MPT_SCANDV_GOOD (0x00000000) /* must be 0 */
85 #define MPT_SCANDV_DID_RESET (0x00000001)
86 #define MPT_SCANDV_SENSE (0x00000002)
87 #define MPT_SCANDV_SOME_ERROR (0x00000004)
88 #define MPT_SCANDV_SELECTION_TIMEOUT (0x00000008)
89 #define MPT_SCANDV_ISSUE_SENSE (0x00000010)
90 #define MPT_SCANDV_FALLBACK (0x00000020)
92 #define MPT_SCANDV_MAX_RETRIES (10)
94 #define MPT_ICFLAG_BUF_CAP 0x01 /* ReadBuffer Read Capacity format */
95 #define MPT_ICFLAG_ECHO 0x02 /* ReadBuffer Echo buffer format */
96 #define MPT_ICFLAG_PHYS_DISK 0x04 /* Any SCSI IO but do Phys Disk Format */
97 #define MPT_ICFLAG_TAGGED_CMD 0x08 /* Do tagged IO */
98 #define MPT_ICFLAG_DID_RESET 0x20 /* Bus Reset occurred with this command */
99 #define MPT_ICFLAG_RESERVED 0x40 /* Reserved has been issued */
101 typedef struct _internal_cmd {
102 char *data; /* data pointer */
103 dma_addr_t data_dma; /* data dma address */
104 int size; /* transfer size */
105 u8 cmd; /* SCSI Op Code */
106 u8 bus; /* bus number */
107 u8 id; /* SCSI ID (virtual) */
109 u8 flags; /* Bit Field - See above */
110 u8 physDiskNum; /* Phys disk number, -1 else */
115 typedef struct _negoparms {
122 typedef struct _dv_parameters {
131 * Other private/forward protos...
133 int mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
134 static void mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq);
135 int mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
137 static int mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
138 SCSIIORequest_t *pReq, int req_idx);
139 static void mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx);
140 static void mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply);
141 static int mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd);
142 static int mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout );
143 static u32 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc);
145 static int mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout);
146 static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout);
148 int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
149 int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
151 static void mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *data, int dlen);
152 static void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56);
153 static void mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq);
154 static void mptscsih_setDevicePage1Flags (u8 width, u8 factor, u8 offset, int *requestedPtr, int *configurationPtr, u8 flags);
155 static void mptscsih_no_negotiate(MPT_SCSI_HOST *hd, int target_id);
156 static int mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target, int flags);
157 static int mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus);
158 int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
159 static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
160 static int mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum);
162 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
163 static int mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io);
164 static void mptscsih_domainValidation(void *hd);
165 static int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id);
166 static void mptscsih_qas_check(MPT_SCSI_HOST *hd, int id);
167 static int mptscsih_doDv(MPT_SCSI_HOST *hd, int channel, int target);
168 static void mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage);
169 static void mptscsih_fillbuf(char *buffer, int size, int index, int width);
172 void mptscsih_remove(struct pci_dev *);
173 void mptscsih_shutdown(struct device *);
175 int mptscsih_suspend(struct pci_dev *pdev, pm_message_t state);
176 int mptscsih_resume(struct pci_dev *pdev);
179 #define SNS_LEN(scp) sizeof((scp)->sense_buffer)
181 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
183 * Domain Validation task structure
185 static DEFINE_SPINLOCK(dvtaskQ_lock);
186 static int dvtaskQ_active = 0;
187 static int dvtaskQ_release = 0;
188 static struct work_struct dvTaskQ_task;
191 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
193 * mptscsih_add_sge - Place a simple SGE at address pAddr.
194 * @pAddr: virtual address for SGE
195 * @flagslength: SGE flags and data transfer length
196 * @dma_addr: Physical address
198 * This routine places a MPT request frame back on the MPT adapter's
202 mptscsih_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
204 if (sizeof(dma_addr_t) == sizeof(u64)) {
205 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
206 u32 tmp = dma_addr & 0xFFFFFFFF;
208 pSge->FlagsLength = cpu_to_le32(flagslength);
209 pSge->Address.Low = cpu_to_le32(tmp);
210 tmp = (u32) ((u64)dma_addr >> 32);
211 pSge->Address.High = cpu_to_le32(tmp);
214 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
215 pSge->FlagsLength = cpu_to_le32(flagslength);
216 pSge->Address = cpu_to_le32(dma_addr);
218 } /* mptscsih_add_sge() */
220 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
222 * mptscsih_add_chain - Place a chain SGE at address pAddr.
223 * @pAddr: virtual address for SGE
224 * @next: nextChainOffset value (u32's)
225 * @length: length of next SGL segment
226 * @dma_addr: Physical address
228 * This routine places a MPT request frame back on the MPT adapter's
232 mptscsih_add_chain(char *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
234 if (sizeof(dma_addr_t) == sizeof(u64)) {
235 SGEChain64_t *pChain = (SGEChain64_t *) pAddr;
236 u32 tmp = dma_addr & 0xFFFFFFFF;
238 pChain->Length = cpu_to_le16(length);
239 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size();
241 pChain->NextChainOffset = next;
243 pChain->Address.Low = cpu_to_le32(tmp);
244 tmp = (u32) ((u64)dma_addr >> 32);
245 pChain->Address.High = cpu_to_le32(tmp);
247 SGEChain32_t *pChain = (SGEChain32_t *) pAddr;
248 pChain->Length = cpu_to_le16(length);
249 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size();
250 pChain->NextChainOffset = next;
251 pChain->Address = cpu_to_le32(dma_addr);
253 } /* mptscsih_add_chain() */
255 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
257 * mptscsih_getFreeChainBuffer - Function to get a free chain
258 * from the MPT_SCSI_HOST FreeChainQ.
259 * @ioc: Pointer to MPT_ADAPTER structure
260 * @req_idx: Index of the SCSI IO request frame. (output)
262 * return SUCCESS or FAILED
265 mptscsih_getFreeChainBuffer(MPT_ADAPTER *ioc, int *retIndex)
267 MPT_FRAME_HDR *chainBuf;
272 dsgprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer called\n",
274 spin_lock_irqsave(&ioc->FreeQlock, flags);
275 if (!list_empty(&ioc->FreeChainQ)) {
278 chainBuf = list_entry(ioc->FreeChainQ.next, MPT_FRAME_HDR,
279 u.frame.linkage.list);
280 list_del(&chainBuf->u.frame.linkage.list);
281 offset = (u8 *)chainBuf - (u8 *)ioc->ChainBuffer;
282 chain_idx = offset / ioc->req_sz;
284 dsgprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer (index %d), got buf=%p\n",
285 ioc->name, *retIndex, chainBuf));
288 chain_idx = MPT_HOST_NO_CHAIN;
289 dfailprintk((MYIOC_s_ERR_FMT "getFreeChainBuffer failed\n",
292 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
294 *retIndex = chain_idx;
296 } /* mptscsih_getFreeChainBuffer() */
298 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
300 * mptscsih_AddSGE - Add a SGE (plus chain buffers) to the
301 * SCSIIORequest_t Message Frame.
302 * @ioc: Pointer to MPT_ADAPTER structure
303 * @SCpnt: Pointer to scsi_cmnd structure
304 * @pReq: Pointer to SCSIIORequest_t structure
309 mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
310 SCSIIORequest_t *pReq, int req_idx)
314 struct scatterlist *sg;
316 int sges_left, sg_done;
317 int chain_idx = MPT_HOST_NO_CHAIN;
319 int numSgeSlots, numSgeThisFrame;
320 u32 sgflags, sgdir, thisxfer = 0;
321 int chain_dma_off = 0;
327 sgdir = le32_to_cpu(pReq->Control) & MPI_SCSIIO_CONTROL_DATADIRECTION_MASK;
328 if (sgdir == MPI_SCSIIO_CONTROL_WRITE) {
329 sgdir = MPT_TRANSFER_HOST_TO_IOC;
331 sgdir = MPT_TRANSFER_IOC_TO_HOST;
334 psge = (char *) &pReq->SGL;
335 frm_sz = ioc->req_sz;
337 /* Map the data portion, if any.
338 * sges_left = 0 if no data transfer.
340 if ( (sges_left = SCpnt->use_sg) ) {
341 sges_left = pci_map_sg(ioc->pcidev,
342 (struct scatterlist *) SCpnt->request_buffer,
344 SCpnt->sc_data_direction);
347 } else if (SCpnt->request_bufflen) {
348 SCpnt->SCp.dma_handle = pci_map_single(ioc->pcidev,
349 SCpnt->request_buffer,
350 SCpnt->request_bufflen,
351 SCpnt->sc_data_direction);
352 dsgprintk((MYIOC_s_INFO_FMT "SG: non-SG for %p, len=%d\n",
353 ioc->name, SCpnt, SCpnt->request_bufflen));
354 mptscsih_add_sge((char *) &pReq->SGL,
355 0xD1000000|MPT_SGE_FLAGS_ADDRESSING|sgdir|SCpnt->request_bufflen,
356 SCpnt->SCp.dma_handle);
361 /* Handle the SG case.
363 sg = (struct scatterlist *) SCpnt->request_buffer;
365 sgeOffset = sizeof(SCSIIORequest_t) - sizeof(SGE_IO_UNION);
368 /* Prior to entering this loop - the following must be set
369 * current MF: sgeOffset (bytes)
370 * chainSge (Null if original MF is not a chain buffer)
371 * sg_done (num SGE done for this MF)
375 numSgeSlots = ((frm_sz - sgeOffset) / (sizeof(u32) + sizeof(dma_addr_t)) );
376 numSgeThisFrame = (sges_left < numSgeSlots) ? sges_left : numSgeSlots;
378 sgflags = MPT_SGE_FLAGS_SIMPLE_ELEMENT | MPT_SGE_FLAGS_ADDRESSING | sgdir;
380 /* Get first (num - 1) SG elements
381 * Skip any SG entries with a length of 0
382 * NOTE: at finish, sg and psge pointed to NEXT data/location positions
384 for (ii=0; ii < (numSgeThisFrame-1); ii++) {
385 thisxfer = sg_dma_len(sg);
387 sg ++; /* Get next SG element from the OS */
392 v2 = sg_dma_address(sg);
393 mptscsih_add_sge(psge, sgflags | thisxfer, v2);
395 sg++; /* Get next SG element from the OS */
396 psge += (sizeof(u32) + sizeof(dma_addr_t));
397 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
401 if (numSgeThisFrame == sges_left) {
402 /* Add last element, end of buffer and end of list flags.
404 sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT |
405 MPT_SGE_FLAGS_END_OF_BUFFER |
406 MPT_SGE_FLAGS_END_OF_LIST;
408 /* Add last SGE and set termination flags.
409 * Note: Last SGE may have a length of 0 - which should be ok.
411 thisxfer = sg_dma_len(sg);
413 v2 = sg_dma_address(sg);
414 mptscsih_add_sge(psge, sgflags | thisxfer, v2);
417 psge += (sizeof(u32) + sizeof(dma_addr_t));
419 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
423 /* The current buffer is a chain buffer,
424 * but there is not another one.
425 * Update the chain element
426 * Offset and Length fields.
428 mptscsih_add_chain((char *)chainSge, 0, sgeOffset, ioc->ChainBufferDMA + chain_dma_off);
430 /* The current buffer is the original MF
431 * and there is no Chain buffer.
433 pReq->ChainOffset = 0;
434 RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor) + 1) & 0x03;
435 dsgprintk((MYIOC_s_ERR_FMT
436 "Single Buffer RequestNB=%x, sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
437 ioc->RequestNB[req_idx] = RequestNB;
440 /* At least one chain buffer is needed.
441 * Complete the first MF
442 * - last SGE element, set the LastElement bit
443 * - set ChainOffset (words) for orig MF
444 * (OR finish previous MF chain buffer)
445 * - update MFStructPtr ChainIndex
446 * - Populate chain element
451 dsgprintk((MYIOC_s_INFO_FMT "SG: Chain Required! sg done %d\n",
452 ioc->name, sg_done));
454 /* Set LAST_ELEMENT flag for last non-chain element
455 * in the buffer. Since psge points at the NEXT
456 * SGE element, go back one SGE element, update the flags
457 * and reset the pointer. (Note: sgflags & thisxfer are already
461 u32 *ptmp = (u32 *) (psge - (sizeof(u32) + sizeof(dma_addr_t)));
462 sgflags = le32_to_cpu(*ptmp);
463 sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT;
464 *ptmp = cpu_to_le32(sgflags);
468 /* The current buffer is a chain buffer.
469 * chainSge points to the previous Chain Element.
470 * Update its chain element Offset and Length (must
471 * include chain element size) fields.
472 * Old chain element is now complete.
474 u8 nextChain = (u8) (sgeOffset >> 2);
475 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
476 mptscsih_add_chain((char *)chainSge, nextChain, sgeOffset, ioc->ChainBufferDMA + chain_dma_off);
478 /* The original MF buffer requires a chain buffer -
480 * Last element in this MF is a chain element.
482 pReq->ChainOffset = (u8) (sgeOffset >> 2);
483 RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor) + 1) & 0x03;
484 dsgprintk((MYIOC_s_ERR_FMT "Chain Buffer Needed, RequestNB=%x sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
485 ioc->RequestNB[req_idx] = RequestNB;
488 sges_left -= sg_done;
491 /* NOTE: psge points to the beginning of the chain element
492 * in current buffer. Get a chain buffer.
494 dsgprintk((MYIOC_s_INFO_FMT
495 "calling getFreeChainBuffer SCSI cmd=%02x (%p)\n",
496 ioc->name, pReq->CDB[0], SCpnt));
497 if ((mptscsih_getFreeChainBuffer(ioc, &newIndex)) == FAILED)
500 /* Update the tracking arrays.
501 * If chainSge == NULL, update ReqToChain, else ChainToChain
504 ioc->ChainToChain[chain_idx] = newIndex;
506 ioc->ReqToChain[req_idx] = newIndex;
508 chain_idx = newIndex;
509 chain_dma_off = ioc->req_sz * chain_idx;
511 /* Populate the chainSGE for the current buffer.
512 * - Set chain buffer pointer to psge and fill
513 * out the Address and Flags fields.
515 chainSge = (char *) psge;
516 dsgprintk((KERN_INFO " Current buff @ %p (index 0x%x)",
519 /* Start the SGE for the next buffer
521 psge = (char *) (ioc->ChainBuffer + chain_dma_off);
525 dsgprintk((KERN_INFO " Chain buff @ %p (index 0x%x)\n",
528 /* Start the SGE for the next buffer
535 } /* mptscsih_AddSGE() */
537 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
539 * mptscsih_io_done - Main SCSI IO callback routine registered to
540 * Fusion MPT (base) driver
541 * @ioc: Pointer to MPT_ADAPTER structure
542 * @mf: Pointer to original MPT request frame
543 * @r: Pointer to MPT reply frame (NULL if TurboReply)
545 * This routine is called from mpt.c::mpt_interrupt() at the completion
546 * of any SCSI IO request.
547 * This routine is registered with the Fusion MPT (base) driver at driver
548 * load/init time via the mpt_register() API call.
550 * Returns 1 indicating alloc'd request frame ptr should be freed.
553 mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
555 struct scsi_cmnd *sc;
557 SCSIIORequest_t *pScsiReq;
558 SCSIIOReply_t *pScsiReply;
561 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
563 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
564 sc = hd->ScsiLookup[req_idx];
566 MPIHeader_t *hdr = (MPIHeader_t *)mf;
568 /* Remark: writeSDP1 will use the ScsiDoneCtx
569 * If a SCSI I/O cmd, device disabled by OS and
570 * completion done. Cannot touch sc struct. Just free mem.
572 if (hdr->Function == MPI_FUNCTION_SCSI_IO_REQUEST)
573 printk(MYIOC_s_ERR_FMT "NULL ScsiCmd ptr!\n",
576 mptscsih_freeChainBuffers(ioc, req_idx);
580 dmfprintk((MYIOC_s_INFO_FMT
581 "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n",
582 ioc->name, mf, mr, sc, req_idx));
584 sc->result = DID_OK << 16; /* Set default reply as OK */
585 pScsiReq = (SCSIIORequest_t *) mf;
586 pScsiReply = (SCSIIOReply_t *) mr;
588 if (pScsiReply == NULL) {
589 /* special context reply handling */
594 u8 scsi_state, scsi_status;
596 status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK;
597 scsi_state = pScsiReply->SCSIState;
598 scsi_status = pScsiReply->SCSIStatus;
599 xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
600 sc->resid = sc->request_bufflen - xfer_cnt;
602 dreplyprintk((KERN_NOTICE "Reply ha=%d id=%d lun=%d:\n"
603 "IOCStatus=%04xh SCSIState=%02xh SCSIStatus=%02xh\n"
604 "resid=%d bufflen=%d xfer_cnt=%d\n",
605 ioc->id, pScsiReq->TargetID, pScsiReq->LUN[1],
606 status, scsi_state, scsi_status, sc->resid,
607 sc->request_bufflen, xfer_cnt));
609 if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)
610 mptscsih_copy_sense_data(sc, hd, mf, pScsiReply);
613 * Look for + dump FCP ResponseInfo[]!
615 if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID) {
616 printk(KERN_NOTICE " FCP_ResponseInfo=%08xh\n",
617 le32_to_cpu(pScsiReply->ResponseInfo));
621 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
623 * Maybe: DRIVER_BUSY | SUGGEST_RETRY | DID_SOFT_ERROR (retry)
624 * But not: DID_BUS_BUSY lest one risk
625 * killing interrupt handler:-(
627 sc->result = SAM_STAT_BUSY;
630 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
631 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
632 sc->result = DID_BAD_TARGET << 16;
635 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
636 /* Spoof to SCSI Selection Timeout! */
637 sc->result = DID_NO_CONNECT << 16;
639 if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF)
640 hd->sel_timeout[pScsiReq->TargetID]++;
643 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
644 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
645 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
646 /* Linux handles an unsolicited DID_RESET better
647 * than an unsolicited DID_ABORT.
649 sc->result = DID_RESET << 16;
651 /* GEM Workaround. */
652 if (ioc->bus_type == SCSI)
653 mptscsih_no_negotiate(hd, sc->device->id);
656 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
657 if ( xfer_cnt >= sc->underflow ) {
658 /* Sufficient data transfer occurred */
659 sc->result = (DID_OK << 16) | scsi_status;
660 } else if ( xfer_cnt == 0 ) {
661 /* A CRC Error causes this condition; retry */
662 sc->result = (DRIVER_SENSE << 24) | (DID_OK << 16) |
663 (CHECK_CONDITION << 1);
664 sc->sense_buffer[0] = 0x70;
665 sc->sense_buffer[2] = NO_SENSE;
666 sc->sense_buffer[12] = 0;
667 sc->sense_buffer[13] = 0;
669 sc->result = DID_SOFT_ERROR << 16;
671 dreplyprintk((KERN_NOTICE "RESIDUAL_MISMATCH: result=%x on id=%d\n", sc->result, sc->target));
674 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
676 * Do upfront check for valid SenseData and give it
679 sc->result = (DID_OK << 16) | scsi_status;
680 if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
681 /* Have already saved the status and sense data
685 if (xfer_cnt < sc->underflow) {
686 sc->result = DID_SOFT_ERROR << 16;
688 if (scsi_state & (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)) {
691 sc->result = DID_SOFT_ERROR << 16;
693 else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
694 /* Not real sure here either... */
695 sc->result = DID_RESET << 16;
699 dreplyprintk((KERN_NOTICE " sc->underflow={report ERR if < %02xh bytes xfer'd}\n",
701 dreplyprintk((KERN_NOTICE " ActBytesXferd=%02xh\n", xfer_cnt));
704 if (scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)
705 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
709 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
710 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
711 scsi_status = pScsiReply->SCSIStatus;
712 sc->result = (DID_OK << 16) | scsi_status;
713 if (scsi_state == 0) {
715 } else if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
717 * If running against circa 200003dd 909 MPT f/w,
718 * may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL
719 * (QUEUE_FULL) returned from device! --> get 0x0000?128
720 * and with SenseBytes set to 0.
722 if (pScsiReply->SCSIStatus == MPI_SCSI_STATUS_TASK_SET_FULL)
723 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
726 else if (scsi_state &
727 (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)
732 sc->result = DID_SOFT_ERROR << 16;
734 else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
735 /* Not real sure here either... */
736 sc->result = DID_RESET << 16;
738 else if (scsi_state & MPI_SCSI_STATE_QUEUE_TAG_REJECTED) {
739 /* Device Inq. data indicates that it supports
740 * QTags, but rejects QTag messages.
741 * This command completed OK.
743 * Not real sure here either so do nothing... */
746 if (sc->result == MPI_SCSI_STATUS_TASK_SET_FULL)
747 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
750 * Reservation Conflict, Busy,
751 * Command Terminated, CHECK
755 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
756 sc->result = DID_SOFT_ERROR << 16;
759 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
760 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
761 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
762 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
763 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
764 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
765 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
766 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
767 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
768 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
773 sc->result = DID_SOFT_ERROR << 16;
776 } /* switch(status) */
778 dreplyprintk((KERN_NOTICE " sc->result is %08xh\n", sc->result));
779 } /* end of address reply case */
781 /* Unmap the DMA buffers, if any. */
783 pci_unmap_sg(ioc->pcidev, (struct scatterlist *) sc->request_buffer,
784 sc->use_sg, sc->sc_data_direction);
785 } else if (sc->request_bufflen) {
786 pci_unmap_single(ioc->pcidev, sc->SCp.dma_handle,
787 sc->request_bufflen, sc->sc_data_direction);
790 hd->ScsiLookup[req_idx] = NULL;
792 sc->scsi_done(sc); /* Issue the command callback */
794 /* Free Chain buffers */
795 mptscsih_freeChainBuffers(ioc, req_idx);
801 * mptscsih_flush_running_cmds - For each command found, search
802 * Scsi_Host instance taskQ and reply to OS.
803 * Called only if recovering from a FW reload.
804 * @hd: Pointer to a SCSI HOST structure
808 * Must be called while new I/Os are being queued.
811 mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
813 MPT_ADAPTER *ioc = hd->ioc;
814 struct scsi_cmnd *SCpnt;
817 int max = ioc->req_depth;
819 dprintk((KERN_INFO MYNAM ": flush_ScsiLookup called\n"));
820 for (ii= 0; ii < max; ii++) {
821 if ((SCpnt = hd->ScsiLookup[ii]) != NULL) {
826 /* Null ScsiLookup index
828 hd->ScsiLookup[ii] = NULL;
830 mf = MPT_INDEX_2_MFPTR(ioc, ii);
831 dmfprintk(( "flush: ScsiDone (mf=%p,sc=%p)\n",
834 /* Set status, free OS resources (SG DMA buffers)
836 * Free driver resources (chain, msg buffers)
839 pci_unmap_sg(ioc->pcidev,
840 (struct scatterlist *) SCpnt->request_buffer,
842 SCpnt->sc_data_direction);
843 } else if (SCpnt->request_bufflen) {
844 pci_unmap_single(ioc->pcidev,
845 SCpnt->SCp.dma_handle,
846 SCpnt->request_bufflen,
847 SCpnt->sc_data_direction);
849 SCpnt->result = DID_RESET << 16;
850 SCpnt->host_scribble = NULL;
852 /* Free Chain buffers */
853 mptscsih_freeChainBuffers(ioc, ii);
855 /* Free Message frames */
856 mpt_free_msg_frame(ioc, mf);
858 SCpnt->scsi_done(SCpnt); /* Issue the command callback */
866 * mptscsih_search_running_cmds - Delete any commands associated
867 * with the specified target and lun. Function called only
868 * when a lun is disable by mid-layer.
869 * Do NOT access the referenced scsi_cmnd structure or
870 * members. Will cause either a paging or NULL ptr error.
871 * @hd: Pointer to a SCSI HOST structure
877 * Called from slave_destroy.
880 mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, uint target, uint lun)
882 SCSIIORequest_t *mf = NULL;
884 int max = hd->ioc->req_depth;
886 dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n",
889 for (ii=0; ii < max; ii++) {
890 if (hd->ScsiLookup[ii] != NULL) {
892 mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii);
894 dsprintk(( "search_running: found (sc=%p, mf = %p) target %d, lun %d \n",
895 hd->ScsiLookup[ii], mf, mf->TargetID, mf->LUN[1]));
897 if ((mf->TargetID != ((u8)target)) || (mf->LUN[1] != ((u8) lun)))
902 hd->ScsiLookup[ii] = NULL;
903 mptscsih_freeChainBuffers(hd->ioc, ii);
904 mpt_free_msg_frame(hd->ioc, (MPT_FRAME_HDR *)mf);
911 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
913 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
915 * mptscsih_report_queue_full - Report QUEUE_FULL status returned
916 * from a SCSI target device.
917 * @sc: Pointer to scsi_cmnd structure
918 * @pScsiReply: Pointer to SCSIIOReply_t
919 * @pScsiReq: Pointer to original SCSI request
921 * This routine periodically reports QUEUE_FULL status returned from a
922 * SCSI target device. It reports this to the console via kernel
923 * printk() API call, not more than once every 10 seconds.
926 mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq)
931 if (sc->device == NULL)
933 if (sc->device->host == NULL)
935 if ((hd = (MPT_SCSI_HOST *)sc->device->host->hostdata) == NULL)
938 if (time - hd->last_queue_full > 10 * HZ) {
939 dprintk((MYIOC_s_WARN_FMT "Device (%d:%d:%d) reported QUEUE_FULL!\n",
940 hd->ioc->name, 0, sc->device->id, sc->device->lun));
941 hd->last_queue_full = time;
945 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
947 * mptscsih_remove - Removed scsi devices
948 * @pdev: Pointer to pci_dev structure
953 mptscsih_remove(struct pci_dev *pdev)
955 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
956 struct Scsi_Host *host = ioc->sh;
965 scsi_remove_host(host);
967 if((hd = (MPT_SCSI_HOST *)host->hostdata) == NULL)
970 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
971 /* Check DV thread active */
973 spin_lock_irqsave(&dvtaskQ_lock, flags);
974 if (dvtaskQ_active) {
975 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
976 while(dvtaskQ_active && --count) {
977 set_current_state(TASK_INTERRUPTIBLE);
981 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
984 printk(KERN_ERR MYNAM ": ERROR - DV thread still active!\n");
985 #if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY)
987 printk(KERN_ERR MYNAM ": DV thread orig %d, count %d\n", 10 * HZ, count);
991 mptscsih_shutdown(&pdev->dev);
995 if (hd->ScsiLookup != NULL) {
996 sz1 = hd->ioc->req_depth * sizeof(void *);
997 kfree(hd->ScsiLookup);
998 hd->ScsiLookup = NULL;
1002 * Free pointer array.
1007 dprintk((MYIOC_s_INFO_FMT
1008 "Free'd ScsiLookup (%d) memory\n",
1009 hd->ioc->name, sz1));
1011 kfree(hd->info_kbuf);
1013 /* NULL the Scsi_Host pointer
1017 scsi_host_put(host);
1023 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1025 * mptscsih_shutdown - reboot notifier
1029 mptscsih_shutdown(struct device * dev)
1031 MPT_ADAPTER *ioc = pci_get_drvdata(to_pci_dev(dev));
1032 struct Scsi_Host *host = ioc->sh;
1038 hd = (MPT_SCSI_HOST *)host->hostdata;
1040 /* Flush the cache of this adapter
1043 mptscsih_synchronize_cache(hd, 0);
1048 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1050 * mptscsih_suspend - Fusion MPT scsi driver suspend routine.
1055 mptscsih_suspend(struct pci_dev *pdev, pm_message_t state)
1057 mptscsih_shutdown(&pdev->dev);
1058 return mpt_suspend(pdev,state);
1061 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1063 * mptscsih_resume - Fusion MPT scsi driver resume routine.
1068 mptscsih_resume(struct pci_dev *pdev)
1070 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1071 struct Scsi_Host *host = ioc->sh;
1079 hd = (MPT_SCSI_HOST *)host->hostdata;
1083 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1085 unsigned long lflags;
1086 spin_lock_irqsave(&dvtaskQ_lock, lflags);
1087 if (!dvtaskQ_active) {
1089 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1090 INIT_WORK(&dvTaskQ_task,
1091 mptscsih_domainValidation, (void *) hd);
1092 schedule_work(&dvTaskQ_task);
1094 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1103 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1105 * mptscsih_info - Return information about MPT adapter
1106 * @SChost: Pointer to Scsi_Host structure
1108 * (linux scsi_host_template.info routine)
1110 * Returns pointer to buffer where information was written.
1113 mptscsih_info(struct Scsi_Host *SChost)
1118 h = (MPT_SCSI_HOST *)SChost->hostdata;
1121 if (h->info_kbuf == NULL)
1122 if ((h->info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)
1123 return h->info_kbuf;
1124 h->info_kbuf[0] = '\0';
1126 mpt_print_ioc_summary(h->ioc, h->info_kbuf, &size, 0, 0);
1127 h->info_kbuf[size-1] = '\0';
1130 return h->info_kbuf;
1141 mptscsih_copy_mem_info(struct info_str *info, char *data, int len)
1143 if (info->pos + len > info->length)
1144 len = info->length - info->pos;
1146 if (info->pos + len < info->offset) {
1151 if (info->pos < info->offset) {
1152 data += (info->offset - info->pos);
1153 len -= (info->offset - info->pos);
1157 memcpy(info->buffer + info->pos, data, len);
1163 mptscsih_copy_info(struct info_str *info, char *fmt, ...)
1169 va_start(args, fmt);
1170 len = vsprintf(buf, fmt, args);
1173 mptscsih_copy_mem_info(info, buf, len);
1178 mptscsih_host_info(MPT_ADAPTER *ioc, char *pbuf, off_t offset, int len)
1180 struct info_str info;
1184 info.offset = offset;
1187 mptscsih_copy_info(&info, "%s: %s, ", ioc->name, ioc->prod_name);
1188 mptscsih_copy_info(&info, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING, ioc->facts.FWVersion.Word);
1189 mptscsih_copy_info(&info, "Ports=%d, ", ioc->facts.NumberOfPorts);
1190 mptscsih_copy_info(&info, "MaxQ=%d\n", ioc->req_depth);
1192 return ((info.pos > info.offset) ? info.pos - info.offset : 0);
1195 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1197 * mptscsih_proc_info - Return information about MPT adapter
1199 * (linux scsi_host_template.info routine)
1201 * buffer: if write, user data; if read, buffer for user
1202 * length: if write, return length;
1203 * offset: if write, 0; if read, the current offset into the buffer from
1204 * the previous read.
1205 * hostno: scsi host number
1206 * func: if write = 1; if read = 0
1209 mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
1210 int length, int func)
1212 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
1213 MPT_ADAPTER *ioc = hd->ioc;
1218 * write is not supported
1224 size = mptscsih_host_info(ioc, buffer, offset, length);
1230 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1231 #define ADD_INDEX_LOG(req_ent) do { } while(0)
1233 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1235 * mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine.
1236 * @SCpnt: Pointer to scsi_cmnd structure
1237 * @done: Pointer SCSI mid-layer IO completion function
1239 * (linux scsi_host_template.queuecommand routine)
1240 * This is the primary SCSI IO start routine. Create a MPI SCSIIORequest
1241 * from a linux scsi_cmnd request and send it to the IOC.
1243 * Returns 0. (rtn value discarded by linux scsi mid-layer)
1246 mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1250 SCSIIORequest_t *pScsiReq;
1251 VirtDevice *pTarget;
1261 hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata;
1262 target = SCpnt->device->id;
1263 lun = SCpnt->device->lun;
1264 SCpnt->scsi_done = done;
1266 pTarget = hd->Targets[target];
1268 dmfprintk((MYIOC_s_INFO_FMT "qcmd: SCpnt=%p, done()=%p\n",
1269 (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt, done));
1271 if (hd->resetPending) {
1272 dtmprintk((MYIOC_s_WARN_FMT "qcmd: SCpnt=%p timeout + 60HZ\n",
1273 (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt));
1274 return SCSI_MLQUEUE_HOST_BUSY;
1278 * Put together a MPT SCSI request...
1280 if ((mf = mpt_get_msg_frame(hd->ioc->DoneCtx, hd->ioc)) == NULL) {
1281 dprintk((MYIOC_s_WARN_FMT "QueueCmd, no msg frames!!\n",
1283 return SCSI_MLQUEUE_HOST_BUSY;
1286 pScsiReq = (SCSIIORequest_t *) mf;
1288 my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
1290 ADD_INDEX_LOG(my_idx);
1292 /* TUR's being issued with scsictl=0x02000000 (DATA_IN)!
1293 * Seems we may receive a buffer (datalen>0) even when there
1294 * will be no data transfer! GRRRRR...
1296 if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
1297 datalen = SCpnt->request_bufflen;
1298 scsidir = MPI_SCSIIO_CONTROL_READ; /* DATA IN (host<--ioc<--dev) */
1299 } else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
1300 datalen = SCpnt->request_bufflen;
1301 scsidir = MPI_SCSIIO_CONTROL_WRITE; /* DATA OUT (host-->ioc-->dev) */
1304 scsidir = MPI_SCSIIO_CONTROL_NODATATRANSFER;
1307 /* Default to untagged. Once a target structure has been allocated,
1308 * use the Inquiry data to determine if device supports tagged.
1311 && (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)
1312 && (SCpnt->device->tagged_supported)) {
1313 scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
1315 scsictl = scsidir | MPI_SCSIIO_CONTROL_UNTAGGED;
1318 /* Use the above information to set up the message frame
1320 pScsiReq->TargetID = (u8) target;
1321 pScsiReq->Bus = (u8) SCpnt->device->channel;
1322 pScsiReq->ChainOffset = 0;
1323 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
1324 pScsiReq->CDBLength = SCpnt->cmd_len;
1325 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
1326 pScsiReq->Reserved = 0;
1327 pScsiReq->MsgFlags = mpt_msg_flags();
1328 pScsiReq->LUN[0] = 0;
1329 pScsiReq->LUN[1] = lun;
1330 pScsiReq->LUN[2] = 0;
1331 pScsiReq->LUN[3] = 0;
1332 pScsiReq->LUN[4] = 0;
1333 pScsiReq->LUN[5] = 0;
1334 pScsiReq->LUN[6] = 0;
1335 pScsiReq->LUN[7] = 0;
1336 pScsiReq->Control = cpu_to_le32(scsictl);
1339 * Write SCSI CDB into the message
1341 cmd_len = SCpnt->cmd_len;
1342 for (ii=0; ii < cmd_len; ii++)
1343 pScsiReq->CDB[ii] = SCpnt->cmnd[ii];
1345 for (ii=cmd_len; ii < 16; ii++)
1346 pScsiReq->CDB[ii] = 0;
1349 pScsiReq->DataLength = cpu_to_le32(datalen);
1351 /* SenseBuffer low address */
1352 pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
1353 + (my_idx * MPT_SENSE_BUFFER_ALLOC));
1355 /* Now add the SG list
1356 * Always have a SGE even if null length.
1359 /* Add a NULL SGE */
1360 mptscsih_add_sge((char *)&pScsiReq->SGL, MPT_SGE_FLAGS_SSIMPLE_READ | 0,
1363 /* Add a 32 or 64 bit SGE */
1364 if (mptscsih_AddSGE(hd->ioc, SCpnt, pScsiReq, my_idx) != SUCCESS)
1368 hd->ScsiLookup[my_idx] = SCpnt;
1369 SCpnt->host_scribble = NULL;
1371 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1372 if (hd->ioc->bus_type == SCSI) {
1373 int dvStatus = hd->ioc->spi_data.dvStatus[target];
1376 if (dvStatus || hd->ioc->spi_data.forceDv) {
1378 if ((dvStatus & MPT_SCSICFG_NEED_DV) ||
1379 (hd->ioc->spi_data.forceDv & MPT_SCSICFG_NEED_DV)) {
1380 unsigned long lflags;
1381 /* Schedule DV if necessary */
1382 spin_lock_irqsave(&dvtaskQ_lock, lflags);
1383 if (!dvtaskQ_active) {
1385 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1386 INIT_WORK(&dvTaskQ_task, mptscsih_domainValidation, (void *) hd);
1388 schedule_work(&dvTaskQ_task);
1390 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1392 hd->ioc->spi_data.forceDv &= ~MPT_SCSICFG_NEED_DV;
1395 /* Trying to do DV to this target, extend timeout.
1396 * Wait to issue until flag is clear
1398 if (dvStatus & MPT_SCSICFG_DV_PENDING) {
1399 mod_timer(&SCpnt->eh_timeout, jiffies + 40 * HZ);
1403 /* Set the DV flags.
1405 if (dvStatus & MPT_SCSICFG_DV_NOT_DONE)
1406 mptscsih_set_dvflags(hd, pScsiReq);
1414 mpt_put_msg_frame(hd->ioc->DoneCtx, hd->ioc, mf);
1415 dmfprintk((MYIOC_s_INFO_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n",
1416 hd->ioc->name, SCpnt, mf, my_idx));
1417 DBG_DUMP_REQUEST_FRAME(mf)
1421 mptscsih_freeChainBuffers(hd->ioc, my_idx);
1422 mpt_free_msg_frame(hd->ioc, mf);
1423 return SCSI_MLQUEUE_HOST_BUSY;
1426 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1428 * mptscsih_freeChainBuffers - Function to free chain buffers associated
1429 * with a SCSI IO request
1430 * @hd: Pointer to the MPT_SCSI_HOST instance
1431 * @req_idx: Index of the SCSI IO request frame.
1433 * Called if SG chain buffer allocation fails and mptscsih callbacks.
1437 mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
1439 MPT_FRAME_HDR *chain;
1440 unsigned long flags;
1444 /* Get the first chain index and reset
1447 chain_idx = ioc->ReqToChain[req_idx];
1448 ioc->ReqToChain[req_idx] = MPT_HOST_NO_CHAIN;
1450 while (chain_idx != MPT_HOST_NO_CHAIN) {
1452 /* Save the next chain buffer index */
1453 next = ioc->ChainToChain[chain_idx];
1455 /* Free this chain buffer and reset
1458 ioc->ChainToChain[chain_idx] = MPT_HOST_NO_CHAIN;
1460 chain = (MPT_FRAME_HDR *) (ioc->ChainBuffer
1461 + (chain_idx * ioc->req_sz));
1463 spin_lock_irqsave(&ioc->FreeQlock, flags);
1464 list_add_tail(&chain->u.frame.linkage.list, &ioc->FreeChainQ);
1465 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1467 dmfprintk((MYIOC_s_INFO_FMT "FreeChainBuffers (index %d)\n",
1468 ioc->name, chain_idx));
1476 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1481 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1483 * mptscsih_TMHandler - Generic handler for SCSI Task Management.
1484 * Fall through to mpt_HardResetHandler if: not operational, too many
1485 * failed TM requests or handshake failure.
1487 * @ioc: Pointer to MPT_ADAPTER structure
1488 * @type: Task Management type
1489 * @target: Logical Target ID for reset (if appropriate)
1490 * @lun: Logical Unit for reset (if appropriate)
1491 * @ctx2abort: Context for the task to be aborted (if appropriate)
1493 * Remark: Currently invoked from a non-interrupt thread (_bh).
1495 * Remark: With old EH code, at most 1 SCSI TaskMgmt function per IOC
1498 * Returns 0 for SUCCESS or -1 if FAILED.
1501 mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout)
1507 unsigned long flags;
1509 /* If FW is being reloaded currently, return success to
1510 * the calling function.
1517 printk(KERN_ERR MYNAM " TMHandler" " NULL ioc!\n");
1520 dtmprintk((MYIOC_s_INFO_FMT "TMHandler Entered!\n", ioc->name));
1522 // SJR - CHECKME - Can we avoid this here?
1523 // (mpt_HardResetHandler has this check...)
1524 spin_lock_irqsave(&ioc->diagLock, flags);
1525 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)) {
1526 spin_unlock_irqrestore(&ioc->diagLock, flags);
1529 spin_unlock_irqrestore(&ioc->diagLock, flags);
1531 /* Wait a fixed amount of time for the TM pending flag to be cleared.
1532 * If we time out and not bus reset, then we return a FAILED status to the caller.
1533 * The call to mptscsih_tm_pending_wait() will set the pending flag if we are
1534 * successful. Otherwise, reload the FW.
1536 if (mptscsih_tm_pending_wait(hd) == FAILED) {
1537 if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
1538 dtmprintk((KERN_WARNING MYNAM ": %s: TMHandler abort: "
1539 "Timed out waiting for last TM (%d) to complete! \n",
1540 hd->ioc->name, hd->tmPending));
1542 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) {
1543 dtmprintk((KERN_WARNING MYNAM ": %s: TMHandler target reset: "
1544 "Timed out waiting for last TM (%d) to complete! \n",
1545 hd->ioc->name, hd->tmPending));
1547 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
1548 dtmprintk((KERN_WARNING MYNAM ": %s: TMHandler bus reset: "
1549 "Timed out waiting for last TM (%d) to complete! \n",
1550 hd->ioc->name, hd->tmPending));
1551 if (hd->tmPending & (1 << MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS))
1557 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
1558 hd->tmPending |= (1 << type);
1559 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1564 ioc_raw_state = mpt_GetIocState(hd->ioc, 0);
1566 #ifdef MPT_DEBUG_RESET
1567 if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) {
1568 printk(MYIOC_s_WARN_FMT
1569 "TM Handler: IOC Not operational(0x%x)!\n",
1570 hd->ioc->name, ioc_raw_state);
1574 if (doTask && ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL)
1575 && !(ioc_raw_state & MPI_DOORBELL_ACTIVE)) {
1577 /* Isse the Task Mgmt request.
1579 if (hd->hard_resets < -1)
1581 rc = mptscsih_IssueTaskMgmt(hd, type, channel, target, lun, ctx2abort, timeout);
1583 printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n", hd->ioc->name);
1585 dtmprintk((MYIOC_s_INFO_FMT "Issue of TaskMgmt Successful!\n", hd->ioc->name));
1589 /* Only fall through to the HRH if this is a bus reset
1591 if ((type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) && (rc ||
1592 ioc->reload_fw || (ioc->alt_ioc && ioc->alt_ioc->reload_fw))) {
1593 dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
1595 rc = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
1598 dtmprintk((MYIOC_s_INFO_FMT "TMHandler rc = %d!\n", hd->ioc->name, rc));
1604 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1606 * mptscsih_IssueTaskMgmt - Generic send Task Management function.
1607 * @hd: Pointer to MPT_SCSI_HOST structure
1608 * @type: Task Management type
1609 * @target: Logical Target ID for reset (if appropriate)
1610 * @lun: Logical Unit for reset (if appropriate)
1611 * @ctx2abort: Context for the task to be aborted (if appropriate)
1613 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
1614 * or a non-interrupt thread. In the former, must not call schedule().
1616 * Not all fields are meaningfull for all task types.
1618 * Returns 0 for SUCCESS, -999 for "no msg frames",
1619 * else other non-zero value returned.
1622 mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout)
1625 SCSITaskMgmt_t *pScsiTm;
1629 /* Return Fail to calling function if no message frames available.
1631 if ((mf = mpt_get_msg_frame(hd->ioc->TaskCtx, hd->ioc)) == NULL) {
1632 dfailprintk((MYIOC_s_ERR_FMT "IssueTaskMgmt, no msg frames!!\n",
1637 dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt request @ %p\n",
1638 hd->ioc->name, mf));
1640 /* Format the Request
1642 pScsiTm = (SCSITaskMgmt_t *) mf;
1643 pScsiTm->TargetID = target;
1644 pScsiTm->Bus = channel;
1645 pScsiTm->ChainOffset = 0;
1646 pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
1648 pScsiTm->Reserved = 0;
1649 pScsiTm->TaskType = type;
1650 pScsiTm->Reserved1 = 0;
1651 pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)
1652 ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0;
1654 for (ii= 0; ii < 8; ii++) {
1655 pScsiTm->LUN[ii] = 0;
1657 pScsiTm->LUN[1] = lun;
1659 for (ii=0; ii < 7; ii++)
1660 pScsiTm->Reserved2[ii] = 0;
1662 pScsiTm->TaskMsgContext = ctx2abort;
1664 dtmprintk((MYIOC_s_INFO_FMT
1665 "IssueTaskMgmt: ctx2abort (0x%08x) type=%d\n",
1666 hd->ioc->name, ctx2abort, type));
1668 DBG_DUMP_TM_REQUEST_FRAME((u32 *)pScsiTm);
1670 if ((retval = mpt_send_handshake_request(hd->ioc->TaskCtx, hd->ioc,
1671 sizeof(SCSITaskMgmt_t), (u32*)pScsiTm,
1673 dfailprintk((MYIOC_s_ERR_FMT "_send_handshake FAILED!"
1674 " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
1676 mpt_free_msg_frame(hd->ioc, mf);
1680 if(mptscsih_tm_wait_for_completion(hd, timeout) == FAILED) {
1681 dfailprintk((MYIOC_s_ERR_FMT "_wait_for_completion FAILED!"
1682 " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
1684 mpt_free_msg_frame(hd->ioc, mf);
1685 dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
1687 retval = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
1693 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1695 * mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant
1696 * @SCpnt: Pointer to scsi_cmnd structure, IO to be aborted
1698 * (linux scsi_host_template.eh_abort_handler routine)
1700 * Returns SUCCESS or FAILED.
1703 mptscsih_abort(struct scsi_cmnd * SCpnt)
1710 spinlock_t *host_lock = SCpnt->device->host->host_lock;
1712 /* If we can't locate our host adapter structure, return FAILED status.
1714 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL) {
1715 SCpnt->result = DID_RESET << 16;
1716 SCpnt->scsi_done(SCpnt);
1717 dfailprintk((KERN_WARNING MYNAM ": mptscsih_abort: "
1718 "Can't locate host! (sc=%p)\n",
1724 if (hd->resetPending)
1727 printk(KERN_WARNING MYNAM ": %s: >> Attempting task abort! (sc=%p)\n",
1728 hd->ioc->name, SCpnt);
1730 if (hd->timeouts < -1)
1733 /* Find this command
1735 if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) {
1736 /* Cmd not found in ScsiLookup.
1739 SCpnt->result = DID_RESET << 16;
1740 dtmprintk((KERN_WARNING MYNAM ": %s: mptscsih_abort: "
1741 "Command not in the active list! (sc=%p)\n",
1742 hd->ioc->name, SCpnt));
1746 /* Most important! Set TaskMsgContext to SCpnt's MsgContext!
1747 * (the IO to be ABORT'd)
1749 * NOTE: Since we do not byteswap MsgContext, we do not
1750 * swap it here either. It is an opaque cookie to
1751 * the controller, so it does not matter. -DaveM
1753 mf = MPT_INDEX_2_MFPTR(hd->ioc, scpnt_idx);
1754 ctx2abort = mf->u.frame.hwhdr.msgctxu.MsgContext;
1756 hd->abortSCpnt = SCpnt;
1758 spin_unlock_irq(host_lock);
1759 if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
1760 SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun,
1761 ctx2abort, 2 /* 2 second timeout */)
1764 /* The TM request failed and the subsequent FW-reload failed!
1767 printk(MYIOC_s_WARN_FMT "Error issuing abort task! (sc=%p)\n",
1768 hd->ioc->name, SCpnt);
1770 /* We must clear our pending flag before clearing our state.
1773 hd->tmState = TM_STATE_NONE;
1775 spin_lock_irq(host_lock);
1777 /* Unmap the DMA buffers, if any. */
1778 if (SCpnt->use_sg) {
1779 pci_unmap_sg(ioc->pcidev, (struct scatterlist *) SCpnt->request_buffer,
1780 SCpnt->use_sg, SCpnt->sc_data_direction);
1781 } else if (SCpnt->request_bufflen) {
1782 pci_unmap_single(ioc->pcidev, SCpnt->SCp.dma_handle,
1783 SCpnt->request_bufflen, SCpnt->sc_data_direction);
1785 hd->ScsiLookup[scpnt_idx] = NULL;
1786 SCpnt->result = DID_RESET << 16;
1787 SCpnt->scsi_done(SCpnt); /* Issue the command callback */
1788 mptscsih_freeChainBuffers(ioc, scpnt_idx);
1789 mpt_free_msg_frame(ioc, mf);
1792 spin_lock_irq(host_lock);
1796 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1798 * mptscsih_dev_reset - Perform a SCSI TARGET_RESET! new_eh variant
1799 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1801 * (linux scsi_host_template.eh_dev_reset_handler routine)
1803 * Returns SUCCESS or FAILED.
1806 mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
1809 spinlock_t *host_lock = SCpnt->device->host->host_lock;
1811 /* If we can't locate our host adapter structure, return FAILED status.
1813 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1814 dtmprintk((KERN_WARNING MYNAM ": mptscsih_dev_reset: "
1815 "Can't locate host! (sc=%p)\n",
1820 if (hd->resetPending)
1823 printk(KERN_WARNING MYNAM ": %s: >> Attempting target reset! (sc=%p)\n",
1824 hd->ioc->name, SCpnt);
1826 spin_unlock_irq(host_lock);
1827 if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
1828 SCpnt->device->channel, SCpnt->device->id,
1829 0, 0, 5 /* 5 second timeout */)
1831 /* The TM request failed and the subsequent FW-reload failed!
1834 printk(MYIOC_s_WARN_FMT "Error processing TaskMgmt request (sc=%p)\n",
1835 hd->ioc->name, SCpnt);
1837 hd->tmState = TM_STATE_NONE;
1838 spin_lock_irq(host_lock);
1841 spin_lock_irq(host_lock);
1846 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1848 * mptscsih_bus_reset - Perform a SCSI BUS_RESET! new_eh variant
1849 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1851 * (linux scsi_host_template.eh_bus_reset_handler routine)
1853 * Returns SUCCESS or FAILED.
1856 mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
1859 spinlock_t *host_lock = SCpnt->device->host->host_lock;
1861 /* If we can't locate our host adapter structure, return FAILED status.
1863 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1864 dtmprintk((KERN_WARNING MYNAM ": mptscsih_bus_reset: "
1865 "Can't locate host! (sc=%p)\n",
1870 printk(KERN_WARNING MYNAM ": %s: >> Attempting bus reset! (sc=%p)\n",
1871 hd->ioc->name, SCpnt);
1873 if (hd->timeouts < -1)
1876 /* We are now ready to execute the task management request. */
1877 spin_unlock_irq(host_lock);
1878 if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
1879 SCpnt->device->channel, 0, 0, 0, 5 /* 5 second timeout */)
1882 /* The TM request failed and the subsequent FW-reload failed!
1885 printk(MYIOC_s_WARN_FMT
1886 "Error processing TaskMgmt request (sc=%p)\n",
1887 hd->ioc->name, SCpnt);
1889 hd->tmState = TM_STATE_NONE;
1890 spin_lock_irq(host_lock);
1893 spin_lock_irq(host_lock);
1897 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1899 * mptscsih_host_reset - Perform a SCSI host adapter RESET!
1901 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1903 * (linux scsi_host_template.eh_host_reset_handler routine)
1905 * Returns SUCCESS or FAILED.
1908 mptscsih_host_reset(struct scsi_cmnd *SCpnt)
1911 int status = SUCCESS;
1912 spinlock_t *host_lock = SCpnt->device->host->host_lock;
1914 /* If we can't locate the host to reset, then we failed. */
1915 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1916 dtmprintk( ( KERN_WARNING MYNAM ": mptscsih_host_reset: "
1917 "Can't locate host! (sc=%p)\n",
1922 printk(KERN_WARNING MYNAM ": %s: >> Attempting host reset! (sc=%p)\n",
1923 hd->ioc->name, SCpnt);
1925 /* If our attempts to reset the host failed, then return a failed
1926 * status. The host will be taken off line by the SCSI mid-layer.
1928 spin_unlock_irq(host_lock);
1929 if (mpt_HardResetHandler(hd->ioc, CAN_SLEEP) < 0){
1932 /* Make sure TM pending is cleared and TM state is set to
1936 hd->tmState = TM_STATE_NONE;
1938 spin_lock_irq(host_lock);
1941 dtmprintk( ( KERN_WARNING MYNAM ": mptscsih_host_reset: "
1943 (status == SUCCESS) ? "SUCCESS" : "FAILED" ) );
1948 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1950 * mptscsih_tm_pending_wait - wait for pending task management request to
1952 * @hd: Pointer to MPT host structure.
1954 * Returns {SUCCESS,FAILED}.
1957 mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd)
1959 unsigned long flags;
1960 int loop_count = 4 * 10; /* Wait 10 seconds */
1961 int status = FAILED;
1964 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
1965 if (hd->tmState == TM_STATE_NONE) {
1966 hd->tmState = TM_STATE_IN_PROGRESS;
1969 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1972 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1974 } while (--loop_count);
1979 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1981 * mptscsih_tm_wait_for_completion - wait for completion of TM task
1982 * @hd: Pointer to MPT host structure.
1984 * Returns {SUCCESS,FAILED}.
1987 mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout )
1989 unsigned long flags;
1990 int loop_count = 4 * timeout;
1991 int status = FAILED;
1994 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
1995 if(hd->tmPending == 0) {
1997 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2000 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2001 msleep_interruptible(250);
2002 } while (--loop_count);
2007 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2009 * mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
2010 * @ioc: Pointer to MPT_ADAPTER structure
2011 * @mf: Pointer to SCSI task mgmt request frame
2012 * @mr: Pointer to SCSI task mgmt reply frame
2014 * This routine is called from mptbase.c::mpt_interrupt() at the completion
2015 * of any SCSI task management request.
2016 * This routine is registered with the MPT (base) driver at driver
2017 * load/init time via the mpt_register() API call.
2019 * Returns 1 indicating alloc'd request frame ptr should be freed.
2022 mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
2024 SCSITaskMgmtReply_t *pScsiTmReply;
2025 SCSITaskMgmt_t *pScsiTmReq;
2027 unsigned long flags;
2031 dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt completed (mf=%p,mr=%p)\n",
2032 ioc->name, mf, mr));
2034 /* Depending on the thread, a timer is activated for
2035 * the TM request. Delete this timer on completion of TM.
2036 * Decrement count of outstanding TM requests.
2038 hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
2040 dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt Complete: NULL Scsi Host Ptr\n",
2046 dtmprintk((MYIOC_s_WARN_FMT "ERROR! TaskMgmt Reply: NULL Request %p\n",
2050 pScsiTmReply = (SCSITaskMgmtReply_t*)mr;
2051 pScsiTmReq = (SCSITaskMgmt_t*)mf;
2053 /* Figure out if this was ABORT_TASK, TARGET_RESET, or BUS_RESET! */
2054 tmType = pScsiTmReq->TaskType;
2056 dtmprintk((MYIOC_s_WARN_FMT " TaskType = %d, TerminationCount=%d\n",
2057 ioc->name, tmType, le32_to_cpu(pScsiTmReply->TerminationCount)));
2058 DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply);
2060 iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2061 dtmprintk((MYIOC_s_WARN_FMT " SCSI TaskMgmt (%d) IOCStatus=%04x IOCLogInfo=%08x\n",
2062 ioc->name, tmType, iocstatus, le32_to_cpu(pScsiTmReply->IOCLogInfo)));
2063 /* Error? (anything non-zero?) */
2066 /* clear flags and continue.
2068 if (tmType == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK)
2069 hd->abortSCpnt = NULL;
2071 /* If an internal command is present
2072 * or the TM failed - reload the FW.
2073 * FC FW may respond FAILED to an ABORT
2075 if (tmType == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
2077 (iocstatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED)) {
2078 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0) {
2079 printk((KERN_WARNING
2080 " Firmware Reload FAILED!!\n"));
2085 dtmprintk((MYIOC_s_WARN_FMT " TaskMgmt SUCCESS\n", ioc->name));
2087 hd->abortSCpnt = NULL;
2092 spin_lock_irqsave(&ioc->FreeQlock, flags);
2094 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2095 hd->tmState = TM_STATE_NONE;
2100 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2102 * This is anyones guess quite frankly.
2105 mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
2106 sector_t capacity, int geom[])
2116 dummy = heads * sectors;
2117 cylinders = capacity;
2118 sector_div(cylinders,dummy);
2121 * Handle extended translation size for logical drives
2124 if ((ulong)capacity >= 0x200000) {
2127 dummy = heads * sectors;
2128 cylinders = capacity;
2129 sector_div(cylinders,dummy);
2135 geom[2] = cylinders;
2137 dprintk((KERN_NOTICE
2138 ": bios_param: Id=%i Lun=%i Channel=%i CHS=%i/%i/%i\n",
2139 sdev->id, sdev->lun,sdev->channel,(int)cylinders,heads,sectors));
2144 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2146 * OS entry point to allow host driver to alloc memory
2147 * for each scsi device. Called once per device the bus scan.
2148 * Return non-zero if allocation fails.
2149 * Init memory once per id (not LUN).
2152 mptscsih_slave_alloc(struct scsi_device *device)
2154 struct Scsi_Host *host = device->host;
2155 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
2157 uint target = device->id;
2162 if ((vdev = hd->Targets[target]) != NULL)
2165 vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL);
2167 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
2168 hd->ioc->name, sizeof(VirtDevice));
2172 memset(vdev, 0, sizeof(VirtDevice));
2173 vdev->tflags = MPT_TARGET_FLAGS_Q_YES;
2174 vdev->ioc_id = hd->ioc->id;
2175 vdev->target_id = device->id;
2176 vdev->bus_id = device->channel;
2177 vdev->raidVolume = 0;
2178 hd->Targets[device->id] = vdev;
2179 if (hd->ioc->bus_type == SCSI) {
2180 if (hd->ioc->spi_data.isRaid & (1 << device->id)) {
2181 vdev->raidVolume = 1;
2182 ddvtprintk((KERN_INFO
2183 "RAID Volume @ id %d\n", device->id));
2186 vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
2195 mptscsih_is_raid_volume(MPT_SCSI_HOST *hd, uint id)
2199 if (!hd->ioc->spi_data.isRaid || !hd->ioc->spi_data.pIocPg3)
2202 for (i = 0; i < hd->ioc->spi_data.pIocPg3->NumPhysDisks; i++) {
2203 if (id == hd->ioc->spi_data.pIocPg3->PhysDisk[i].PhysDiskID)
2211 * OS entry point to allow for host driver to free allocated memory
2212 * Called if no device present or device being unloaded
2215 mptscsih_slave_destroy(struct scsi_device *device)
2217 struct Scsi_Host *host = device->host;
2218 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
2220 uint target = device->id;
2221 uint lun = device->lun;
2226 mptscsih_search_running_cmds(hd, target, lun);
2228 vdev = hd->Targets[target];
2229 vdev->luns[0] &= ~(1 << lun);
2230 if (--vdev->num_luns)
2233 kfree(hd->Targets[target]);
2234 hd->Targets[target] = NULL;
2236 if (hd->ioc->bus_type == SCSI) {
2237 if (mptscsih_is_raid_volume(hd, target)) {
2238 hd->ioc->spi_data.forceDv |= MPT_SCSICFG_RELOAD_IOC_PG3;
2240 hd->ioc->spi_data.dvStatus[target] =
2241 MPT_SCSICFG_NEGOTIATE;
2243 if (!hd->negoNvram) {
2244 hd->ioc->spi_data.dvStatus[target] |=
2245 MPT_SCSICFG_DV_NOT_DONE;
2252 mptscsih_set_queue_depth(struct scsi_device *device, MPT_SCSI_HOST *hd,
2253 VirtDevice *pTarget, int qdepth)
2258 if (hd->ioc->bus_type == SCSI) {
2259 if (pTarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) {
2260 if (!(pTarget->tflags & MPT_TARGET_FLAGS_Q_YES))
2262 else if (((pTarget->inq_data[0] & 0x1f) == 0x00) &&
2263 (pTarget->minSyncFactor <= MPT_ULTRA160 ))
2264 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2266 max_depth = MPT_SCSI_CMD_PER_DEV_LOW;
2268 /* error case - No Inq. Data */
2272 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2274 if (qdepth > max_depth)
2279 tagged = MSG_SIMPLE_TAG;
2281 scsi_adjust_queue_depth(device, tagged, qdepth);
2286 * OS entry point to adjust the queue_depths on a per-device basis.
2287 * Called once per device the bus scan. Use it to force the queue_depth
2288 * member to 1 if a device does not support Q tags.
2289 * Return non-zero if fails.
2292 mptscsih_slave_configure(struct scsi_device *device)
2294 struct Scsi_Host *sh = device->host;
2295 VirtDevice *pTarget;
2296 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sh->hostdata;
2298 if ((hd == NULL) || (hd->Targets == NULL)) {
2302 dsprintk((MYIOC_s_INFO_FMT
2303 "device @ %p, id=%d, LUN=%d, channel=%d\n",
2304 hd->ioc->name, device, device->id, device->lun, device->channel));
2305 dsprintk((MYIOC_s_INFO_FMT
2306 "sdtr %d wdtr %d ppr %d inq length=%d\n",
2307 hd->ioc->name, device->sdtr, device->wdtr,
2308 device->ppr, device->inquiry_len));
2310 if (device->id > sh->max_id) {
2311 /* error case, should never happen */
2312 scsi_adjust_queue_depth(device, 0, 1);
2313 goto slave_configure_exit;
2316 pTarget = hd->Targets[device->id];
2318 if (pTarget == NULL) {
2319 /* Driver doesn't know about this device.
2320 * Kernel may generate a "Dummy Lun 0" which
2321 * may become a real Lun if a
2322 * "scsi add-single-device" command is executed
2323 * while the driver is active (hot-plug a
2324 * device). LSI Raid controllers need
2325 * queue_depth set to DEV_HIGH for this reason.
2327 scsi_adjust_queue_depth(device, MSG_SIMPLE_TAG,
2328 MPT_SCSI_CMD_PER_DEV_HIGH);
2329 goto slave_configure_exit;
2332 mptscsih_initTarget(hd, device->channel, device->id, device->lun,
2333 device->inquiry, device->inquiry_len );
2334 mptscsih_set_queue_depth(device, hd, pTarget, MPT_SCSI_CMD_PER_DEV_HIGH);
2336 dsprintk((MYIOC_s_INFO_FMT
2337 "Queue depth=%d, tflags=%x\n",
2338 hd->ioc->name, device->queue_depth, pTarget->tflags));
2340 dsprintk((MYIOC_s_INFO_FMT
2341 "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
2342 hd->ioc->name, pTarget->negoFlags, pTarget->maxOffset, pTarget->minSyncFactor));
2344 slave_configure_exit:
2346 dsprintk((MYIOC_s_INFO_FMT
2347 "tagged %d, simple %d, ordered %d\n",
2348 hd->ioc->name,device->tagged_supported, device->simple_tags,
2349 device->ordered_tags));
2355 mptscsih_store_queue_depth(struct device *dev, const char *buf, size_t count)
2358 struct scsi_device *sdev = to_scsi_device(dev);
2359 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) sdev->host->hostdata;
2360 VirtDevice *pTarget;
2362 depth = simple_strtoul(buf, NULL, 0);
2365 pTarget = hd->Targets[sdev->id];
2366 if (pTarget == NULL)
2368 mptscsih_set_queue_depth(sdev, (MPT_SCSI_HOST *) sdev->host->hostdata,
2373 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2375 * Private routines...
2378 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2379 /* Utility function to copy sense data from the scsi_cmnd buffer
2380 * to the FC and SCSI target structures.
2384 mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
2387 SCSIIORequest_t *pReq;
2388 u32 sense_count = le32_to_cpu(pScsiReply->SenseCount);
2391 /* Get target structure
2393 pReq = (SCSIIORequest_t *) mf;
2394 index = (int) pReq->TargetID;
2395 target = hd->Targets[index];
2401 /* Copy the sense received into the scsi command block. */
2402 req_index = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2403 sense_data = ((u8 *)hd->ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC));
2404 memcpy(sc->sense_buffer, sense_data, SNS_LEN(sc));
2406 /* Log SMART data (asc = 0x5D, non-IM case only) if required.
2408 if ((hd->ioc->events) && (hd->ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) {
2409 if ((sense_data[12] == 0x5D) && (target->raidVolume == 0)) {
2411 MPT_ADAPTER *ioc = hd->ioc;
2413 idx = ioc->eventContext % ioc->eventLogSize;
2414 ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
2415 ioc->events[idx].eventContext = ioc->eventContext;
2417 ioc->events[idx].data[0] = (pReq->LUN[1] << 24) ||
2418 (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) ||
2419 (pReq->Bus << 8) || pReq->TargetID;
2421 ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12];
2423 ioc->eventContext++;
2427 dprintk((MYIOC_s_INFO_FMT "Hmmm... SenseData len=0! (?)\n",
2433 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc)
2438 hd = (MPT_SCSI_HOST *) sc->device->host->hostdata;
2440 for (i = 0; i < hd->ioc->req_depth; i++) {
2441 if (hd->ScsiLookup[i] == sc) {
2449 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2451 mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2454 unsigned long flags;
2456 dtmprintk((KERN_WARNING MYNAM
2457 ": IOC %s_reset routed to SCSI host driver!\n",
2458 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
2459 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
2461 /* If a FW reload request arrives after base installed but
2462 * before all scsi hosts have been attached, then an alt_ioc
2463 * may have a NULL sh pointer.
2465 if ((ioc->sh == NULL) || (ioc->sh->hostdata == NULL))
2468 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2470 if (reset_phase == MPT_IOC_SETUP_RESET) {
2471 dtmprintk((MYIOC_s_WARN_FMT "Setup-Diag Reset\n", ioc->name));
2474 * 1. Set Hard Reset Pending Flag
2475 * All new commands go to doneQ
2477 hd->resetPending = 1;
2479 } else if (reset_phase == MPT_IOC_PRE_RESET) {
2480 dtmprintk((MYIOC_s_WARN_FMT "Pre-Diag Reset\n", ioc->name));
2482 /* 2. Flush running commands
2483 * Clean ScsiLookup (and associated memory)
2487 /* 2b. Reply to OS all known outstanding I/O commands.
2489 mptscsih_flush_running_cmds(hd);
2491 /* 2c. If there was an internal command that
2492 * has not completed, configuration or io request,
2493 * free these resources.
2496 del_timer(&hd->timer);
2497 mpt_free_msg_frame(ioc, hd->cmdPtr);
2500 dtmprintk((MYIOC_s_WARN_FMT "Pre-Reset complete.\n", ioc->name));
2503 dtmprintk((MYIOC_s_WARN_FMT "Post-Diag Reset\n", ioc->name));
2505 /* Once a FW reload begins, all new OS commands are
2506 * redirected to the doneQ w/ a reset status.
2507 * Init all control structures.
2510 /* ScsiLookup initialization
2514 for (ii=0; ii < hd->ioc->req_depth; ii++)
2515 hd->ScsiLookup[ii] = NULL;
2518 /* 2. Chain Buffer initialization
2521 /* 4. Renegotiate to all devices, if SCSI
2523 if (ioc->bus_type == SCSI) {
2524 dnegoprintk(("writeSDP1: ALL_IDS USE_NVRAM\n"));
2525 mptscsih_writeSDP1(hd, 0, 0, MPT_SCSICFG_ALL_IDS | MPT_SCSICFG_USE_NVRAM);
2528 /* 5. Enable new commands to be posted
2530 spin_lock_irqsave(&ioc->FreeQlock, flags);
2532 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2533 hd->resetPending = 0;
2534 hd->tmState = TM_STATE_NONE;
2536 /* 6. If there was an internal command,
2537 * wake this process up.
2541 * Wake up the original calling thread
2543 hd->pLocal = &hd->localReply;
2544 hd->pLocal->completion = MPT_SCANDV_DID_RESET;
2545 hd->scandv_wait_done = 1;
2546 wake_up(&hd->scandv_waitq);
2550 /* 7. Set flag to force DV and re-read IOC Page 3
2552 if (ioc->bus_type == SCSI) {
2553 ioc->spi_data.forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
2554 ddvtprintk(("Set reload IOC Pg3 Flag\n"));
2557 dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name));
2561 return 1; /* currently means nothing really */
2564 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2566 mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2569 u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
2571 devtprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
2575 case MPI_EVENT_UNIT_ATTENTION: /* 03 */
2578 case MPI_EVENT_IOC_BUS_RESET: /* 04 */
2579 case MPI_EVENT_EXT_BUS_RESET: /* 05 */
2582 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2583 if (hd && (ioc->bus_type == SCSI) && (hd->soft_resets < -1))
2587 case MPI_EVENT_LOGOUT: /* 09 */
2592 * CHECKME! Don't think we need to do
2593 * anything for these, but...
2595 case MPI_EVENT_RESCAN: /* 06 */
2596 case MPI_EVENT_LINK_STATUS_CHANGE: /* 07 */
2597 case MPI_EVENT_LOOP_STATE_CHANGE: /* 08 */
2599 * CHECKME! Falling thru...
2603 case MPI_EVENT_INTEGRATED_RAID: /* 0B */
2604 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
2605 /* negoNvram set to 0 if DV enabled and to USE_NVRAM if
2606 * if DV disabled. Need to check for target mode.
2610 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2612 if (hd && (ioc->bus_type == SCSI) && (hd->negoNvram == 0)) {
2614 Ioc3PhysDisk_t *pPDisk;
2619 reason = (le32_to_cpu(pEvReply->Data[0]) & 0x00FF0000) >> 16;
2620 if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
2621 /* New or replaced disk.
2622 * Set DV flag and schedule DV.
2624 pSpi = &ioc->spi_data;
2625 physDiskNum = (le32_to_cpu(pEvReply->Data[0]) & 0xFF000000) >> 24;
2626 ddvtprintk(("DV requested for phys disk id %d\n", physDiskNum));
2627 if (pSpi->pIocPg3) {
2628 pPDisk = pSpi->pIocPg3->PhysDisk;
2629 numPDisk =pSpi->pIocPg3->NumPhysDisks;
2632 if (physDiskNum == pPDisk->PhysDiskNum) {
2633 pSpi->dvStatus[pPDisk->PhysDiskID] = (MPT_SCSICFG_NEED_DV | MPT_SCSICFG_DV_NOT_DONE);
2634 pSpi->forceDv = MPT_SCSICFG_NEED_DV;
2635 ddvtprintk(("NEED_DV set for phys disk id %d\n", pPDisk->PhysDiskID));
2642 if (numPDisk == 0) {
2643 /* The physical disk that needs DV was not found
2644 * in the stored IOC Page 3. The driver must reload
2645 * this page. DV routine will set the NEED_DV flag for
2646 * all phys disks that have DV_NOT_DONE set.
2648 pSpi->forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
2649 ddvtprintk(("phys disk %d not found. Setting reload IOC Pg3 Flag\n", physDiskNum));
2656 #if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY)
2657 printk("Raid Event RF: ");
2659 u32 *m = (u32 *)pEvReply;
2661 int n = (int)pEvReply->MsgLength;
2662 for (ii=6; ii < n; ii++)
2663 printk(" %08x", le32_to_cpu(m[ii]));
2669 case MPI_EVENT_NONE: /* 00 */
2670 case MPI_EVENT_LOG_DATA: /* 01 */
2671 case MPI_EVENT_STATE_CHANGE: /* 02 */
2672 case MPI_EVENT_EVENT_CHANGE: /* 0A */
2674 dprintk((KERN_INFO " Ignoring event (=%02Xh)\n", event));
2678 return 1; /* currently means nothing really */
2681 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2683 * mptscsih_initTarget - Target, LUN alloc/free functionality.
2684 * @hd: Pointer to MPT_SCSI_HOST structure
2685 * @bus_id: Bus number (?)
2686 * @target_id: SCSI target id
2688 * @data: Pointer to data
2689 * @dlen: Number of INQUIRY bytes
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, int bus_id, int target_id, u8 lun, char *data, int dlen)
2701 int indexed_lun, lun_index;
2706 dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n",
2707 hd->ioc->name, bus_id, target_id, lun, hd));
2710 * If the peripheral qualifier filter is enabled then if the target reports a 0x1
2711 * (i.e. The targer is capable of supporting the specified peripheral device type
2712 * on this logical unit; however, the physical device is not currently connected
2713 * to this logical unit) it will be converted to a 0x3 (i.e. The target is not
2714 * capable of supporting a physical device on this logical unit). This is to work
2715 * around a bug in th emid-layer in some distributions in which the mid-layer will
2716 * continue to try to communicate to the LUN and evntually create a dummy LUN.
2718 if (hd->mpt_pq_filter && dlen && (data[0] & 0xE0))
2721 /* Is LUN supported? If so, upper 2 bits will be 0
2722 * in first byte of inquiry data.
2727 if ((vdev = hd->Targets[target_id]) == NULL) {
2731 lun_index = (lun >> 5); /* 32 luns per lun_index */
2732 indexed_lun = (lun % 32);
2733 vdev->luns[lun_index] |= (1 << indexed_lun);
2735 if (hd->ioc->bus_type == SCSI) {
2736 if ((data[0] == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) {
2737 /* Treat all Processors as SAF-TE if
2738 * command line option is set */
2739 vdev->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
2740 mptscsih_writeIOCPage4(hd, target_id, bus_id);
2741 }else if ((data[0] == TYPE_PROCESSOR) &&
2742 !(vdev->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) {
2744 vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
2745 if ( data[44] == 'S' &&
2751 vdev->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
2752 mptscsih_writeIOCPage4(hd, target_id, bus_id);
2756 if (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY)) {
2758 memcpy (vdev->inq_data, data, 8);
2760 memcpy (vdev->inq_data, data, dlen);
2763 /* If have not done DV, set the DV flag.
2765 pSpi = &hd->ioc->spi_data;
2766 if ((data[0] == TYPE_TAPE) || (data[0] == TYPE_PROCESSOR)) {
2767 if (pSpi->dvStatus[target_id] & MPT_SCSICFG_DV_NOT_DONE)
2768 pSpi->dvStatus[target_id] |= MPT_SCSICFG_NEED_DV;
2771 vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
2774 data_56 = 0x0F; /* Default to full capabilities if Inq data length is < 57 */
2776 if ( (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_56))) {
2777 /* Update the target capabilities
2780 vdev->tflags |= MPT_TARGET_FLAGS_VALID_56;
2783 mptscsih_setTargetNegoParms(hd, vdev, data_56);
2785 /* Initial Inquiry may not request enough data bytes to
2786 * obtain byte 57. DV will; if target doesn't return
2787 * at least 57 bytes, data[56] will be zero. */
2789 if ( (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_56))) {
2790 /* Update the target capabilities
2793 vdev->tflags |= MPT_TARGET_FLAGS_VALID_56;
2794 mptscsih_setTargetNegoParms(hd, vdev, data_56);
2801 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2803 * Update the target negotiation parameters based on the
2804 * the Inquiry data, adapter capabilities, and NVRAM settings.
2808 mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56)
2810 ScsiCfgData *pspi_data = &hd->ioc->spi_data;
2811 int id = (int) target->target_id;
2815 u8 width = MPT_NARROW;
2816 u8 factor = MPT_ASYNC;
2818 u8 version, nfactor;
2821 target->negoFlags = pspi_data->noQas;
2823 /* noQas == 0 => device supports QAS. Need byte 56 of Inq to determine
2824 * support. If available, default QAS to off and allow enabling.
2825 * If not available, default QAS to on, turn off for non-disks.
2828 /* Set flags based on Inquiry data
2830 version = target->inq_data[2] & 0x07;
2833 factor = MPT_ULTRA2;
2834 offset = pspi_data->maxSyncOffset;
2835 target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
2837 if (target->inq_data[7] & 0x20) {
2841 if (target->inq_data[7] & 0x10) {
2842 factor = pspi_data->minSyncFactor;
2843 if (target->tflags & MPT_TARGET_FLAGS_VALID_56) {
2844 /* bits 2 & 3 show Clocking support */
2845 if ((byte56 & 0x0C) == 0)
2846 factor = MPT_ULTRA2;
2848 if ((byte56 & 0x03) == 0)
2849 factor = MPT_ULTRA160;
2851 factor = MPT_ULTRA320;
2854 ddvtprintk((KERN_INFO "Enabling QAS due to byte56=%02x on id=%d!\n", byte56, id));
2857 if (target->inq_data[0] == TYPE_TAPE) {
2859 target->negoFlags |= MPT_TAPE_NEGO_IDP;
2864 ddvtprintk((KERN_INFO "Enabling QAS on id=%d due to ~TARGET_FLAGS_VALID_56!\n", id));
2868 offset = pspi_data->maxSyncOffset;
2870 /* If RAID, never disable QAS
2871 * else if non RAID, do not disable
2872 * QAS if bit 1 is set
2873 * bit 1 QAS support, non-raid only
2876 if (target->raidVolume == 1) {
2885 if ( (target->inq_data[7] & 0x02) == 0) {
2886 target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
2889 /* Update tflags based on NVRAM settings. (SCSI only)
2891 if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
2892 nvram = pspi_data->nvram[id];
2893 nfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
2896 width = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
2899 /* Ensure factor is set to the
2900 * maximum of: adapter, nvram, inquiry
2903 if (nfactor < pspi_data->minSyncFactor )
2904 nfactor = pspi_data->minSyncFactor;
2906 factor = max(factor, nfactor);
2907 if (factor == MPT_ASYNC)
2918 /* Make sure data is consistent
2920 if ((!width) && (factor < MPT_ULTRA2)) {
2921 factor = MPT_ULTRA2;
2924 /* Save the data to the target structure.
2926 target->minSyncFactor = factor;
2927 target->maxOffset = offset;
2928 target->maxWidth = width;
2930 target->tflags |= MPT_TARGET_FLAGS_VALID_NEGO;
2932 /* Disable unused features.
2935 target->negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
2938 target->negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
2940 if ( factor > MPT_ULTRA320 )
2943 /* GEM, processor WORKAROUND
2945 if ((target->inq_data[0] == TYPE_PROCESSOR) || (target->inq_data[0] > 0x08)) {
2946 target->negoFlags |= (MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC);
2947 pspi_data->dvStatus[id] |= MPT_SCSICFG_BLK_NEGO;
2949 if (noQas && (pspi_data->noQas == 0)) {
2950 pspi_data->noQas |= MPT_TARGET_NO_NEGO_QAS;
2951 target->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
2953 /* Disable QAS in a mixed configuration case
2956 ddvtprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id));
2957 for (ii = 0; ii < id; ii++) {
2958 if ( (vdev = hd->Targets[ii]) ) {
2959 vdev->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
2960 mptscsih_writeSDP1(hd, 0, ii, vdev->negoFlags);
2966 /* Write SDP1 on this I/O to this target */
2967 if (pspi_data->dvStatus[id] & MPT_SCSICFG_NEGOTIATE) {
2968 ddvtprintk((KERN_INFO "MPT_SCSICFG_NEGOTIATE on id=%d!\n", id));
2969 mptscsih_writeSDP1(hd, 0, id, hd->negoNvram);
2970 pspi_data->dvStatus[id] &= ~MPT_SCSICFG_NEGOTIATE;
2971 } else if (pspi_data->dvStatus[id] & MPT_SCSICFG_BLK_NEGO) {
2972 ddvtprintk((KERN_INFO "MPT_SCSICFG_BLK_NEGO on id=%d!\n", id));
2973 mptscsih_writeSDP1(hd, 0, id, MPT_SCSICFG_BLK_NEGO);
2974 pspi_data->dvStatus[id] &= ~MPT_SCSICFG_BLK_NEGO;
2978 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2979 /* If DV disabled (negoNvram set to USE_NVARM) or if not LUN 0, return.
2980 * Else set the NEED_DV flag after Read Capacity Issued (disks)
2981 * or Mode Sense (cdroms).
2983 * Tapes, initTarget will set this flag on completion of Inquiry command.
2984 * Called only if DV_NOT_DONE flag is set
2987 mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq)
2992 ddvtprintk((" set_dvflags: id=%d lun=%d negoNvram=%x cmd=%x\n",
2993 pReq->TargetID, pReq->LUN[1], hd->negoNvram, pReq->CDB[0]));
2995 if ((pReq->LUN[1] != 0) || (hd->negoNvram != 0))
3000 if ((cmd == READ_CAPACITY) || (cmd == MODE_SENSE)) {
3001 pSpi = &hd->ioc->spi_data;
3002 if ((pSpi->isRaid & (1 << pReq->TargetID)) && pSpi->pIocPg3) {
3003 /* Set NEED_DV for all hidden disks
3005 Ioc3PhysDisk_t *pPDisk = pSpi->pIocPg3->PhysDisk;
3006 int numPDisk = pSpi->pIocPg3->NumPhysDisks;
3009 pSpi->dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV;
3010 ddvtprintk(("NEED_DV set for phys disk id %d\n", pPDisk->PhysDiskID));
3015 pSpi->dvStatus[pReq->TargetID] |= MPT_SCSICFG_NEED_DV;
3016 ddvtprintk(("NEED_DV set for visible disk id %d\n", pReq->TargetID));
3020 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3022 * If no Target, bus reset on 1st I/O. Set the flag to
3023 * prevent any future negotiations to this device.
3026 mptscsih_no_negotiate(MPT_SCSI_HOST *hd, int target_id)
3029 if ((hd->Targets) && (hd->Targets[target_id] == NULL))
3030 hd->ioc->spi_data.dvStatus[target_id] |= MPT_SCSICFG_BLK_NEGO;
3035 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3037 * SCSI Config Page functionality ...
3039 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3040 /* mptscsih_setDevicePage1Flags - add Requested and Configuration fields flags
3041 * based on width, factor and offset parameters.
3043 * @factor: sync factor
3044 * @offset: sync offset
3045 * @requestedPtr: pointer to requested values (updated)
3046 * @configurationPtr: pointer to configuration values (updated)
3047 * @flags: flags to block WDTR or SDTR negotiation
3051 * Remark: Called by writeSDP1 and _dv_params
3054 mptscsih_setDevicePage1Flags (u8 width, u8 factor, u8 offset, int *requestedPtr, int *configurationPtr, u8 flags)
3056 u8 nowide = flags & MPT_TARGET_NO_NEGO_WIDE;
3057 u8 nosync = flags & MPT_TARGET_NO_NEGO_SYNC;
3059 *configurationPtr = 0;
3060 *requestedPtr = width ? MPI_SCSIDEVPAGE1_RP_WIDE : 0;
3061 *requestedPtr |= (offset << 16) | (factor << 8);
3063 if (width && offset && !nowide && !nosync) {
3064 if (factor < MPT_ULTRA160) {
3065 *requestedPtr |= (MPI_SCSIDEVPAGE1_RP_IU + MPI_SCSIDEVPAGE1_RP_DT);
3066 if ((flags & MPT_TARGET_NO_NEGO_QAS) == 0)
3067 *requestedPtr |= MPI_SCSIDEVPAGE1_RP_QAS;
3068 if (flags & MPT_TAPE_NEGO_IDP)
3069 *requestedPtr |= 0x08000000;
3070 } else if (factor < MPT_ULTRA2) {
3071 *requestedPtr |= MPI_SCSIDEVPAGE1_RP_DT;
3076 *configurationPtr |= MPI_SCSIDEVPAGE1_CONF_WDTR_DISALLOWED;
3079 *configurationPtr |= MPI_SCSIDEVPAGE1_CONF_SDTR_DISALLOWED;
3084 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3085 /* mptscsih_writeSDP1 - write SCSI Device Page 1
3086 * @hd: Pointer to a SCSI Host Strucutre
3087 * @portnum: IOC port number
3088 * @target_id: writeSDP1 for single ID
3089 * @flags: MPT_SCSICFG_ALL_IDS, MPT_SCSICFG_USE_NVRAM, MPT_SCSICFG_BLK_NEGO
3091 * Return: -EFAULT if read of config page header fails
3094 * Remark: If a target has been found, the settings from the
3095 * target structure are used, else the device is set
3098 * Remark: Called during init and after a FW reload.
3099 * Remark: We do not wait for a return, write pages sequentially.
3102 mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
3104 MPT_ADAPTER *ioc = hd->ioc;
3106 SCSIDevicePage1_t *pData;
3107 VirtDevice *pTarget;
3112 u32 requested, configuration, flagsLength;
3114 int id = 0, maxid = 0;
3120 u8 maxwidth, maxoffset, maxfactor;
3122 if (ioc->spi_data.sdp1length == 0)
3125 if (flags & MPT_SCSICFG_ALL_IDS) {
3127 maxid = ioc->sh->max_id - 1;
3128 } else if (ioc->sh) {
3130 maxid = min_t(int, id, ioc->sh->max_id - 1);
3133 for (; id <= maxid; id++) {
3135 if (id == ioc->pfacts[portnum].PortSCSIID)
3138 /* Use NVRAM to get adapter and target maximums
3139 * Data over-riden by target structure information, if present
3141 maxwidth = ioc->spi_data.maxBusWidth;
3142 maxoffset = ioc->spi_data.maxSyncOffset;
3143 maxfactor = ioc->spi_data.minSyncFactor;
3144 if (ioc->spi_data.nvram && (ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
3145 nvram = ioc->spi_data.nvram[id];
3148 maxwidth = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
3150 if (maxoffset > 0) {
3151 maxfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
3152 if (maxfactor == 0) {
3154 maxfactor = MPT_ASYNC;
3156 } else if (maxfactor < ioc->spi_data.minSyncFactor) {
3157 maxfactor = ioc->spi_data.minSyncFactor;
3160 maxfactor = MPT_ASYNC;
3163 /* Set the negotiation flags.
3165 negoFlags = ioc->spi_data.noQas;
3167 negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
3170 negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
3172 if (flags & MPT_SCSICFG_USE_NVRAM) {
3181 //negoFlags = MPT_TARGET_NO_NEGO_SYNC;
3184 /* If id is not a raid volume, get the updated
3185 * transmission settings from the target structure.
3187 if (hd->Targets && (pTarget = hd->Targets[id]) && !pTarget->raidVolume) {
3188 width = pTarget->maxWidth;
3189 factor = pTarget->minSyncFactor;
3190 offset = pTarget->maxOffset;
3191 negoFlags = pTarget->negoFlags;
3194 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
3195 /* Force to async and narrow if DV has not been executed
3198 if ((hd->ioc->spi_data.dvStatus[id] & MPT_SCSICFG_DV_NOT_DONE) != 0) {
3205 if (flags & MPT_SCSICFG_BLK_NEGO)
3206 negoFlags = MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC;
3208 mptscsih_setDevicePage1Flags(width, factor, offset,
3209 &requested, &configuration, negoFlags);
3210 dnegoprintk(("writeSDP1: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
3211 target_id, width, factor, offset, negoFlags, requested, configuration));
3213 /* Get a MF for this command.
3215 if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
3216 dprintk((MYIOC_s_WARN_FMT "write SDP1: no msg frames!\n",
3221 ddvprintk((MYIOC_s_INFO_FMT "WriteSDP1 (mf=%p, id=%d, req=0x%x, cfg=0x%x)\n",
3222 hd->ioc->name, mf, id, requested, configuration));
3225 /* Set the request and the data pointers.
3226 * Request takes: 36 bytes (32 bit SGE)
3227 * SCSI Device Page 1 requires 16 bytes
3228 * 40 + 16 <= size of SCSI IO Request = 56 bytes
3229 * and MF size >= 64 bytes.
3230 * Place data at end of MF.
3232 pReq = (Config_t *)mf;
3234 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3235 frameOffset = ioc->req_sz - sizeof(SCSIDevicePage1_t);
3237 pData = (SCSIDevicePage1_t *)((u8 *) mf + frameOffset);
3238 dataDma = ioc->req_frames_dma + (req_idx * ioc->req_sz) + frameOffset;
3240 /* Complete the request frame (same for all requests).
3242 pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
3244 pReq->ChainOffset = 0;
3245 pReq->Function = MPI_FUNCTION_CONFIG;
3246 pReq->ExtPageLength = 0;
3247 pReq->ExtPageType = 0;
3249 for (ii=0; ii < 8; ii++) {
3250 pReq->Reserved2[ii] = 0;
3252 pReq->Header.PageVersion = ioc->spi_data.sdp1version;
3253 pReq->Header.PageLength = ioc->spi_data.sdp1length;
3254 pReq->Header.PageNumber = 1;
3255 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
3256 pReq->PageAddress = cpu_to_le32(id | (bus << 8 ));
3258 /* Add a SGE to the config request.
3260 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE | ioc->spi_data.sdp1length * 4;
3262 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma);
3264 /* Set up the common data portion
3266 pData->Header.PageVersion = pReq->Header.PageVersion;
3267 pData->Header.PageLength = pReq->Header.PageLength;
3268 pData->Header.PageNumber = pReq->Header.PageNumber;
3269 pData->Header.PageType = pReq->Header.PageType;
3270 pData->RequestedParameters = cpu_to_le32(requested);
3271 pData->Reserved = 0;
3272 pData->Configuration = cpu_to_le32(configuration);
3274 dprintk((MYIOC_s_INFO_FMT
3275 "write SDP1: id %d pgaddr 0x%x req 0x%x config 0x%x\n",
3276 ioc->name, id, (id | (bus<<8)),
3277 requested, configuration));
3279 mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
3285 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3286 /* mptscsih_writeIOCPage4 - write IOC Page 4
3287 * @hd: Pointer to a SCSI Host Structure
3288 * @target_id: write IOC Page4 for this ID & Bus
3290 * Return: -EAGAIN if unable to obtain a Message Frame
3293 * Remark: We do not wait for a return, write pages sequentially.
3296 mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus)
3298 MPT_ADAPTER *ioc = hd->ioc;
3300 IOCPage4_t *IOCPage4Ptr;
3308 /* Get a MF for this command.
3310 if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
3311 dprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n",
3316 /* Set the request and the data pointers.
3317 * Place data at end of MF.
3319 pReq = (Config_t *)mf;
3321 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3322 frameOffset = ioc->req_sz - sizeof(IOCPage4_t);
3324 /* Complete the request frame (same for all requests).
3326 pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
3328 pReq->ChainOffset = 0;
3329 pReq->Function = MPI_FUNCTION_CONFIG;
3330 pReq->ExtPageLength = 0;
3331 pReq->ExtPageType = 0;
3333 for (ii=0; ii < 8; ii++) {
3334 pReq->Reserved2[ii] = 0;
3337 IOCPage4Ptr = ioc->spi_data.pIocPg4;
3338 dataDma = ioc->spi_data.IocPg4_dma;
3339 ii = IOCPage4Ptr->ActiveSEP++;
3340 IOCPage4Ptr->SEP[ii].SEPTargetID = target_id;
3341 IOCPage4Ptr->SEP[ii].SEPBus = bus;
3342 pReq->Header = IOCPage4Ptr->Header;
3343 pReq->PageAddress = cpu_to_le32(target_id | (bus << 8 ));
3345 /* Add a SGE to the config request.
3347 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE |
3348 (IOCPage4Ptr->Header.PageLength + ii) * 4;
3350 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma);
3352 dinitprintk((MYIOC_s_INFO_FMT
3353 "writeIOCPage4: MaxSEP=%d ActiveSEP=%d id=%d bus=%d\n",
3354 ioc->name, IOCPage4Ptr->MaxSEP, IOCPage4Ptr->ActiveSEP, target_id, bus));
3356 mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
3361 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3363 * Bus Scan and Domain Validation functionality ...
3366 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3368 * mptscsih_scandv_complete - Scan and DV callback routine registered
3369 * to Fustion MPT (base) driver.
3371 * @ioc: Pointer to MPT_ADAPTER structure
3372 * @mf: Pointer to original MPT request frame
3373 * @mr: Pointer to MPT reply frame (NULL if TurboReply)
3375 * This routine is called from mpt.c::mpt_interrupt() at the completion
3376 * of any SCSI IO request.
3377 * This routine is registered with the Fusion MPT (base) driver at driver
3378 * load/init time via the mpt_register() API call.
3380 * Returns 1 indicating alloc'd request frame ptr should be freed.
3382 * Remark: Sets a completion code and (possibly) saves sense data
3383 * in the IOC member localReply structure.
3384 * Used ONLY for DV and other internal commands.
3387 mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
3390 SCSIIORequest_t *pReq;
3394 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
3397 (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) {
3398 printk(MYIOC_s_ERR_FMT
3399 "ScanDvComplete, %s req frame ptr! (=%p)\n",
3400 ioc->name, mf?"BAD":"NULL", (void *) mf);
3404 del_timer(&hd->timer);
3405 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3406 hd->ScsiLookup[req_idx] = NULL;
3407 pReq = (SCSIIORequest_t *) mf;
3409 if (mf != hd->cmdPtr) {
3410 printk(MYIOC_s_WARN_FMT "ScanDvComplete (mf=%p, cmdPtr=%p, idx=%d)\n",
3411 hd->ioc->name, (void *)mf, (void *) hd->cmdPtr, req_idx);
3415 ddvprintk((MYIOC_s_INFO_FMT "ScanDvComplete (mf=%p,mr=%p,idx=%d)\n",
3416 hd->ioc->name, mf, mr, req_idx));
3418 hd->pLocal = &hd->localReply;
3419 hd->pLocal->scsiStatus = 0;
3421 /* If target struct exists, clear sense valid flag.
3424 completionCode = MPT_SCANDV_GOOD;
3426 SCSIIOReply_t *pReply;
3430 pReply = (SCSIIOReply_t *) mr;
3432 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
3433 scsi_status = pReply->SCSIStatus;
3435 ddvtprintk((KERN_NOTICE " IOCStatus=%04xh, SCSIState=%02xh, SCSIStatus=%02xh, IOCLogInfo=%08xh\n",
3436 status, pReply->SCSIState, scsi_status,
3437 le32_to_cpu(pReply->IOCLogInfo)));
3441 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
3442 completionCode = MPT_SCANDV_SELECTION_TIMEOUT;
3445 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
3446 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
3447 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
3448 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
3449 completionCode = MPT_SCANDV_DID_RESET;
3452 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
3453 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
3454 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
3455 if (pReply->Function == MPI_FUNCTION_CONFIG) {
3456 ConfigReply_t *pr = (ConfigReply_t *)mr;
3457 completionCode = MPT_SCANDV_GOOD;
3458 hd->pLocal->header.PageVersion = pr->Header.PageVersion;
3459 hd->pLocal->header.PageLength = pr->Header.PageLength;
3460 hd->pLocal->header.PageNumber = pr->Header.PageNumber;
3461 hd->pLocal->header.PageType = pr->Header.PageType;
3463 } else if (pReply->Function == MPI_FUNCTION_RAID_ACTION) {
3464 /* If the RAID Volume request is successful,
3465 * return GOOD, else indicate that
3466 * some type of error occurred.
3468 MpiRaidActionReply_t *pr = (MpiRaidActionReply_t *)mr;
3469 if (pr->ActionStatus == MPI_RAID_ACTION_ASTATUS_SUCCESS)
3470 completionCode = MPT_SCANDV_GOOD;
3472 completionCode = MPT_SCANDV_SOME_ERROR;
3474 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID) {
3478 /* save sense data in global structure
3480 completionCode = MPT_SCANDV_SENSE;
3481 hd->pLocal->scsiStatus = scsi_status;
3482 sense_data = ((u8 *)hd->ioc->sense_buf_pool +
3483 (req_idx * MPT_SENSE_BUFFER_ALLOC));
3485 sz = min_t(int, pReq->SenseBufferLength,
3486 SCSI_STD_SENSE_BYTES);
3487 memcpy(hd->pLocal->sense, sense_data, sz);
3489 ddvprintk((KERN_NOTICE " Check Condition, sense ptr %p\n",
3491 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_FAILED) {
3492 if (pReq->CDB[0] == INQUIRY)
3493 completionCode = MPT_SCANDV_ISSUE_SENSE;
3495 completionCode = MPT_SCANDV_DID_RESET;
3497 else if (pReply->SCSIState & MPI_SCSI_STATE_NO_SCSI_STATUS)
3498 completionCode = MPT_SCANDV_DID_RESET;
3499 else if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
3500 completionCode = MPT_SCANDV_DID_RESET;
3502 completionCode = MPT_SCANDV_GOOD;
3503 hd->pLocal->scsiStatus = scsi_status;
3507 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
3508 if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
3509 completionCode = MPT_SCANDV_DID_RESET;
3511 completionCode = MPT_SCANDV_SOME_ERROR;
3515 completionCode = MPT_SCANDV_SOME_ERROR;
3518 } /* switch(status) */
3520 ddvtprintk((KERN_NOTICE " completionCode set to %08xh\n",
3522 } /* end of address reply case */
3524 hd->pLocal->completion = completionCode;
3526 /* MF and RF are freed in mpt_interrupt
3529 /* Free Chain buffers (will never chain) in scan or dv */
3530 //mptscsih_freeChainBuffers(ioc, req_idx);
3533 * Wake up the original calling thread
3535 hd->scandv_wait_done = 1;
3536 wake_up(&hd->scandv_waitq);
3541 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3542 /* mptscsih_timer_expired - Call back for timer process.
3543 * Used only for dv functionality.
3544 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
3548 mptscsih_timer_expired(unsigned long data)
3550 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) data;
3552 ddvprintk((MYIOC_s_WARN_FMT "Timer Expired! Cmd %p\n", hd->ioc->name, hd->cmdPtr));
3555 MPIHeader_t *cmd = (MPIHeader_t *)hd->cmdPtr;
3557 if (cmd->Function == MPI_FUNCTION_SCSI_IO_REQUEST) {
3558 /* Desire to issue a task management request here.
3559 * TM requests MUST be single threaded.
3560 * If old eh code and no TM current, issue request.
3561 * If new eh code, do nothing. Wait for OS cmd timeout
3564 ddvtprintk((MYIOC_s_NOTE_FMT "DV Cmd Timeout: NoOp\n", hd->ioc->name));
3566 /* Perform a FW reload */
3567 if (mpt_HardResetHandler(hd->ioc, NO_SLEEP) < 0) {
3568 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", hd->ioc->name);
3572 /* This should NEVER happen */
3573 printk(MYIOC_s_WARN_FMT "Null cmdPtr!!!!\n", hd->ioc->name);
3576 /* No more processing.
3577 * TM call will generate an interrupt for SCSI TM Management.
3578 * The FW will reply to all outstanding commands, callback will finish cleanup.
3579 * Hard reset clean-up will free all resources.
3581 ddvprintk((MYIOC_s_WARN_FMT "Timer Expired Complete!\n", hd->ioc->name));
3586 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
3587 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3588 /* mptscsih_do_raid - Format and Issue a RAID volume request message.
3589 * @hd: Pointer to scsi host structure
3590 * @action: What do be done.
3591 * @id: Logical target id.
3592 * @bus: Target locations bus.
3594 * Returns: < 0 on a fatal error
3597 * Remark: Wait to return until reply processed by the ISR.
3600 mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io)
3602 MpiRaidActionRequest_t *pReq;
3606 in_isr = in_interrupt();
3608 dprintk((MYIOC_s_WARN_FMT "Internal raid request not allowed in ISR context!\n",
3613 /* Get and Populate a free Frame
3615 if ((mf = mpt_get_msg_frame(hd->ioc->InternalCtx, hd->ioc)) == NULL) {
3616 ddvprintk((MYIOC_s_WARN_FMT "_do_raid: no msg frames!\n",
3620 pReq = (MpiRaidActionRequest_t *)mf;
3621 pReq->Action = action;
3622 pReq->Reserved1 = 0;
3623 pReq->ChainOffset = 0;
3624 pReq->Function = MPI_FUNCTION_RAID_ACTION;
3625 pReq->VolumeID = io->id;
3626 pReq->VolumeBus = io->bus;
3627 pReq->PhysDiskNum = io->physDiskNum;
3629 pReq->Reserved2 = 0;
3630 pReq->ActionDataWord = 0; /* Reserved for this action */
3631 //pReq->ActionDataSGE = 0;
3633 mpt_add_sge((char *)&pReq->ActionDataSGE,
3634 MPT_SGE_FLAGS_SSIMPLE_READ | 0, (dma_addr_t) -1);
3636 ddvprintk((MYIOC_s_INFO_FMT "RAID Volume action %x id %d\n",
3637 hd->ioc->name, action, io->id));
3640 hd->timer.expires = jiffies + HZ*10; /* 10 second timeout */
3641 hd->scandv_wait_done = 0;
3643 /* Save cmd pointer, for resource free if timeout or
3648 add_timer(&hd->timer);
3649 mpt_put_msg_frame(hd->ioc->InternalCtx, hd->ioc, mf);
3650 wait_event(hd->scandv_waitq, hd->scandv_wait_done);
3652 if ((hd->pLocal == NULL) || (hd->pLocal->completion != MPT_SCANDV_GOOD))
3657 #endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */
3659 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3661 * mptscsih_do_cmd - Do internal command.
3662 * @hd: MPT_SCSI_HOST pointer
3663 * @io: INTERNAL_CMD pointer.
3665 * Issue the specified internally generated command and do command
3666 * specific cleanup. For bus scan / DV only.
3667 * NOTES: If command is Inquiry and status is good,
3668 * initialize a target structure, save the data
3670 * Remark: Single threaded access only.
3673 * < 0 if an illegal command or no resources
3677 * > 0 if command complete but some type of completion error.
3680 mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
3683 SCSIIORequest_t *pScsiReq;
3684 SCSIIORequest_t ReqCopy;
3685 int my_idx, ii, dir;
3689 char CDB[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
3692 in_isr = in_interrupt();
3694 dprintk((MYIOC_s_WARN_FMT "Internal SCSI IO request not allowed in ISR context!\n",
3700 /* Set command specific information
3705 dir = MPI_SCSIIO_CONTROL_READ;
3711 case TEST_UNIT_READY:
3713 dir = MPI_SCSIIO_CONTROL_READ;
3719 dir = MPI_SCSIIO_CONTROL_READ;
3721 CDB[4] = 1; /*Spin up the disk */
3729 dir = MPI_SCSIIO_CONTROL_READ;
3735 dir = MPI_SCSIIO_CONTROL_READ;
3737 if (io->flags & MPT_ICFLAG_ECHO) {
3743 if (io->flags & MPT_ICFLAG_BUF_CAP) {
3746 CDB[6] = (io->size >> 16) & 0xFF;
3747 CDB[7] = (io->size >> 8) & 0xFF;
3748 CDB[8] = io->size & 0xFF;
3754 dir = MPI_SCSIIO_CONTROL_WRITE;
3756 if (io->flags & MPT_ICFLAG_ECHO) {
3761 CDB[6] = (io->size >> 16) & 0xFF;
3762 CDB[7] = (io->size >> 8) & 0xFF;
3763 CDB[8] = io->size & 0xFF;
3769 dir = MPI_SCSIIO_CONTROL_READ;
3776 dir = MPI_SCSIIO_CONTROL_READ;
3781 case SYNCHRONIZE_CACHE:
3783 dir = MPI_SCSIIO_CONTROL_READ;
3785 // CDB[1] = 0x02; /* set immediate bit */
3794 /* Get and Populate a free Frame
3796 if ((mf = mpt_get_msg_frame(hd->ioc->InternalCtx, hd->ioc)) == NULL) {
3797 ddvprintk((MYIOC_s_WARN_FMT "No msg frames!\n",
3802 pScsiReq = (SCSIIORequest_t *) mf;
3804 /* Get the request index */
3805 my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3806 ADD_INDEX_LOG(my_idx); /* for debug */
3808 if (io->flags & MPT_ICFLAG_PHYS_DISK) {
3809 pScsiReq->TargetID = io->physDiskNum;
3811 pScsiReq->ChainOffset = 0;
3812 pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
3814 pScsiReq->TargetID = io->id;
3815 pScsiReq->Bus = io->bus;
3816 pScsiReq->ChainOffset = 0;
3817 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
3820 pScsiReq->CDBLength = cmdLen;
3821 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
3823 pScsiReq->Reserved = 0;
3825 pScsiReq->MsgFlags = mpt_msg_flags();
3826 /* MsgContext set in mpt_get_msg_fram call */
3828 for (ii=0; ii < 8; ii++)
3829 pScsiReq->LUN[ii] = 0;
3830 pScsiReq->LUN[1] = io->lun;
3832 if (io->flags & MPT_ICFLAG_TAGGED_CMD)
3833 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ);
3835 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3837 if (cmd == REQUEST_SENSE) {
3838 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3839 ddvprintk((MYIOC_s_INFO_FMT "Untagged! 0x%2x\n",
3840 hd->ioc->name, cmd));
3843 for (ii=0; ii < 16; ii++)
3844 pScsiReq->CDB[ii] = CDB[ii];
3846 pScsiReq->DataLength = cpu_to_le32(io->size);
3847 pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
3848 + (my_idx * MPT_SENSE_BUFFER_ALLOC));
3850 ddvprintk((MYIOC_s_INFO_FMT "Sending Command 0x%x for (%d:%d:%d)\n",
3851 hd->ioc->name, cmd, io->bus, io->id, io->lun));
3853 if (dir == MPI_SCSIIO_CONTROL_READ) {
3854 mpt_add_sge((char *) &pScsiReq->SGL,
3855 MPT_SGE_FLAGS_SSIMPLE_READ | io->size,
3858 mpt_add_sge((char *) &pScsiReq->SGL,
3859 MPT_SGE_FLAGS_SSIMPLE_WRITE | io->size,
3863 /* The ISR will free the request frame, but we need
3864 * the information to initialize the target. Duplicate.
3866 memcpy(&ReqCopy, pScsiReq, sizeof(SCSIIORequest_t));
3868 /* Issue this command after:
3871 * Wait until the reply has been received
3872 * ScsiScanDvCtx callback function will
3874 * set scandv_wait_done and call wake_up
3877 hd->timer.expires = jiffies + HZ*cmdTimeout;
3878 hd->scandv_wait_done = 0;
3880 /* Save cmd pointer, for resource free if timeout or
3885 add_timer(&hd->timer);
3886 mpt_put_msg_frame(hd->ioc->InternalCtx, hd->ioc, mf);
3887 wait_event(hd->scandv_waitq, hd->scandv_wait_done);
3890 rc = hd->pLocal->completion;
3891 hd->pLocal->skip = 0;
3893 /* Always set fatal error codes in some cases.
3895 if (rc == MPT_SCANDV_SELECTION_TIMEOUT)
3897 else if (rc == MPT_SCANDV_SOME_ERROR)
3901 /* This should never happen. */
3902 ddvprintk((MYIOC_s_INFO_FMT "_do_cmd: Null pLocal!!!\n",
3909 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3911 * mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
3912 * @hd: Pointer to MPT_SCSI_HOST structure
3913 * @portnum: IOC port number
3915 * Uses the ISR, but with special processing.
3916 * MUST be single-threaded.
3918 * Return: 0 on completion
3921 mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum)
3923 MPT_ADAPTER *ioc= hd->ioc;
3924 VirtDevice *pTarget;
3925 SCSIDevicePage1_t *pcfg1Data = NULL;
3928 dma_addr_t cfg1_dma_addr = -1;
3929 ConfigPageHeader_t header1;
3933 int indexed_lun, lun_index;
3934 int hostId = ioc->pfacts[portnum].PortSCSIID;
3936 int requested, configuration, data;
3940 max_id = ioc->sh->max_id - 1;
3942 /* Following parameters will not change
3945 iocmd.cmd = SYNCHRONIZE_CACHE;
3947 iocmd.physDiskNum = -1;
3949 iocmd.data_dma = -1;
3951 iocmd.rsvd = iocmd.rsvd2 = 0;
3955 if (hd->Targets == NULL)
3963 /* Write SDP1 for all SCSI devices
3964 * Alloc memory and set up config buffer
3966 if (ioc->bus_type == SCSI) {
3967 if (ioc->spi_data.sdp1length > 0) {
3968 pcfg1Data = (SCSIDevicePage1_t *)pci_alloc_consistent(ioc->pcidev,
3969 ioc->spi_data.sdp1length * 4, &cfg1_dma_addr);
3971 if (pcfg1Data != NULL) {
3973 header1.PageVersion = ioc->spi_data.sdp1version;
3974 header1.PageLength = ioc->spi_data.sdp1length;
3975 header1.PageNumber = 1;
3976 header1.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
3978 cfg.physAddr = cfg1_dma_addr;
3979 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
3986 /* loop through all devices on this port
3988 while (bus < MPT_MAX_BUS) {
3991 pTarget = hd->Targets[(int)id];
3995 /* Set the negotiation flags */
3996 if (pTarget && (pTarget = hd->Targets[id]) && !pTarget->raidVolume) {
3997 flags = pTarget->negoFlags;
3999 flags = hd->ioc->spi_data.noQas;
4000 if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
4001 data = hd->ioc->spi_data.nvram[id];
4003 if (data & MPT_NVRAM_WIDE_DISABLE)
4004 flags |= MPT_TARGET_NO_NEGO_WIDE;
4006 factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT;
4007 if ((factor == 0) || (factor == MPT_ASYNC))
4008 flags |= MPT_TARGET_NO_NEGO_SYNC;
4012 /* Force to async, narrow */
4013 mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested,
4014 &configuration, flags);
4015 dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC "
4016 "offset=0 negoFlags=%x request=%x config=%x\n",
4017 id, flags, requested, configuration));
4018 pcfg1Data->RequestedParameters = le32_to_cpu(requested);
4019 pcfg1Data->Reserved = 0;
4020 pcfg1Data->Configuration = le32_to_cpu(configuration);
4021 cfg.pageAddr = (bus<<8) | id;
4022 mpt_config(hd->ioc, &cfg);
4025 /* If target Ptr NULL or if this target is NOT a disk, skip.
4027 if ((pTarget) && (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)){
4028 for (lun=0; lun <= MPT_LAST_LUN; lun++) {
4029 /* If LUN present, issue the command
4031 lun_index = (lun >> 5); /* 32 luns per lun_index */
4032 indexed_lun = (lun % 32);
4033 if (pTarget->luns[lun_index] & (1<<indexed_lun)) {
4035 (void) mptscsih_do_cmd(hd, &iocmd);
4040 /* get next relevant device */
4053 pci_free_consistent(ioc->pcidev, header1.PageLength * 4, pcfg1Data, cfg1_dma_addr);
4059 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
4060 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4062 * mptscsih_domainValidation - Top level handler for domain validation.
4063 * @hd: Pointer to MPT_SCSI_HOST structure.
4065 * Uses the ISR, but with special processing.
4066 * Called from schedule, should not be in interrupt mode.
4067 * While thread alive, do dv for all devices needing dv
4072 mptscsih_domainValidation(void *arg)
4076 unsigned long flags;
4077 int id, maxid, dvStatus, did;
4080 spin_lock_irqsave(&dvtaskQ_lock, flags);
4082 if (dvtaskQ_release) {
4084 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4087 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4089 /* For this ioc, loop through all devices and do dv to each device.
4090 * When complete with this ioc, search through the ioc list, and
4091 * for each scsi ioc found, do dv for all devices. Exit when no
4097 list_for_each_entry(ioc, &ioc_list, list) {
4098 spin_lock_irqsave(&dvtaskQ_lock, flags);
4099 if (dvtaskQ_release) {
4101 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4104 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4108 /* DV only to SCSI adapters */
4109 if (ioc->bus_type != SCSI)
4112 /* Make sure everything looks ok */
4113 if (ioc->sh == NULL)
4116 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
4120 if ((ioc->spi_data.forceDv & MPT_SCSICFG_RELOAD_IOC_PG3) != 0) {
4121 mpt_read_ioc_pg_3(ioc);
4122 if (ioc->spi_data.pIocPg3) {
4123 Ioc3PhysDisk_t *pPDisk = ioc->spi_data.pIocPg3->PhysDisk;
4124 int numPDisk = ioc->spi_data.pIocPg3->NumPhysDisks;
4127 if (ioc->spi_data.dvStatus[pPDisk->PhysDiskID] & MPT_SCSICFG_DV_NOT_DONE)
4128 ioc->spi_data.dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV;
4134 ioc->spi_data.forceDv &= ~MPT_SCSICFG_RELOAD_IOC_PG3;
4137 maxid = min_t(int, ioc->sh->max_id, MPT_MAX_SCSI_DEVICES);
4139 for (id = 0; id < maxid; id++) {
4140 spin_lock_irqsave(&dvtaskQ_lock, flags);
4141 if (dvtaskQ_release) {
4143 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4146 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4147 dvStatus = hd->ioc->spi_data.dvStatus[id];
4149 if (dvStatus & MPT_SCSICFG_NEED_DV) {
4151 hd->ioc->spi_data.dvStatus[id] |= MPT_SCSICFG_DV_PENDING;
4152 hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_NEED_DV;
4156 /* If hidden phys disk, block IO's to all
4158 * else, process normally
4160 isPhysDisk = mptscsih_is_phys_disk(ioc, id);
4162 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4163 if (hd->ioc->spi_data.isRaid & (1 << ii)) {
4164 hd->ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_DV_PENDING;
4169 if (mptscsih_doDv(hd, 0, id) == 1) {
4170 /* Untagged device was busy, try again
4172 hd->ioc->spi_data.dvStatus[id] |= MPT_SCSICFG_NEED_DV;
4173 hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_PENDING;
4175 /* DV is complete. Clear flags.
4177 hd->ioc->spi_data.dvStatus[id] &= ~(MPT_SCSICFG_DV_NOT_DONE | MPT_SCSICFG_DV_PENDING);
4181 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4182 if (hd->ioc->spi_data.isRaid & (1 << ii)) {
4183 hd->ioc->spi_data.dvStatus[ii] &= ~MPT_SCSICFG_DV_PENDING;
4188 if (hd->ioc->spi_data.noQas)
4189 mptscsih_qas_check(hd, id);
4195 spin_lock_irqsave(&dvtaskQ_lock, flags);
4197 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4202 /* Search IOC page 3 to determine if this is hidden physical disk
4205 mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id)
4207 if (ioc->spi_data.pIocPg3) {
4208 Ioc3PhysDisk_t *pPDisk = ioc->spi_data.pIocPg3->PhysDisk;
4209 int numPDisk = ioc->spi_data.pIocPg3->NumPhysDisks;
4212 if (pPDisk->PhysDiskID == id) {
4222 /* Write SDP1 if no QAS has been enabled
4225 mptscsih_qas_check(MPT_SCSI_HOST *hd, int id)
4227 VirtDevice *pTarget;
4230 if (hd->Targets == NULL)
4233 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4237 if ((hd->ioc->spi_data.dvStatus[ii] & MPT_SCSICFG_DV_NOT_DONE) != 0)
4240 pTarget = hd->Targets[ii];
4242 if ((pTarget != NULL) && (!pTarget->raidVolume)) {
4243 if ((pTarget->negoFlags & hd->ioc->spi_data.noQas) == 0) {
4244 pTarget->negoFlags |= hd->ioc->spi_data.noQas;
4245 dnegoprintk(("writeSDP1: id=%d flags=0\n", id));
4246 mptscsih_writeSDP1(hd, 0, ii, 0);
4249 if (mptscsih_is_phys_disk(hd->ioc, ii) == 1) {
4250 dnegoprintk(("writeSDP1: id=%d SCSICFG_USE_NVRAM\n", id));
4251 mptscsih_writeSDP1(hd, 0, ii, MPT_SCSICFG_USE_NVRAM);
4260 #define MPT_GET_NVRAM_VALS 0x01
4261 #define MPT_UPDATE_MAX 0x02
4262 #define MPT_SET_MAX 0x04
4263 #define MPT_SET_MIN 0x08
4264 #define MPT_FALLBACK 0x10
4265 #define MPT_SAVE 0x20
4267 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4269 * mptscsih_doDv - Perform domain validation to a target.
4270 * @hd: Pointer to MPT_SCSI_HOST structure.
4271 * @portnum: IOC port number.
4272 * @target: Physical ID of this target
4274 * Uses the ISR, but with special processing.
4275 * MUST be single-threaded.
4276 * Test will exit if target is at async & narrow.
4281 mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
4283 MPT_ADAPTER *ioc = hd->ioc;
4284 VirtDevice *pTarget;
4285 SCSIDevicePage1_t *pcfg1Data;
4286 SCSIDevicePage0_t *pcfg0Data;
4290 dma_addr_t dvbuf_dma = -1;
4291 dma_addr_t buf1_dma = -1;
4292 dma_addr_t buf2_dma = -1;
4293 dma_addr_t cfg1_dma_addr = -1;
4294 dma_addr_t cfg0_dma_addr = -1;
4295 ConfigPageHeader_t header1;
4296 ConfigPageHeader_t header0;
4303 int dataBufSize = 0;
4304 int echoBufSize = 0;
4309 int nfactor = MPT_ULTRA320;
4311 char doFallback = 0;
4316 if (ioc->spi_data.sdp1length == 0)
4319 if (ioc->spi_data.sdp0length == 0)
4322 /* If multiple buses are used, require that the initiator
4323 * id be the same on all buses.
4325 if (id == ioc->pfacts[0].PortSCSIID)
4329 bus = (u8) bus_number;
4330 ddvtprintk((MYIOC_s_NOTE_FMT
4331 "DV started: bus=%d, id=%d dv @ %p\n",
4332 ioc->name, bus, id, &dv));
4334 /* Prep DV structure
4336 memset (&dv, 0, sizeof(DVPARAMETERS));
4339 /* Populate tmax with the current maximum
4340 * transfer parameters for this target.
4341 * Exit if narrow and async.
4343 dv.cmd = MPT_GET_NVRAM_VALS;
4344 mptscsih_dv_parms(hd, &dv, NULL);
4346 /* Prep SCSI IO structure
4352 iocmd.physDiskNum = -1;
4353 iocmd.rsvd = iocmd.rsvd2 = 0;
4355 pTarget = hd->Targets[id];
4357 /* Use tagged commands if possible.
4360 if (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)
4361 iocmd.flags |= MPT_ICFLAG_TAGGED_CMD;
4363 if (hd->ioc->facts.FWVersion.Word < 0x01000600)
4366 if ((hd->ioc->facts.FWVersion.Word >= 0x01010000) &&
4367 (hd->ioc->facts.FWVersion.Word < 0x01010B00))
4372 /* Prep cfg structure
4374 cfg.pageAddr = (bus<<8) | id;
4379 header0.PageVersion = ioc->spi_data.sdp0version;
4380 header0.PageLength = ioc->spi_data.sdp0length;
4381 header0.PageNumber = 0;
4382 header0.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4386 header1.PageVersion = ioc->spi_data.sdp1version;
4387 header1.PageLength = ioc->spi_data.sdp1length;
4388 header1.PageNumber = 1;
4389 header1.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4391 if (header0.PageLength & 1)
4392 dv_alloc = (header0.PageLength * 4) + 4;
4394 dv_alloc += (2048 + (header1.PageLength * 4));
4396 pDvBuf = pci_alloc_consistent(ioc->pcidev, dv_alloc, &dvbuf_dma);
4401 pbuf1 = (u8 *)pDvBuf;
4402 buf1_dma = dvbuf_dma;
4405 pbuf2 = (u8 *) (pDvBuf + sz);
4406 buf2_dma = dvbuf_dma + sz;
4409 pcfg0Data = (SCSIDevicePage0_t *) (pDvBuf + sz);
4410 cfg0_dma_addr = dvbuf_dma + sz;
4411 sz += header0.PageLength * 4;
4415 if (header0.PageLength & 1)
4418 pcfg1Data = (SCSIDevicePage1_t *) (pDvBuf + sz);
4419 cfg1_dma_addr = dvbuf_dma + sz;
4421 /* Skip this ID? Set cfg.hdr to force config page write
4424 ScsiCfgData *pspi_data = &hd->ioc->spi_data;
4425 if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
4426 /* Set the factor from nvram */
4427 nfactor = (pspi_data->nvram[id] & MPT_NVRAM_SYNC_MASK) >> 8;
4428 if (nfactor < pspi_data->minSyncFactor )
4429 nfactor = pspi_data->minSyncFactor;
4431 if (!(pspi_data->nvram[id] & MPT_NVRAM_ID_SCAN_ENABLE) ||
4432 (pspi_data->PortFlags == MPI_SCSIPORTPAGE2_PORT_FLAGS_OFF_DV) ) {
4434 ddvprintk((MYIOC_s_NOTE_FMT "DV Skipped: bus, id, lun (%d, %d, %d)\n",
4435 ioc->name, bus, id, lun));
4437 dv.cmd = MPT_SET_MAX;
4438 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
4441 /* Save the final negotiated settings to
4442 * SCSI device page 1.
4444 cfg.physAddr = cfg1_dma_addr;
4445 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4447 mpt_config(hd->ioc, &cfg);
4453 /* Finish iocmd inititialization - hidden or visible disk? */
4454 if (ioc->spi_data.pIocPg3) {
4455 /* Search IOC page 3 for matching id
4457 Ioc3PhysDisk_t *pPDisk = ioc->spi_data.pIocPg3->PhysDisk;
4458 int numPDisk = ioc->spi_data.pIocPg3->NumPhysDisks;
4461 if (pPDisk->PhysDiskID == id) {
4463 iocmd.flags |= MPT_ICFLAG_PHYS_DISK;
4464 iocmd.physDiskNum = pPDisk->PhysDiskNum;
4468 if (mptscsih_do_raid(hd, MPI_RAID_ACTION_QUIESCE_PHYS_IO, &iocmd) < 0) {
4469 ddvprintk((MYIOC_s_ERR_FMT "RAID Queisce FAILED!\n", ioc->name));
4479 /* RAID Volume ID's may double for a physical device. If RAID but
4480 * not a physical ID as well, skip DV.
4482 if ((hd->ioc->spi_data.isRaid & (1 << id)) && !(iocmd.flags & MPT_ICFLAG_PHYS_DISK))
4487 * Async & Narrow - Inquiry
4488 * Async & Narrow - Inquiry
4489 * Maximum transfer rate - Inquiry
4491 * If compare, test complete.
4492 * If miscompare and first pass, repeat
4493 * If miscompare and not first pass, fall back and repeat
4497 sz = SCSI_MAX_INQUIRY_BYTES;
4498 rc = MPT_SCANDV_GOOD;
4500 ddvprintk((MYIOC_s_NOTE_FMT "DV: Start Basic test on id=%d\n", ioc->name, id));
4502 dv.cmd = MPT_SET_MIN;
4503 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
4506 cfg.physAddr = cfg1_dma_addr;
4507 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4509 if (mpt_config(hd->ioc, &cfg) != 0)
4512 /* Wide - narrow - wide workaround case
4514 if ((rc == MPT_SCANDV_ISSUE_SENSE) && dv.max.width) {
4515 /* Send an untagged command to reset disk Qs corrupted
4516 * when a parity error occurs on a Request Sense.
4518 if ((hd->ioc->facts.FWVersion.Word >= 0x01000600) ||
4519 ((hd->ioc->facts.FWVersion.Word >= 0x01010000) &&
4520 (hd->ioc->facts.FWVersion.Word < 0x01010B00)) ) {
4522 iocmd.cmd = REQUEST_SENSE;
4523 iocmd.data_dma = buf1_dma;
4526 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4529 if (hd->pLocal == NULL)
4531 rc = hd->pLocal->completion;
4532 if ((rc == MPT_SCANDV_GOOD) || (rc == MPT_SCANDV_SENSE)) {
4542 iocmd.cmd = INQUIRY;
4543 iocmd.data_dma = buf1_dma;
4546 memset(pbuf1, 0x00, sz);
4547 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4550 if (hd->pLocal == NULL)
4552 rc = hd->pLocal->completion;
4553 if (rc == MPT_SCANDV_GOOD) {
4554 if (hd->pLocal->scsiStatus == SAM_STAT_BUSY) {
4555 if ((iocmd.flags & MPT_ICFLAG_TAGGED_CMD) == 0)
4562 } else if (rc == MPT_SCANDV_SENSE) {
4565 /* If first command doesn't complete
4566 * with a good status or with a check condition,
4573 /* Reset the size for disks
4575 inq0 = (*pbuf1) & 0x1F;
4576 if ((inq0 == 0) && pTarget && !pTarget->raidVolume) {
4581 /* Another GEM workaround. Check peripheral device type,
4582 * if PROCESSOR, quit DV.
4584 if (inq0 == TYPE_PROCESSOR) {
4585 mptscsih_initTarget(hd,
4597 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4601 if ((pTarget->maxWidth == 1) && (pTarget->maxOffset) && (nfactor < 0x0A)
4602 && (pTarget->minSyncFactor > 0x09)) {
4603 if ((pbuf1[56] & 0x04) == 0)
4605 else if ((pbuf1[56] & 0x01) == 1) {
4606 pTarget->minSyncFactor =
4607 nfactor > MPT_ULTRA320 ? nfactor : MPT_ULTRA320;
4609 pTarget->minSyncFactor =
4610 nfactor > MPT_ULTRA160 ? nfactor : MPT_ULTRA160;
4613 dv.max.factor = pTarget->minSyncFactor;
4615 if ((pbuf1[56] & 0x02) == 0) {
4616 pTarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
4617 hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS;
4618 ddvprintk((MYIOC_s_NOTE_FMT
4619 "DV: Start Basic noQas on id=%d due to pbuf1[56]=%x\n",
4620 ioc->name, id, pbuf1[56]));
4626 dv.cmd = MPT_FALLBACK;
4628 dv.cmd = MPT_SET_MAX;
4630 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
4631 if (mpt_config(hd->ioc, &cfg) != 0)
4634 if ((!dv.now.width) && (!dv.now.offset))
4637 iocmd.cmd = INQUIRY;
4638 iocmd.data_dma = buf2_dma;
4641 memset(pbuf2, 0x00, sz);
4642 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4644 else if (hd->pLocal == NULL)
4647 /* Save the return code.
4648 * If this is the first pass,
4649 * read SCSI Device Page 0
4650 * and update the target max parameters.
4652 rc = hd->pLocal->completion;
4654 if (rc == MPT_SCANDV_GOOD) {
4660 cfg.physAddr = cfg0_dma_addr;
4661 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4664 if (mpt_config(hd->ioc, &cfg) != 0)
4667 sdp0_info = le32_to_cpu(pcfg0Data->Information) & 0x0E;
4668 sdp0_nego = (le32_to_cpu(pcfg0Data->NegotiatedParameters) & 0xFF00 ) >> 8;
4670 /* Quantum and Fujitsu workarounds.
4671 * Quantum: PPR U320 -> PPR reply with Ultra2 and wide
4672 * Fujitsu: PPR U320 -> Msg Reject and Ultra2 and wide
4673 * Resetart with a request for U160.
4675 if ((dv.now.factor == MPT_ULTRA320) && (sdp0_nego == MPT_ULTRA2)) {
4678 dv.cmd = MPT_UPDATE_MAX;
4679 mptscsih_dv_parms(hd, &dv, (void *)pcfg0Data);
4680 /* Update the SCSI device page 1 area
4682 pcfg1Data->RequestedParameters = pcfg0Data->NegotiatedParameters;
4687 /* Quantum workaround. Restart this test will the fallback
4690 if (doFallback == 0) {
4691 if (memcmp(pbuf1, pbuf2, sz) != 0) {
4695 ddvprintk((MYIOC_s_NOTE_FMT
4696 "DV:Inquiry compared id=%d, calling initTarget\n", ioc->name, id));
4697 hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_NOT_DONE;
4698 mptscsih_initTarget(hd,
4704 break; /* test complete */
4709 } else if (rc == MPT_SCANDV_ISSUE_SENSE)
4710 doFallback = 1; /* set fallback flag */
4711 else if ((rc == MPT_SCANDV_DID_RESET) ||
4712 (rc == MPT_SCANDV_SENSE) ||
4713 (rc == MPT_SCANDV_FALLBACK))
4714 doFallback = 1; /* set fallback flag */
4721 ddvprintk((MYIOC_s_NOTE_FMT "DV: Basic test on id=%d completed OK.\n", ioc->name, id));
4723 if (ioc->spi_data.mpt_dv == 0)
4726 inq0 = (*pbuf1) & 0x1F;
4728 /* Continue only for disks
4733 if ( ioc->spi_data.PortFlags == MPI_SCSIPORTPAGE2_PORT_FLAGS_BASIC_DV_ONLY )
4736 /* Start the Enhanced Test.
4737 * 0) issue TUR to clear out check conditions
4738 * 1) read capacity of echo (regular) buffer
4740 * 3) do write-read-compare data pattern test
4742 * 5) update nego parms to target struct
4745 cfg.physAddr = cfg1_dma_addr;
4746 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4749 iocmd.cmd = TEST_UNIT_READY;
4750 iocmd.data_dma = -1;
4755 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4758 if (hd->pLocal == NULL)
4761 rc = hd->pLocal->completion;
4762 if (rc == MPT_SCANDV_GOOD)
4764 else if (rc == MPT_SCANDV_SENSE) {
4765 u8 skey = hd->pLocal->sense[2] & 0x0F;
4766 u8 asc = hd->pLocal->sense[12];
4767 u8 ascq = hd->pLocal->sense[13];
4768 ddvprintk((MYIOC_s_INFO_FMT
4769 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
4770 ioc->name, skey, asc, ascq));
4772 if (skey == UNIT_ATTENTION)
4773 notDone++; /* repeat */
4774 else if ((skey == NOT_READY) &&
4775 (asc == 0x04)&&(ascq == 0x01)) {
4776 /* wait then repeat */
4779 } else if ((skey == NOT_READY) && (asc == 0x3A)) {
4780 /* no medium, try read test anyway */
4783 /* All other errors are fatal.
4785 ddvprintk((MYIOC_s_INFO_FMT "DV: fatal error.",
4793 iocmd.cmd = READ_BUFFER;
4794 iocmd.data_dma = buf1_dma;
4797 iocmd.flags |= MPT_ICFLAG_BUF_CAP;
4801 for (patt = 0; patt < 2; patt++) {
4803 iocmd.flags |= MPT_ICFLAG_ECHO;
4805 iocmd.flags &= ~MPT_ICFLAG_ECHO;
4811 /* If not ready after 8 trials,
4812 * give up on this device.
4817 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4819 else if (hd->pLocal == NULL)
4822 rc = hd->pLocal->completion;
4823 ddvprintk(("ReadBuffer Comp Code %d", rc));
4824 ddvprintk((" buff: %0x %0x %0x %0x\n",
4825 pbuf1[0], pbuf1[1], pbuf1[2], pbuf1[3]));
4827 if (rc == MPT_SCANDV_GOOD) {
4829 if (iocmd.flags & MPT_ICFLAG_ECHO) {
4830 bufsize = ((pbuf1[2] & 0x1F) <<8) | pbuf1[3];
4832 bufsize = pbuf1[1]<<16 | pbuf1[2]<<8 | pbuf1[3];
4834 } else if (rc == MPT_SCANDV_SENSE) {
4835 u8 skey = hd->pLocal->sense[2] & 0x0F;
4836 u8 asc = hd->pLocal->sense[12];
4837 u8 ascq = hd->pLocal->sense[13];
4838 ddvprintk((MYIOC_s_INFO_FMT
4839 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
4840 ioc->name, skey, asc, ascq));
4841 if (skey == ILLEGAL_REQUEST) {
4843 } else if (skey == UNIT_ATTENTION) {
4844 notDone++; /* repeat */
4845 } else if ((skey == NOT_READY) &&
4846 (asc == 0x04)&&(ascq == 0x01)) {
4847 /* wait then repeat */
4851 /* All other errors are fatal.
4853 ddvprintk((MYIOC_s_INFO_FMT "DV: fatal error.",
4858 /* All other errors are fatal
4865 if (iocmd.flags & MPT_ICFLAG_ECHO)
4866 echoBufSize = bufsize;
4868 dataBufSize = bufsize;
4871 iocmd.flags &= ~MPT_ICFLAG_BUF_CAP;
4873 /* Use echo buffers if possible,
4874 * Exit if both buffers are 0.
4876 if (echoBufSize > 0) {
4877 iocmd.flags |= MPT_ICFLAG_ECHO;
4878 if (dataBufSize > 0)
4879 bufsize = min(echoBufSize, dataBufSize);
4881 bufsize = echoBufSize;
4882 } else if (dataBufSize == 0)
4885 ddvprintk((MYIOC_s_INFO_FMT "%s Buffer Capacity %d\n", ioc->name,
4886 (iocmd.flags & MPT_ICFLAG_ECHO) ? "Echo" : " ", bufsize));
4888 /* Data buffers for write-read-compare test max 1K.
4890 sz = min(bufsize, 1024);
4893 * On first pass, always issue a reserve.
4894 * On additional loops, only if a reset has occurred.
4895 * iocmd.flags indicates if echo or regular buffer
4897 for (patt = 0; patt < 4; patt++) {
4898 ddvprintk(("Pattern %d\n", patt));
4899 if ((iocmd.flags & MPT_ICFLAG_RESERVED) && (iocmd.flags & MPT_ICFLAG_DID_RESET)) {
4900 iocmd.cmd = TEST_UNIT_READY;
4901 iocmd.data_dma = -1;
4904 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4907 iocmd.cmd = RELEASE;
4908 iocmd.data_dma = -1;
4911 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4913 else if (hd->pLocal == NULL)
4916 rc = hd->pLocal->completion;
4917 ddvprintk(("Release rc %d\n", rc));
4918 if (rc == MPT_SCANDV_GOOD)
4919 iocmd.flags &= ~MPT_ICFLAG_RESERVED;
4923 iocmd.flags &= ~MPT_ICFLAG_RESERVED;
4925 iocmd.flags &= ~MPT_ICFLAG_DID_RESET;
4928 while (repeat && (!(iocmd.flags & MPT_ICFLAG_RESERVED))) {
4929 iocmd.cmd = RESERVE;
4930 iocmd.data_dma = -1;
4933 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4935 else if (hd->pLocal == NULL)
4938 rc = hd->pLocal->completion;
4939 if (rc == MPT_SCANDV_GOOD) {
4940 iocmd.flags |= MPT_ICFLAG_RESERVED;
4941 } else if (rc == MPT_SCANDV_SENSE) {
4942 /* Wait if coming ready
4944 u8 skey = hd->pLocal->sense[2] & 0x0F;
4945 u8 asc = hd->pLocal->sense[12];
4946 u8 ascq = hd->pLocal->sense[13];
4947 ddvprintk((MYIOC_s_INFO_FMT
4948 "DV: Reserve Failed: ", ioc->name));
4949 ddvprintk(("SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
4952 if ((skey == NOT_READY) && (asc == 0x04)&&
4954 /* wait then repeat */
4958 ddvprintk((MYIOC_s_INFO_FMT
4959 "DV: Reserved Failed.", ioc->name));
4963 ddvprintk((MYIOC_s_INFO_FMT "DV: Reserved Failed.",
4970 mptscsih_fillbuf(pbuf1, sz, patt, 1);
4971 iocmd.cmd = WRITE_BUFFER;
4972 iocmd.data_dma = buf1_dma;
4975 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4977 else if (hd->pLocal == NULL)
4980 rc = hd->pLocal->completion;
4981 if (rc == MPT_SCANDV_GOOD)
4982 ; /* Issue read buffer */
4983 else if (rc == MPT_SCANDV_DID_RESET) {
4984 /* If using echo buffers, reset to data buffers.
4985 * Else do Fallback and restart
4986 * this test (re-issue reserve
4987 * because of bus reset).
4989 if ((iocmd.flags & MPT_ICFLAG_ECHO) && (dataBufSize >= bufsize)) {
4990 iocmd.flags &= ~MPT_ICFLAG_ECHO;
4992 dv.cmd = MPT_FALLBACK;
4993 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
4995 if (mpt_config(hd->ioc, &cfg) != 0)
4998 if ((!dv.now.width) && (!dv.now.offset))
5002 iocmd.flags |= MPT_ICFLAG_DID_RESET;
5005 } else if (rc == MPT_SCANDV_SENSE) {
5006 /* Restart data test if UA, else quit.
5008 u8 skey = hd->pLocal->sense[2] & 0x0F;
5009 ddvprintk((MYIOC_s_INFO_FMT
5010 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n", ioc->name, skey,
5011 hd->pLocal->sense[12], hd->pLocal->sense[13]));
5012 if (skey == UNIT_ATTENTION) {
5015 } else if (skey == ILLEGAL_REQUEST) {
5016 if (iocmd.flags & MPT_ICFLAG_ECHO) {
5017 if (dataBufSize >= bufsize) {
5018 iocmd.flags &= ~MPT_ICFLAG_ECHO;
5033 iocmd.cmd = READ_BUFFER;
5034 iocmd.data_dma = buf2_dma;
5037 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5039 else if (hd->pLocal == NULL)
5042 rc = hd->pLocal->completion;
5043 if (rc == MPT_SCANDV_GOOD) {
5044 /* If buffers compare,
5045 * go to next pattern,
5046 * else, do a fallback and restart
5047 * data transfer test.
5049 if (memcmp (pbuf1, pbuf2, sz) == 0) {
5050 ; /* goto next pattern */
5052 /* Miscompare with Echo buffer, go to data buffer,
5053 * if that buffer exists.
5054 * Miscompare with Data buffer, check first 4 bytes,
5055 * some devices return capacity. Exit in this case.
5057 if (iocmd.flags & MPT_ICFLAG_ECHO) {
5058 if (dataBufSize >= bufsize)
5059 iocmd.flags &= ~MPT_ICFLAG_ECHO;
5063 if (dataBufSize == (pbuf2[1]<<16 | pbuf2[2]<<8 | pbuf2[3])) {
5064 /* Argh. Device returning wrong data.
5065 * Quit DV for this device.
5070 /* Had an actual miscompare. Slow down.*/
5071 dv.cmd = MPT_FALLBACK;
5072 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5074 if (mpt_config(hd->ioc, &cfg) != 0)
5077 if ((!dv.now.width) && (!dv.now.offset))
5084 } else if (rc == MPT_SCANDV_DID_RESET) {
5085 /* Do Fallback and restart
5086 * this test (re-issue reserve
5087 * because of bus reset).
5089 dv.cmd = MPT_FALLBACK;
5090 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5092 if (mpt_config(hd->ioc, &cfg) != 0)
5095 if ((!dv.now.width) && (!dv.now.offset))
5098 iocmd.flags |= MPT_ICFLAG_DID_RESET;
5101 } else if (rc == MPT_SCANDV_SENSE) {
5102 /* Restart data test if UA, else quit.
5104 u8 skey = hd->pLocal->sense[2] & 0x0F;
5105 ddvprintk((MYIOC_s_INFO_FMT
5106 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n", ioc->name, skey,
5107 hd->pLocal->sense[12], hd->pLocal->sense[13]));
5108 if (skey == UNIT_ATTENTION) {
5120 } /* --- end of patt loop ---- */
5123 if (iocmd.flags & MPT_ICFLAG_RESERVED) {
5124 iocmd.cmd = RELEASE;
5125 iocmd.data_dma = -1;
5128 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5129 printk(MYIOC_s_INFO_FMT "DV: Release failed. id %d",
5131 else if (hd->pLocal) {
5132 if (hd->pLocal->completion == MPT_SCANDV_GOOD)
5133 iocmd.flags &= ~MPT_ICFLAG_RESERVED;
5135 printk(MYIOC_s_INFO_FMT "DV: Release failed. id %d",
5141 /* Set if cfg1_dma_addr contents is valid
5143 if ((cfg.hdr != NULL) && (retcode == 0)){
5144 /* If disk, not U320, disable QAS
5146 if ((inq0 == 0) && (dv.now.factor > MPT_ULTRA320)) {
5147 hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS;
5148 ddvprintk((MYIOC_s_NOTE_FMT
5149 "noQas set due to id=%d has factor=%x\n", ioc->name, id, dv.now.factor));
5153 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5155 /* Double writes to SDP1 can cause problems,
5156 * skip save of the final negotiated settings to
5157 * SCSI device page 1.
5160 cfg.physAddr = cfg1_dma_addr;
5161 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5163 mpt_config(hd->ioc, &cfg);
5167 /* If this is a RAID Passthrough, enable internal IOs
5169 if (iocmd.flags & MPT_ICFLAG_PHYS_DISK) {
5170 if (mptscsih_do_raid(hd, MPI_RAID_ACTION_ENABLE_PHYS_IO, &iocmd) < 0)
5171 ddvprintk((MYIOC_s_ERR_FMT "RAID Enable FAILED!\n", ioc->name));
5174 /* Done with the DV scan of the current target
5177 pci_free_consistent(ioc->pcidev, dv_alloc, pDvBuf, dvbuf_dma);
5179 ddvtprintk((MYIOC_s_INFO_FMT "DV Done id=%d\n",
5185 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5186 /* mptscsih_dv_parms - perform a variety of operations on the
5187 * parameters used for negotiation.
5188 * @hd: Pointer to a SCSI host.
5189 * @dv: Pointer to a structure that contains the maximum and current
5190 * negotiated parameters.
5193 mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
5195 VirtDevice *pTarget;
5196 SCSIDevicePage0_t *pPage0;
5197 SCSIDevicePage1_t *pPage1;
5198 int val = 0, data, configuration;
5207 case MPT_GET_NVRAM_VALS:
5208 ddvprintk((MYIOC_s_NOTE_FMT "Getting NVRAM: ",
5210 /* Get the NVRAM values and save in tmax
5211 * If not an LVD bus, the adapter minSyncFactor has been
5212 * already throttled back.
5214 if ((hd->Targets)&&((pTarget = hd->Targets[(int)id]) != NULL) && !pTarget->raidVolume) {
5215 width = pTarget->maxWidth;
5216 offset = pTarget->maxOffset;
5217 factor = pTarget->minSyncFactor;
5218 negoFlags = pTarget->negoFlags;
5220 if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
5221 data = hd->ioc->spi_data.nvram[id];
5222 width = data & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
5223 if ((offset = hd->ioc->spi_data.maxSyncOffset) == 0)
5226 factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT;
5227 if ((factor == 0) || (factor == MPT_ASYNC)){
5238 /* Set the negotiation flags */
5239 negoFlags = hd->ioc->spi_data.noQas;
5241 negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
5244 negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
5247 /* limit by adapter capabilities */
5248 width = min(width, hd->ioc->spi_data.maxBusWidth);
5249 offset = min(offset, hd->ioc->spi_data.maxSyncOffset);
5250 factor = max(factor, hd->ioc->spi_data.minSyncFactor);
5252 /* Check Consistency */
5253 if (offset && (factor < MPT_ULTRA2) && !width)
5254 factor = MPT_ULTRA2;
5256 dv->max.width = width;
5257 dv->max.offset = offset;
5258 dv->max.factor = factor;
5259 dv->max.flags = negoFlags;
5260 ddvprintk((" id=%d width=%d factor=%x offset=%x flags=%x\n",
5261 id, width, factor, offset, negoFlags));
5264 case MPT_UPDATE_MAX:
5265 ddvprintk((MYIOC_s_NOTE_FMT
5266 "Updating with SDP0 Data: ", hd->ioc->name));
5267 /* Update tmax values with those from Device Page 0.*/
5268 pPage0 = (SCSIDevicePage0_t *) pPage;
5270 val = cpu_to_le32(pPage0->NegotiatedParameters);
5271 dv->max.width = val & MPI_SCSIDEVPAGE0_NP_WIDE ? 1 : 0;
5272 dv->max.offset = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK) >> 16;
5273 dv->max.factor = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK) >> 8;
5276 dv->now.width = dv->max.width;
5277 dv->now.offset = dv->max.offset;
5278 dv->now.factor = dv->max.factor;
5279 ddvprintk(("id=%d width=%d factor=%x offset=%x flags=%x\n",
5280 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags));
5284 ddvprintk((MYIOC_s_NOTE_FMT "Setting Max: ",
5286 /* Set current to the max values. Update the config page.*/
5287 dv->now.width = dv->max.width;
5288 dv->now.offset = dv->max.offset;
5289 dv->now.factor = dv->max.factor;
5290 dv->now.flags = dv->max.flags;
5292 pPage1 = (SCSIDevicePage1_t *)pPage;
5294 mptscsih_setDevicePage1Flags (dv->now.width, dv->now.factor,
5295 dv->now.offset, &val, &configuration, dv->now.flags);
5296 dnegoprintk(("Setting Max: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
5297 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags, val, configuration));
5298 pPage1->RequestedParameters = le32_to_cpu(val);
5299 pPage1->Reserved = 0;
5300 pPage1->Configuration = le32_to_cpu(configuration);
5303 ddvprintk(("id=%d width=%d factor=%x offset=%x flags=%x request=%x configuration=%x\n",
5304 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags, val, configuration));
5308 ddvprintk((MYIOC_s_NOTE_FMT "Setting Min: ",
5310 /* Set page to asynchronous and narrow
5311 * Do not update now, breaks fallback routine. */
5315 negoFlags = dv->max.flags;
5317 pPage1 = (SCSIDevicePage1_t *)pPage;
5319 mptscsih_setDevicePage1Flags (width, factor,
5320 offset, &val, &configuration, negoFlags);
5321 dnegoprintk(("Setting Min: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
5322 id, width, factor, offset, negoFlags, val, configuration));
5323 pPage1->RequestedParameters = le32_to_cpu(val);
5324 pPage1->Reserved = 0;
5325 pPage1->Configuration = le32_to_cpu(configuration);
5327 ddvprintk(("id=%d width=%d factor=%x offset=%x request=%x config=%x negoFlags=%x\n",
5328 id, width, factor, offset, val, configuration, negoFlags));
5332 ddvprintk((MYIOC_s_NOTE_FMT
5333 "Fallback: Start: offset %d, factor %x, width %d \n",
5334 hd->ioc->name, dv->now.offset,
5335 dv->now.factor, dv->now.width));
5336 width = dv->now.width;
5337 offset = dv->now.offset;
5338 factor = dv->now.factor;
5339 if ((offset) && (dv->max.width)) {
5340 if (factor < MPT_ULTRA160)
5341 factor = MPT_ULTRA160;
5342 else if (factor < MPT_ULTRA2) {
5343 factor = MPT_ULTRA2;
5345 } else if ((factor == MPT_ULTRA2) && width) {
5346 factor = MPT_ULTRA2;
5348 } else if (factor < MPT_ULTRA) {
5351 } else if ((factor == MPT_ULTRA) && width) {
5353 } else if (factor < MPT_FAST) {
5356 } else if ((factor == MPT_FAST) && width) {
5359 } else if (factor < MPT_SCSI) {
5362 } else if ((factor == MPT_SCSI) && width) {
5370 } else if (offset) {
5372 if (factor < MPT_ULTRA)
5374 else if (factor < MPT_FAST)
5376 else if (factor < MPT_SCSI)
5387 dv->max.flags |= MPT_TARGET_NO_NEGO_QAS;
5388 dv->max.flags &= ~MPT_TAPE_NEGO_IDP;
5390 dv->now.width = width;
5391 dv->now.offset = offset;
5392 dv->now.factor = factor;
5393 dv->now.flags = dv->max.flags;
5395 pPage1 = (SCSIDevicePage1_t *)pPage;
5397 mptscsih_setDevicePage1Flags (width, factor, offset, &val,
5398 &configuration, dv->now.flags);
5399 dnegoprintk(("Finish: id=%d width=%d offset=%d factor=%x flags=%x request=%x config=%x\n",
5400 id, width, offset, factor, dv->now.flags, val, configuration));
5402 pPage1->RequestedParameters = le32_to_cpu(val);
5403 pPage1->Reserved = 0;
5404 pPage1->Configuration = le32_to_cpu(configuration);
5407 ddvprintk(("Finish: id=%d offset=%d factor=%x width=%d request=%x config=%x\n",
5408 id, dv->now.offset, dv->now.factor, dv->now.width, val, configuration));
5412 ddvprintk((MYIOC_s_NOTE_FMT
5413 "Saving to Target structure: ", hd->ioc->name));
5414 ddvprintk(("id=%d width=%x factor=%x offset=%d flags=%x\n",
5415 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags));
5417 /* Save these values to target structures
5418 * or overwrite nvram (phys disks only).
5421 if ((hd->Targets)&&((pTarget = hd->Targets[(int)id]) != NULL) && !pTarget->raidVolume ) {
5422 pTarget->maxWidth = dv->now.width;
5423 pTarget->maxOffset = dv->now.offset;
5424 pTarget->minSyncFactor = dv->now.factor;
5425 pTarget->negoFlags = dv->now.flags;
5427 /* Preserv all flags, use
5428 * read-modify-write algorithm
5430 if (hd->ioc->spi_data.nvram) {
5431 data = hd->ioc->spi_data.nvram[id];
5434 data &= ~MPT_NVRAM_WIDE_DISABLE;
5436 data |= MPT_NVRAM_WIDE_DISABLE;
5438 if (!dv->now.offset)
5441 data &= ~MPT_NVRAM_SYNC_MASK;
5442 data |= (dv->now.factor << MPT_NVRAM_SYNC_SHIFT) & MPT_NVRAM_SYNC_MASK;
5444 hd->ioc->spi_data.nvram[id] = data;
5451 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5452 /* mptscsih_fillbuf - fill a buffer with a special data pattern
5453 * cleanup. For bus scan only.
5455 * @buffer: Pointer to data buffer to be filled.
5456 * @size: Number of bytes to fill
5457 * @index: Pattern index
5458 * @width: bus width, 0 (8 bits) or 1 (16 bits)
5461 mptscsih_fillbuf(char *buffer, int size, int index, int width)
5472 /* Pattern: 0000 FFFF 0000 FFFF
5474 for (ii=0; ii < size; ii++, ptr++) {
5481 /* Pattern: 00 FF 00 FF
5483 for (ii=0; ii < size; ii++, ptr++) {
5494 /* Pattern: 5555 AAAA 5555 AAAA 5555
5496 for (ii=0; ii < size; ii++, ptr++) {
5503 /* Pattern: 55 AA 55 AA 55
5505 for (ii=0; ii < size; ii++, ptr++) {
5515 /* Pattern: 00 01 02 03 04 05
5518 for (ii=0; ii < size; ii++, ptr++)
5524 /* Wide Pattern: FFFE 0001 FFFD 0002
5525 * ... 4000 DFFF 8000 EFFF
5528 for (ii=0; ii < size/2; ii++) {
5529 /* Create the base pattern
5532 /* every 64 (0x40) bytes flip the pattern
5533 * since we fill 2 bytes / iteration,
5534 * test for ii = 0x20
5540 *ptr = (char)( (val & 0xFF00) >> 8);
5542 *ptr = (char)(val & 0xFF);
5547 *ptr = (char)( (val & 0xFF00) >> 8);
5549 *ptr = (char)(val & 0xFF);
5555 /* Narrow Pattern: FE 01 FD 02 FB 04
5556 * .. 7F 80 01 FE 02 FD ... 80 7F
5559 for (ii=0; ii < size; ii++, ptr++) {
5560 /* Base pattern - first 32 bytes
5567 *ptr = (char) (~(1 << byte));
5570 /* Flip the pattern every 32 bytes
5579 #endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */
5581 EXPORT_SYMBOL(mptscsih_remove);
5582 EXPORT_SYMBOL(mptscsih_shutdown);
5584 EXPORT_SYMBOL(mptscsih_suspend);
5585 EXPORT_SYMBOL(mptscsih_resume);
5587 EXPORT_SYMBOL(mptscsih_proc_info);
5588 EXPORT_SYMBOL(mptscsih_info);
5589 EXPORT_SYMBOL(mptscsih_qcmd);
5590 EXPORT_SYMBOL(mptscsih_slave_alloc);
5591 EXPORT_SYMBOL(mptscsih_slave_destroy);
5592 EXPORT_SYMBOL(mptscsih_slave_configure);
5593 EXPORT_SYMBOL(mptscsih_abort);
5594 EXPORT_SYMBOL(mptscsih_dev_reset);
5595 EXPORT_SYMBOL(mptscsih_bus_reset);
5596 EXPORT_SYMBOL(mptscsih_host_reset);
5597 EXPORT_SYMBOL(mptscsih_bios_param);
5598 EXPORT_SYMBOL(mptscsih_io_done);
5599 EXPORT_SYMBOL(mptscsih_taskmgmt_complete);
5600 EXPORT_SYMBOL(mptscsih_scandv_complete);
5601 EXPORT_SYMBOL(mptscsih_event_process);
5602 EXPORT_SYMBOL(mptscsih_ioc_reset);
5603 EXPORT_SYMBOL(mptscsih_store_queue_depth);
5604 EXPORT_SYMBOL(mptscsih_timer_expired);
5606 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/