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 pci_dev *);
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_ERR_FMT "getFreeChainBuffer chainBuf=%p ChainBuffer=%p offset=%d chain_idx=%d\n",
285 ioc->name, chainBuf, ioc->ChainBuffer, offset, chain_idx));
288 chain_idx = MPT_HOST_NO_CHAIN;
289 dfailprintk((MYIOC_s_INFO_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_INFO_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 if ((mptscsih_getFreeChainBuffer(ioc, &newIndex)) == FAILED) {
495 dfailprintk((MYIOC_s_INFO_FMT
496 "getFreeChainBuffer FAILED SCSI cmd=%02x (%p)\n",
497 ioc->name, pReq->CDB[0], SCpnt));
501 /* Update the tracking arrays.
502 * If chainSge == NULL, update ReqToChain, else ChainToChain
505 ioc->ChainToChain[chain_idx] = newIndex;
507 ioc->ReqToChain[req_idx] = newIndex;
509 chain_idx = newIndex;
510 chain_dma_off = ioc->req_sz * chain_idx;
512 /* Populate the chainSGE for the current buffer.
513 * - Set chain buffer pointer to psge and fill
514 * out the Address and Flags fields.
516 chainSge = (char *) psge;
517 dsgprintk((KERN_INFO " Current buff @ %p (index 0x%x)",
520 /* Start the SGE for the next buffer
522 psge = (char *) (ioc->ChainBuffer + chain_dma_off);
526 dsgprintk((KERN_INFO " Chain buff @ %p (index 0x%x)\n",
529 /* Start the SGE for the next buffer
536 } /* mptscsih_AddSGE() */
538 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
540 * mptscsih_io_done - Main SCSI IO callback routine registered to
541 * Fusion MPT (base) driver
542 * @ioc: Pointer to MPT_ADAPTER structure
543 * @mf: Pointer to original MPT request frame
544 * @r: Pointer to MPT reply frame (NULL if TurboReply)
546 * This routine is called from mpt.c::mpt_interrupt() at the completion
547 * of any SCSI IO request.
548 * This routine is registered with the Fusion MPT (base) driver at driver
549 * load/init time via the mpt_register() API call.
551 * Returns 1 indicating alloc'd request frame ptr should be freed.
554 mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
556 struct scsi_cmnd *sc;
558 SCSIIORequest_t *pScsiReq;
559 SCSIIOReply_t *pScsiReply;
562 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
564 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
565 sc = hd->ScsiLookup[req_idx];
567 MPIHeader_t *hdr = (MPIHeader_t *)mf;
569 /* Remark: writeSDP1 will use the ScsiDoneCtx
570 * If a SCSI I/O cmd, device disabled by OS and
571 * completion done. Cannot touch sc struct. Just free mem.
573 if (hdr->Function == MPI_FUNCTION_SCSI_IO_REQUEST)
574 printk(MYIOC_s_ERR_FMT "NULL ScsiCmd ptr!\n",
577 mptscsih_freeChainBuffers(ioc, req_idx);
581 sc->result = DID_OK << 16; /* Set default reply as OK */
582 pScsiReq = (SCSIIORequest_t *) mf;
583 pScsiReply = (SCSIIOReply_t *) mr;
585 if((ioc->facts.MsgVersion >= MPI_VERSION_01_05) && pScsiReply){
586 dmfprintk((MYIOC_s_INFO_FMT
587 "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d,task-tag=%d)\n",
588 ioc->name, mf, mr, sc, req_idx, pScsiReply->TaskTag));
590 dmfprintk((MYIOC_s_INFO_FMT
591 "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n",
592 ioc->name, mf, mr, sc, req_idx));
595 if (pScsiReply == NULL) {
596 /* special context reply handling */
601 u8 scsi_state, scsi_status;
603 status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK;
604 scsi_state = pScsiReply->SCSIState;
605 scsi_status = pScsiReply->SCSIStatus;
606 xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
607 sc->resid = sc->request_bufflen - xfer_cnt;
609 dreplyprintk((KERN_NOTICE "Reply ha=%d id=%d lun=%d:\n"
610 "IOCStatus=%04xh SCSIState=%02xh SCSIStatus=%02xh\n"
611 "resid=%d bufflen=%d xfer_cnt=%d\n",
612 ioc->id, pScsiReq->TargetID, pScsiReq->LUN[1],
613 status, scsi_state, scsi_status, sc->resid,
614 sc->request_bufflen, xfer_cnt));
616 if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)
617 mptscsih_copy_sense_data(sc, hd, mf, pScsiReply);
620 * Look for + dump FCP ResponseInfo[]!
622 if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID) {
623 printk(KERN_NOTICE " FCP_ResponseInfo=%08xh\n",
624 le32_to_cpu(pScsiReply->ResponseInfo));
628 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
630 * Maybe: DRIVER_BUSY | SUGGEST_RETRY | DID_SOFT_ERROR (retry)
631 * But not: DID_BUS_BUSY lest one risk
632 * killing interrupt handler:-(
634 sc->result = SAM_STAT_BUSY;
637 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
638 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
639 sc->result = DID_BAD_TARGET << 16;
642 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
643 /* Spoof to SCSI Selection Timeout! */
644 sc->result = DID_NO_CONNECT << 16;
646 if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF)
647 hd->sel_timeout[pScsiReq->TargetID]++;
650 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
651 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
652 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
653 /* Linux handles an unsolicited DID_RESET better
654 * than an unsolicited DID_ABORT.
656 sc->result = DID_RESET << 16;
658 /* GEM Workaround. */
659 if (ioc->bus_type == SCSI)
660 mptscsih_no_negotiate(hd, sc->device->id);
663 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
664 if ( xfer_cnt >= sc->underflow ) {
665 /* Sufficient data transfer occurred */
666 sc->result = (DID_OK << 16) | scsi_status;
667 } else if ( xfer_cnt == 0 ) {
668 /* A CRC Error causes this condition; retry */
669 sc->result = (DRIVER_SENSE << 24) | (DID_OK << 16) |
670 (CHECK_CONDITION << 1);
671 sc->sense_buffer[0] = 0x70;
672 sc->sense_buffer[2] = NO_SENSE;
673 sc->sense_buffer[12] = 0;
674 sc->sense_buffer[13] = 0;
676 sc->result = DID_SOFT_ERROR << 16;
678 dreplyprintk((KERN_NOTICE
679 "RESIDUAL_MISMATCH: result=%x on id=%d\n",
680 sc->result, sc->device->id));
683 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
685 * Do upfront check for valid SenseData and give it
688 sc->result = (DID_OK << 16) | scsi_status;
689 if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
690 /* Have already saved the status and sense data
694 if (xfer_cnt < sc->underflow) {
695 sc->result = DID_SOFT_ERROR << 16;
697 if (scsi_state & (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)) {
700 sc->result = DID_SOFT_ERROR << 16;
702 else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
703 /* Not real sure here either... */
704 sc->result = DID_RESET << 16;
708 dreplyprintk((KERN_NOTICE " sc->underflow={report ERR if < %02xh bytes xfer'd}\n",
710 dreplyprintk((KERN_NOTICE " ActBytesXferd=%02xh\n", xfer_cnt));
713 if (scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)
714 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
718 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
719 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
720 scsi_status = pScsiReply->SCSIStatus;
721 sc->result = (DID_OK << 16) | scsi_status;
722 if (scsi_state == 0) {
724 } else if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
726 * If running against circa 200003dd 909 MPT f/w,
727 * may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL
728 * (QUEUE_FULL) returned from device! --> get 0x0000?128
729 * and with SenseBytes set to 0.
731 if (pScsiReply->SCSIStatus == MPI_SCSI_STATUS_TASK_SET_FULL)
732 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
735 else if (scsi_state &
736 (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)
741 sc->result = DID_SOFT_ERROR << 16;
743 else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
744 /* Not real sure here either... */
745 sc->result = DID_RESET << 16;
747 else if (scsi_state & MPI_SCSI_STATE_QUEUE_TAG_REJECTED) {
748 /* Device Inq. data indicates that it supports
749 * QTags, but rejects QTag messages.
750 * This command completed OK.
752 * Not real sure here either so do nothing... */
755 if (sc->result == MPI_SCSI_STATUS_TASK_SET_FULL)
756 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
759 * Reservation Conflict, Busy,
760 * Command Terminated, CHECK
764 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
765 sc->result = DID_SOFT_ERROR << 16;
768 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
769 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
770 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
771 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
772 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
773 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
774 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
775 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
776 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
777 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
782 sc->result = DID_SOFT_ERROR << 16;
785 } /* switch(status) */
787 dreplyprintk((KERN_NOTICE " sc->result is %08xh\n", sc->result));
788 } /* end of address reply case */
790 /* Unmap the DMA buffers, if any. */
792 pci_unmap_sg(ioc->pcidev, (struct scatterlist *) sc->request_buffer,
793 sc->use_sg, sc->sc_data_direction);
794 } else if (sc->request_bufflen) {
795 pci_unmap_single(ioc->pcidev, sc->SCp.dma_handle,
796 sc->request_bufflen, sc->sc_data_direction);
799 hd->ScsiLookup[req_idx] = NULL;
801 sc->scsi_done(sc); /* Issue the command callback */
803 /* Free Chain buffers */
804 mptscsih_freeChainBuffers(ioc, req_idx);
809 * mptscsih_flush_running_cmds - For each command found, search
810 * Scsi_Host instance taskQ and reply to OS.
811 * Called only if recovering from a FW reload.
812 * @hd: Pointer to a SCSI HOST structure
816 * Must be called while new I/Os are being queued.
819 mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
821 MPT_ADAPTER *ioc = hd->ioc;
822 struct scsi_cmnd *SCpnt;
825 int max = ioc->req_depth;
827 dprintk((KERN_INFO MYNAM ": flush_ScsiLookup called\n"));
828 for (ii= 0; ii < max; ii++) {
829 if ((SCpnt = hd->ScsiLookup[ii]) != NULL) {
834 /* Null ScsiLookup index
836 hd->ScsiLookup[ii] = NULL;
838 mf = MPT_INDEX_2_MFPTR(ioc, ii);
839 dmfprintk(( "flush: ScsiDone (mf=%p,sc=%p)\n",
842 /* Set status, free OS resources (SG DMA buffers)
844 * Free driver resources (chain, msg buffers)
847 pci_unmap_sg(ioc->pcidev,
848 (struct scatterlist *) SCpnt->request_buffer,
850 SCpnt->sc_data_direction);
851 } else if (SCpnt->request_bufflen) {
852 pci_unmap_single(ioc->pcidev,
853 SCpnt->SCp.dma_handle,
854 SCpnt->request_bufflen,
855 SCpnt->sc_data_direction);
857 SCpnt->result = DID_RESET << 16;
858 SCpnt->host_scribble = NULL;
860 /* Free Chain buffers */
861 mptscsih_freeChainBuffers(ioc, ii);
863 /* Free Message frames */
864 mpt_free_msg_frame(ioc, mf);
866 SCpnt->scsi_done(SCpnt); /* Issue the command callback */
874 * mptscsih_search_running_cmds - Delete any commands associated
875 * with the specified target and lun. Function called only
876 * when a lun is disable by mid-layer.
877 * Do NOT access the referenced scsi_cmnd structure or
878 * members. Will cause either a paging or NULL ptr error.
879 * @hd: Pointer to a SCSI HOST structure
885 * Called from slave_destroy.
888 mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, uint target, uint lun)
890 SCSIIORequest_t *mf = NULL;
892 int max = hd->ioc->req_depth;
894 dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n",
897 for (ii=0; ii < max; ii++) {
898 if (hd->ScsiLookup[ii] != NULL) {
900 mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii);
902 dsprintk(( "search_running: found (sc=%p, mf = %p) target %d, lun %d \n",
903 hd->ScsiLookup[ii], mf, mf->TargetID, mf->LUN[1]));
905 if ((mf->TargetID != ((u8)target)) || (mf->LUN[1] != ((u8) lun)))
910 hd->ScsiLookup[ii] = NULL;
911 mptscsih_freeChainBuffers(hd->ioc, ii);
912 mpt_free_msg_frame(hd->ioc, (MPT_FRAME_HDR *)mf);
919 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
921 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
923 * mptscsih_report_queue_full - Report QUEUE_FULL status returned
924 * from a SCSI target device.
925 * @sc: Pointer to scsi_cmnd structure
926 * @pScsiReply: Pointer to SCSIIOReply_t
927 * @pScsiReq: Pointer to original SCSI request
929 * This routine periodically reports QUEUE_FULL status returned from a
930 * SCSI target device. It reports this to the console via kernel
931 * printk() API call, not more than once every 10 seconds.
934 mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq)
939 if (sc->device == NULL)
941 if (sc->device->host == NULL)
943 if ((hd = (MPT_SCSI_HOST *)sc->device->host->hostdata) == NULL)
946 if (time - hd->last_queue_full > 10 * HZ) {
947 dprintk((MYIOC_s_WARN_FMT "Device (%d:%d:%d) reported QUEUE_FULL!\n",
948 hd->ioc->name, 0, sc->device->id, sc->device->lun));
949 hd->last_queue_full = time;
953 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
955 * mptscsih_remove - Removed scsi devices
956 * @pdev: Pointer to pci_dev structure
961 mptscsih_remove(struct pci_dev *pdev)
963 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
964 struct Scsi_Host *host = ioc->sh;
973 scsi_remove_host(host);
975 if((hd = (MPT_SCSI_HOST *)host->hostdata) == NULL)
978 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
979 /* Check DV thread active */
981 spin_lock_irqsave(&dvtaskQ_lock, flags);
982 if (dvtaskQ_active) {
983 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
984 while(dvtaskQ_active && --count) {
985 set_current_state(TASK_INTERRUPTIBLE);
989 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
992 printk(KERN_ERR MYNAM ": ERROR - DV thread still active!\n");
993 #if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY)
995 printk(KERN_ERR MYNAM ": DV thread orig %d, count %d\n", 10 * HZ, count);
999 mptscsih_shutdown(pdev);
1003 if (hd->ScsiLookup != NULL) {
1004 sz1 = hd->ioc->req_depth * sizeof(void *);
1005 kfree(hd->ScsiLookup);
1006 hd->ScsiLookup = NULL;
1010 * Free pointer array.
1015 dprintk((MYIOC_s_INFO_FMT
1016 "Free'd ScsiLookup (%d) memory\n",
1017 hd->ioc->name, sz1));
1019 kfree(hd->info_kbuf);
1021 /* NULL the Scsi_Host pointer
1025 scsi_host_put(host);
1031 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1033 * mptscsih_shutdown - reboot notifier
1037 mptscsih_shutdown(struct pci_dev *pdev)
1039 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1040 struct Scsi_Host *host = ioc->sh;
1046 hd = (MPT_SCSI_HOST *)host->hostdata;
1048 /* Flush the cache of this adapter
1051 mptscsih_synchronize_cache(hd, 0);
1056 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1058 * mptscsih_suspend - Fusion MPT scsi driver suspend routine.
1063 mptscsih_suspend(struct pci_dev *pdev, pm_message_t state)
1065 mptscsih_shutdown(pdev);
1066 return mpt_suspend(pdev,state);
1069 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1071 * mptscsih_resume - Fusion MPT scsi driver resume routine.
1076 mptscsih_resume(struct pci_dev *pdev)
1078 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1079 struct Scsi_Host *host = ioc->sh;
1087 hd = (MPT_SCSI_HOST *)host->hostdata;
1091 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1093 unsigned long lflags;
1094 spin_lock_irqsave(&dvtaskQ_lock, lflags);
1095 if (!dvtaskQ_active) {
1097 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1098 INIT_WORK(&dvTaskQ_task,
1099 mptscsih_domainValidation, (void *) hd);
1100 schedule_work(&dvTaskQ_task);
1102 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1111 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1113 * mptscsih_info - Return information about MPT adapter
1114 * @SChost: Pointer to Scsi_Host structure
1116 * (linux scsi_host_template.info routine)
1118 * Returns pointer to buffer where information was written.
1121 mptscsih_info(struct Scsi_Host *SChost)
1126 h = (MPT_SCSI_HOST *)SChost->hostdata;
1129 if (h->info_kbuf == NULL)
1130 if ((h->info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)
1131 return h->info_kbuf;
1132 h->info_kbuf[0] = '\0';
1134 mpt_print_ioc_summary(h->ioc, h->info_kbuf, &size, 0, 0);
1135 h->info_kbuf[size-1] = '\0';
1138 return h->info_kbuf;
1149 mptscsih_copy_mem_info(struct info_str *info, char *data, int len)
1151 if (info->pos + len > info->length)
1152 len = info->length - info->pos;
1154 if (info->pos + len < info->offset) {
1159 if (info->pos < info->offset) {
1160 data += (info->offset - info->pos);
1161 len -= (info->offset - info->pos);
1165 memcpy(info->buffer + info->pos, data, len);
1171 mptscsih_copy_info(struct info_str *info, char *fmt, ...)
1177 va_start(args, fmt);
1178 len = vsprintf(buf, fmt, args);
1181 mptscsih_copy_mem_info(info, buf, len);
1186 mptscsih_host_info(MPT_ADAPTER *ioc, char *pbuf, off_t offset, int len)
1188 struct info_str info;
1192 info.offset = offset;
1195 mptscsih_copy_info(&info, "%s: %s, ", ioc->name, ioc->prod_name);
1196 mptscsih_copy_info(&info, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING, ioc->facts.FWVersion.Word);
1197 mptscsih_copy_info(&info, "Ports=%d, ", ioc->facts.NumberOfPorts);
1198 mptscsih_copy_info(&info, "MaxQ=%d\n", ioc->req_depth);
1200 return ((info.pos > info.offset) ? info.pos - info.offset : 0);
1203 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1205 * mptscsih_proc_info - Return information about MPT adapter
1207 * (linux scsi_host_template.info routine)
1209 * buffer: if write, user data; if read, buffer for user
1210 * length: if write, return length;
1211 * offset: if write, 0; if read, the current offset into the buffer from
1212 * the previous read.
1213 * hostno: scsi host number
1214 * func: if write = 1; if read = 0
1217 mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
1218 int length, int func)
1220 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
1221 MPT_ADAPTER *ioc = hd->ioc;
1226 * write is not supported
1232 size = mptscsih_host_info(ioc, buffer, offset, length);
1238 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1239 #define ADD_INDEX_LOG(req_ent) do { } while(0)
1241 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1243 * mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine.
1244 * @SCpnt: Pointer to scsi_cmnd structure
1245 * @done: Pointer SCSI mid-layer IO completion function
1247 * (linux scsi_host_template.queuecommand routine)
1248 * This is the primary SCSI IO start routine. Create a MPI SCSIIORequest
1249 * from a linux scsi_cmnd request and send it to the IOC.
1251 * Returns 0. (rtn value discarded by linux scsi mid-layer)
1254 mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1258 SCSIIORequest_t *pScsiReq;
1259 VirtDevice *pTarget;
1269 hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata;
1270 target = SCpnt->device->id;
1271 lun = SCpnt->device->lun;
1272 SCpnt->scsi_done = done;
1274 pTarget = hd->Targets[target];
1276 dmfprintk((MYIOC_s_INFO_FMT "qcmd: SCpnt=%p, done()=%p\n",
1277 (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt, done));
1279 if (hd->resetPending) {
1280 dtmprintk((MYIOC_s_WARN_FMT "qcmd: SCpnt=%p timeout + 60HZ\n",
1281 (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt));
1282 return SCSI_MLQUEUE_HOST_BUSY;
1286 * Put together a MPT SCSI request...
1288 if ((mf = mpt_get_msg_frame(hd->ioc->DoneCtx, hd->ioc)) == NULL) {
1289 dprintk((MYIOC_s_WARN_FMT "QueueCmd, no msg frames!!\n",
1291 return SCSI_MLQUEUE_HOST_BUSY;
1294 pScsiReq = (SCSIIORequest_t *) mf;
1296 my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
1298 ADD_INDEX_LOG(my_idx);
1300 /* TUR's being issued with scsictl=0x02000000 (DATA_IN)!
1301 * Seems we may receive a buffer (datalen>0) even when there
1302 * will be no data transfer! GRRRRR...
1304 if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
1305 datalen = SCpnt->request_bufflen;
1306 scsidir = MPI_SCSIIO_CONTROL_READ; /* DATA IN (host<--ioc<--dev) */
1307 } else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
1308 datalen = SCpnt->request_bufflen;
1309 scsidir = MPI_SCSIIO_CONTROL_WRITE; /* DATA OUT (host-->ioc-->dev) */
1312 scsidir = MPI_SCSIIO_CONTROL_NODATATRANSFER;
1315 /* Default to untagged. Once a target structure has been allocated,
1316 * use the Inquiry data to determine if device supports tagged.
1319 && (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)
1320 && (SCpnt->device->tagged_supported)) {
1321 scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
1323 scsictl = scsidir | MPI_SCSIIO_CONTROL_UNTAGGED;
1326 /* Use the above information to set up the message frame
1328 pScsiReq->TargetID = (u8) target;
1329 pScsiReq->Bus = (u8) SCpnt->device->channel;
1330 pScsiReq->ChainOffset = 0;
1331 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
1332 pScsiReq->CDBLength = SCpnt->cmd_len;
1333 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
1334 pScsiReq->Reserved = 0;
1335 pScsiReq->MsgFlags = mpt_msg_flags();
1336 pScsiReq->LUN[0] = 0;
1337 pScsiReq->LUN[1] = lun;
1338 pScsiReq->LUN[2] = 0;
1339 pScsiReq->LUN[3] = 0;
1340 pScsiReq->LUN[4] = 0;
1341 pScsiReq->LUN[5] = 0;
1342 pScsiReq->LUN[6] = 0;
1343 pScsiReq->LUN[7] = 0;
1344 pScsiReq->Control = cpu_to_le32(scsictl);
1347 * Write SCSI CDB into the message
1349 cmd_len = SCpnt->cmd_len;
1350 for (ii=0; ii < cmd_len; ii++)
1351 pScsiReq->CDB[ii] = SCpnt->cmnd[ii];
1353 for (ii=cmd_len; ii < 16; ii++)
1354 pScsiReq->CDB[ii] = 0;
1357 pScsiReq->DataLength = cpu_to_le32(datalen);
1359 /* SenseBuffer low address */
1360 pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
1361 + (my_idx * MPT_SENSE_BUFFER_ALLOC));
1363 /* Now add the SG list
1364 * Always have a SGE even if null length.
1367 /* Add a NULL SGE */
1368 mptscsih_add_sge((char *)&pScsiReq->SGL, MPT_SGE_FLAGS_SSIMPLE_READ | 0,
1371 /* Add a 32 or 64 bit SGE */
1372 if (mptscsih_AddSGE(hd->ioc, SCpnt, pScsiReq, my_idx) != SUCCESS)
1376 hd->ScsiLookup[my_idx] = SCpnt;
1377 SCpnt->host_scribble = NULL;
1379 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1380 if (hd->ioc->bus_type == SCSI) {
1381 int dvStatus = hd->ioc->spi_data.dvStatus[target];
1384 if (dvStatus || hd->ioc->spi_data.forceDv) {
1386 if ((dvStatus & MPT_SCSICFG_NEED_DV) ||
1387 (hd->ioc->spi_data.forceDv & MPT_SCSICFG_NEED_DV)) {
1388 unsigned long lflags;
1389 /* Schedule DV if necessary */
1390 spin_lock_irqsave(&dvtaskQ_lock, lflags);
1391 if (!dvtaskQ_active) {
1393 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1394 INIT_WORK(&dvTaskQ_task, mptscsih_domainValidation, (void *) hd);
1396 schedule_work(&dvTaskQ_task);
1398 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1400 hd->ioc->spi_data.forceDv &= ~MPT_SCSICFG_NEED_DV;
1403 /* Trying to do DV to this target, extend timeout.
1404 * Wait to issue until flag is clear
1406 if (dvStatus & MPT_SCSICFG_DV_PENDING) {
1407 mod_timer(&SCpnt->eh_timeout, jiffies + 40 * HZ);
1411 /* Set the DV flags.
1413 if (dvStatus & MPT_SCSICFG_DV_NOT_DONE)
1414 mptscsih_set_dvflags(hd, pScsiReq);
1422 mpt_put_msg_frame(hd->ioc->DoneCtx, hd->ioc, mf);
1423 dmfprintk((MYIOC_s_INFO_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n",
1424 hd->ioc->name, SCpnt, mf, my_idx));
1425 DBG_DUMP_REQUEST_FRAME(mf)
1429 mptscsih_freeChainBuffers(hd->ioc, my_idx);
1430 mpt_free_msg_frame(hd->ioc, mf);
1431 return SCSI_MLQUEUE_HOST_BUSY;
1434 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1436 * mptscsih_freeChainBuffers - Function to free chain buffers associated
1437 * with a SCSI IO request
1438 * @hd: Pointer to the MPT_SCSI_HOST instance
1439 * @req_idx: Index of the SCSI IO request frame.
1441 * Called if SG chain buffer allocation fails and mptscsih callbacks.
1445 mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
1447 MPT_FRAME_HDR *chain;
1448 unsigned long flags;
1452 /* Get the first chain index and reset
1455 chain_idx = ioc->ReqToChain[req_idx];
1456 ioc->ReqToChain[req_idx] = MPT_HOST_NO_CHAIN;
1458 while (chain_idx != MPT_HOST_NO_CHAIN) {
1460 /* Save the next chain buffer index */
1461 next = ioc->ChainToChain[chain_idx];
1463 /* Free this chain buffer and reset
1466 ioc->ChainToChain[chain_idx] = MPT_HOST_NO_CHAIN;
1468 chain = (MPT_FRAME_HDR *) (ioc->ChainBuffer
1469 + (chain_idx * ioc->req_sz));
1471 spin_lock_irqsave(&ioc->FreeQlock, flags);
1472 list_add_tail(&chain->u.frame.linkage.list, &ioc->FreeChainQ);
1473 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1475 dmfprintk((MYIOC_s_INFO_FMT "FreeChainBuffers (index %d)\n",
1476 ioc->name, chain_idx));
1484 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1489 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1491 * mptscsih_TMHandler - Generic handler for SCSI Task Management.
1492 * Fall through to mpt_HardResetHandler if: not operational, too many
1493 * failed TM requests or handshake failure.
1495 * @ioc: Pointer to MPT_ADAPTER structure
1496 * @type: Task Management type
1497 * @target: Logical Target ID for reset (if appropriate)
1498 * @lun: Logical Unit for reset (if appropriate)
1499 * @ctx2abort: Context for the task to be aborted (if appropriate)
1501 * Remark: Currently invoked from a non-interrupt thread (_bh).
1503 * Remark: With old EH code, at most 1 SCSI TaskMgmt function per IOC
1506 * Returns 0 for SUCCESS or -1 if FAILED.
1509 mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout)
1515 unsigned long flags;
1517 /* If FW is being reloaded currently, return success to
1518 * the calling function.
1525 printk(KERN_ERR MYNAM " TMHandler" " NULL ioc!\n");
1528 dtmprintk((MYIOC_s_INFO_FMT "TMHandler Entered!\n", ioc->name));
1530 // SJR - CHECKME - Can we avoid this here?
1531 // (mpt_HardResetHandler has this check...)
1532 spin_lock_irqsave(&ioc->diagLock, flags);
1533 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)) {
1534 spin_unlock_irqrestore(&ioc->diagLock, flags);
1537 spin_unlock_irqrestore(&ioc->diagLock, flags);
1539 /* Wait a fixed amount of time for the TM pending flag to be cleared.
1540 * If we time out and not bus reset, then we return a FAILED status to the caller.
1541 * The call to mptscsih_tm_pending_wait() will set the pending flag if we are
1542 * successful. Otherwise, reload the FW.
1544 if (mptscsih_tm_pending_wait(hd) == FAILED) {
1545 if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
1546 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler abort: "
1547 "Timed out waiting for last TM (%d) to complete! \n",
1548 hd->ioc->name, hd->tmPending));
1550 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) {
1551 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler target reset: "
1552 "Timed out waiting for last TM (%d) to complete! \n",
1553 hd->ioc->name, hd->tmPending));
1555 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
1556 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler bus reset: "
1557 "Timed out waiting for last TM (%d) to complete! \n",
1558 hd->ioc->name, hd->tmPending));
1559 if (hd->tmPending & (1 << MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS))
1565 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
1566 hd->tmPending |= (1 << type);
1567 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1572 ioc_raw_state = mpt_GetIocState(hd->ioc, 0);
1574 #ifdef MPT_DEBUG_RESET
1575 if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) {
1576 printk(MYIOC_s_WARN_FMT
1577 "TM Handler: IOC Not operational(0x%x)!\n",
1578 hd->ioc->name, ioc_raw_state);
1582 if (doTask && ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL)
1583 && !(ioc_raw_state & MPI_DOORBELL_ACTIVE)) {
1585 /* Isse the Task Mgmt request.
1587 if (hd->hard_resets < -1)
1589 rc = mptscsih_IssueTaskMgmt(hd, type, channel, target, lun, ctx2abort, timeout);
1591 printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n", hd->ioc->name);
1593 dtmprintk((MYIOC_s_INFO_FMT "Issue of TaskMgmt Successful!\n", hd->ioc->name));
1597 /* Only fall through to the HRH if this is a bus reset
1599 if ((type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) && (rc ||
1600 ioc->reload_fw || (ioc->alt_ioc && ioc->alt_ioc->reload_fw))) {
1601 dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
1603 rc = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
1606 dtmprintk((MYIOC_s_INFO_FMT "TMHandler rc = %d!\n", hd->ioc->name, rc));
1612 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1614 * mptscsih_IssueTaskMgmt - Generic send Task Management function.
1615 * @hd: Pointer to MPT_SCSI_HOST structure
1616 * @type: Task Management type
1617 * @target: Logical Target ID for reset (if appropriate)
1618 * @lun: Logical Unit for reset (if appropriate)
1619 * @ctx2abort: Context for the task to be aborted (if appropriate)
1621 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
1622 * or a non-interrupt thread. In the former, must not call schedule().
1624 * Not all fields are meaningfull for all task types.
1626 * Returns 0 for SUCCESS, -999 for "no msg frames",
1627 * else other non-zero value returned.
1630 mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout)
1633 SCSITaskMgmt_t *pScsiTm;
1637 /* Return Fail to calling function if no message frames available.
1639 if ((mf = mpt_get_msg_frame(hd->ioc->TaskCtx, hd->ioc)) == NULL) {
1640 dfailprintk((MYIOC_s_ERR_FMT "IssueTaskMgmt, no msg frames!!\n",
1644 dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt request @ %p\n",
1645 hd->ioc->name, mf));
1647 /* Format the Request
1649 pScsiTm = (SCSITaskMgmt_t *) mf;
1650 pScsiTm->TargetID = target;
1651 pScsiTm->Bus = channel;
1652 pScsiTm->ChainOffset = 0;
1653 pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
1655 pScsiTm->Reserved = 0;
1656 pScsiTm->TaskType = type;
1657 pScsiTm->Reserved1 = 0;
1658 pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)
1659 ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0;
1661 for (ii= 0; ii < 8; ii++) {
1662 pScsiTm->LUN[ii] = 0;
1664 pScsiTm->LUN[1] = lun;
1666 for (ii=0; ii < 7; ii++)
1667 pScsiTm->Reserved2[ii] = 0;
1669 pScsiTm->TaskMsgContext = ctx2abort;
1671 dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt: ctx2abort (0x%08x) type=%d\n",
1672 hd->ioc->name, ctx2abort, type));
1674 DBG_DUMP_TM_REQUEST_FRAME((u32 *)pScsiTm);
1676 if ((retval = mpt_send_handshake_request(hd->ioc->TaskCtx, hd->ioc,
1677 sizeof(SCSITaskMgmt_t), (u32*)pScsiTm,
1679 dfailprintk((MYIOC_s_ERR_FMT "_send_handshake FAILED!"
1680 " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
1682 mpt_free_msg_frame(hd->ioc, mf);
1686 if(mptscsih_tm_wait_for_completion(hd, timeout) == FAILED) {
1687 dfailprintk((MYIOC_s_ERR_FMT "_wait_for_completion FAILED!"
1688 " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
1690 mpt_free_msg_frame(hd->ioc, mf);
1691 dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
1693 retval = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
1699 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1701 * mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant
1702 * @SCpnt: Pointer to scsi_cmnd structure, IO to be aborted
1704 * (linux scsi_host_template.eh_abort_handler routine)
1706 * Returns SUCCESS or FAILED.
1709 mptscsih_abort(struct scsi_cmnd * SCpnt)
1717 /* If we can't locate our host adapter structure, return FAILED status.
1719 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL) {
1720 SCpnt->result = DID_RESET << 16;
1721 SCpnt->scsi_done(SCpnt);
1722 dfailprintk((KERN_WARNING MYNAM ": mptscsih_abort: "
1723 "Can't locate host! (sc=%p)\n",
1729 if (hd->resetPending)
1732 printk(KERN_WARNING MYNAM ": %s: >> Attempting task abort! (sc=%p)\n",
1733 hd->ioc->name, SCpnt);
1735 if (hd->timeouts < -1)
1738 /* Find this command
1740 if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) {
1741 /* Cmd not found in ScsiLookup.
1744 SCpnt->result = DID_RESET << 16;
1745 dtmprintk((KERN_WARNING MYNAM ": %s: mptscsih_abort: "
1746 "Command not in the active list! (sc=%p)\n",
1747 hd->ioc->name, SCpnt));
1751 /* Most important! Set TaskMsgContext to SCpnt's MsgContext!
1752 * (the IO to be ABORT'd)
1754 * NOTE: Since we do not byteswap MsgContext, we do not
1755 * swap it here either. It is an opaque cookie to
1756 * the controller, so it does not matter. -DaveM
1758 mf = MPT_INDEX_2_MFPTR(hd->ioc, scpnt_idx);
1759 ctx2abort = mf->u.frame.hwhdr.msgctxu.MsgContext;
1761 hd->abortSCpnt = SCpnt;
1763 if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
1764 SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun,
1765 ctx2abort, 2 /* 2 second timeout */)
1768 /* The TM request failed and the subsequent FW-reload failed!
1771 printk(MYIOC_s_WARN_FMT "Error issuing abort task! (sc=%p)\n",
1772 hd->ioc->name, SCpnt);
1774 /* We must clear our pending flag before clearing our state.
1777 hd->tmState = TM_STATE_NONE;
1779 /* Unmap the DMA buffers, if any. */
1780 if (SCpnt->use_sg) {
1781 pci_unmap_sg(ioc->pcidev, (struct scatterlist *) SCpnt->request_buffer,
1782 SCpnt->use_sg, SCpnt->sc_data_direction);
1783 } else if (SCpnt->request_bufflen) {
1784 pci_unmap_single(ioc->pcidev, SCpnt->SCp.dma_handle,
1785 SCpnt->request_bufflen, SCpnt->sc_data_direction);
1787 hd->ScsiLookup[scpnt_idx] = NULL;
1788 SCpnt->result = DID_RESET << 16;
1789 SCpnt->scsi_done(SCpnt); /* Issue the command callback */
1790 mptscsih_freeChainBuffers(ioc, scpnt_idx);
1791 mpt_free_msg_frame(ioc, mf);
1797 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1799 * mptscsih_dev_reset - Perform a SCSI TARGET_RESET! new_eh variant
1800 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1802 * (linux scsi_host_template.eh_dev_reset_handler routine)
1804 * Returns SUCCESS or FAILED.
1807 mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
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 if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
1827 SCpnt->device->channel, SCpnt->device->id,
1828 0, 0, 5 /* 5 second timeout */)
1830 /* The TM request failed and the subsequent FW-reload failed!
1833 printk(MYIOC_s_WARN_FMT "Error processing TaskMgmt request (sc=%p)\n",
1834 hd->ioc->name, SCpnt);
1836 hd->tmState = TM_STATE_NONE;
1843 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1845 * mptscsih_bus_reset - Perform a SCSI BUS_RESET! new_eh variant
1846 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1848 * (linux scsi_host_template.eh_bus_reset_handler routine)
1850 * Returns SUCCESS or FAILED.
1853 mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
1856 spinlock_t *host_lock = SCpnt->device->host->host_lock;
1858 /* If we can't locate our host adapter structure, return FAILED status.
1860 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1861 dtmprintk((KERN_WARNING MYNAM ": mptscsih_bus_reset: "
1862 "Can't locate host! (sc=%p)\n",
1867 printk(KERN_WARNING MYNAM ": %s: >> Attempting bus reset! (sc=%p)\n",
1868 hd->ioc->name, SCpnt);
1870 if (hd->timeouts < -1)
1873 /* We are now ready to execute the task management request. */
1874 if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
1875 SCpnt->device->channel, 0, 0, 0, 5 /* 5 second timeout */)
1878 /* The TM request failed and the subsequent FW-reload failed!
1881 printk(MYIOC_s_WARN_FMT
1882 "Error processing TaskMgmt request (sc=%p)\n",
1883 hd->ioc->name, SCpnt);
1885 hd->tmState = TM_STATE_NONE;
1886 spin_lock_irq(host_lock);
1893 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1895 * mptscsih_host_reset - Perform a SCSI host adapter RESET!
1897 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1899 * (linux scsi_host_template.eh_host_reset_handler routine)
1901 * Returns SUCCESS or FAILED.
1904 mptscsih_host_reset(struct scsi_cmnd *SCpnt)
1907 int status = SUCCESS;
1909 /* If we can't locate the host to reset, then we failed. */
1910 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1911 dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
1912 "Can't locate host! (sc=%p)\n",
1917 printk(KERN_WARNING MYNAM ": %s: Attempting host reset! (sc=%p)\n",
1918 hd->ioc->name, SCpnt);
1920 /* If our attempts to reset the host failed, then return a failed
1921 * status. The host will be taken off line by the SCSI mid-layer.
1923 if (mpt_HardResetHandler(hd->ioc, CAN_SLEEP) < 0){
1926 /* Make sure TM pending is cleared and TM state is set to
1930 hd->tmState = TM_STATE_NONE;
1933 dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
1935 (status == SUCCESS) ? "SUCCESS" : "FAILED" ) );
1940 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1942 * mptscsih_tm_pending_wait - wait for pending task management request to
1944 * @hd: Pointer to MPT host structure.
1946 * Returns {SUCCESS,FAILED}.
1949 mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd)
1951 unsigned long flags;
1952 int loop_count = 4 * 10; /* Wait 10 seconds */
1953 int status = FAILED;
1956 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
1957 if (hd->tmState == TM_STATE_NONE) {
1958 hd->tmState = TM_STATE_IN_PROGRESS;
1960 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1964 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1966 } while (--loop_count);
1971 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1973 * mptscsih_tm_wait_for_completion - wait for completion of TM task
1974 * @hd: Pointer to MPT host structure.
1976 * Returns {SUCCESS,FAILED}.
1979 mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout )
1981 unsigned long flags;
1982 int loop_count = 4 * timeout;
1983 int status = FAILED;
1986 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
1987 if(hd->tmPending == 0) {
1989 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1992 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1993 msleep_interruptible(250);
1994 } while (--loop_count);
1999 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2001 * mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
2002 * @ioc: Pointer to MPT_ADAPTER structure
2003 * @mf: Pointer to SCSI task mgmt request frame
2004 * @mr: Pointer to SCSI task mgmt reply frame
2006 * This routine is called from mptbase.c::mpt_interrupt() at the completion
2007 * of any SCSI task management request.
2008 * This routine is registered with the MPT (base) driver at driver
2009 * load/init time via the mpt_register() API call.
2011 * Returns 1 indicating alloc'd request frame ptr should be freed.
2014 mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
2016 SCSITaskMgmtReply_t *pScsiTmReply;
2017 SCSITaskMgmt_t *pScsiTmReq;
2019 unsigned long flags;
2023 dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt completed (mf=%p,mr=%p)\n",
2024 ioc->name, mf, mr));
2026 /* Depending on the thread, a timer is activated for
2027 * the TM request. Delete this timer on completion of TM.
2028 * Decrement count of outstanding TM requests.
2030 hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
2032 dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt Complete: NULL Scsi Host Ptr\n",
2038 dtmprintk((MYIOC_s_WARN_FMT "ERROR! TaskMgmt Reply: NULL Request %p\n",
2042 pScsiTmReply = (SCSITaskMgmtReply_t*)mr;
2043 pScsiTmReq = (SCSITaskMgmt_t*)mf;
2045 /* Figure out if this was ABORT_TASK, TARGET_RESET, or BUS_RESET! */
2046 tmType = pScsiTmReq->TaskType;
2048 dtmprintk((MYIOC_s_WARN_FMT " TaskType = %d, TerminationCount=%d\n",
2049 ioc->name, tmType, le32_to_cpu(pScsiTmReply->TerminationCount)));
2050 DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply);
2052 iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2053 dtmprintk((MYIOC_s_WARN_FMT " SCSI TaskMgmt (%d) IOCStatus=%04x IOCLogInfo=%08x\n",
2054 ioc->name, tmType, iocstatus, le32_to_cpu(pScsiTmReply->IOCLogInfo)));
2055 /* Error? (anything non-zero?) */
2058 /* clear flags and continue.
2060 if (tmType == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK)
2061 hd->abortSCpnt = NULL;
2063 /* If an internal command is present
2064 * or the TM failed - reload the FW.
2065 * FC FW may respond FAILED to an ABORT
2067 if (tmType == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
2069 (iocstatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED)) {
2070 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0) {
2071 printk((KERN_WARNING
2072 " Firmware Reload FAILED!!\n"));
2077 dtmprintk((MYIOC_s_WARN_FMT " TaskMgmt SUCCESS\n", ioc->name));
2079 hd->abortSCpnt = NULL;
2084 spin_lock_irqsave(&ioc->FreeQlock, flags);
2086 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2087 hd->tmState = TM_STATE_NONE;
2092 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2094 * This is anyones guess quite frankly.
2097 mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
2098 sector_t capacity, int geom[])
2108 dummy = heads * sectors;
2109 cylinders = capacity;
2110 sector_div(cylinders,dummy);
2113 * Handle extended translation size for logical drives
2116 if ((ulong)capacity >= 0x200000) {
2119 dummy = heads * sectors;
2120 cylinders = capacity;
2121 sector_div(cylinders,dummy);
2127 geom[2] = cylinders;
2129 dprintk((KERN_NOTICE
2130 ": bios_param: Id=%i Lun=%i Channel=%i CHS=%i/%i/%i\n",
2131 sdev->id, sdev->lun,sdev->channel,(int)cylinders,heads,sectors));
2136 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2138 * OS entry point to allow host driver to alloc memory
2139 * for each scsi device. Called once per device the bus scan.
2140 * Return non-zero if allocation fails.
2141 * Init memory once per id (not LUN).
2144 mptscsih_slave_alloc(struct scsi_device *device)
2146 struct Scsi_Host *host = device->host;
2147 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
2149 uint target = device->id;
2154 if ((vdev = hd->Targets[target]) != NULL)
2157 vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL);
2159 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
2160 hd->ioc->name, sizeof(VirtDevice));
2164 memset(vdev, 0, sizeof(VirtDevice));
2165 vdev->tflags = MPT_TARGET_FLAGS_Q_YES;
2166 vdev->ioc_id = hd->ioc->id;
2167 vdev->target_id = device->id;
2168 vdev->bus_id = device->channel;
2169 vdev->raidVolume = 0;
2170 hd->Targets[device->id] = vdev;
2171 if (hd->ioc->bus_type == SCSI) {
2172 if (hd->ioc->spi_data.isRaid & (1 << device->id)) {
2173 vdev->raidVolume = 1;
2174 ddvtprintk((KERN_INFO
2175 "RAID Volume @ id %d\n", device->id));
2178 vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
2187 mptscsih_is_raid_volume(MPT_SCSI_HOST *hd, uint id)
2191 if (!hd->ioc->spi_data.isRaid || !hd->ioc->spi_data.pIocPg3)
2194 for (i = 0; i < hd->ioc->spi_data.pIocPg3->NumPhysDisks; i++) {
2195 if (id == hd->ioc->spi_data.pIocPg3->PhysDisk[i].PhysDiskID)
2203 * OS entry point to allow for host driver to free allocated memory
2204 * Called if no device present or device being unloaded
2207 mptscsih_slave_destroy(struct scsi_device *device)
2209 struct Scsi_Host *host = device->host;
2210 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
2212 uint target = device->id;
2213 uint lun = device->lun;
2218 mptscsih_search_running_cmds(hd, target, lun);
2220 vdev = hd->Targets[target];
2221 vdev->luns[0] &= ~(1 << lun);
2222 if (--vdev->num_luns)
2225 kfree(hd->Targets[target]);
2226 hd->Targets[target] = NULL;
2228 if (hd->ioc->bus_type == SCSI) {
2229 if (mptscsih_is_raid_volume(hd, target)) {
2230 hd->ioc->spi_data.forceDv |= MPT_SCSICFG_RELOAD_IOC_PG3;
2232 hd->ioc->spi_data.dvStatus[target] =
2233 MPT_SCSICFG_NEGOTIATE;
2235 if (!hd->negoNvram) {
2236 hd->ioc->spi_data.dvStatus[target] |=
2237 MPT_SCSICFG_DV_NOT_DONE;
2243 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2245 * mptscsih_change_queue_depth - This function will set a devices queue depth
2246 * @sdev: per scsi_device pointer
2247 * @qdepth: requested queue depth
2249 * Adding support for new 'change_queue_depth' api.
2252 mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
2254 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sdev->host->hostdata;
2255 VirtDevice *pTarget;
2261 if (!(pTarget = hd->Targets[sdev->id]))
2264 if (hd->ioc->bus_type == SCSI) {
2265 if (pTarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) {
2266 if (!(pTarget->tflags & MPT_TARGET_FLAGS_Q_YES))
2268 else if (((pTarget->inq_data[0] & 0x1f) == 0x00) &&
2269 (pTarget->minSyncFactor <= MPT_ULTRA160 ))
2270 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2272 max_depth = MPT_SCSI_CMD_PER_DEV_LOW;
2274 /* error case - No Inq. Data */
2278 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2280 if (qdepth > max_depth)
2285 tagged = MSG_SIMPLE_TAG;
2287 scsi_adjust_queue_depth(sdev, tagged, qdepth);
2288 return sdev->queue_depth;
2292 * OS entry point to adjust the queue_depths on a per-device basis.
2293 * Called once per device the bus scan. Use it to force the queue_depth
2294 * member to 1 if a device does not support Q tags.
2295 * Return non-zero if fails.
2298 mptscsih_slave_configure(struct scsi_device *device)
2300 struct Scsi_Host *sh = device->host;
2301 VirtDevice *pTarget;
2302 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sh->hostdata;
2304 if ((hd == NULL) || (hd->Targets == NULL)) {
2308 dsprintk((MYIOC_s_INFO_FMT
2309 "device @ %p, id=%d, LUN=%d, channel=%d\n",
2310 hd->ioc->name, device, device->id, device->lun, device->channel));
2311 dsprintk((MYIOC_s_INFO_FMT
2312 "sdtr %d wdtr %d ppr %d inq length=%d\n",
2313 hd->ioc->name, device->sdtr, device->wdtr,
2314 device->ppr, device->inquiry_len));
2316 if (device->id > sh->max_id) {
2317 /* error case, should never happen */
2318 scsi_adjust_queue_depth(device, 0, 1);
2319 goto slave_configure_exit;
2322 pTarget = hd->Targets[device->id];
2324 if (pTarget == NULL) {
2325 /* Driver doesn't know about this device.
2326 * Kernel may generate a "Dummy Lun 0" which
2327 * may become a real Lun if a
2328 * "scsi add-single-device" command is executed
2329 * while the driver is active (hot-plug a
2330 * device). LSI Raid controllers need
2331 * queue_depth set to DEV_HIGH for this reason.
2333 scsi_adjust_queue_depth(device, MSG_SIMPLE_TAG,
2334 MPT_SCSI_CMD_PER_DEV_HIGH);
2335 goto slave_configure_exit;
2338 mptscsih_initTarget(hd, device->channel, device->id, device->lun,
2339 device->inquiry, device->inquiry_len );
2340 mptscsih_change_queue_depth(device, MPT_SCSI_CMD_PER_DEV_HIGH);
2342 dsprintk((MYIOC_s_INFO_FMT
2343 "Queue depth=%d, tflags=%x\n",
2344 hd->ioc->name, device->queue_depth, pTarget->tflags));
2346 dsprintk((MYIOC_s_INFO_FMT
2347 "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
2348 hd->ioc->name, pTarget->negoFlags, pTarget->maxOffset, pTarget->minSyncFactor));
2350 slave_configure_exit:
2352 dsprintk((MYIOC_s_INFO_FMT
2353 "tagged %d, simple %d, ordered %d\n",
2354 hd->ioc->name,device->tagged_supported, device->simple_tags,
2355 device->ordered_tags));
2360 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2362 * Private routines...
2365 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2366 /* Utility function to copy sense data from the scsi_cmnd buffer
2367 * to the FC and SCSI target structures.
2371 mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
2374 SCSIIORequest_t *pReq;
2375 u32 sense_count = le32_to_cpu(pScsiReply->SenseCount);
2378 /* Get target structure
2380 pReq = (SCSIIORequest_t *) mf;
2381 index = (int) pReq->TargetID;
2382 target = hd->Targets[index];
2388 /* Copy the sense received into the scsi command block. */
2389 req_index = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2390 sense_data = ((u8 *)hd->ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC));
2391 memcpy(sc->sense_buffer, sense_data, SNS_LEN(sc));
2393 /* Log SMART data (asc = 0x5D, non-IM case only) if required.
2395 if ((hd->ioc->events) && (hd->ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) {
2396 if ((sense_data[12] == 0x5D) && (target->raidVolume == 0)) {
2398 MPT_ADAPTER *ioc = hd->ioc;
2400 idx = ioc->eventContext % ioc->eventLogSize;
2401 ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
2402 ioc->events[idx].eventContext = ioc->eventContext;
2404 ioc->events[idx].data[0] = (pReq->LUN[1] << 24) ||
2405 (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) ||
2406 (pReq->Bus << 8) || pReq->TargetID;
2408 ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12];
2410 ioc->eventContext++;
2414 dprintk((MYIOC_s_INFO_FMT "Hmmm... SenseData len=0! (?)\n",
2420 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc)
2425 hd = (MPT_SCSI_HOST *) sc->device->host->hostdata;
2427 for (i = 0; i < hd->ioc->req_depth; i++) {
2428 if (hd->ScsiLookup[i] == sc) {
2436 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2438 mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2441 unsigned long flags;
2443 dtmprintk((KERN_WARNING MYNAM
2444 ": IOC %s_reset routed to SCSI host driver!\n",
2445 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
2446 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
2448 /* If a FW reload request arrives after base installed but
2449 * before all scsi hosts have been attached, then an alt_ioc
2450 * may have a NULL sh pointer.
2452 if ((ioc->sh == NULL) || (ioc->sh->hostdata == NULL))
2455 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2457 if (reset_phase == MPT_IOC_SETUP_RESET) {
2458 dtmprintk((MYIOC_s_WARN_FMT "Setup-Diag Reset\n", ioc->name));
2461 * 1. Set Hard Reset Pending Flag
2462 * All new commands go to doneQ
2464 hd->resetPending = 1;
2466 } else if (reset_phase == MPT_IOC_PRE_RESET) {
2467 dtmprintk((MYIOC_s_WARN_FMT "Pre-Diag Reset\n", ioc->name));
2469 /* 2. Flush running commands
2470 * Clean ScsiLookup (and associated memory)
2474 /* 2b. Reply to OS all known outstanding I/O commands.
2476 mptscsih_flush_running_cmds(hd);
2478 /* 2c. If there was an internal command that
2479 * has not completed, configuration or io request,
2480 * free these resources.
2483 del_timer(&hd->timer);
2484 mpt_free_msg_frame(ioc, hd->cmdPtr);
2487 dtmprintk((MYIOC_s_WARN_FMT "Pre-Reset complete.\n", ioc->name));
2490 dtmprintk((MYIOC_s_WARN_FMT "Post-Diag Reset\n", ioc->name));
2492 /* Once a FW reload begins, all new OS commands are
2493 * redirected to the doneQ w/ a reset status.
2494 * Init all control structures.
2497 /* ScsiLookup initialization
2501 for (ii=0; ii < hd->ioc->req_depth; ii++)
2502 hd->ScsiLookup[ii] = NULL;
2505 /* 2. Chain Buffer initialization
2508 /* 4. Renegotiate to all devices, if SCSI
2510 if (ioc->bus_type == SCSI) {
2511 dnegoprintk(("writeSDP1: ALL_IDS USE_NVRAM\n"));
2512 mptscsih_writeSDP1(hd, 0, 0, MPT_SCSICFG_ALL_IDS | MPT_SCSICFG_USE_NVRAM);
2515 /* 5. Enable new commands to be posted
2517 spin_lock_irqsave(&ioc->FreeQlock, flags);
2519 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2520 hd->resetPending = 0;
2521 hd->tmState = TM_STATE_NONE;
2523 /* 6. If there was an internal command,
2524 * wake this process up.
2528 * Wake up the original calling thread
2530 hd->pLocal = &hd->localReply;
2531 hd->pLocal->completion = MPT_SCANDV_DID_RESET;
2532 hd->scandv_wait_done = 1;
2533 wake_up(&hd->scandv_waitq);
2537 /* 7. Set flag to force DV and re-read IOC Page 3
2539 if (ioc->bus_type == SCSI) {
2540 ioc->spi_data.forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
2541 ddvtprintk(("Set reload IOC Pg3 Flag\n"));
2544 dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name));
2548 return 1; /* currently means nothing really */
2551 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2553 mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2556 u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
2558 devtprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
2562 case MPI_EVENT_UNIT_ATTENTION: /* 03 */
2565 case MPI_EVENT_IOC_BUS_RESET: /* 04 */
2566 case MPI_EVENT_EXT_BUS_RESET: /* 05 */
2569 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2570 if (hd && (ioc->bus_type == SCSI) && (hd->soft_resets < -1))
2574 case MPI_EVENT_LOGOUT: /* 09 */
2579 * CHECKME! Don't think we need to do
2580 * anything for these, but...
2582 case MPI_EVENT_RESCAN: /* 06 */
2583 case MPI_EVENT_LINK_STATUS_CHANGE: /* 07 */
2584 case MPI_EVENT_LOOP_STATE_CHANGE: /* 08 */
2586 * CHECKME! Falling thru...
2590 case MPI_EVENT_INTEGRATED_RAID: /* 0B */
2591 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
2592 /* negoNvram set to 0 if DV enabled and to USE_NVRAM if
2593 * if DV disabled. Need to check for target mode.
2597 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2599 if (hd && (ioc->bus_type == SCSI) && (hd->negoNvram == 0)) {
2601 Ioc3PhysDisk_t *pPDisk;
2606 reason = (le32_to_cpu(pEvReply->Data[0]) & 0x00FF0000) >> 16;
2607 if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
2608 /* New or replaced disk.
2609 * Set DV flag and schedule DV.
2611 pSpi = &ioc->spi_data;
2612 physDiskNum = (le32_to_cpu(pEvReply->Data[0]) & 0xFF000000) >> 24;
2613 ddvtprintk(("DV requested for phys disk id %d\n", physDiskNum));
2614 if (pSpi->pIocPg3) {
2615 pPDisk = pSpi->pIocPg3->PhysDisk;
2616 numPDisk =pSpi->pIocPg3->NumPhysDisks;
2619 if (physDiskNum == pPDisk->PhysDiskNum) {
2620 pSpi->dvStatus[pPDisk->PhysDiskID] = (MPT_SCSICFG_NEED_DV | MPT_SCSICFG_DV_NOT_DONE);
2621 pSpi->forceDv = MPT_SCSICFG_NEED_DV;
2622 ddvtprintk(("NEED_DV set for phys disk id %d\n", pPDisk->PhysDiskID));
2629 if (numPDisk == 0) {
2630 /* The physical disk that needs DV was not found
2631 * in the stored IOC Page 3. The driver must reload
2632 * this page. DV routine will set the NEED_DV flag for
2633 * all phys disks that have DV_NOT_DONE set.
2635 pSpi->forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
2636 ddvtprintk(("phys disk %d not found. Setting reload IOC Pg3 Flag\n", physDiskNum));
2643 #if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY)
2644 printk("Raid Event RF: ");
2646 u32 *m = (u32 *)pEvReply;
2648 int n = (int)pEvReply->MsgLength;
2649 for (ii=6; ii < n; ii++)
2650 printk(" %08x", le32_to_cpu(m[ii]));
2656 case MPI_EVENT_NONE: /* 00 */
2657 case MPI_EVENT_LOG_DATA: /* 01 */
2658 case MPI_EVENT_STATE_CHANGE: /* 02 */
2659 case MPI_EVENT_EVENT_CHANGE: /* 0A */
2661 dprintk((KERN_INFO " Ignoring event (=%02Xh)\n", event));
2665 return 1; /* currently means nothing really */
2668 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2670 * mptscsih_initTarget - Target, LUN alloc/free functionality.
2671 * @hd: Pointer to MPT_SCSI_HOST structure
2672 * @bus_id: Bus number (?)
2673 * @target_id: SCSI target id
2675 * @data: Pointer to data
2676 * @dlen: Number of INQUIRY bytes
2678 * NOTE: It's only SAFE to call this routine if data points to
2679 * sane & valid STANDARD INQUIRY data!
2681 * Allocate and initialize memory for this target.
2682 * Save inquiry data.
2686 mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *data, int dlen)
2688 int indexed_lun, lun_index;
2693 dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n",
2694 hd->ioc->name, bus_id, target_id, lun, hd));
2697 * If the peripheral qualifier filter is enabled then if the target reports a 0x1
2698 * (i.e. The targer is capable of supporting the specified peripheral device type
2699 * on this logical unit; however, the physical device is not currently connected
2700 * to this logical unit) it will be converted to a 0x3 (i.e. The target is not
2701 * capable of supporting a physical device on this logical unit). This is to work
2702 * around a bug in th emid-layer in some distributions in which the mid-layer will
2703 * continue to try to communicate to the LUN and evntually create a dummy LUN.
2705 if (hd->mpt_pq_filter && dlen && (data[0] & 0xE0))
2708 /* Is LUN supported? If so, upper 2 bits will be 0
2709 * in first byte of inquiry data.
2714 if ((vdev = hd->Targets[target_id]) == NULL) {
2718 lun_index = (lun >> 5); /* 32 luns per lun_index */
2719 indexed_lun = (lun % 32);
2720 vdev->luns[lun_index] |= (1 << indexed_lun);
2722 if (hd->ioc->bus_type == SCSI) {
2723 if ((data[0] == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) {
2724 /* Treat all Processors as SAF-TE if
2725 * command line option is set */
2726 vdev->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
2727 mptscsih_writeIOCPage4(hd, target_id, bus_id);
2728 }else if ((data[0] == TYPE_PROCESSOR) &&
2729 !(vdev->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) {
2731 vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
2732 if ( data[44] == 'S' &&
2738 vdev->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
2739 mptscsih_writeIOCPage4(hd, target_id, bus_id);
2743 if (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY)) {
2745 memcpy (vdev->inq_data, data, 8);
2747 memcpy (vdev->inq_data, data, dlen);
2750 /* If have not done DV, set the DV flag.
2752 pSpi = &hd->ioc->spi_data;
2753 if ((data[0] == TYPE_TAPE) || (data[0] == TYPE_PROCESSOR)) {
2754 if (pSpi->dvStatus[target_id] & MPT_SCSICFG_DV_NOT_DONE)
2755 pSpi->dvStatus[target_id] |= MPT_SCSICFG_NEED_DV;
2758 vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
2761 data_56 = 0x0F; /* Default to full capabilities if Inq data length is < 57 */
2763 if ( (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_56))) {
2764 /* Update the target capabilities
2767 vdev->tflags |= MPT_TARGET_FLAGS_VALID_56;
2770 mptscsih_setTargetNegoParms(hd, vdev, data_56);
2772 /* Initial Inquiry may not request enough data bytes to
2773 * obtain byte 57. DV will; if target doesn't return
2774 * at least 57 bytes, data[56] will be zero. */
2776 if ( (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_56))) {
2777 /* Update the target capabilities
2780 vdev->tflags |= MPT_TARGET_FLAGS_VALID_56;
2781 mptscsih_setTargetNegoParms(hd, vdev, data_56);
2788 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2790 * Update the target negotiation parameters based on the
2791 * the Inquiry data, adapter capabilities, and NVRAM settings.
2795 mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56)
2797 ScsiCfgData *pspi_data = &hd->ioc->spi_data;
2798 int id = (int) target->target_id;
2802 u8 width = MPT_NARROW;
2803 u8 factor = MPT_ASYNC;
2805 u8 version, nfactor;
2808 target->negoFlags = pspi_data->noQas;
2810 /* noQas == 0 => device supports QAS. Need byte 56 of Inq to determine
2811 * support. If available, default QAS to off and allow enabling.
2812 * If not available, default QAS to on, turn off for non-disks.
2815 /* Set flags based on Inquiry data
2817 version = target->inq_data[2] & 0x07;
2820 factor = MPT_ULTRA2;
2821 offset = pspi_data->maxSyncOffset;
2822 target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
2824 if (target->inq_data[7] & 0x20) {
2828 if (target->inq_data[7] & 0x10) {
2829 factor = pspi_data->minSyncFactor;
2830 if (target->tflags & MPT_TARGET_FLAGS_VALID_56) {
2831 /* bits 2 & 3 show Clocking support */
2832 if ((byte56 & 0x0C) == 0)
2833 factor = MPT_ULTRA2;
2835 if ((byte56 & 0x03) == 0)
2836 factor = MPT_ULTRA160;
2838 factor = MPT_ULTRA320;
2841 ddvtprintk((KERN_INFO "Enabling QAS due to byte56=%02x on id=%d!\n", byte56, id));
2844 if (target->inq_data[0] == TYPE_TAPE) {
2846 target->negoFlags |= MPT_TAPE_NEGO_IDP;
2851 ddvtprintk((KERN_INFO "Enabling QAS on id=%d due to ~TARGET_FLAGS_VALID_56!\n", id));
2855 offset = pspi_data->maxSyncOffset;
2857 /* If RAID, never disable QAS
2858 * else if non RAID, do not disable
2859 * QAS if bit 1 is set
2860 * bit 1 QAS support, non-raid only
2863 if (target->raidVolume == 1) {
2872 if ( (target->inq_data[7] & 0x02) == 0) {
2873 target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
2876 /* Update tflags based on NVRAM settings. (SCSI only)
2878 if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
2879 nvram = pspi_data->nvram[id];
2880 nfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
2883 width = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
2886 /* Ensure factor is set to the
2887 * maximum of: adapter, nvram, inquiry
2890 if (nfactor < pspi_data->minSyncFactor )
2891 nfactor = pspi_data->minSyncFactor;
2893 factor = max(factor, nfactor);
2894 if (factor == MPT_ASYNC)
2905 /* Make sure data is consistent
2907 if ((!width) && (factor < MPT_ULTRA2)) {
2908 factor = MPT_ULTRA2;
2911 /* Save the data to the target structure.
2913 target->minSyncFactor = factor;
2914 target->maxOffset = offset;
2915 target->maxWidth = width;
2917 target->tflags |= MPT_TARGET_FLAGS_VALID_NEGO;
2919 /* Disable unused features.
2922 target->negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
2925 target->negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
2927 if ( factor > MPT_ULTRA320 )
2930 /* GEM, processor WORKAROUND
2932 if ((target->inq_data[0] == TYPE_PROCESSOR) || (target->inq_data[0] > 0x08)) {
2933 target->negoFlags |= (MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC);
2934 pspi_data->dvStatus[id] |= MPT_SCSICFG_BLK_NEGO;
2936 if (noQas && (pspi_data->noQas == 0)) {
2937 pspi_data->noQas |= MPT_TARGET_NO_NEGO_QAS;
2938 target->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
2940 /* Disable QAS in a mixed configuration case
2943 ddvtprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id));
2944 for (ii = 0; ii < id; ii++) {
2945 if ( (vdev = hd->Targets[ii]) ) {
2946 vdev->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
2947 mptscsih_writeSDP1(hd, 0, ii, vdev->negoFlags);
2953 /* Write SDP1 on this I/O to this target */
2954 if (pspi_data->dvStatus[id] & MPT_SCSICFG_NEGOTIATE) {
2955 ddvtprintk((KERN_INFO "MPT_SCSICFG_NEGOTIATE on id=%d!\n", id));
2956 mptscsih_writeSDP1(hd, 0, id, hd->negoNvram);
2957 pspi_data->dvStatus[id] &= ~MPT_SCSICFG_NEGOTIATE;
2958 } else if (pspi_data->dvStatus[id] & MPT_SCSICFG_BLK_NEGO) {
2959 ddvtprintk((KERN_INFO "MPT_SCSICFG_BLK_NEGO on id=%d!\n", id));
2960 mptscsih_writeSDP1(hd, 0, id, MPT_SCSICFG_BLK_NEGO);
2961 pspi_data->dvStatus[id] &= ~MPT_SCSICFG_BLK_NEGO;
2965 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2966 /* If DV disabled (negoNvram set to USE_NVARM) or if not LUN 0, return.
2967 * Else set the NEED_DV flag after Read Capacity Issued (disks)
2968 * or Mode Sense (cdroms).
2970 * Tapes, initTarget will set this flag on completion of Inquiry command.
2971 * Called only if DV_NOT_DONE flag is set
2974 mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq)
2979 ddvtprintk((" set_dvflags: id=%d lun=%d negoNvram=%x cmd=%x\n",
2980 pReq->TargetID, pReq->LUN[1], hd->negoNvram, pReq->CDB[0]));
2982 if ((pReq->LUN[1] != 0) || (hd->negoNvram != 0))
2987 if ((cmd == READ_CAPACITY) || (cmd == MODE_SENSE)) {
2988 pSpi = &hd->ioc->spi_data;
2989 if ((pSpi->isRaid & (1 << pReq->TargetID)) && pSpi->pIocPg3) {
2990 /* Set NEED_DV for all hidden disks
2992 Ioc3PhysDisk_t *pPDisk = pSpi->pIocPg3->PhysDisk;
2993 int numPDisk = pSpi->pIocPg3->NumPhysDisks;
2996 pSpi->dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV;
2997 ddvtprintk(("NEED_DV set for phys disk id %d\n", pPDisk->PhysDiskID));
3002 pSpi->dvStatus[pReq->TargetID] |= MPT_SCSICFG_NEED_DV;
3003 ddvtprintk(("NEED_DV set for visible disk id %d\n", pReq->TargetID));
3007 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3009 * If no Target, bus reset on 1st I/O. Set the flag to
3010 * prevent any future negotiations to this device.
3013 mptscsih_no_negotiate(MPT_SCSI_HOST *hd, int target_id)
3016 if ((hd->Targets) && (hd->Targets[target_id] == NULL))
3017 hd->ioc->spi_data.dvStatus[target_id] |= MPT_SCSICFG_BLK_NEGO;
3022 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3024 * SCSI Config Page functionality ...
3026 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3027 /* mptscsih_setDevicePage1Flags - add Requested and Configuration fields flags
3028 * based on width, factor and offset parameters.
3030 * @factor: sync factor
3031 * @offset: sync offset
3032 * @requestedPtr: pointer to requested values (updated)
3033 * @configurationPtr: pointer to configuration values (updated)
3034 * @flags: flags to block WDTR or SDTR negotiation
3038 * Remark: Called by writeSDP1 and _dv_params
3041 mptscsih_setDevicePage1Flags (u8 width, u8 factor, u8 offset, int *requestedPtr, int *configurationPtr, u8 flags)
3043 u8 nowide = flags & MPT_TARGET_NO_NEGO_WIDE;
3044 u8 nosync = flags & MPT_TARGET_NO_NEGO_SYNC;
3046 *configurationPtr = 0;
3047 *requestedPtr = width ? MPI_SCSIDEVPAGE1_RP_WIDE : 0;
3048 *requestedPtr |= (offset << 16) | (factor << 8);
3050 if (width && offset && !nowide && !nosync) {
3051 if (factor < MPT_ULTRA160) {
3052 *requestedPtr |= (MPI_SCSIDEVPAGE1_RP_IU + MPI_SCSIDEVPAGE1_RP_DT);
3053 if ((flags & MPT_TARGET_NO_NEGO_QAS) == 0)
3054 *requestedPtr |= MPI_SCSIDEVPAGE1_RP_QAS;
3055 if (flags & MPT_TAPE_NEGO_IDP)
3056 *requestedPtr |= 0x08000000;
3057 } else if (factor < MPT_ULTRA2) {
3058 *requestedPtr |= MPI_SCSIDEVPAGE1_RP_DT;
3063 *configurationPtr |= MPI_SCSIDEVPAGE1_CONF_WDTR_DISALLOWED;
3066 *configurationPtr |= MPI_SCSIDEVPAGE1_CONF_SDTR_DISALLOWED;
3071 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3072 /* mptscsih_writeSDP1 - write SCSI Device Page 1
3073 * @hd: Pointer to a SCSI Host Strucutre
3074 * @portnum: IOC port number
3075 * @target_id: writeSDP1 for single ID
3076 * @flags: MPT_SCSICFG_ALL_IDS, MPT_SCSICFG_USE_NVRAM, MPT_SCSICFG_BLK_NEGO
3078 * Return: -EFAULT if read of config page header fails
3081 * Remark: If a target has been found, the settings from the
3082 * target structure are used, else the device is set
3085 * Remark: Called during init and after a FW reload.
3086 * Remark: We do not wait for a return, write pages sequentially.
3089 mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
3091 MPT_ADAPTER *ioc = hd->ioc;
3093 SCSIDevicePage1_t *pData;
3094 VirtDevice *pTarget;
3099 u32 requested, configuration, flagsLength;
3101 int id = 0, maxid = 0;
3107 u8 maxwidth, maxoffset, maxfactor;
3109 if (ioc->spi_data.sdp1length == 0)
3112 if (flags & MPT_SCSICFG_ALL_IDS) {
3114 maxid = ioc->sh->max_id - 1;
3115 } else if (ioc->sh) {
3117 maxid = min_t(int, id, ioc->sh->max_id - 1);
3120 for (; id <= maxid; id++) {
3122 if (id == ioc->pfacts[portnum].PortSCSIID)
3125 /* Use NVRAM to get adapter and target maximums
3126 * Data over-riden by target structure information, if present
3128 maxwidth = ioc->spi_data.maxBusWidth;
3129 maxoffset = ioc->spi_data.maxSyncOffset;
3130 maxfactor = ioc->spi_data.minSyncFactor;
3131 if (ioc->spi_data.nvram && (ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
3132 nvram = ioc->spi_data.nvram[id];
3135 maxwidth = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
3137 if (maxoffset > 0) {
3138 maxfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
3139 if (maxfactor == 0) {
3141 maxfactor = MPT_ASYNC;
3143 } else if (maxfactor < ioc->spi_data.minSyncFactor) {
3144 maxfactor = ioc->spi_data.minSyncFactor;
3147 maxfactor = MPT_ASYNC;
3150 /* Set the negotiation flags.
3152 negoFlags = ioc->spi_data.noQas;
3154 negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
3157 negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
3159 if (flags & MPT_SCSICFG_USE_NVRAM) {
3168 //negoFlags = MPT_TARGET_NO_NEGO_SYNC;
3171 /* If id is not a raid volume, get the updated
3172 * transmission settings from the target structure.
3174 if (hd->Targets && (pTarget = hd->Targets[id]) && !pTarget->raidVolume) {
3175 width = pTarget->maxWidth;
3176 factor = pTarget->minSyncFactor;
3177 offset = pTarget->maxOffset;
3178 negoFlags = pTarget->negoFlags;
3181 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
3182 /* Force to async and narrow if DV has not been executed
3185 if ((hd->ioc->spi_data.dvStatus[id] & MPT_SCSICFG_DV_NOT_DONE) != 0) {
3192 if (flags & MPT_SCSICFG_BLK_NEGO)
3193 negoFlags = MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC;
3195 mptscsih_setDevicePage1Flags(width, factor, offset,
3196 &requested, &configuration, negoFlags);
3197 dnegoprintk(("writeSDP1: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
3198 target_id, width, factor, offset, negoFlags, requested, configuration));
3200 /* Get a MF for this command.
3202 if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
3203 dfailprintk((MYIOC_s_WARN_FMT "write SDP1: no msg frames!\n",
3208 ddvprintk((MYIOC_s_INFO_FMT "WriteSDP1 (mf=%p, id=%d, req=0x%x, cfg=0x%x)\n",
3209 hd->ioc->name, mf, id, requested, configuration));
3212 /* Set the request and the data pointers.
3213 * Request takes: 36 bytes (32 bit SGE)
3214 * SCSI Device Page 1 requires 16 bytes
3215 * 40 + 16 <= size of SCSI IO Request = 56 bytes
3216 * and MF size >= 64 bytes.
3217 * Place data at end of MF.
3219 pReq = (Config_t *)mf;
3221 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3222 frameOffset = ioc->req_sz - sizeof(SCSIDevicePage1_t);
3224 pData = (SCSIDevicePage1_t *)((u8 *) mf + frameOffset);
3225 dataDma = ioc->req_frames_dma + (req_idx * ioc->req_sz) + frameOffset;
3227 /* Complete the request frame (same for all requests).
3229 pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
3231 pReq->ChainOffset = 0;
3232 pReq->Function = MPI_FUNCTION_CONFIG;
3233 pReq->ExtPageLength = 0;
3234 pReq->ExtPageType = 0;
3236 for (ii=0; ii < 8; ii++) {
3237 pReq->Reserved2[ii] = 0;
3239 pReq->Header.PageVersion = ioc->spi_data.sdp1version;
3240 pReq->Header.PageLength = ioc->spi_data.sdp1length;
3241 pReq->Header.PageNumber = 1;
3242 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
3243 pReq->PageAddress = cpu_to_le32(id | (bus << 8 ));
3245 /* Add a SGE to the config request.
3247 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE | ioc->spi_data.sdp1length * 4;
3249 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma);
3251 /* Set up the common data portion
3253 pData->Header.PageVersion = pReq->Header.PageVersion;
3254 pData->Header.PageLength = pReq->Header.PageLength;
3255 pData->Header.PageNumber = pReq->Header.PageNumber;
3256 pData->Header.PageType = pReq->Header.PageType;
3257 pData->RequestedParameters = cpu_to_le32(requested);
3258 pData->Reserved = 0;
3259 pData->Configuration = cpu_to_le32(configuration);
3261 dprintk((MYIOC_s_INFO_FMT
3262 "write SDP1: id %d pgaddr 0x%x req 0x%x config 0x%x\n",
3263 ioc->name, id, (id | (bus<<8)),
3264 requested, configuration));
3266 mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
3272 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3273 /* mptscsih_writeIOCPage4 - write IOC Page 4
3274 * @hd: Pointer to a SCSI Host Structure
3275 * @target_id: write IOC Page4 for this ID & Bus
3277 * Return: -EAGAIN if unable to obtain a Message Frame
3280 * Remark: We do not wait for a return, write pages sequentially.
3283 mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus)
3285 MPT_ADAPTER *ioc = hd->ioc;
3287 IOCPage4_t *IOCPage4Ptr;
3295 /* Get a MF for this command.
3297 if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
3298 dfailprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n",
3303 /* Set the request and the data pointers.
3304 * Place data at end of MF.
3306 pReq = (Config_t *)mf;
3308 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3309 frameOffset = ioc->req_sz - sizeof(IOCPage4_t);
3311 /* Complete the request frame (same for all requests).
3313 pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
3315 pReq->ChainOffset = 0;
3316 pReq->Function = MPI_FUNCTION_CONFIG;
3317 pReq->ExtPageLength = 0;
3318 pReq->ExtPageType = 0;
3320 for (ii=0; ii < 8; ii++) {
3321 pReq->Reserved2[ii] = 0;
3324 IOCPage4Ptr = ioc->spi_data.pIocPg4;
3325 dataDma = ioc->spi_data.IocPg4_dma;
3326 ii = IOCPage4Ptr->ActiveSEP++;
3327 IOCPage4Ptr->SEP[ii].SEPTargetID = target_id;
3328 IOCPage4Ptr->SEP[ii].SEPBus = bus;
3329 pReq->Header = IOCPage4Ptr->Header;
3330 pReq->PageAddress = cpu_to_le32(target_id | (bus << 8 ));
3332 /* Add a SGE to the config request.
3334 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE |
3335 (IOCPage4Ptr->Header.PageLength + ii) * 4;
3337 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma);
3339 dinitprintk((MYIOC_s_INFO_FMT
3340 "writeIOCPage4: MaxSEP=%d ActiveSEP=%d id=%d bus=%d\n",
3341 ioc->name, IOCPage4Ptr->MaxSEP, IOCPage4Ptr->ActiveSEP, target_id, bus));
3343 mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
3348 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3350 * Bus Scan and Domain Validation functionality ...
3353 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3355 * mptscsih_scandv_complete - Scan and DV callback routine registered
3356 * to Fustion MPT (base) driver.
3358 * @ioc: Pointer to MPT_ADAPTER structure
3359 * @mf: Pointer to original MPT request frame
3360 * @mr: Pointer to MPT reply frame (NULL if TurboReply)
3362 * This routine is called from mpt.c::mpt_interrupt() at the completion
3363 * of any SCSI IO request.
3364 * This routine is registered with the Fusion MPT (base) driver at driver
3365 * load/init time via the mpt_register() API call.
3367 * Returns 1 indicating alloc'd request frame ptr should be freed.
3369 * Remark: Sets a completion code and (possibly) saves sense data
3370 * in the IOC member localReply structure.
3371 * Used ONLY for DV and other internal commands.
3374 mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
3377 SCSIIORequest_t *pReq;
3381 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
3384 (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) {
3385 printk(MYIOC_s_ERR_FMT
3386 "ScanDvComplete, %s req frame ptr! (=%p)\n",
3387 ioc->name, mf?"BAD":"NULL", (void *) mf);
3391 del_timer(&hd->timer);
3392 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3393 hd->ScsiLookup[req_idx] = NULL;
3394 pReq = (SCSIIORequest_t *) mf;
3396 if (mf != hd->cmdPtr) {
3397 printk(MYIOC_s_WARN_FMT "ScanDvComplete (mf=%p, cmdPtr=%p, idx=%d)\n",
3398 hd->ioc->name, (void *)mf, (void *) hd->cmdPtr, req_idx);
3402 ddvprintk((MYIOC_s_INFO_FMT "ScanDvComplete (mf=%p,mr=%p,idx=%d)\n",
3403 hd->ioc->name, mf, mr, req_idx));
3405 hd->pLocal = &hd->localReply;
3406 hd->pLocal->scsiStatus = 0;
3408 /* If target struct exists, clear sense valid flag.
3411 completionCode = MPT_SCANDV_GOOD;
3413 SCSIIOReply_t *pReply;
3417 pReply = (SCSIIOReply_t *) mr;
3419 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
3420 scsi_status = pReply->SCSIStatus;
3422 ddvtprintk((KERN_NOTICE " IOCStatus=%04xh, SCSIState=%02xh, SCSIStatus=%02xh, IOCLogInfo=%08xh\n",
3423 status, pReply->SCSIState, scsi_status,
3424 le32_to_cpu(pReply->IOCLogInfo)));
3428 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
3429 completionCode = MPT_SCANDV_SELECTION_TIMEOUT;
3432 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
3433 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
3434 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
3435 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
3436 completionCode = MPT_SCANDV_DID_RESET;
3439 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
3440 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
3441 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
3442 if (pReply->Function == MPI_FUNCTION_CONFIG) {
3443 ConfigReply_t *pr = (ConfigReply_t *)mr;
3444 completionCode = MPT_SCANDV_GOOD;
3445 hd->pLocal->header.PageVersion = pr->Header.PageVersion;
3446 hd->pLocal->header.PageLength = pr->Header.PageLength;
3447 hd->pLocal->header.PageNumber = pr->Header.PageNumber;
3448 hd->pLocal->header.PageType = pr->Header.PageType;
3450 } else if (pReply->Function == MPI_FUNCTION_RAID_ACTION) {
3451 /* If the RAID Volume request is successful,
3452 * return GOOD, else indicate that
3453 * some type of error occurred.
3455 MpiRaidActionReply_t *pr = (MpiRaidActionReply_t *)mr;
3456 if (le16_to_cpu(pr->ActionStatus) == MPI_RAID_ACTION_ASTATUS_SUCCESS)
3457 completionCode = MPT_SCANDV_GOOD;
3459 completionCode = MPT_SCANDV_SOME_ERROR;
3461 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID) {
3465 /* save sense data in global structure
3467 completionCode = MPT_SCANDV_SENSE;
3468 hd->pLocal->scsiStatus = scsi_status;
3469 sense_data = ((u8 *)hd->ioc->sense_buf_pool +
3470 (req_idx * MPT_SENSE_BUFFER_ALLOC));
3472 sz = min_t(int, pReq->SenseBufferLength,
3473 SCSI_STD_SENSE_BYTES);
3474 memcpy(hd->pLocal->sense, sense_data, sz);
3476 ddvprintk((KERN_NOTICE " Check Condition, sense ptr %p\n",
3478 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_FAILED) {
3479 if (pReq->CDB[0] == INQUIRY)
3480 completionCode = MPT_SCANDV_ISSUE_SENSE;
3482 completionCode = MPT_SCANDV_DID_RESET;
3484 else if (pReply->SCSIState & MPI_SCSI_STATE_NO_SCSI_STATUS)
3485 completionCode = MPT_SCANDV_DID_RESET;
3486 else if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
3487 completionCode = MPT_SCANDV_DID_RESET;
3489 completionCode = MPT_SCANDV_GOOD;
3490 hd->pLocal->scsiStatus = scsi_status;
3494 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
3495 if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
3496 completionCode = MPT_SCANDV_DID_RESET;
3498 completionCode = MPT_SCANDV_SOME_ERROR;
3502 completionCode = MPT_SCANDV_SOME_ERROR;
3505 } /* switch(status) */
3507 ddvtprintk((KERN_NOTICE " completionCode set to %08xh\n",
3509 } /* end of address reply case */
3511 hd->pLocal->completion = completionCode;
3513 /* MF and RF are freed in mpt_interrupt
3516 /* Free Chain buffers (will never chain) in scan or dv */
3517 //mptscsih_freeChainBuffers(ioc, req_idx);
3520 * Wake up the original calling thread
3522 hd->scandv_wait_done = 1;
3523 wake_up(&hd->scandv_waitq);
3528 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3529 /* mptscsih_timer_expired - Call back for timer process.
3530 * Used only for dv functionality.
3531 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
3535 mptscsih_timer_expired(unsigned long data)
3537 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) data;
3539 ddvprintk((MYIOC_s_WARN_FMT "Timer Expired! Cmd %p\n", hd->ioc->name, hd->cmdPtr));
3542 MPIHeader_t *cmd = (MPIHeader_t *)hd->cmdPtr;
3544 if (cmd->Function == MPI_FUNCTION_SCSI_IO_REQUEST) {
3545 /* Desire to issue a task management request here.
3546 * TM requests MUST be single threaded.
3547 * If old eh code and no TM current, issue request.
3548 * If new eh code, do nothing. Wait for OS cmd timeout
3551 ddvtprintk((MYIOC_s_NOTE_FMT "DV Cmd Timeout: NoOp\n", hd->ioc->name));
3553 /* Perform a FW reload */
3554 if (mpt_HardResetHandler(hd->ioc, NO_SLEEP) < 0) {
3555 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", hd->ioc->name);
3559 /* This should NEVER happen */
3560 printk(MYIOC_s_WARN_FMT "Null cmdPtr!!!!\n", hd->ioc->name);
3563 /* No more processing.
3564 * TM call will generate an interrupt for SCSI TM Management.
3565 * The FW will reply to all outstanding commands, callback will finish cleanup.
3566 * Hard reset clean-up will free all resources.
3568 ddvprintk((MYIOC_s_WARN_FMT "Timer Expired Complete!\n", hd->ioc->name));
3573 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
3574 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3575 /* mptscsih_do_raid - Format and Issue a RAID volume request message.
3576 * @hd: Pointer to scsi host structure
3577 * @action: What do be done.
3578 * @id: Logical target id.
3579 * @bus: Target locations bus.
3581 * Returns: < 0 on a fatal error
3584 * Remark: Wait to return until reply processed by the ISR.
3587 mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io)
3589 MpiRaidActionRequest_t *pReq;
3593 in_isr = in_interrupt();
3595 dprintk((MYIOC_s_WARN_FMT "Internal raid request not allowed in ISR context!\n",
3600 /* Get and Populate a free Frame
3602 if ((mf = mpt_get_msg_frame(hd->ioc->InternalCtx, hd->ioc)) == NULL) {
3603 ddvprintk((MYIOC_s_WARN_FMT "_do_raid: no msg frames!\n",
3607 pReq = (MpiRaidActionRequest_t *)mf;
3608 pReq->Action = action;
3609 pReq->Reserved1 = 0;
3610 pReq->ChainOffset = 0;
3611 pReq->Function = MPI_FUNCTION_RAID_ACTION;
3612 pReq->VolumeID = io->id;
3613 pReq->VolumeBus = io->bus;
3614 pReq->PhysDiskNum = io->physDiskNum;
3616 pReq->Reserved2 = 0;
3617 pReq->ActionDataWord = 0; /* Reserved for this action */
3618 //pReq->ActionDataSGE = 0;
3620 mpt_add_sge((char *)&pReq->ActionDataSGE,
3621 MPT_SGE_FLAGS_SSIMPLE_READ | 0, (dma_addr_t) -1);
3623 ddvprintk((MYIOC_s_INFO_FMT "RAID Volume action %x id %d\n",
3624 hd->ioc->name, action, io->id));
3627 hd->timer.expires = jiffies + HZ*10; /* 10 second timeout */
3628 hd->scandv_wait_done = 0;
3630 /* Save cmd pointer, for resource free if timeout or
3635 add_timer(&hd->timer);
3636 mpt_put_msg_frame(hd->ioc->InternalCtx, hd->ioc, mf);
3637 wait_event(hd->scandv_waitq, hd->scandv_wait_done);
3639 if ((hd->pLocal == NULL) || (hd->pLocal->completion != MPT_SCANDV_GOOD))
3644 #endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */
3646 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3648 * mptscsih_do_cmd - Do internal command.
3649 * @hd: MPT_SCSI_HOST pointer
3650 * @io: INTERNAL_CMD pointer.
3652 * Issue the specified internally generated command and do command
3653 * specific cleanup. For bus scan / DV only.
3654 * NOTES: If command is Inquiry and status is good,
3655 * initialize a target structure, save the data
3657 * Remark: Single threaded access only.
3660 * < 0 if an illegal command or no resources
3664 * > 0 if command complete but some type of completion error.
3667 mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
3670 SCSIIORequest_t *pScsiReq;
3671 SCSIIORequest_t ReqCopy;
3672 int my_idx, ii, dir;
3676 char CDB[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
3679 in_isr = in_interrupt();
3681 dprintk((MYIOC_s_WARN_FMT "Internal SCSI IO request not allowed in ISR context!\n",
3687 /* Set command specific information
3692 dir = MPI_SCSIIO_CONTROL_READ;
3698 case TEST_UNIT_READY:
3700 dir = MPI_SCSIIO_CONTROL_READ;
3706 dir = MPI_SCSIIO_CONTROL_READ;
3708 CDB[4] = 1; /*Spin up the disk */
3716 dir = MPI_SCSIIO_CONTROL_READ;
3722 dir = MPI_SCSIIO_CONTROL_READ;
3724 if (io->flags & MPT_ICFLAG_ECHO) {
3730 if (io->flags & MPT_ICFLAG_BUF_CAP) {
3733 CDB[6] = (io->size >> 16) & 0xFF;
3734 CDB[7] = (io->size >> 8) & 0xFF;
3735 CDB[8] = io->size & 0xFF;
3741 dir = MPI_SCSIIO_CONTROL_WRITE;
3743 if (io->flags & MPT_ICFLAG_ECHO) {
3748 CDB[6] = (io->size >> 16) & 0xFF;
3749 CDB[7] = (io->size >> 8) & 0xFF;
3750 CDB[8] = io->size & 0xFF;
3756 dir = MPI_SCSIIO_CONTROL_READ;
3763 dir = MPI_SCSIIO_CONTROL_READ;
3768 case SYNCHRONIZE_CACHE:
3770 dir = MPI_SCSIIO_CONTROL_READ;
3772 // CDB[1] = 0x02; /* set immediate bit */
3781 /* Get and Populate a free Frame
3783 if ((mf = mpt_get_msg_frame(hd->ioc->InternalCtx, hd->ioc)) == NULL) {
3784 ddvprintk((MYIOC_s_WARN_FMT "No msg frames!\n",
3789 pScsiReq = (SCSIIORequest_t *) mf;
3791 /* Get the request index */
3792 my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3793 ADD_INDEX_LOG(my_idx); /* for debug */
3795 if (io->flags & MPT_ICFLAG_PHYS_DISK) {
3796 pScsiReq->TargetID = io->physDiskNum;
3798 pScsiReq->ChainOffset = 0;
3799 pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
3801 pScsiReq->TargetID = io->id;
3802 pScsiReq->Bus = io->bus;
3803 pScsiReq->ChainOffset = 0;
3804 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
3807 pScsiReq->CDBLength = cmdLen;
3808 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
3810 pScsiReq->Reserved = 0;
3812 pScsiReq->MsgFlags = mpt_msg_flags();
3813 /* MsgContext set in mpt_get_msg_fram call */
3815 for (ii=0; ii < 8; ii++)
3816 pScsiReq->LUN[ii] = 0;
3817 pScsiReq->LUN[1] = io->lun;
3819 if (io->flags & MPT_ICFLAG_TAGGED_CMD)
3820 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ);
3822 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3824 if (cmd == REQUEST_SENSE) {
3825 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3826 ddvprintk((MYIOC_s_INFO_FMT "Untagged! 0x%2x\n",
3827 hd->ioc->name, cmd));
3830 for (ii=0; ii < 16; ii++)
3831 pScsiReq->CDB[ii] = CDB[ii];
3833 pScsiReq->DataLength = cpu_to_le32(io->size);
3834 pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
3835 + (my_idx * MPT_SENSE_BUFFER_ALLOC));
3837 ddvprintk((MYIOC_s_INFO_FMT "Sending Command 0x%x for (%d:%d:%d)\n",
3838 hd->ioc->name, cmd, io->bus, io->id, io->lun));
3840 if (dir == MPI_SCSIIO_CONTROL_READ) {
3841 mpt_add_sge((char *) &pScsiReq->SGL,
3842 MPT_SGE_FLAGS_SSIMPLE_READ | io->size,
3845 mpt_add_sge((char *) &pScsiReq->SGL,
3846 MPT_SGE_FLAGS_SSIMPLE_WRITE | io->size,
3850 /* The ISR will free the request frame, but we need
3851 * the information to initialize the target. Duplicate.
3853 memcpy(&ReqCopy, pScsiReq, sizeof(SCSIIORequest_t));
3855 /* Issue this command after:
3858 * Wait until the reply has been received
3859 * ScsiScanDvCtx callback function will
3861 * set scandv_wait_done and call wake_up
3864 hd->timer.expires = jiffies + HZ*cmdTimeout;
3865 hd->scandv_wait_done = 0;
3867 /* Save cmd pointer, for resource free if timeout or
3872 add_timer(&hd->timer);
3873 mpt_put_msg_frame(hd->ioc->InternalCtx, hd->ioc, mf);
3874 wait_event(hd->scandv_waitq, hd->scandv_wait_done);
3877 rc = hd->pLocal->completion;
3878 hd->pLocal->skip = 0;
3880 /* Always set fatal error codes in some cases.
3882 if (rc == MPT_SCANDV_SELECTION_TIMEOUT)
3884 else if (rc == MPT_SCANDV_SOME_ERROR)
3888 /* This should never happen. */
3889 ddvprintk((MYIOC_s_INFO_FMT "_do_cmd: Null pLocal!!!\n",
3896 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3898 * mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
3899 * @hd: Pointer to MPT_SCSI_HOST structure
3900 * @portnum: IOC port number
3902 * Uses the ISR, but with special processing.
3903 * MUST be single-threaded.
3905 * Return: 0 on completion
3908 mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum)
3910 MPT_ADAPTER *ioc= hd->ioc;
3911 VirtDevice *pTarget;
3912 SCSIDevicePage1_t *pcfg1Data = NULL;
3915 dma_addr_t cfg1_dma_addr = -1;
3916 ConfigPageHeader_t header1;
3920 int indexed_lun, lun_index;
3921 int hostId = ioc->pfacts[portnum].PortSCSIID;
3923 int requested, configuration, data;
3927 max_id = ioc->sh->max_id - 1;
3929 /* Following parameters will not change
3932 iocmd.cmd = SYNCHRONIZE_CACHE;
3934 iocmd.physDiskNum = -1;
3936 iocmd.data_dma = -1;
3938 iocmd.rsvd = iocmd.rsvd2 = 0;
3942 if (hd->Targets == NULL)
3950 /* Write SDP1 for all SCSI devices
3951 * Alloc memory and set up config buffer
3953 if (ioc->bus_type == SCSI) {
3954 if (ioc->spi_data.sdp1length > 0) {
3955 pcfg1Data = (SCSIDevicePage1_t *)pci_alloc_consistent(ioc->pcidev,
3956 ioc->spi_data.sdp1length * 4, &cfg1_dma_addr);
3958 if (pcfg1Data != NULL) {
3960 header1.PageVersion = ioc->spi_data.sdp1version;
3961 header1.PageLength = ioc->spi_data.sdp1length;
3962 header1.PageNumber = 1;
3963 header1.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
3964 cfg.cfghdr.hdr = &header1;
3965 cfg.physAddr = cfg1_dma_addr;
3966 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
3973 /* loop through all devices on this port
3975 while (bus < MPT_MAX_BUS) {
3978 pTarget = hd->Targets[(int)id];
3982 /* Set the negotiation flags */
3983 if (pTarget && (pTarget = hd->Targets[id]) && !pTarget->raidVolume) {
3984 flags = pTarget->negoFlags;
3986 flags = hd->ioc->spi_data.noQas;
3987 if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
3988 data = hd->ioc->spi_data.nvram[id];
3990 if (data & MPT_NVRAM_WIDE_DISABLE)
3991 flags |= MPT_TARGET_NO_NEGO_WIDE;
3993 factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT;
3994 if ((factor == 0) || (factor == MPT_ASYNC))
3995 flags |= MPT_TARGET_NO_NEGO_SYNC;
3999 /* Force to async, narrow */
4000 mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested,
4001 &configuration, flags);
4002 dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC "
4003 "offset=0 negoFlags=%x request=%x config=%x\n",
4004 id, flags, requested, configuration));
4005 pcfg1Data->RequestedParameters = cpu_to_le32(requested);
4006 pcfg1Data->Reserved = 0;
4007 pcfg1Data->Configuration = cpu_to_le32(configuration);
4008 cfg.pageAddr = (bus<<8) | id;
4009 mpt_config(hd->ioc, &cfg);
4012 /* If target Ptr NULL or if this target is NOT a disk, skip.
4014 if ((pTarget) && (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)){
4015 for (lun=0; lun <= MPT_LAST_LUN; lun++) {
4016 /* If LUN present, issue the command
4018 lun_index = (lun >> 5); /* 32 luns per lun_index */
4019 indexed_lun = (lun % 32);
4020 if (pTarget->luns[lun_index] & (1<<indexed_lun)) {
4022 (void) mptscsih_do_cmd(hd, &iocmd);
4027 /* get next relevant device */
4040 pci_free_consistent(ioc->pcidev, header1.PageLength * 4, pcfg1Data, cfg1_dma_addr);
4046 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
4047 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4049 * mptscsih_domainValidation - Top level handler for domain validation.
4050 * @hd: Pointer to MPT_SCSI_HOST structure.
4052 * Uses the ISR, but with special processing.
4053 * Called from schedule, should not be in interrupt mode.
4054 * While thread alive, do dv for all devices needing dv
4059 mptscsih_domainValidation(void *arg)
4063 unsigned long flags;
4064 int id, maxid, dvStatus, did;
4067 spin_lock_irqsave(&dvtaskQ_lock, flags);
4069 if (dvtaskQ_release) {
4071 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4074 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4076 /* For this ioc, loop through all devices and do dv to each device.
4077 * When complete with this ioc, search through the ioc list, and
4078 * for each scsi ioc found, do dv for all devices. Exit when no
4084 list_for_each_entry(ioc, &ioc_list, list) {
4085 spin_lock_irqsave(&dvtaskQ_lock, flags);
4086 if (dvtaskQ_release) {
4088 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4091 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4095 /* DV only to SCSI adapters */
4096 if (ioc->bus_type != SCSI)
4099 /* Make sure everything looks ok */
4100 if (ioc->sh == NULL)
4103 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
4107 if ((ioc->spi_data.forceDv & MPT_SCSICFG_RELOAD_IOC_PG3) != 0) {
4108 mpt_read_ioc_pg_3(ioc);
4109 if (ioc->spi_data.pIocPg3) {
4110 Ioc3PhysDisk_t *pPDisk = ioc->spi_data.pIocPg3->PhysDisk;
4111 int numPDisk = ioc->spi_data.pIocPg3->NumPhysDisks;
4114 if (ioc->spi_data.dvStatus[pPDisk->PhysDiskID] & MPT_SCSICFG_DV_NOT_DONE)
4115 ioc->spi_data.dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV;
4121 ioc->spi_data.forceDv &= ~MPT_SCSICFG_RELOAD_IOC_PG3;
4124 maxid = min_t(int, ioc->sh->max_id, MPT_MAX_SCSI_DEVICES);
4126 for (id = 0; id < maxid; id++) {
4127 spin_lock_irqsave(&dvtaskQ_lock, flags);
4128 if (dvtaskQ_release) {
4130 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4133 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4134 dvStatus = hd->ioc->spi_data.dvStatus[id];
4136 if (dvStatus & MPT_SCSICFG_NEED_DV) {
4138 hd->ioc->spi_data.dvStatus[id] |= MPT_SCSICFG_DV_PENDING;
4139 hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_NEED_DV;
4143 /* If hidden phys disk, block IO's to all
4145 * else, process normally
4147 isPhysDisk = mptscsih_is_phys_disk(ioc, id);
4149 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4150 if (hd->ioc->spi_data.isRaid & (1 << ii)) {
4151 hd->ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_DV_PENDING;
4156 if (mptscsih_doDv(hd, 0, id) == 1) {
4157 /* Untagged device was busy, try again
4159 hd->ioc->spi_data.dvStatus[id] |= MPT_SCSICFG_NEED_DV;
4160 hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_PENDING;
4162 /* DV is complete. Clear flags.
4164 hd->ioc->spi_data.dvStatus[id] &= ~(MPT_SCSICFG_DV_NOT_DONE | MPT_SCSICFG_DV_PENDING);
4168 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4169 if (hd->ioc->spi_data.isRaid & (1 << ii)) {
4170 hd->ioc->spi_data.dvStatus[ii] &= ~MPT_SCSICFG_DV_PENDING;
4175 if (hd->ioc->spi_data.noQas)
4176 mptscsih_qas_check(hd, id);
4182 spin_lock_irqsave(&dvtaskQ_lock, flags);
4184 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4189 /* Search IOC page 3 to determine if this is hidden physical disk
4192 mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id)
4194 if (ioc->spi_data.pIocPg3) {
4195 Ioc3PhysDisk_t *pPDisk = ioc->spi_data.pIocPg3->PhysDisk;
4196 int numPDisk = ioc->spi_data.pIocPg3->NumPhysDisks;
4199 if (pPDisk->PhysDiskID == id) {
4209 /* Write SDP1 if no QAS has been enabled
4212 mptscsih_qas_check(MPT_SCSI_HOST *hd, int id)
4214 VirtDevice *pTarget;
4217 if (hd->Targets == NULL)
4220 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4224 if ((hd->ioc->spi_data.dvStatus[ii] & MPT_SCSICFG_DV_NOT_DONE) != 0)
4227 pTarget = hd->Targets[ii];
4229 if ((pTarget != NULL) && (!pTarget->raidVolume)) {
4230 if ((pTarget->negoFlags & hd->ioc->spi_data.noQas) == 0) {
4231 pTarget->negoFlags |= hd->ioc->spi_data.noQas;
4232 dnegoprintk(("writeSDP1: id=%d flags=0\n", id));
4233 mptscsih_writeSDP1(hd, 0, ii, 0);
4236 if (mptscsih_is_phys_disk(hd->ioc, ii) == 1) {
4237 dnegoprintk(("writeSDP1: id=%d SCSICFG_USE_NVRAM\n", id));
4238 mptscsih_writeSDP1(hd, 0, ii, MPT_SCSICFG_USE_NVRAM);
4247 #define MPT_GET_NVRAM_VALS 0x01
4248 #define MPT_UPDATE_MAX 0x02
4249 #define MPT_SET_MAX 0x04
4250 #define MPT_SET_MIN 0x08
4251 #define MPT_FALLBACK 0x10
4252 #define MPT_SAVE 0x20
4254 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4256 * mptscsih_doDv - Perform domain validation to a target.
4257 * @hd: Pointer to MPT_SCSI_HOST structure.
4258 * @portnum: IOC port number.
4259 * @target: Physical ID of this target
4261 * Uses the ISR, but with special processing.
4262 * MUST be single-threaded.
4263 * Test will exit if target is at async & narrow.
4268 mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
4270 MPT_ADAPTER *ioc = hd->ioc;
4271 VirtDevice *pTarget;
4272 SCSIDevicePage1_t *pcfg1Data;
4273 SCSIDevicePage0_t *pcfg0Data;
4277 dma_addr_t dvbuf_dma = -1;
4278 dma_addr_t buf1_dma = -1;
4279 dma_addr_t buf2_dma = -1;
4280 dma_addr_t cfg1_dma_addr = -1;
4281 dma_addr_t cfg0_dma_addr = -1;
4282 ConfigPageHeader_t header1;
4283 ConfigPageHeader_t header0;
4290 int dataBufSize = 0;
4291 int echoBufSize = 0;
4296 int nfactor = MPT_ULTRA320;
4298 char doFallback = 0;
4303 if (ioc->spi_data.sdp1length == 0)
4306 if (ioc->spi_data.sdp0length == 0)
4309 /* If multiple buses are used, require that the initiator
4310 * id be the same on all buses.
4312 if (id == ioc->pfacts[0].PortSCSIID)
4316 bus = (u8) bus_number;
4317 ddvtprintk((MYIOC_s_NOTE_FMT
4318 "DV started: bus=%d, id=%d dv @ %p\n",
4319 ioc->name, bus, id, &dv));
4321 /* Prep DV structure
4323 memset (&dv, 0, sizeof(DVPARAMETERS));
4326 /* Populate tmax with the current maximum
4327 * transfer parameters for this target.
4328 * Exit if narrow and async.
4330 dv.cmd = MPT_GET_NVRAM_VALS;
4331 mptscsih_dv_parms(hd, &dv, NULL);
4333 /* Prep SCSI IO structure
4339 iocmd.physDiskNum = -1;
4340 iocmd.rsvd = iocmd.rsvd2 = 0;
4342 pTarget = hd->Targets[id];
4344 /* Use tagged commands if possible.
4347 if (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)
4348 iocmd.flags |= MPT_ICFLAG_TAGGED_CMD;
4350 if (hd->ioc->facts.FWVersion.Word < 0x01000600)
4353 if ((hd->ioc->facts.FWVersion.Word >= 0x01010000) &&
4354 (hd->ioc->facts.FWVersion.Word < 0x01010B00))
4359 /* Prep cfg structure
4361 cfg.pageAddr = (bus<<8) | id;
4362 cfg.cfghdr.hdr = NULL;
4366 header0.PageVersion = ioc->spi_data.sdp0version;
4367 header0.PageLength = ioc->spi_data.sdp0length;
4368 header0.PageNumber = 0;
4369 header0.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4373 header1.PageVersion = ioc->spi_data.sdp1version;
4374 header1.PageLength = ioc->spi_data.sdp1length;
4375 header1.PageNumber = 1;
4376 header1.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4378 if (header0.PageLength & 1)
4379 dv_alloc = (header0.PageLength * 4) + 4;
4381 dv_alloc += (2048 + (header1.PageLength * 4));
4383 pDvBuf = pci_alloc_consistent(ioc->pcidev, dv_alloc, &dvbuf_dma);
4388 pbuf1 = (u8 *)pDvBuf;
4389 buf1_dma = dvbuf_dma;
4392 pbuf2 = (u8 *) (pDvBuf + sz);
4393 buf2_dma = dvbuf_dma + sz;
4396 pcfg0Data = (SCSIDevicePage0_t *) (pDvBuf + sz);
4397 cfg0_dma_addr = dvbuf_dma + sz;
4398 sz += header0.PageLength * 4;
4402 if (header0.PageLength & 1)
4405 pcfg1Data = (SCSIDevicePage1_t *) (pDvBuf + sz);
4406 cfg1_dma_addr = dvbuf_dma + sz;
4408 /* Skip this ID? Set cfg.cfghdr.hdr to force config page write
4411 ScsiCfgData *pspi_data = &hd->ioc->spi_data;
4412 if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
4413 /* Set the factor from nvram */
4414 nfactor = (pspi_data->nvram[id] & MPT_NVRAM_SYNC_MASK) >> 8;
4415 if (nfactor < pspi_data->minSyncFactor )
4416 nfactor = pspi_data->minSyncFactor;
4418 if (!(pspi_data->nvram[id] & MPT_NVRAM_ID_SCAN_ENABLE) ||
4419 (pspi_data->PortFlags == MPI_SCSIPORTPAGE2_PORT_FLAGS_OFF_DV) ) {
4421 ddvprintk((MYIOC_s_NOTE_FMT "DV Skipped: bus, id, lun (%d, %d, %d)\n",
4422 ioc->name, bus, id, lun));
4424 dv.cmd = MPT_SET_MAX;
4425 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
4426 cfg.cfghdr.hdr = &header1;
4428 /* Save the final negotiated settings to
4429 * SCSI device page 1.
4431 cfg.physAddr = cfg1_dma_addr;
4432 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4434 mpt_config(hd->ioc, &cfg);
4440 /* Finish iocmd inititialization - hidden or visible disk? */
4441 if (ioc->spi_data.pIocPg3) {
4442 /* Search IOC page 3 for matching id
4444 Ioc3PhysDisk_t *pPDisk = ioc->spi_data.pIocPg3->PhysDisk;
4445 int numPDisk = ioc->spi_data.pIocPg3->NumPhysDisks;
4448 if (pPDisk->PhysDiskID == id) {
4450 iocmd.flags |= MPT_ICFLAG_PHYS_DISK;
4451 iocmd.physDiskNum = pPDisk->PhysDiskNum;
4455 if (mptscsih_do_raid(hd, MPI_RAID_ACTION_QUIESCE_PHYS_IO, &iocmd) < 0) {
4456 ddvprintk((MYIOC_s_ERR_FMT "RAID Queisce FAILED!\n", ioc->name));
4466 /* RAID Volume ID's may double for a physical device. If RAID but
4467 * not a physical ID as well, skip DV.
4469 if ((hd->ioc->spi_data.isRaid & (1 << id)) && !(iocmd.flags & MPT_ICFLAG_PHYS_DISK))
4474 * Async & Narrow - Inquiry
4475 * Async & Narrow - Inquiry
4476 * Maximum transfer rate - Inquiry
4478 * If compare, test complete.
4479 * If miscompare and first pass, repeat
4480 * If miscompare and not first pass, fall back and repeat
4484 sz = SCSI_MAX_INQUIRY_BYTES;
4485 rc = MPT_SCANDV_GOOD;
4487 ddvprintk((MYIOC_s_NOTE_FMT "DV: Start Basic test on id=%d\n", ioc->name, id));
4489 dv.cmd = MPT_SET_MIN;
4490 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
4492 cfg.cfghdr.hdr = &header1;
4493 cfg.physAddr = cfg1_dma_addr;
4494 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4496 if (mpt_config(hd->ioc, &cfg) != 0)
4499 /* Wide - narrow - wide workaround case
4501 if ((rc == MPT_SCANDV_ISSUE_SENSE) && dv.max.width) {
4502 /* Send an untagged command to reset disk Qs corrupted
4503 * when a parity error occurs on a Request Sense.
4505 if ((hd->ioc->facts.FWVersion.Word >= 0x01000600) ||
4506 ((hd->ioc->facts.FWVersion.Word >= 0x01010000) &&
4507 (hd->ioc->facts.FWVersion.Word < 0x01010B00)) ) {
4509 iocmd.cmd = REQUEST_SENSE;
4510 iocmd.data_dma = buf1_dma;
4513 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4516 if (hd->pLocal == NULL)
4518 rc = hd->pLocal->completion;
4519 if ((rc == MPT_SCANDV_GOOD) || (rc == MPT_SCANDV_SENSE)) {
4529 iocmd.cmd = INQUIRY;
4530 iocmd.data_dma = buf1_dma;
4533 memset(pbuf1, 0x00, sz);
4534 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4537 if (hd->pLocal == NULL)
4539 rc = hd->pLocal->completion;
4540 if (rc == MPT_SCANDV_GOOD) {
4541 if (hd->pLocal->scsiStatus == SAM_STAT_BUSY) {
4542 if ((iocmd.flags & MPT_ICFLAG_TAGGED_CMD) == 0)
4549 } else if (rc == MPT_SCANDV_SENSE) {
4552 /* If first command doesn't complete
4553 * with a good status or with a check condition,
4560 /* Reset the size for disks
4562 inq0 = (*pbuf1) & 0x1F;
4563 if ((inq0 == 0) && pTarget && !pTarget->raidVolume) {
4568 /* Another GEM workaround. Check peripheral device type,
4569 * if PROCESSOR, quit DV.
4571 if (inq0 == TYPE_PROCESSOR) {
4572 mptscsih_initTarget(hd,
4584 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4588 if ((pTarget->maxWidth == 1) && (pTarget->maxOffset) && (nfactor < 0x0A)
4589 && (pTarget->minSyncFactor > 0x09)) {
4590 if ((pbuf1[56] & 0x04) == 0)
4592 else if ((pbuf1[56] & 0x01) == 1) {
4593 pTarget->minSyncFactor =
4594 nfactor > MPT_ULTRA320 ? nfactor : MPT_ULTRA320;
4596 pTarget->minSyncFactor =
4597 nfactor > MPT_ULTRA160 ? nfactor : MPT_ULTRA160;
4600 dv.max.factor = pTarget->minSyncFactor;
4602 if ((pbuf1[56] & 0x02) == 0) {
4603 pTarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
4604 hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS;
4605 ddvprintk((MYIOC_s_NOTE_FMT
4606 "DV: Start Basic noQas on id=%d due to pbuf1[56]=%x\n",
4607 ioc->name, id, pbuf1[56]));
4613 dv.cmd = MPT_FALLBACK;
4615 dv.cmd = MPT_SET_MAX;
4617 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
4618 if (mpt_config(hd->ioc, &cfg) != 0)
4621 if ((!dv.now.width) && (!dv.now.offset))
4624 iocmd.cmd = INQUIRY;
4625 iocmd.data_dma = buf2_dma;
4628 memset(pbuf2, 0x00, sz);
4629 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4631 else if (hd->pLocal == NULL)
4634 /* Save the return code.
4635 * If this is the first pass,
4636 * read SCSI Device Page 0
4637 * and update the target max parameters.
4639 rc = hd->pLocal->completion;
4641 if (rc == MPT_SCANDV_GOOD) {
4646 cfg.cfghdr.hdr = &header0;
4647 cfg.physAddr = cfg0_dma_addr;
4648 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4651 if (mpt_config(hd->ioc, &cfg) != 0)
4654 sdp0_info = le32_to_cpu(pcfg0Data->Information) & 0x0E;
4655 sdp0_nego = (le32_to_cpu(pcfg0Data->NegotiatedParameters) & 0xFF00 ) >> 8;
4657 /* Quantum and Fujitsu workarounds.
4658 * Quantum: PPR U320 -> PPR reply with Ultra2 and wide
4659 * Fujitsu: PPR U320 -> Msg Reject and Ultra2 and wide
4660 * Resetart with a request for U160.
4662 if ((dv.now.factor == MPT_ULTRA320) && (sdp0_nego == MPT_ULTRA2)) {
4665 dv.cmd = MPT_UPDATE_MAX;
4666 mptscsih_dv_parms(hd, &dv, (void *)pcfg0Data);
4667 /* Update the SCSI device page 1 area
4669 pcfg1Data->RequestedParameters = pcfg0Data->NegotiatedParameters;
4674 /* Quantum workaround. Restart this test will the fallback
4677 if (doFallback == 0) {
4678 if (memcmp(pbuf1, pbuf2, sz) != 0) {
4682 ddvprintk((MYIOC_s_NOTE_FMT
4683 "DV:Inquiry compared id=%d, calling initTarget\n", ioc->name, id));
4684 hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_NOT_DONE;
4685 mptscsih_initTarget(hd,
4691 break; /* test complete */
4696 } else if (rc == MPT_SCANDV_ISSUE_SENSE)
4697 doFallback = 1; /* set fallback flag */
4698 else if ((rc == MPT_SCANDV_DID_RESET) ||
4699 (rc == MPT_SCANDV_SENSE) ||
4700 (rc == MPT_SCANDV_FALLBACK))
4701 doFallback = 1; /* set fallback flag */
4708 ddvprintk((MYIOC_s_NOTE_FMT "DV: Basic test on id=%d completed OK.\n", ioc->name, id));
4710 if (ioc->spi_data.mpt_dv == 0)
4713 inq0 = (*pbuf1) & 0x1F;
4715 /* Continue only for disks
4720 if ( ioc->spi_data.PortFlags == MPI_SCSIPORTPAGE2_PORT_FLAGS_BASIC_DV_ONLY )
4723 /* Start the Enhanced Test.
4724 * 0) issue TUR to clear out check conditions
4725 * 1) read capacity of echo (regular) buffer
4727 * 3) do write-read-compare data pattern test
4729 * 5) update nego parms to target struct
4731 cfg.cfghdr.hdr = &header1;
4732 cfg.physAddr = cfg1_dma_addr;
4733 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4736 iocmd.cmd = TEST_UNIT_READY;
4737 iocmd.data_dma = -1;
4742 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4745 if (hd->pLocal == NULL)
4748 rc = hd->pLocal->completion;
4749 if (rc == MPT_SCANDV_GOOD)
4751 else if (rc == MPT_SCANDV_SENSE) {
4752 u8 skey = hd->pLocal->sense[2] & 0x0F;
4753 u8 asc = hd->pLocal->sense[12];
4754 u8 ascq = hd->pLocal->sense[13];
4755 ddvprintk((MYIOC_s_INFO_FMT
4756 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
4757 ioc->name, skey, asc, ascq));
4759 if (skey == UNIT_ATTENTION)
4760 notDone++; /* repeat */
4761 else if ((skey == NOT_READY) &&
4762 (asc == 0x04)&&(ascq == 0x01)) {
4763 /* wait then repeat */
4766 } else if ((skey == NOT_READY) && (asc == 0x3A)) {
4767 /* no medium, try read test anyway */
4770 /* All other errors are fatal.
4772 ddvprintk((MYIOC_s_INFO_FMT "DV: fatal error.",
4780 iocmd.cmd = READ_BUFFER;
4781 iocmd.data_dma = buf1_dma;
4784 iocmd.flags |= MPT_ICFLAG_BUF_CAP;
4788 for (patt = 0; patt < 2; patt++) {
4790 iocmd.flags |= MPT_ICFLAG_ECHO;
4792 iocmd.flags &= ~MPT_ICFLAG_ECHO;
4798 /* If not ready after 8 trials,
4799 * give up on this device.
4804 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4806 else if (hd->pLocal == NULL)
4809 rc = hd->pLocal->completion;
4810 ddvprintk(("ReadBuffer Comp Code %d", rc));
4811 ddvprintk((" buff: %0x %0x %0x %0x\n",
4812 pbuf1[0], pbuf1[1], pbuf1[2], pbuf1[3]));
4814 if (rc == MPT_SCANDV_GOOD) {
4816 if (iocmd.flags & MPT_ICFLAG_ECHO) {
4817 bufsize = ((pbuf1[2] & 0x1F) <<8) | pbuf1[3];
4819 bufsize = pbuf1[1]<<16 | pbuf1[2]<<8 | pbuf1[3];
4821 } else if (rc == MPT_SCANDV_SENSE) {
4822 u8 skey = hd->pLocal->sense[2] & 0x0F;
4823 u8 asc = hd->pLocal->sense[12];
4824 u8 ascq = hd->pLocal->sense[13];
4825 ddvprintk((MYIOC_s_INFO_FMT
4826 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
4827 ioc->name, skey, asc, ascq));
4828 if (skey == ILLEGAL_REQUEST) {
4830 } else if (skey == UNIT_ATTENTION) {
4831 notDone++; /* repeat */
4832 } else if ((skey == NOT_READY) &&
4833 (asc == 0x04)&&(ascq == 0x01)) {
4834 /* wait then repeat */
4838 /* All other errors are fatal.
4840 ddvprintk((MYIOC_s_INFO_FMT "DV: fatal error.",
4845 /* All other errors are fatal
4852 if (iocmd.flags & MPT_ICFLAG_ECHO)
4853 echoBufSize = bufsize;
4855 dataBufSize = bufsize;
4858 iocmd.flags &= ~MPT_ICFLAG_BUF_CAP;
4860 /* Use echo buffers if possible,
4861 * Exit if both buffers are 0.
4863 if (echoBufSize > 0) {
4864 iocmd.flags |= MPT_ICFLAG_ECHO;
4865 if (dataBufSize > 0)
4866 bufsize = min(echoBufSize, dataBufSize);
4868 bufsize = echoBufSize;
4869 } else if (dataBufSize == 0)
4872 ddvprintk((MYIOC_s_INFO_FMT "%s Buffer Capacity %d\n", ioc->name,
4873 (iocmd.flags & MPT_ICFLAG_ECHO) ? "Echo" : " ", bufsize));
4875 /* Data buffers for write-read-compare test max 1K.
4877 sz = min(bufsize, 1024);
4880 * On first pass, always issue a reserve.
4881 * On additional loops, only if a reset has occurred.
4882 * iocmd.flags indicates if echo or regular buffer
4884 for (patt = 0; patt < 4; patt++) {
4885 ddvprintk(("Pattern %d\n", patt));
4886 if ((iocmd.flags & MPT_ICFLAG_RESERVED) && (iocmd.flags & MPT_ICFLAG_DID_RESET)) {
4887 iocmd.cmd = TEST_UNIT_READY;
4888 iocmd.data_dma = -1;
4891 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4894 iocmd.cmd = RELEASE;
4895 iocmd.data_dma = -1;
4898 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4900 else if (hd->pLocal == NULL)
4903 rc = hd->pLocal->completion;
4904 ddvprintk(("Release rc %d\n", rc));
4905 if (rc == MPT_SCANDV_GOOD)
4906 iocmd.flags &= ~MPT_ICFLAG_RESERVED;
4910 iocmd.flags &= ~MPT_ICFLAG_RESERVED;
4912 iocmd.flags &= ~MPT_ICFLAG_DID_RESET;
4915 while (repeat && (!(iocmd.flags & MPT_ICFLAG_RESERVED))) {
4916 iocmd.cmd = RESERVE;
4917 iocmd.data_dma = -1;
4920 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4922 else if (hd->pLocal == NULL)
4925 rc = hd->pLocal->completion;
4926 if (rc == MPT_SCANDV_GOOD) {
4927 iocmd.flags |= MPT_ICFLAG_RESERVED;
4928 } else if (rc == MPT_SCANDV_SENSE) {
4929 /* Wait if coming ready
4931 u8 skey = hd->pLocal->sense[2] & 0x0F;
4932 u8 asc = hd->pLocal->sense[12];
4933 u8 ascq = hd->pLocal->sense[13];
4934 ddvprintk((MYIOC_s_INFO_FMT
4935 "DV: Reserve Failed: ", ioc->name));
4936 ddvprintk(("SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
4939 if ((skey == NOT_READY) && (asc == 0x04)&&
4941 /* wait then repeat */
4945 ddvprintk((MYIOC_s_INFO_FMT
4946 "DV: Reserved Failed.", ioc->name));
4950 ddvprintk((MYIOC_s_INFO_FMT "DV: Reserved Failed.",
4957 mptscsih_fillbuf(pbuf1, sz, patt, 1);
4958 iocmd.cmd = WRITE_BUFFER;
4959 iocmd.data_dma = buf1_dma;
4962 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4964 else if (hd->pLocal == NULL)
4967 rc = hd->pLocal->completion;
4968 if (rc == MPT_SCANDV_GOOD)
4969 ; /* Issue read buffer */
4970 else if (rc == MPT_SCANDV_DID_RESET) {
4971 /* If using echo buffers, reset to data buffers.
4972 * Else do Fallback and restart
4973 * this test (re-issue reserve
4974 * because of bus reset).
4976 if ((iocmd.flags & MPT_ICFLAG_ECHO) && (dataBufSize >= bufsize)) {
4977 iocmd.flags &= ~MPT_ICFLAG_ECHO;
4979 dv.cmd = MPT_FALLBACK;
4980 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
4982 if (mpt_config(hd->ioc, &cfg) != 0)
4985 if ((!dv.now.width) && (!dv.now.offset))
4989 iocmd.flags |= MPT_ICFLAG_DID_RESET;
4992 } else if (rc == MPT_SCANDV_SENSE) {
4993 /* Restart data test if UA, else quit.
4995 u8 skey = hd->pLocal->sense[2] & 0x0F;
4996 ddvprintk((MYIOC_s_INFO_FMT
4997 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n", ioc->name, skey,
4998 hd->pLocal->sense[12], hd->pLocal->sense[13]));
4999 if (skey == UNIT_ATTENTION) {
5002 } else if (skey == ILLEGAL_REQUEST) {
5003 if (iocmd.flags & MPT_ICFLAG_ECHO) {
5004 if (dataBufSize >= bufsize) {
5005 iocmd.flags &= ~MPT_ICFLAG_ECHO;
5020 iocmd.cmd = READ_BUFFER;
5021 iocmd.data_dma = buf2_dma;
5024 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5026 else if (hd->pLocal == NULL)
5029 rc = hd->pLocal->completion;
5030 if (rc == MPT_SCANDV_GOOD) {
5031 /* If buffers compare,
5032 * go to next pattern,
5033 * else, do a fallback and restart
5034 * data transfer test.
5036 if (memcmp (pbuf1, pbuf2, sz) == 0) {
5037 ; /* goto next pattern */
5039 /* Miscompare with Echo buffer, go to data buffer,
5040 * if that buffer exists.
5041 * Miscompare with Data buffer, check first 4 bytes,
5042 * some devices return capacity. Exit in this case.
5044 if (iocmd.flags & MPT_ICFLAG_ECHO) {
5045 if (dataBufSize >= bufsize)
5046 iocmd.flags &= ~MPT_ICFLAG_ECHO;
5050 if (dataBufSize == (pbuf2[1]<<16 | pbuf2[2]<<8 | pbuf2[3])) {
5051 /* Argh. Device returning wrong data.
5052 * Quit DV for this device.
5057 /* Had an actual miscompare. Slow down.*/
5058 dv.cmd = MPT_FALLBACK;
5059 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5061 if (mpt_config(hd->ioc, &cfg) != 0)
5064 if ((!dv.now.width) && (!dv.now.offset))
5071 } else if (rc == MPT_SCANDV_DID_RESET) {
5072 /* Do Fallback and restart
5073 * this test (re-issue reserve
5074 * because of bus reset).
5076 dv.cmd = MPT_FALLBACK;
5077 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5079 if (mpt_config(hd->ioc, &cfg) != 0)
5082 if ((!dv.now.width) && (!dv.now.offset))
5085 iocmd.flags |= MPT_ICFLAG_DID_RESET;
5088 } else if (rc == MPT_SCANDV_SENSE) {
5089 /* Restart data test if UA, else quit.
5091 u8 skey = hd->pLocal->sense[2] & 0x0F;
5092 ddvprintk((MYIOC_s_INFO_FMT
5093 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n", ioc->name, skey,
5094 hd->pLocal->sense[12], hd->pLocal->sense[13]));
5095 if (skey == UNIT_ATTENTION) {
5107 } /* --- end of patt loop ---- */
5110 if (iocmd.flags & MPT_ICFLAG_RESERVED) {
5111 iocmd.cmd = RELEASE;
5112 iocmd.data_dma = -1;
5115 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5116 printk(MYIOC_s_INFO_FMT "DV: Release failed. id %d",
5118 else if (hd->pLocal) {
5119 if (hd->pLocal->completion == MPT_SCANDV_GOOD)
5120 iocmd.flags &= ~MPT_ICFLAG_RESERVED;
5122 printk(MYIOC_s_INFO_FMT "DV: Release failed. id %d",
5128 /* Set if cfg1_dma_addr contents is valid
5130 if ((cfg.cfghdr.hdr != NULL) && (retcode == 0)){
5131 /* If disk, not U320, disable QAS
5133 if ((inq0 == 0) && (dv.now.factor > MPT_ULTRA320)) {
5134 hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS;
5135 ddvprintk((MYIOC_s_NOTE_FMT
5136 "noQas set due to id=%d has factor=%x\n", ioc->name, id, dv.now.factor));
5140 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5142 /* Double writes to SDP1 can cause problems,
5143 * skip save of the final negotiated settings to
5144 * SCSI device page 1.
5146 cfg.cfghdr.hdr = &header1;
5147 cfg.physAddr = cfg1_dma_addr;
5148 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5150 mpt_config(hd->ioc, &cfg);
5154 /* If this is a RAID Passthrough, enable internal IOs
5156 if (iocmd.flags & MPT_ICFLAG_PHYS_DISK) {
5157 if (mptscsih_do_raid(hd, MPI_RAID_ACTION_ENABLE_PHYS_IO, &iocmd) < 0)
5158 ddvprintk((MYIOC_s_ERR_FMT "RAID Enable FAILED!\n", ioc->name));
5161 /* Done with the DV scan of the current target
5164 pci_free_consistent(ioc->pcidev, dv_alloc, pDvBuf, dvbuf_dma);
5166 ddvtprintk((MYIOC_s_INFO_FMT "DV Done id=%d\n",
5172 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5173 /* mptscsih_dv_parms - perform a variety of operations on the
5174 * parameters used for negotiation.
5175 * @hd: Pointer to a SCSI host.
5176 * @dv: Pointer to a structure that contains the maximum and current
5177 * negotiated parameters.
5180 mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
5182 VirtDevice *pTarget;
5183 SCSIDevicePage0_t *pPage0;
5184 SCSIDevicePage1_t *pPage1;
5185 int val = 0, data, configuration;
5194 case MPT_GET_NVRAM_VALS:
5195 ddvprintk((MYIOC_s_NOTE_FMT "Getting NVRAM: ",
5197 /* Get the NVRAM values and save in tmax
5198 * If not an LVD bus, the adapter minSyncFactor has been
5199 * already throttled back.
5201 if ((hd->Targets)&&((pTarget = hd->Targets[(int)id]) != NULL) && !pTarget->raidVolume) {
5202 width = pTarget->maxWidth;
5203 offset = pTarget->maxOffset;
5204 factor = pTarget->minSyncFactor;
5205 negoFlags = pTarget->negoFlags;
5207 if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
5208 data = hd->ioc->spi_data.nvram[id];
5209 width = data & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
5210 if ((offset = hd->ioc->spi_data.maxSyncOffset) == 0)
5213 factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT;
5214 if ((factor == 0) || (factor == MPT_ASYNC)){
5225 /* Set the negotiation flags */
5226 negoFlags = hd->ioc->spi_data.noQas;
5228 negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
5231 negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
5234 /* limit by adapter capabilities */
5235 width = min(width, hd->ioc->spi_data.maxBusWidth);
5236 offset = min(offset, hd->ioc->spi_data.maxSyncOffset);
5237 factor = max(factor, hd->ioc->spi_data.minSyncFactor);
5239 /* Check Consistency */
5240 if (offset && (factor < MPT_ULTRA2) && !width)
5241 factor = MPT_ULTRA2;
5243 dv->max.width = width;
5244 dv->max.offset = offset;
5245 dv->max.factor = factor;
5246 dv->max.flags = negoFlags;
5247 ddvprintk((" id=%d width=%d factor=%x offset=%x flags=%x\n",
5248 id, width, factor, offset, negoFlags));
5251 case MPT_UPDATE_MAX:
5252 ddvprintk((MYIOC_s_NOTE_FMT
5253 "Updating with SDP0 Data: ", hd->ioc->name));
5254 /* Update tmax values with those from Device Page 0.*/
5255 pPage0 = (SCSIDevicePage0_t *) pPage;
5257 val = le32_to_cpu(pPage0->NegotiatedParameters);
5258 dv->max.width = val & MPI_SCSIDEVPAGE0_NP_WIDE ? 1 : 0;
5259 dv->max.offset = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK) >> 16;
5260 dv->max.factor = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK) >> 8;
5263 dv->now.width = dv->max.width;
5264 dv->now.offset = dv->max.offset;
5265 dv->now.factor = dv->max.factor;
5266 ddvprintk(("id=%d width=%d factor=%x offset=%x flags=%x\n",
5267 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags));
5271 ddvprintk((MYIOC_s_NOTE_FMT "Setting Max: ",
5273 /* Set current to the max values. Update the config page.*/
5274 dv->now.width = dv->max.width;
5275 dv->now.offset = dv->max.offset;
5276 dv->now.factor = dv->max.factor;
5277 dv->now.flags = dv->max.flags;
5279 pPage1 = (SCSIDevicePage1_t *)pPage;
5281 mptscsih_setDevicePage1Flags (dv->now.width, dv->now.factor,
5282 dv->now.offset, &val, &configuration, dv->now.flags);
5283 dnegoprintk(("Setting Max: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
5284 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags, val, configuration));
5285 pPage1->RequestedParameters = cpu_to_le32(val);
5286 pPage1->Reserved = 0;
5287 pPage1->Configuration = cpu_to_le32(configuration);
5290 ddvprintk(("id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x configuration=%x\n",
5291 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags, val, configuration));
5295 ddvprintk((MYIOC_s_NOTE_FMT "Setting Min: ",
5297 /* Set page to asynchronous and narrow
5298 * Do not update now, breaks fallback routine. */
5302 negoFlags = dv->max.flags;
5304 pPage1 = (SCSIDevicePage1_t *)pPage;
5306 mptscsih_setDevicePage1Flags (width, factor,
5307 offset, &val, &configuration, negoFlags);
5308 dnegoprintk(("Setting Min: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
5309 id, width, factor, offset, negoFlags, val, configuration));
5310 pPage1->RequestedParameters = cpu_to_le32(val);
5311 pPage1->Reserved = 0;
5312 pPage1->Configuration = cpu_to_le32(configuration);
5314 ddvprintk(("id=%d width=%d factor=%x offset=%x request=%x config=%x negoFlags=%x\n",
5315 id, width, factor, offset, val, configuration, negoFlags));
5319 ddvprintk((MYIOC_s_NOTE_FMT
5320 "Fallback: Start: offset %d, factor %x, width %d \n",
5321 hd->ioc->name, dv->now.offset,
5322 dv->now.factor, dv->now.width));
5323 width = dv->now.width;
5324 offset = dv->now.offset;
5325 factor = dv->now.factor;
5326 if ((offset) && (dv->max.width)) {
5327 if (factor < MPT_ULTRA160)
5328 factor = MPT_ULTRA160;
5329 else if (factor < MPT_ULTRA2) {
5330 factor = MPT_ULTRA2;
5332 } else if ((factor == MPT_ULTRA2) && width) {
5333 factor = MPT_ULTRA2;
5335 } else if (factor < MPT_ULTRA) {
5338 } else if ((factor == MPT_ULTRA) && width) {
5340 } else if (factor < MPT_FAST) {
5343 } else if ((factor == MPT_FAST) && width) {
5346 } else if (factor < MPT_SCSI) {
5349 } else if ((factor == MPT_SCSI) && width) {
5357 } else if (offset) {
5359 if (factor < MPT_ULTRA)
5361 else if (factor < MPT_FAST)
5363 else if (factor < MPT_SCSI)
5374 dv->max.flags |= MPT_TARGET_NO_NEGO_QAS;
5375 dv->max.flags &= ~MPT_TAPE_NEGO_IDP;
5377 dv->now.width = width;
5378 dv->now.offset = offset;
5379 dv->now.factor = factor;
5380 dv->now.flags = dv->max.flags;
5382 pPage1 = (SCSIDevicePage1_t *)pPage;
5384 mptscsih_setDevicePage1Flags (width, factor, offset, &val,
5385 &configuration, dv->now.flags);
5386 dnegoprintk(("Finish: id=%d width=%d offset=%d factor=%x negoFlags=%x request=%x config=%x\n",
5387 id, width, offset, factor, dv->now.flags, val, configuration));
5389 pPage1->RequestedParameters = cpu_to_le32(val);
5390 pPage1->Reserved = 0;
5391 pPage1->Configuration = cpu_to_le32(configuration);
5394 ddvprintk(("Finish: id=%d offset=%d factor=%x width=%d request=%x config=%x\n",
5395 id, dv->now.offset, dv->now.factor, dv->now.width, val, configuration));
5399 ddvprintk((MYIOC_s_NOTE_FMT
5400 "Saving to Target structure: ", hd->ioc->name));
5401 ddvprintk(("id=%d width=%x factor=%x offset=%d flags=%x\n",
5402 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags));
5404 /* Save these values to target structures
5405 * or overwrite nvram (phys disks only).
5408 if ((hd->Targets)&&((pTarget = hd->Targets[(int)id]) != NULL) && !pTarget->raidVolume ) {
5409 pTarget->maxWidth = dv->now.width;
5410 pTarget->maxOffset = dv->now.offset;
5411 pTarget->minSyncFactor = dv->now.factor;
5412 pTarget->negoFlags = dv->now.flags;
5414 /* Preserv all flags, use
5415 * read-modify-write algorithm
5417 if (hd->ioc->spi_data.nvram) {
5418 data = hd->ioc->spi_data.nvram[id];
5421 data &= ~MPT_NVRAM_WIDE_DISABLE;
5423 data |= MPT_NVRAM_WIDE_DISABLE;
5425 if (!dv->now.offset)
5428 data &= ~MPT_NVRAM_SYNC_MASK;
5429 data |= (dv->now.factor << MPT_NVRAM_SYNC_SHIFT) & MPT_NVRAM_SYNC_MASK;
5431 hd->ioc->spi_data.nvram[id] = data;
5438 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5439 /* mptscsih_fillbuf - fill a buffer with a special data pattern
5440 * cleanup. For bus scan only.
5442 * @buffer: Pointer to data buffer to be filled.
5443 * @size: Number of bytes to fill
5444 * @index: Pattern index
5445 * @width: bus width, 0 (8 bits) or 1 (16 bits)
5448 mptscsih_fillbuf(char *buffer, int size, int index, int width)
5459 /* Pattern: 0000 FFFF 0000 FFFF
5461 for (ii=0; ii < size; ii++, ptr++) {
5468 /* Pattern: 00 FF 00 FF
5470 for (ii=0; ii < size; ii++, ptr++) {
5481 /* Pattern: 5555 AAAA 5555 AAAA 5555
5483 for (ii=0; ii < size; ii++, ptr++) {
5490 /* Pattern: 55 AA 55 AA 55
5492 for (ii=0; ii < size; ii++, ptr++) {
5502 /* Pattern: 00 01 02 03 04 05
5505 for (ii=0; ii < size; ii++, ptr++)
5511 /* Wide Pattern: FFFE 0001 FFFD 0002
5512 * ... 4000 DFFF 8000 EFFF
5515 for (ii=0; ii < size/2; ii++) {
5516 /* Create the base pattern
5519 /* every 64 (0x40) bytes flip the pattern
5520 * since we fill 2 bytes / iteration,
5521 * test for ii = 0x20
5527 *ptr = (char)( (val & 0xFF00) >> 8);
5529 *ptr = (char)(val & 0xFF);
5534 *ptr = (char)( (val & 0xFF00) >> 8);
5536 *ptr = (char)(val & 0xFF);
5542 /* Narrow Pattern: FE 01 FD 02 FB 04
5543 * .. 7F 80 01 FE 02 FD ... 80 7F
5546 for (ii=0; ii < size; ii++, ptr++) {
5547 /* Base pattern - first 32 bytes
5554 *ptr = (char) (~(1 << byte));
5557 /* Flip the pattern every 32 bytes
5566 #endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */
5568 EXPORT_SYMBOL(mptscsih_remove);
5569 EXPORT_SYMBOL(mptscsih_shutdown);
5571 EXPORT_SYMBOL(mptscsih_suspend);
5572 EXPORT_SYMBOL(mptscsih_resume);
5574 EXPORT_SYMBOL(mptscsih_proc_info);
5575 EXPORT_SYMBOL(mptscsih_info);
5576 EXPORT_SYMBOL(mptscsih_qcmd);
5577 EXPORT_SYMBOL(mptscsih_slave_alloc);
5578 EXPORT_SYMBOL(mptscsih_slave_destroy);
5579 EXPORT_SYMBOL(mptscsih_slave_configure);
5580 EXPORT_SYMBOL(mptscsih_abort);
5581 EXPORT_SYMBOL(mptscsih_dev_reset);
5582 EXPORT_SYMBOL(mptscsih_bus_reset);
5583 EXPORT_SYMBOL(mptscsih_host_reset);
5584 EXPORT_SYMBOL(mptscsih_bios_param);
5585 EXPORT_SYMBOL(mptscsih_io_done);
5586 EXPORT_SYMBOL(mptscsih_taskmgmt_complete);
5587 EXPORT_SYMBOL(mptscsih_scandv_complete);
5588 EXPORT_SYMBOL(mptscsih_event_process);
5589 EXPORT_SYMBOL(mptscsih_ioc_reset);
5590 EXPORT_SYMBOL(mptscsih_change_queue_depth);
5591 EXPORT_SYMBOL(mptscsih_timer_expired);
5593 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/