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_EBOS 0x04 /* ReadBuffer Echo buffer has EBOS */
97 #define MPT_ICFLAG_PHYS_DISK 0x08 /* Any SCSI IO but do Phys Disk Format */
98 #define MPT_ICFLAG_TAGGED_CMD 0x10 /* Do tagged IO */
99 #define MPT_ICFLAG_DID_RESET 0x20 /* Bus Reset occurred with this command */
100 #define MPT_ICFLAG_RESERVED 0x40 /* Reserved has been issued */
102 typedef struct _internal_cmd {
103 char *data; /* data pointer */
104 dma_addr_t data_dma; /* data dma address */
105 int size; /* transfer size */
106 u8 cmd; /* SCSI Op Code */
107 u8 bus; /* bus number */
108 u8 id; /* SCSI ID (virtual) */
110 u8 flags; /* Bit Field - See above */
111 u8 physDiskNum; /* Phys disk number, -1 else */
116 typedef struct _negoparms {
123 typedef struct _dv_parameters {
132 * Other private/forward protos...
134 int mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
135 static void mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq);
136 int mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
138 static int mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
139 SCSIIORequest_t *pReq, int req_idx);
140 static void mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx);
141 static void mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply);
142 static int mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd);
143 static int mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout );
144 static u32 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc);
146 static int mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout);
147 static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout);
149 int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
150 int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
152 static void mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *data, int dlen);
153 static void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56);
154 static void mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq);
155 static void mptscsih_setDevicePage1Flags (u8 width, u8 factor, u8 offset, int *requestedPtr, int *configurationPtr, u8 flags);
156 static void mptscsih_no_negotiate(MPT_SCSI_HOST *hd, int target_id);
157 static int mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target, int flags);
158 static int mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus);
159 int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
160 static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
161 static int mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum);
163 static struct work_struct mptscsih_persistTask;
165 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
166 static int mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io);
167 static void mptscsih_domainValidation(void *hd);
168 static int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id);
169 static void mptscsih_qas_check(MPT_SCSI_HOST *hd, int id);
170 static int mptscsih_doDv(MPT_SCSI_HOST *hd, int channel, int target);
171 static void mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage);
172 static void mptscsih_fillbuf(char *buffer, int size, int index, int width);
173 static void mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id);
176 void mptscsih_remove(struct pci_dev *);
177 void mptscsih_shutdown(struct pci_dev *);
179 int mptscsih_suspend(struct pci_dev *pdev, pm_message_t state);
180 int mptscsih_resume(struct pci_dev *pdev);
183 #define SNS_LEN(scp) sizeof((scp)->sense_buffer)
185 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
187 * Domain Validation task structure
189 static DEFINE_SPINLOCK(dvtaskQ_lock);
190 static int dvtaskQ_active = 0;
191 static int dvtaskQ_release = 0;
192 static struct work_struct dvTaskQ_task;
195 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
197 * mptscsih_add_sge - Place a simple SGE at address pAddr.
198 * @pAddr: virtual address for SGE
199 * @flagslength: SGE flags and data transfer length
200 * @dma_addr: Physical address
202 * This routine places a MPT request frame back on the MPT adapter's
206 mptscsih_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
208 if (sizeof(dma_addr_t) == sizeof(u64)) {
209 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
210 u32 tmp = dma_addr & 0xFFFFFFFF;
212 pSge->FlagsLength = cpu_to_le32(flagslength);
213 pSge->Address.Low = cpu_to_le32(tmp);
214 tmp = (u32) ((u64)dma_addr >> 32);
215 pSge->Address.High = cpu_to_le32(tmp);
218 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
219 pSge->FlagsLength = cpu_to_le32(flagslength);
220 pSge->Address = cpu_to_le32(dma_addr);
222 } /* mptscsih_add_sge() */
224 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
226 * mptscsih_add_chain - Place a chain SGE at address pAddr.
227 * @pAddr: virtual address for SGE
228 * @next: nextChainOffset value (u32's)
229 * @length: length of next SGL segment
230 * @dma_addr: Physical address
232 * This routine places a MPT request frame back on the MPT adapter's
236 mptscsih_add_chain(char *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
238 if (sizeof(dma_addr_t) == sizeof(u64)) {
239 SGEChain64_t *pChain = (SGEChain64_t *) pAddr;
240 u32 tmp = dma_addr & 0xFFFFFFFF;
242 pChain->Length = cpu_to_le16(length);
243 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size();
245 pChain->NextChainOffset = next;
247 pChain->Address.Low = cpu_to_le32(tmp);
248 tmp = (u32) ((u64)dma_addr >> 32);
249 pChain->Address.High = cpu_to_le32(tmp);
251 SGEChain32_t *pChain = (SGEChain32_t *) pAddr;
252 pChain->Length = cpu_to_le16(length);
253 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size();
254 pChain->NextChainOffset = next;
255 pChain->Address = cpu_to_le32(dma_addr);
257 } /* mptscsih_add_chain() */
259 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
261 * mptscsih_getFreeChainBuffer - Function to get a free chain
262 * from the MPT_SCSI_HOST FreeChainQ.
263 * @ioc: Pointer to MPT_ADAPTER structure
264 * @req_idx: Index of the SCSI IO request frame. (output)
266 * return SUCCESS or FAILED
269 mptscsih_getFreeChainBuffer(MPT_ADAPTER *ioc, int *retIndex)
271 MPT_FRAME_HDR *chainBuf;
276 dsgprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer called\n",
278 spin_lock_irqsave(&ioc->FreeQlock, flags);
279 if (!list_empty(&ioc->FreeChainQ)) {
282 chainBuf = list_entry(ioc->FreeChainQ.next, MPT_FRAME_HDR,
283 u.frame.linkage.list);
284 list_del(&chainBuf->u.frame.linkage.list);
285 offset = (u8 *)chainBuf - (u8 *)ioc->ChainBuffer;
286 chain_idx = offset / ioc->req_sz;
288 dsgprintk((MYIOC_s_ERR_FMT "getFreeChainBuffer chainBuf=%p ChainBuffer=%p offset=%d chain_idx=%d\n",
289 ioc->name, chainBuf, ioc->ChainBuffer, offset, chain_idx));
292 chain_idx = MPT_HOST_NO_CHAIN;
293 dfailprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer failed\n",
296 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
298 *retIndex = chain_idx;
300 } /* mptscsih_getFreeChainBuffer() */
302 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
304 * mptscsih_AddSGE - Add a SGE (plus chain buffers) to the
305 * SCSIIORequest_t Message Frame.
306 * @ioc: Pointer to MPT_ADAPTER structure
307 * @SCpnt: Pointer to scsi_cmnd structure
308 * @pReq: Pointer to SCSIIORequest_t structure
313 mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
314 SCSIIORequest_t *pReq, int req_idx)
318 struct scatterlist *sg;
320 int sges_left, sg_done;
321 int chain_idx = MPT_HOST_NO_CHAIN;
323 int numSgeSlots, numSgeThisFrame;
324 u32 sgflags, sgdir, thisxfer = 0;
325 int chain_dma_off = 0;
331 sgdir = le32_to_cpu(pReq->Control) & MPI_SCSIIO_CONTROL_DATADIRECTION_MASK;
332 if (sgdir == MPI_SCSIIO_CONTROL_WRITE) {
333 sgdir = MPT_TRANSFER_HOST_TO_IOC;
335 sgdir = MPT_TRANSFER_IOC_TO_HOST;
338 psge = (char *) &pReq->SGL;
339 frm_sz = ioc->req_sz;
341 /* Map the data portion, if any.
342 * sges_left = 0 if no data transfer.
344 if ( (sges_left = SCpnt->use_sg) ) {
345 sges_left = pci_map_sg(ioc->pcidev,
346 (struct scatterlist *) SCpnt->request_buffer,
348 SCpnt->sc_data_direction);
351 } else if (SCpnt->request_bufflen) {
352 SCpnt->SCp.dma_handle = pci_map_single(ioc->pcidev,
353 SCpnt->request_buffer,
354 SCpnt->request_bufflen,
355 SCpnt->sc_data_direction);
356 dsgprintk((MYIOC_s_INFO_FMT "SG: non-SG for %p, len=%d\n",
357 ioc->name, SCpnt, SCpnt->request_bufflen));
358 mptscsih_add_sge((char *) &pReq->SGL,
359 0xD1000000|MPT_SGE_FLAGS_ADDRESSING|sgdir|SCpnt->request_bufflen,
360 SCpnt->SCp.dma_handle);
365 /* Handle the SG case.
367 sg = (struct scatterlist *) SCpnt->request_buffer;
369 sgeOffset = sizeof(SCSIIORequest_t) - sizeof(SGE_IO_UNION);
372 /* Prior to entering this loop - the following must be set
373 * current MF: sgeOffset (bytes)
374 * chainSge (Null if original MF is not a chain buffer)
375 * sg_done (num SGE done for this MF)
379 numSgeSlots = ((frm_sz - sgeOffset) / (sizeof(u32) + sizeof(dma_addr_t)) );
380 numSgeThisFrame = (sges_left < numSgeSlots) ? sges_left : numSgeSlots;
382 sgflags = MPT_SGE_FLAGS_SIMPLE_ELEMENT | MPT_SGE_FLAGS_ADDRESSING | sgdir;
384 /* Get first (num - 1) SG elements
385 * Skip any SG entries with a length of 0
386 * NOTE: at finish, sg and psge pointed to NEXT data/location positions
388 for (ii=0; ii < (numSgeThisFrame-1); ii++) {
389 thisxfer = sg_dma_len(sg);
391 sg ++; /* Get next SG element from the OS */
396 v2 = sg_dma_address(sg);
397 mptscsih_add_sge(psge, sgflags | thisxfer, v2);
399 sg++; /* Get next SG element from the OS */
400 psge += (sizeof(u32) + sizeof(dma_addr_t));
401 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
405 if (numSgeThisFrame == sges_left) {
406 /* Add last element, end of buffer and end of list flags.
408 sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT |
409 MPT_SGE_FLAGS_END_OF_BUFFER |
410 MPT_SGE_FLAGS_END_OF_LIST;
412 /* Add last SGE and set termination flags.
413 * Note: Last SGE may have a length of 0 - which should be ok.
415 thisxfer = sg_dma_len(sg);
417 v2 = sg_dma_address(sg);
418 mptscsih_add_sge(psge, sgflags | thisxfer, v2);
421 psge += (sizeof(u32) + sizeof(dma_addr_t));
423 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
427 /* The current buffer is a chain buffer,
428 * but there is not another one.
429 * Update the chain element
430 * Offset and Length fields.
432 mptscsih_add_chain((char *)chainSge, 0, sgeOffset, ioc->ChainBufferDMA + chain_dma_off);
434 /* The current buffer is the original MF
435 * and there is no Chain buffer.
437 pReq->ChainOffset = 0;
438 RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor) + 1) & 0x03;
439 dsgprintk((MYIOC_s_INFO_FMT
440 "Single Buffer RequestNB=%x, sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
441 ioc->RequestNB[req_idx] = RequestNB;
444 /* At least one chain buffer is needed.
445 * Complete the first MF
446 * - last SGE element, set the LastElement bit
447 * - set ChainOffset (words) for orig MF
448 * (OR finish previous MF chain buffer)
449 * - update MFStructPtr ChainIndex
450 * - Populate chain element
455 dsgprintk((MYIOC_s_INFO_FMT "SG: Chain Required! sg done %d\n",
456 ioc->name, sg_done));
458 /* Set LAST_ELEMENT flag for last non-chain element
459 * in the buffer. Since psge points at the NEXT
460 * SGE element, go back one SGE element, update the flags
461 * and reset the pointer. (Note: sgflags & thisxfer are already
465 u32 *ptmp = (u32 *) (psge - (sizeof(u32) + sizeof(dma_addr_t)));
466 sgflags = le32_to_cpu(*ptmp);
467 sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT;
468 *ptmp = cpu_to_le32(sgflags);
472 /* The current buffer is a chain buffer.
473 * chainSge points to the previous Chain Element.
474 * Update its chain element Offset and Length (must
475 * include chain element size) fields.
476 * Old chain element is now complete.
478 u8 nextChain = (u8) (sgeOffset >> 2);
479 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
480 mptscsih_add_chain((char *)chainSge, nextChain, sgeOffset, ioc->ChainBufferDMA + chain_dma_off);
482 /* The original MF buffer requires a chain buffer -
484 * Last element in this MF is a chain element.
486 pReq->ChainOffset = (u8) (sgeOffset >> 2);
487 RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor) + 1) & 0x03;
488 dsgprintk((MYIOC_s_ERR_FMT "Chain Buffer Needed, RequestNB=%x sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
489 ioc->RequestNB[req_idx] = RequestNB;
492 sges_left -= sg_done;
495 /* NOTE: psge points to the beginning of the chain element
496 * in current buffer. Get a chain buffer.
498 if ((mptscsih_getFreeChainBuffer(ioc, &newIndex)) == FAILED) {
499 dfailprintk((MYIOC_s_INFO_FMT
500 "getFreeChainBuffer FAILED SCSI cmd=%02x (%p)\n",
501 ioc->name, pReq->CDB[0], SCpnt));
505 /* Update the tracking arrays.
506 * If chainSge == NULL, update ReqToChain, else ChainToChain
509 ioc->ChainToChain[chain_idx] = newIndex;
511 ioc->ReqToChain[req_idx] = newIndex;
513 chain_idx = newIndex;
514 chain_dma_off = ioc->req_sz * chain_idx;
516 /* Populate the chainSGE for the current buffer.
517 * - Set chain buffer pointer to psge and fill
518 * out the Address and Flags fields.
520 chainSge = (char *) psge;
521 dsgprintk((KERN_INFO " Current buff @ %p (index 0x%x)",
524 /* Start the SGE for the next buffer
526 psge = (char *) (ioc->ChainBuffer + chain_dma_off);
530 dsgprintk((KERN_INFO " Chain buff @ %p (index 0x%x)\n",
533 /* Start the SGE for the next buffer
540 } /* mptscsih_AddSGE() */
542 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
544 * mptscsih_io_done - Main SCSI IO callback routine registered to
545 * Fusion MPT (base) driver
546 * @ioc: Pointer to MPT_ADAPTER structure
547 * @mf: Pointer to original MPT request frame
548 * @r: Pointer to MPT reply frame (NULL if TurboReply)
550 * This routine is called from mpt.c::mpt_interrupt() at the completion
551 * of any SCSI IO request.
552 * This routine is registered with the Fusion MPT (base) driver at driver
553 * load/init time via the mpt_register() API call.
555 * Returns 1 indicating alloc'd request frame ptr should be freed.
558 mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
560 struct scsi_cmnd *sc;
562 SCSIIORequest_t *pScsiReq;
563 SCSIIOReply_t *pScsiReply;
566 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
568 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
569 sc = hd->ScsiLookup[req_idx];
571 MPIHeader_t *hdr = (MPIHeader_t *)mf;
573 /* Remark: writeSDP1 will use the ScsiDoneCtx
574 * If a SCSI I/O cmd, device disabled by OS and
575 * completion done. Cannot touch sc struct. Just free mem.
577 if (hdr->Function == MPI_FUNCTION_SCSI_IO_REQUEST)
578 printk(MYIOC_s_ERR_FMT "NULL ScsiCmd ptr!\n",
581 mptscsih_freeChainBuffers(ioc, req_idx);
585 sc->result = DID_OK << 16; /* Set default reply as OK */
586 pScsiReq = (SCSIIORequest_t *) mf;
587 pScsiReply = (SCSIIOReply_t *) mr;
589 if((ioc->facts.MsgVersion >= MPI_VERSION_01_05) && pScsiReply){
590 dmfprintk((MYIOC_s_INFO_FMT
591 "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d,task-tag=%d)\n",
592 ioc->name, mf, mr, sc, req_idx, pScsiReply->TaskTag));
594 dmfprintk((MYIOC_s_INFO_FMT
595 "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n",
596 ioc->name, mf, mr, sc, req_idx));
599 if (pScsiReply == NULL) {
600 /* special context reply handling */
605 u8 scsi_state, scsi_status;
607 status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK;
608 scsi_state = pScsiReply->SCSIState;
609 scsi_status = pScsiReply->SCSIStatus;
610 xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
611 sc->resid = sc->request_bufflen - xfer_cnt;
614 * if we get a data underrun indication, yet no data was
615 * transferred and the SCSI status indicates that the
616 * command was never started, change the data underrun
619 if (status == MPI_IOCSTATUS_SCSI_DATA_UNDERRUN && xfer_cnt == 0 &&
620 (scsi_status == MPI_SCSI_STATUS_BUSY ||
621 scsi_status == MPI_SCSI_STATUS_RESERVATION_CONFLICT ||
622 scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)) {
623 status = MPI_IOCSTATUS_SUCCESS;
626 dreplyprintk((KERN_NOTICE "Reply ha=%d id=%d lun=%d:\n"
627 "IOCStatus=%04xh SCSIState=%02xh SCSIStatus=%02xh\n"
628 "resid=%d bufflen=%d xfer_cnt=%d\n",
629 ioc->id, pScsiReq->TargetID, pScsiReq->LUN[1],
630 status, scsi_state, scsi_status, sc->resid,
631 sc->request_bufflen, xfer_cnt));
633 if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)
634 mptscsih_copy_sense_data(sc, hd, mf, pScsiReply);
637 * Look for + dump FCP ResponseInfo[]!
639 if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID &&
640 pScsiReply->ResponseInfo) {
641 printk(KERN_NOTICE "ha=%d id=%d lun=%d: "
642 "FCP_ResponseInfo=%08xh\n",
643 ioc->id, pScsiReq->TargetID, pScsiReq->LUN[1],
644 le32_to_cpu(pScsiReply->ResponseInfo));
648 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
650 * Maybe: DRIVER_BUSY | SUGGEST_RETRY | DID_SOFT_ERROR (retry)
651 * But not: DID_BUS_BUSY lest one risk
652 * killing interrupt handler:-(
654 sc->result = SAM_STAT_BUSY;
657 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
658 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
659 sc->result = DID_BAD_TARGET << 16;
662 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
663 /* Spoof to SCSI Selection Timeout! */
664 sc->result = DID_NO_CONNECT << 16;
666 if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF)
667 hd->sel_timeout[pScsiReq->TargetID]++;
670 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
671 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
672 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
673 /* Linux handles an unsolicited DID_RESET better
674 * than an unsolicited DID_ABORT.
676 sc->result = DID_RESET << 16;
678 /* GEM Workaround. */
679 if (ioc->bus_type == SCSI)
680 mptscsih_no_negotiate(hd, sc->device->id);
683 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
684 sc->resid = sc->request_bufflen - xfer_cnt;
685 if((xfer_cnt==0)||(sc->underflow > xfer_cnt))
686 sc->result=DID_SOFT_ERROR << 16;
687 else /* Sufficient data transfer occurred */
688 sc->result = (DID_OK << 16) | scsi_status;
689 dreplyprintk((KERN_NOTICE
690 "RESIDUAL_MISMATCH: result=%x on id=%d\n", sc->result, sc->device->id));
693 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
695 * Do upfront check for valid SenseData and give it
698 sc->result = (DID_OK << 16) | scsi_status;
699 if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
700 /* Have already saved the status and sense data
704 if (xfer_cnt < sc->underflow) {
705 if (scsi_status == SAM_STAT_BUSY)
706 sc->result = SAM_STAT_BUSY;
708 sc->result = DID_SOFT_ERROR << 16;
710 if (scsi_state & (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)) {
713 sc->result = DID_SOFT_ERROR << 16;
715 else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
716 /* Not real sure here either... */
717 sc->result = DID_RESET << 16;
721 dreplyprintk((KERN_NOTICE " sc->underflow={report ERR if < %02xh bytes xfer'd}\n",
723 dreplyprintk((KERN_NOTICE " ActBytesXferd=%02xh\n", xfer_cnt));
726 if (scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)
727 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
731 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
732 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
733 if (scsi_status == MPI_SCSI_STATUS_BUSY)
734 sc->result = (DID_BUS_BUSY << 16) | scsi_status;
736 sc->result = (DID_OK << 16) | scsi_status;
737 if (scsi_state == 0) {
739 } else if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
741 * If running against circa 200003dd 909 MPT f/w,
742 * may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL
743 * (QUEUE_FULL) returned from device! --> get 0x0000?128
744 * and with SenseBytes set to 0.
746 if (pScsiReply->SCSIStatus == MPI_SCSI_STATUS_TASK_SET_FULL)
747 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
750 else if (scsi_state &
751 (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)
756 sc->result = DID_SOFT_ERROR << 16;
758 else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
759 /* Not real sure here either... */
760 sc->result = DID_RESET << 16;
762 else if (scsi_state & MPI_SCSI_STATE_QUEUE_TAG_REJECTED) {
763 /* Device Inq. data indicates that it supports
764 * QTags, but rejects QTag messages.
765 * This command completed OK.
767 * Not real sure here either so do nothing... */
770 if (sc->result == MPI_SCSI_STATUS_TASK_SET_FULL)
771 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
774 * Reservation Conflict, Busy,
775 * Command Terminated, CHECK
779 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
780 sc->result = DID_SOFT_ERROR << 16;
783 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
784 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
785 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
786 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
787 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
788 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
789 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
790 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
791 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
792 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
797 sc->result = DID_SOFT_ERROR << 16;
800 } /* switch(status) */
802 dreplyprintk((KERN_NOTICE " sc->result is %08xh\n", sc->result));
803 } /* end of address reply case */
805 /* Unmap the DMA buffers, if any. */
807 pci_unmap_sg(ioc->pcidev, (struct scatterlist *) sc->request_buffer,
808 sc->use_sg, sc->sc_data_direction);
809 } else if (sc->request_bufflen) {
810 pci_unmap_single(ioc->pcidev, sc->SCp.dma_handle,
811 sc->request_bufflen, sc->sc_data_direction);
814 hd->ScsiLookup[req_idx] = NULL;
816 sc->scsi_done(sc); /* Issue the command callback */
818 /* Free Chain buffers */
819 mptscsih_freeChainBuffers(ioc, req_idx);
824 * mptscsih_flush_running_cmds - For each command found, search
825 * Scsi_Host instance taskQ and reply to OS.
826 * Called only if recovering from a FW reload.
827 * @hd: Pointer to a SCSI HOST structure
831 * Must be called while new I/Os are being queued.
834 mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
836 MPT_ADAPTER *ioc = hd->ioc;
837 struct scsi_cmnd *SCpnt;
840 int max = ioc->req_depth;
842 dprintk((KERN_INFO MYNAM ": flush_ScsiLookup called\n"));
843 for (ii= 0; ii < max; ii++) {
844 if ((SCpnt = hd->ScsiLookup[ii]) != NULL) {
849 /* Null ScsiLookup index
851 hd->ScsiLookup[ii] = NULL;
853 mf = MPT_INDEX_2_MFPTR(ioc, ii);
854 dmfprintk(( "flush: ScsiDone (mf=%p,sc=%p)\n",
857 /* Set status, free OS resources (SG DMA buffers)
859 * Free driver resources (chain, msg buffers)
862 pci_unmap_sg(ioc->pcidev,
863 (struct scatterlist *) SCpnt->request_buffer,
865 SCpnt->sc_data_direction);
866 } else if (SCpnt->request_bufflen) {
867 pci_unmap_single(ioc->pcidev,
868 SCpnt->SCp.dma_handle,
869 SCpnt->request_bufflen,
870 SCpnt->sc_data_direction);
872 SCpnt->result = DID_RESET << 16;
873 SCpnt->host_scribble = NULL;
875 /* Free Chain buffers */
876 mptscsih_freeChainBuffers(ioc, ii);
878 /* Free Message frames */
879 mpt_free_msg_frame(ioc, mf);
881 SCpnt->scsi_done(SCpnt); /* Issue the command callback */
889 * mptscsih_search_running_cmds - Delete any commands associated
890 * with the specified target and lun. Function called only
891 * when a lun is disable by mid-layer.
892 * Do NOT access the referenced scsi_cmnd structure or
893 * members. Will cause either a paging or NULL ptr error.
894 * @hd: Pointer to a SCSI HOST structure
900 * Called from slave_destroy.
903 mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, uint target, uint lun)
905 SCSIIORequest_t *mf = NULL;
907 int max = hd->ioc->req_depth;
908 struct scsi_cmnd *sc;
910 dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n",
913 for (ii=0; ii < max; ii++) {
914 if ((sc = hd->ScsiLookup[ii]) != NULL) {
916 mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii);
918 dsprintk(( "search_running: found (sc=%p, mf = %p) target %d, lun %d \n",
919 hd->ScsiLookup[ii], mf, mf->TargetID, mf->LUN[1]));
921 if ((mf->TargetID != ((u8)target)) || (mf->LUN[1] != ((u8) lun)))
926 hd->ScsiLookup[ii] = NULL;
927 mptscsih_freeChainBuffers(hd->ioc, ii);
928 mpt_free_msg_frame(hd->ioc, (MPT_FRAME_HDR *)mf);
930 pci_unmap_sg(hd->ioc->pcidev,
931 (struct scatterlist *) sc->request_buffer,
933 sc->sc_data_direction);
934 } else if (sc->request_bufflen) {
935 pci_unmap_single(hd->ioc->pcidev,
938 sc->sc_data_direction);
940 sc->host_scribble = NULL;
941 sc->result = DID_NO_CONNECT << 16;
948 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
950 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
952 * mptscsih_report_queue_full - Report QUEUE_FULL status returned
953 * from a SCSI target device.
954 * @sc: Pointer to scsi_cmnd structure
955 * @pScsiReply: Pointer to SCSIIOReply_t
956 * @pScsiReq: Pointer to original SCSI request
958 * This routine periodically reports QUEUE_FULL status returned from a
959 * SCSI target device. It reports this to the console via kernel
960 * printk() API call, not more than once every 10 seconds.
963 mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq)
968 if (sc->device == NULL)
970 if (sc->device->host == NULL)
972 if ((hd = (MPT_SCSI_HOST *)sc->device->host->hostdata) == NULL)
975 if (time - hd->last_queue_full > 10 * HZ) {
976 dprintk((MYIOC_s_WARN_FMT "Device (%d:%d:%d) reported QUEUE_FULL!\n",
977 hd->ioc->name, 0, sc->device->id, sc->device->lun));
978 hd->last_queue_full = time;
982 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
984 * mptscsih_remove - Removed scsi devices
985 * @pdev: Pointer to pci_dev structure
990 mptscsih_remove(struct pci_dev *pdev)
992 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
993 struct Scsi_Host *host = ioc->sh;
1004 scsi_remove_host(host);
1006 if((hd = (MPT_SCSI_HOST *)host->hostdata) == NULL)
1009 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1010 /* Check DV thread active */
1012 spin_lock_irqsave(&dvtaskQ_lock, flags);
1013 if (dvtaskQ_active) {
1014 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
1015 while(dvtaskQ_active && --count) {
1016 set_current_state(TASK_INTERRUPTIBLE);
1017 schedule_timeout(1);
1020 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
1023 printk(KERN_ERR MYNAM ": ERROR - DV thread still active!\n");
1024 #if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY)
1026 printk(KERN_ERR MYNAM ": DV thread orig %d, count %d\n", 10 * HZ, count);
1030 mptscsih_shutdown(pdev);
1034 if (hd->ScsiLookup != NULL) {
1035 sz1 = hd->ioc->req_depth * sizeof(void *);
1036 kfree(hd->ScsiLookup);
1037 hd->ScsiLookup = NULL;
1041 * Free pointer array.
1046 dprintk((MYIOC_s_INFO_FMT
1047 "Free'd ScsiLookup (%d) memory\n",
1048 hd->ioc->name, sz1));
1050 kfree(hd->info_kbuf);
1052 /* NULL the Scsi_Host pointer
1056 scsi_host_put(host);
1062 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1064 * mptscsih_shutdown - reboot notifier
1068 mptscsih_shutdown(struct pci_dev *pdev)
1070 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1071 struct Scsi_Host *host = ioc->sh;
1077 hd = (MPT_SCSI_HOST *)host->hostdata;
1079 /* Flush the cache of this adapter
1082 mptscsih_synchronize_cache(hd, 0);
1087 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1089 * mptscsih_suspend - Fusion MPT scsi driver suspend routine.
1094 mptscsih_suspend(struct pci_dev *pdev, pm_message_t state)
1096 mptscsih_shutdown(pdev);
1097 return mpt_suspend(pdev,state);
1100 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1102 * mptscsih_resume - Fusion MPT scsi driver resume routine.
1107 mptscsih_resume(struct pci_dev *pdev)
1109 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1110 struct Scsi_Host *host = ioc->sh;
1118 hd = (MPT_SCSI_HOST *)host->hostdata;
1122 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1124 unsigned long lflags;
1125 spin_lock_irqsave(&dvtaskQ_lock, lflags);
1126 if (!dvtaskQ_active) {
1128 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1129 INIT_WORK(&dvTaskQ_task,
1130 mptscsih_domainValidation, (void *) hd);
1131 schedule_work(&dvTaskQ_task);
1133 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1142 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1144 * mptscsih_info - Return information about MPT adapter
1145 * @SChost: Pointer to Scsi_Host structure
1147 * (linux scsi_host_template.info routine)
1149 * Returns pointer to buffer where information was written.
1152 mptscsih_info(struct Scsi_Host *SChost)
1157 h = (MPT_SCSI_HOST *)SChost->hostdata;
1160 if (h->info_kbuf == NULL)
1161 if ((h->info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)
1162 return h->info_kbuf;
1163 h->info_kbuf[0] = '\0';
1165 mpt_print_ioc_summary(h->ioc, h->info_kbuf, &size, 0, 0);
1166 h->info_kbuf[size-1] = '\0';
1169 return h->info_kbuf;
1180 mptscsih_copy_mem_info(struct info_str *info, char *data, int len)
1182 if (info->pos + len > info->length)
1183 len = info->length - info->pos;
1185 if (info->pos + len < info->offset) {
1190 if (info->pos < info->offset) {
1191 data += (info->offset - info->pos);
1192 len -= (info->offset - info->pos);
1196 memcpy(info->buffer + info->pos, data, len);
1202 mptscsih_copy_info(struct info_str *info, char *fmt, ...)
1208 va_start(args, fmt);
1209 len = vsprintf(buf, fmt, args);
1212 mptscsih_copy_mem_info(info, buf, len);
1217 mptscsih_host_info(MPT_ADAPTER *ioc, char *pbuf, off_t offset, int len)
1219 struct info_str info;
1223 info.offset = offset;
1226 mptscsih_copy_info(&info, "%s: %s, ", ioc->name, ioc->prod_name);
1227 mptscsih_copy_info(&info, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING, ioc->facts.FWVersion.Word);
1228 mptscsih_copy_info(&info, "Ports=%d, ", ioc->facts.NumberOfPorts);
1229 mptscsih_copy_info(&info, "MaxQ=%d\n", ioc->req_depth);
1231 return ((info.pos > info.offset) ? info.pos - info.offset : 0);
1234 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1236 * mptscsih_proc_info - Return information about MPT adapter
1238 * (linux scsi_host_template.info routine)
1240 * buffer: if write, user data; if read, buffer for user
1241 * length: if write, return length;
1242 * offset: if write, 0; if read, the current offset into the buffer from
1243 * the previous read.
1244 * hostno: scsi host number
1245 * func: if write = 1; if read = 0
1248 mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
1249 int length, int func)
1251 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
1252 MPT_ADAPTER *ioc = hd->ioc;
1257 * write is not supported
1263 size = mptscsih_host_info(ioc, buffer, offset, length);
1269 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1270 #define ADD_INDEX_LOG(req_ent) do { } while(0)
1272 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1274 * mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine.
1275 * @SCpnt: Pointer to scsi_cmnd structure
1276 * @done: Pointer SCSI mid-layer IO completion function
1278 * (linux scsi_host_template.queuecommand routine)
1279 * This is the primary SCSI IO start routine. Create a MPI SCSIIORequest
1280 * from a linux scsi_cmnd request and send it to the IOC.
1282 * Returns 0. (rtn value discarded by linux scsi mid-layer)
1285 mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1289 SCSIIORequest_t *pScsiReq;
1290 VirtDevice *pTarget = SCpnt->device->hostdata;
1299 hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata;
1300 lun = SCpnt->device->lun;
1301 SCpnt->scsi_done = done;
1303 dmfprintk((MYIOC_s_INFO_FMT "qcmd: SCpnt=%p, done()=%p\n",
1304 (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt, done));
1306 if (hd->resetPending) {
1307 dtmprintk((MYIOC_s_WARN_FMT "qcmd: SCpnt=%p timeout + 60HZ\n",
1308 (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt));
1309 return SCSI_MLQUEUE_HOST_BUSY;
1313 * Put together a MPT SCSI request...
1315 if ((mf = mpt_get_msg_frame(hd->ioc->DoneCtx, hd->ioc)) == NULL) {
1316 dprintk((MYIOC_s_WARN_FMT "QueueCmd, no msg frames!!\n",
1318 return SCSI_MLQUEUE_HOST_BUSY;
1321 pScsiReq = (SCSIIORequest_t *) mf;
1323 my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
1325 ADD_INDEX_LOG(my_idx);
1327 /* TUR's being issued with scsictl=0x02000000 (DATA_IN)!
1328 * Seems we may receive a buffer (datalen>0) even when there
1329 * will be no data transfer! GRRRRR...
1331 if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
1332 datalen = SCpnt->request_bufflen;
1333 scsidir = MPI_SCSIIO_CONTROL_READ; /* DATA IN (host<--ioc<--dev) */
1334 } else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
1335 datalen = SCpnt->request_bufflen;
1336 scsidir = MPI_SCSIIO_CONTROL_WRITE; /* DATA OUT (host-->ioc-->dev) */
1339 scsidir = MPI_SCSIIO_CONTROL_NODATATRANSFER;
1342 /* Default to untagged. Once a target structure has been allocated,
1343 * use the Inquiry data to determine if device supports tagged.
1346 && (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)
1347 && (SCpnt->device->tagged_supported)) {
1348 scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
1350 scsictl = scsidir | MPI_SCSIIO_CONTROL_UNTAGGED;
1353 /* Use the above information to set up the message frame
1355 pScsiReq->TargetID = (u8) pTarget->target_id;
1356 pScsiReq->Bus = pTarget->bus_id;
1357 pScsiReq->ChainOffset = 0;
1358 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
1359 pScsiReq->CDBLength = SCpnt->cmd_len;
1360 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
1361 pScsiReq->Reserved = 0;
1362 pScsiReq->MsgFlags = mpt_msg_flags();
1363 pScsiReq->LUN[0] = 0;
1364 pScsiReq->LUN[1] = lun;
1365 pScsiReq->LUN[2] = 0;
1366 pScsiReq->LUN[3] = 0;
1367 pScsiReq->LUN[4] = 0;
1368 pScsiReq->LUN[5] = 0;
1369 pScsiReq->LUN[6] = 0;
1370 pScsiReq->LUN[7] = 0;
1371 pScsiReq->Control = cpu_to_le32(scsictl);
1374 * Write SCSI CDB into the message
1376 cmd_len = SCpnt->cmd_len;
1377 for (ii=0; ii < cmd_len; ii++)
1378 pScsiReq->CDB[ii] = SCpnt->cmnd[ii];
1380 for (ii=cmd_len; ii < 16; ii++)
1381 pScsiReq->CDB[ii] = 0;
1384 pScsiReq->DataLength = cpu_to_le32(datalen);
1386 /* SenseBuffer low address */
1387 pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
1388 + (my_idx * MPT_SENSE_BUFFER_ALLOC));
1390 /* Now add the SG list
1391 * Always have a SGE even if null length.
1394 /* Add a NULL SGE */
1395 mptscsih_add_sge((char *)&pScsiReq->SGL, MPT_SGE_FLAGS_SSIMPLE_READ | 0,
1398 /* Add a 32 or 64 bit SGE */
1399 if (mptscsih_AddSGE(hd->ioc, SCpnt, pScsiReq, my_idx) != SUCCESS)
1403 hd->ScsiLookup[my_idx] = SCpnt;
1404 SCpnt->host_scribble = NULL;
1406 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1407 if (hd->ioc->bus_type == SCSI) {
1408 int dvStatus = hd->ioc->spi_data.dvStatus[pTarget->target_id];
1411 if (dvStatus || hd->ioc->spi_data.forceDv) {
1413 if ((dvStatus & MPT_SCSICFG_NEED_DV) ||
1414 (hd->ioc->spi_data.forceDv & MPT_SCSICFG_NEED_DV)) {
1415 unsigned long lflags;
1416 /* Schedule DV if necessary */
1417 spin_lock_irqsave(&dvtaskQ_lock, lflags);
1418 if (!dvtaskQ_active) {
1420 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1421 INIT_WORK(&dvTaskQ_task, mptscsih_domainValidation, (void *) hd);
1423 schedule_work(&dvTaskQ_task);
1425 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1427 hd->ioc->spi_data.forceDv &= ~MPT_SCSICFG_NEED_DV;
1430 /* Trying to do DV to this target, extend timeout.
1431 * Wait to issue until flag is clear
1433 if (dvStatus & MPT_SCSICFG_DV_PENDING) {
1434 mod_timer(&SCpnt->eh_timeout, jiffies + 40 * HZ);
1438 /* Set the DV flags.
1440 if (dvStatus & MPT_SCSICFG_DV_NOT_DONE)
1441 mptscsih_set_dvflags(hd, pScsiReq);
1449 mpt_put_msg_frame(hd->ioc->DoneCtx, hd->ioc, mf);
1450 dmfprintk((MYIOC_s_INFO_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n",
1451 hd->ioc->name, SCpnt, mf, my_idx));
1452 DBG_DUMP_REQUEST_FRAME(mf)
1456 hd->ScsiLookup[my_idx] = NULL;
1457 mptscsih_freeChainBuffers(hd->ioc, my_idx);
1458 mpt_free_msg_frame(hd->ioc, mf);
1459 return SCSI_MLQUEUE_HOST_BUSY;
1462 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1464 * mptscsih_freeChainBuffers - Function to free chain buffers associated
1465 * with a SCSI IO request
1466 * @hd: Pointer to the MPT_SCSI_HOST instance
1467 * @req_idx: Index of the SCSI IO request frame.
1469 * Called if SG chain buffer allocation fails and mptscsih callbacks.
1473 mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
1475 MPT_FRAME_HDR *chain;
1476 unsigned long flags;
1480 /* Get the first chain index and reset
1483 chain_idx = ioc->ReqToChain[req_idx];
1484 ioc->ReqToChain[req_idx] = MPT_HOST_NO_CHAIN;
1486 while (chain_idx != MPT_HOST_NO_CHAIN) {
1488 /* Save the next chain buffer index */
1489 next = ioc->ChainToChain[chain_idx];
1491 /* Free this chain buffer and reset
1494 ioc->ChainToChain[chain_idx] = MPT_HOST_NO_CHAIN;
1496 chain = (MPT_FRAME_HDR *) (ioc->ChainBuffer
1497 + (chain_idx * ioc->req_sz));
1499 spin_lock_irqsave(&ioc->FreeQlock, flags);
1500 list_add_tail(&chain->u.frame.linkage.list, &ioc->FreeChainQ);
1501 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1503 dmfprintk((MYIOC_s_INFO_FMT "FreeChainBuffers (index %d)\n",
1504 ioc->name, chain_idx));
1512 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1517 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1519 * mptscsih_TMHandler - Generic handler for SCSI Task Management.
1520 * Fall through to mpt_HardResetHandler if: not operational, too many
1521 * failed TM requests or handshake failure.
1523 * @ioc: Pointer to MPT_ADAPTER structure
1524 * @type: Task Management type
1525 * @target: Logical Target ID for reset (if appropriate)
1526 * @lun: Logical Unit for reset (if appropriate)
1527 * @ctx2abort: Context for the task to be aborted (if appropriate)
1529 * Remark: Currently invoked from a non-interrupt thread (_bh).
1531 * Remark: With old EH code, at most 1 SCSI TaskMgmt function per IOC
1534 * Returns 0 for SUCCESS or -1 if FAILED.
1537 mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout)
1543 unsigned long flags;
1545 /* If FW is being reloaded currently, return success to
1546 * the calling function.
1553 printk(KERN_ERR MYNAM " TMHandler" " NULL ioc!\n");
1556 dtmprintk((MYIOC_s_INFO_FMT "TMHandler Entered!\n", ioc->name));
1558 // SJR - CHECKME - Can we avoid this here?
1559 // (mpt_HardResetHandler has this check...)
1560 spin_lock_irqsave(&ioc->diagLock, flags);
1561 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)) {
1562 spin_unlock_irqrestore(&ioc->diagLock, flags);
1565 spin_unlock_irqrestore(&ioc->diagLock, flags);
1567 /* Wait a fixed amount of time for the TM pending flag to be cleared.
1568 * If we time out and not bus reset, then we return a FAILED status to the caller.
1569 * The call to mptscsih_tm_pending_wait() will set the pending flag if we are
1570 * successful. Otherwise, reload the FW.
1572 if (mptscsih_tm_pending_wait(hd) == FAILED) {
1573 if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
1574 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler abort: "
1575 "Timed out waiting for last TM (%d) to complete! \n",
1576 hd->ioc->name, hd->tmPending));
1578 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) {
1579 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler target reset: "
1580 "Timed out waiting for last TM (%d) to complete! \n",
1581 hd->ioc->name, hd->tmPending));
1583 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
1584 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler bus reset: "
1585 "Timed out waiting for last TM (%d) to complete! \n",
1586 hd->ioc->name, hd->tmPending));
1587 if (hd->tmPending & (1 << MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS))
1593 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
1594 hd->tmPending |= (1 << type);
1595 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1600 ioc_raw_state = mpt_GetIocState(hd->ioc, 0);
1602 #ifdef MPT_DEBUG_RESET
1603 if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) {
1604 printk(MYIOC_s_WARN_FMT
1605 "TM Handler: IOC Not operational(0x%x)!\n",
1606 hd->ioc->name, ioc_raw_state);
1610 if (doTask && ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL)
1611 && !(ioc_raw_state & MPI_DOORBELL_ACTIVE)) {
1613 /* Isse the Task Mgmt request.
1615 if (hd->hard_resets < -1)
1617 rc = mptscsih_IssueTaskMgmt(hd, type, channel, target, lun, ctx2abort, timeout);
1619 printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n", hd->ioc->name);
1621 dtmprintk((MYIOC_s_INFO_FMT "Issue of TaskMgmt Successful!\n", hd->ioc->name));
1625 /* Only fall through to the HRH if this is a bus reset
1627 if ((type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) && (rc ||
1628 ioc->reload_fw || (ioc->alt_ioc && ioc->alt_ioc->reload_fw))) {
1629 dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
1631 rc = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
1634 dtmprintk((MYIOC_s_INFO_FMT "TMHandler rc = %d!\n", hd->ioc->name, rc));
1640 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1642 * mptscsih_IssueTaskMgmt - Generic send Task Management function.
1643 * @hd: Pointer to MPT_SCSI_HOST structure
1644 * @type: Task Management type
1645 * @target: Logical Target ID for reset (if appropriate)
1646 * @lun: Logical Unit for reset (if appropriate)
1647 * @ctx2abort: Context for the task to be aborted (if appropriate)
1649 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
1650 * or a non-interrupt thread. In the former, must not call schedule().
1652 * Not all fields are meaningfull for all task types.
1654 * Returns 0 for SUCCESS, -999 for "no msg frames",
1655 * else other non-zero value returned.
1658 mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout)
1661 SCSITaskMgmt_t *pScsiTm;
1665 /* Return Fail to calling function if no message frames available.
1667 if ((mf = mpt_get_msg_frame(hd->ioc->TaskCtx, hd->ioc)) == NULL) {
1668 dfailprintk((MYIOC_s_ERR_FMT "IssueTaskMgmt, no msg frames!!\n",
1672 dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt request @ %p\n",
1673 hd->ioc->name, mf));
1675 /* Format the Request
1677 pScsiTm = (SCSITaskMgmt_t *) mf;
1678 pScsiTm->TargetID = target;
1679 pScsiTm->Bus = channel;
1680 pScsiTm->ChainOffset = 0;
1681 pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
1683 pScsiTm->Reserved = 0;
1684 pScsiTm->TaskType = type;
1685 pScsiTm->Reserved1 = 0;
1686 pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)
1687 ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0;
1689 for (ii= 0; ii < 8; ii++) {
1690 pScsiTm->LUN[ii] = 0;
1692 pScsiTm->LUN[1] = lun;
1694 for (ii=0; ii < 7; ii++)
1695 pScsiTm->Reserved2[ii] = 0;
1697 pScsiTm->TaskMsgContext = ctx2abort;
1699 dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt: ctx2abort (0x%08x) type=%d\n",
1700 hd->ioc->name, ctx2abort, type));
1702 DBG_DUMP_TM_REQUEST_FRAME((u32 *)pScsiTm);
1704 if ((retval = mpt_send_handshake_request(hd->ioc->TaskCtx, hd->ioc,
1705 sizeof(SCSITaskMgmt_t), (u32*)pScsiTm,
1707 dfailprintk((MYIOC_s_ERR_FMT "_send_handshake FAILED!"
1708 " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
1710 mpt_free_msg_frame(hd->ioc, mf);
1714 if(mptscsih_tm_wait_for_completion(hd, timeout) == FAILED) {
1715 dfailprintk((MYIOC_s_ERR_FMT "_wait_for_completion FAILED!"
1716 " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
1718 mpt_free_msg_frame(hd->ioc, mf);
1719 dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
1721 retval = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
1727 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1729 * mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant
1730 * @SCpnt: Pointer to scsi_cmnd structure, IO to be aborted
1732 * (linux scsi_host_template.eh_abort_handler routine)
1734 * Returns SUCCESS or FAILED.
1737 mptscsih_abort(struct scsi_cmnd * SCpnt)
1746 /* If we can't locate our host adapter structure, return FAILED status.
1748 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL) {
1749 SCpnt->result = DID_RESET << 16;
1750 SCpnt->scsi_done(SCpnt);
1751 dfailprintk((KERN_INFO MYNAM ": mptscsih_abort: "
1752 "Can't locate host! (sc=%p)\n",
1758 if (hd->resetPending) {
1762 if (hd->timeouts < -1)
1765 /* Find this command
1767 if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) {
1768 /* Cmd not found in ScsiLookup.
1771 SCpnt->result = DID_RESET << 16;
1772 dtmprintk((KERN_INFO MYNAM ": %s: mptscsih_abort: "
1773 "Command not in the active list! (sc=%p)\n",
1774 hd->ioc->name, SCpnt));
1778 printk(KERN_WARNING MYNAM ": %s: attempting task abort! (sc=%p)\n",
1779 hd->ioc->name, SCpnt);
1780 scsi_print_command(SCpnt);
1782 /* Most important! Set TaskMsgContext to SCpnt's MsgContext!
1783 * (the IO to be ABORT'd)
1785 * NOTE: Since we do not byteswap MsgContext, we do not
1786 * swap it here either. It is an opaque cookie to
1787 * the controller, so it does not matter. -DaveM
1789 mf = MPT_INDEX_2_MFPTR(hd->ioc, scpnt_idx);
1790 ctx2abort = mf->u.frame.hwhdr.msgctxu.MsgContext;
1792 hd->abortSCpnt = SCpnt;
1794 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
1795 SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun,
1796 ctx2abort, 2 /* 2 second timeout */);
1798 printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n",
1800 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1805 if(retval != FAILED ) {
1807 hd->tmState = TM_STATE_NONE;
1812 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1814 * mptscsih_dev_reset - Perform a SCSI TARGET_RESET! new_eh variant
1815 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1817 * (linux scsi_host_template.eh_dev_reset_handler routine)
1819 * Returns SUCCESS or FAILED.
1822 mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
1827 /* If we can't locate our host adapter structure, return FAILED status.
1829 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1830 dtmprintk((KERN_INFO MYNAM ": mptscsih_dev_reset: "
1831 "Can't locate host! (sc=%p)\n",
1836 if (hd->resetPending)
1839 printk(KERN_WARNING MYNAM ": %s: attempting target reset! (sc=%p)\n",
1840 hd->ioc->name, SCpnt);
1841 scsi_print_command(SCpnt);
1843 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
1844 SCpnt->device->channel, SCpnt->device->id,
1845 0, 0, 5 /* 5 second timeout */);
1847 printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n",
1849 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1854 if(retval != FAILED ) {
1856 hd->tmState = TM_STATE_NONE;
1861 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1863 * mptscsih_bus_reset - Perform a SCSI BUS_RESET! new_eh variant
1864 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1866 * (linux scsi_host_template.eh_bus_reset_handler routine)
1868 * Returns SUCCESS or FAILED.
1871 mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
1876 /* If we can't locate our host adapter structure, return FAILED status.
1878 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1879 dtmprintk((KERN_INFO MYNAM ": mptscsih_bus_reset: "
1880 "Can't locate host! (sc=%p)\n",
1885 printk(KERN_WARNING MYNAM ": %s: attempting bus reset! (sc=%p)\n",
1886 hd->ioc->name, SCpnt);
1887 scsi_print_command(SCpnt);
1889 if (hd->timeouts < -1)
1892 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
1893 SCpnt->device->channel, 0, 0, 0, 5 /* 5 second timeout */);
1895 printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n",
1897 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1902 if(retval != FAILED ) {
1904 hd->tmState = TM_STATE_NONE;
1909 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1911 * mptscsih_host_reset - Perform a SCSI host adapter RESET!
1913 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1915 * (linux scsi_host_template.eh_host_reset_handler routine)
1917 * Returns SUCCESS or FAILED.
1920 mptscsih_host_reset(struct scsi_cmnd *SCpnt)
1923 int status = SUCCESS;
1925 /* If we can't locate the host to reset, then we failed. */
1926 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1927 dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
1928 "Can't locate host! (sc=%p)\n",
1933 printk(KERN_WARNING MYNAM ": %s: Attempting host reset! (sc=%p)\n",
1934 hd->ioc->name, SCpnt);
1936 /* If our attempts to reset the host failed, then return a failed
1937 * status. The host will be taken off line by the SCSI mid-layer.
1939 if (mpt_HardResetHandler(hd->ioc, CAN_SLEEP) < 0){
1942 /* Make sure TM pending is cleared and TM state is set to
1946 hd->tmState = TM_STATE_NONE;
1949 dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
1951 (status == SUCCESS) ? "SUCCESS" : "FAILED" ) );
1956 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1958 * mptscsih_tm_pending_wait - wait for pending task management request to
1960 * @hd: Pointer to MPT host structure.
1962 * Returns {SUCCESS,FAILED}.
1965 mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd)
1967 unsigned long flags;
1968 int loop_count = 4 * 10; /* Wait 10 seconds */
1969 int status = FAILED;
1972 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
1973 if (hd->tmState == TM_STATE_NONE) {
1974 hd->tmState = TM_STATE_IN_PROGRESS;
1976 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1980 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1982 } while (--loop_count);
1987 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1989 * mptscsih_tm_wait_for_completion - wait for completion of TM task
1990 * @hd: Pointer to MPT host structure.
1992 * Returns {SUCCESS,FAILED}.
1995 mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout )
1997 unsigned long flags;
1998 int loop_count = 4 * timeout;
1999 int status = FAILED;
2002 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
2003 if(hd->tmPending == 0) {
2005 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2008 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2009 msleep_interruptible(250);
2010 } while (--loop_count);
2015 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2017 * mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
2018 * @ioc: Pointer to MPT_ADAPTER structure
2019 * @mf: Pointer to SCSI task mgmt request frame
2020 * @mr: Pointer to SCSI task mgmt reply frame
2022 * This routine is called from mptbase.c::mpt_interrupt() at the completion
2023 * of any SCSI task management request.
2024 * This routine is registered with the MPT (base) driver at driver
2025 * load/init time via the mpt_register() API call.
2027 * Returns 1 indicating alloc'd request frame ptr should be freed.
2030 mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
2032 SCSITaskMgmtReply_t *pScsiTmReply;
2033 SCSITaskMgmt_t *pScsiTmReq;
2035 unsigned long flags;
2039 dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt completed (mf=%p,mr=%p)\n",
2040 ioc->name, mf, mr));
2042 /* Depending on the thread, a timer is activated for
2043 * the TM request. Delete this timer on completion of TM.
2044 * Decrement count of outstanding TM requests.
2046 hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
2048 dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt Complete: NULL Scsi Host Ptr\n",
2054 dtmprintk((MYIOC_s_WARN_FMT "ERROR! TaskMgmt Reply: NULL Request %p\n",
2058 pScsiTmReply = (SCSITaskMgmtReply_t*)mr;
2059 pScsiTmReq = (SCSITaskMgmt_t*)mf;
2061 /* Figure out if this was ABORT_TASK, TARGET_RESET, or BUS_RESET! */
2062 tmType = pScsiTmReq->TaskType;
2064 dtmprintk((MYIOC_s_WARN_FMT " TaskType = %d, TerminationCount=%d\n",
2065 ioc->name, tmType, le32_to_cpu(pScsiTmReply->TerminationCount)));
2066 DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply);
2068 iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2069 dtmprintk((MYIOC_s_WARN_FMT " SCSI TaskMgmt (%d) IOCStatus=%04x IOCLogInfo=%08x\n",
2070 ioc->name, tmType, iocstatus, le32_to_cpu(pScsiTmReply->IOCLogInfo)));
2071 /* Error? (anything non-zero?) */
2074 /* clear flags and continue.
2076 if (tmType == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK)
2077 hd->abortSCpnt = NULL;
2079 /* If an internal command is present
2080 * or the TM failed - reload the FW.
2081 * FC FW may respond FAILED to an ABORT
2083 if (tmType == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
2085 (iocstatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED)) {
2086 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0) {
2087 printk((KERN_WARNING
2088 " Firmware Reload FAILED!!\n"));
2093 dtmprintk((MYIOC_s_WARN_FMT " TaskMgmt SUCCESS\n", ioc->name));
2095 hd->abortSCpnt = NULL;
2100 spin_lock_irqsave(&ioc->FreeQlock, flags);
2102 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2103 hd->tmState = TM_STATE_NONE;
2108 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2110 * This is anyones guess quite frankly.
2113 mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
2114 sector_t capacity, int geom[])
2124 dummy = heads * sectors;
2125 cylinders = capacity;
2126 sector_div(cylinders,dummy);
2129 * Handle extended translation size for logical drives
2132 if ((ulong)capacity >= 0x200000) {
2135 dummy = heads * sectors;
2136 cylinders = capacity;
2137 sector_div(cylinders,dummy);
2143 geom[2] = cylinders;
2145 dprintk((KERN_NOTICE
2146 ": bios_param: Id=%i Lun=%i Channel=%i CHS=%i/%i/%i\n",
2147 sdev->id, sdev->lun,sdev->channel,(int)cylinders,heads,sectors));
2152 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2154 * OS entry point to allow host driver to alloc memory
2155 * for each scsi device. Called once per device the bus scan.
2156 * Return non-zero if allocation fails.
2157 * Init memory once per id (not LUN).
2160 mptscsih_slave_alloc(struct scsi_device *device)
2162 struct Scsi_Host *host = device->host;
2163 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
2165 uint target = device->id;
2170 if ((vdev = hd->Targets[target]) != NULL)
2173 vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL);
2175 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
2176 hd->ioc->name, sizeof(VirtDevice));
2180 memset(vdev, 0, sizeof(VirtDevice));
2181 vdev->tflags = MPT_TARGET_FLAGS_Q_YES;
2182 vdev->ioc_id = hd->ioc->id;
2183 vdev->target_id = device->id;
2184 vdev->bus_id = device->channel;
2185 vdev->raidVolume = 0;
2186 hd->Targets[device->id] = vdev;
2187 if (hd->ioc->bus_type == SCSI) {
2188 if (hd->ioc->raid_data.isRaid & (1 << device->id)) {
2189 vdev->raidVolume = 1;
2190 ddvtprintk((KERN_INFO
2191 "RAID Volume @ id %d\n", device->id));
2194 vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
2199 device->hostdata = vdev;
2204 * OS entry point to allow for host driver to free allocated memory
2205 * Called if no device present or device being unloaded
2208 mptscsih_slave_destroy(struct scsi_device *device)
2210 struct Scsi_Host *host = device->host;
2211 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
2213 uint target = device->id;
2214 uint lun = device->lun;
2219 mptscsih_search_running_cmds(hd, target, lun);
2221 vdev = hd->Targets[target];
2222 vdev->luns[0] &= ~(1 << lun);
2223 if (--vdev->num_luns)
2226 kfree(hd->Targets[target]);
2227 hd->Targets[target] = NULL;
2229 if (hd->ioc->bus_type == SCSI) {
2230 if (mptscsih_is_phys_disk(hd->ioc, target)) {
2231 hd->ioc->spi_data.forceDv |= MPT_SCSICFG_RELOAD_IOC_PG3;
2233 hd->ioc->spi_data.dvStatus[target] =
2234 MPT_SCSICFG_NEGOTIATE;
2236 if (!hd->negoNvram) {
2237 hd->ioc->spi_data.dvStatus[target] |=
2238 MPT_SCSICFG_DV_NOT_DONE;
2244 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2246 * mptscsih_change_queue_depth - This function will set a devices queue depth
2247 * @sdev: per scsi_device pointer
2248 * @qdepth: requested queue depth
2250 * Adding support for new 'change_queue_depth' api.
2253 mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
2255 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sdev->host->hostdata;
2256 VirtDevice *pTarget;
2262 if (!(pTarget = hd->Targets[sdev->id]))
2265 if (hd->ioc->bus_type == SCSI) {
2266 if (pTarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) {
2267 if (!(pTarget->tflags & MPT_TARGET_FLAGS_Q_YES))
2269 else if (((pTarget->inq_data[0] & 0x1f) == 0x00) &&
2270 (pTarget->minSyncFactor <= MPT_ULTRA160 ))
2271 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2273 max_depth = MPT_SCSI_CMD_PER_DEV_LOW;
2275 /* error case - No Inq. Data */
2279 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2281 if (qdepth > max_depth)
2286 tagged = MSG_SIMPLE_TAG;
2288 scsi_adjust_queue_depth(sdev, tagged, qdepth);
2289 return sdev->queue_depth;
2293 * OS entry point to adjust the queue_depths on a per-device basis.
2294 * Called once per device the bus scan. Use it to force the queue_depth
2295 * member to 1 if a device does not support Q tags.
2296 * Return non-zero if fails.
2299 mptscsih_slave_configure(struct scsi_device *device)
2301 struct Scsi_Host *sh = device->host;
2302 VirtDevice *pTarget;
2303 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sh->hostdata;
2305 if ((hd == NULL) || (hd->Targets == NULL)) {
2309 dsprintk((MYIOC_s_INFO_FMT
2310 "device @ %p, id=%d, LUN=%d, channel=%d\n",
2311 hd->ioc->name, device, device->id, device->lun, device->channel));
2312 dsprintk((MYIOC_s_INFO_FMT
2313 "sdtr %d wdtr %d ppr %d inq length=%d\n",
2314 hd->ioc->name, device->sdtr, device->wdtr,
2315 device->ppr, device->inquiry_len));
2317 if (device->id > sh->max_id) {
2318 /* error case, should never happen */
2319 scsi_adjust_queue_depth(device, 0, 1);
2320 goto slave_configure_exit;
2323 pTarget = hd->Targets[device->id];
2325 if (pTarget == NULL) {
2326 /* Driver doesn't know about this device.
2327 * Kernel may generate a "Dummy Lun 0" which
2328 * may become a real Lun if a
2329 * "scsi add-single-device" command is executed
2330 * while the driver is active (hot-plug a
2331 * device). LSI Raid controllers need
2332 * queue_depth set to DEV_HIGH for this reason.
2334 scsi_adjust_queue_depth(device, MSG_SIMPLE_TAG,
2335 MPT_SCSI_CMD_PER_DEV_HIGH);
2336 goto slave_configure_exit;
2339 mptscsih_initTarget(hd, device->channel, device->id, device->lun,
2340 device->inquiry, device->inquiry_len );
2341 mptscsih_change_queue_depth(device, MPT_SCSI_CMD_PER_DEV_HIGH);
2343 dsprintk((MYIOC_s_INFO_FMT
2344 "Queue depth=%d, tflags=%x\n",
2345 hd->ioc->name, device->queue_depth, pTarget->tflags));
2347 dsprintk((MYIOC_s_INFO_FMT
2348 "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
2349 hd->ioc->name, pTarget->negoFlags, pTarget->maxOffset, pTarget->minSyncFactor));
2351 slave_configure_exit:
2353 dsprintk((MYIOC_s_INFO_FMT
2354 "tagged %d, simple %d, ordered %d\n",
2355 hd->ioc->name,device->tagged_supported, device->simple_tags,
2356 device->ordered_tags));
2361 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2363 * Private routines...
2366 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2367 /* Utility function to copy sense data from the scsi_cmnd buffer
2368 * to the FC and SCSI target structures.
2372 mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
2375 SCSIIORequest_t *pReq;
2376 u32 sense_count = le32_to_cpu(pScsiReply->SenseCount);
2379 /* Get target structure
2381 pReq = (SCSIIORequest_t *) mf;
2382 index = (int) pReq->TargetID;
2383 target = hd->Targets[index];
2389 /* Copy the sense received into the scsi command block. */
2390 req_index = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2391 sense_data = ((u8 *)hd->ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC));
2392 memcpy(sc->sense_buffer, sense_data, SNS_LEN(sc));
2394 /* Log SMART data (asc = 0x5D, non-IM case only) if required.
2396 if ((hd->ioc->events) && (hd->ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) {
2397 if ((sense_data[12] == 0x5D) && (target->raidVolume == 0)) {
2399 MPT_ADAPTER *ioc = hd->ioc;
2401 idx = ioc->eventContext % ioc->eventLogSize;
2402 ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
2403 ioc->events[idx].eventContext = ioc->eventContext;
2405 ioc->events[idx].data[0] = (pReq->LUN[1] << 24) ||
2406 (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) ||
2407 (pReq->Bus << 8) || pReq->TargetID;
2409 ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12];
2411 ioc->eventContext++;
2415 dprintk((MYIOC_s_INFO_FMT "Hmmm... SenseData len=0! (?)\n",
2421 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc)
2426 hd = (MPT_SCSI_HOST *) sc->device->host->hostdata;
2428 for (i = 0; i < hd->ioc->req_depth; i++) {
2429 if (hd->ScsiLookup[i] == sc) {
2437 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2439 mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2442 unsigned long flags;
2445 dtmprintk((KERN_WARNING MYNAM
2446 ": IOC %s_reset routed to SCSI host driver!\n",
2447 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
2448 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
2450 /* If a FW reload request arrives after base installed but
2451 * before all scsi hosts have been attached, then an alt_ioc
2452 * may have a NULL sh pointer.
2454 if ((ioc->sh == NULL) || (ioc->sh->hostdata == NULL))
2457 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2459 if (reset_phase == MPT_IOC_SETUP_RESET) {
2460 dtmprintk((MYIOC_s_WARN_FMT "Setup-Diag Reset\n", ioc->name));
2463 * 1. Set Hard Reset Pending Flag
2464 * All new commands go to doneQ
2466 hd->resetPending = 1;
2468 } else if (reset_phase == MPT_IOC_PRE_RESET) {
2469 dtmprintk((MYIOC_s_WARN_FMT "Pre-Diag Reset\n", ioc->name));
2471 /* 2. Flush running commands
2472 * Clean ScsiLookup (and associated memory)
2476 /* 2b. Reply to OS all known outstanding I/O commands.
2478 mptscsih_flush_running_cmds(hd);
2480 /* 2c. If there was an internal command that
2481 * has not completed, configuration or io request,
2482 * free these resources.
2485 del_timer(&hd->timer);
2486 mpt_free_msg_frame(ioc, hd->cmdPtr);
2489 dtmprintk((MYIOC_s_WARN_FMT "Pre-Reset complete.\n", ioc->name));
2492 dtmprintk((MYIOC_s_WARN_FMT "Post-Diag Reset\n", ioc->name));
2494 /* Once a FW reload begins, all new OS commands are
2495 * redirected to the doneQ w/ a reset status.
2496 * Init all control structures.
2499 /* ScsiLookup initialization
2501 for (ii=0; ii < hd->ioc->req_depth; ii++)
2502 hd->ScsiLookup[ii] = NULL;
2504 /* 2. Chain Buffer initialization
2507 /* 4. Renegotiate to all devices, if SCSI
2509 if (ioc->bus_type == SCSI) {
2510 dnegoprintk(("writeSDP1: ALL_IDS USE_NVRAM\n"));
2511 mptscsih_writeSDP1(hd, 0, 0, MPT_SCSICFG_ALL_IDS | MPT_SCSICFG_USE_NVRAM);
2514 /* 5. Enable new commands to be posted
2516 spin_lock_irqsave(&ioc->FreeQlock, flags);
2518 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2519 hd->resetPending = 0;
2520 hd->tmState = TM_STATE_NONE;
2522 /* 6. If there was an internal command,
2523 * wake this process up.
2527 * Wake up the original calling thread
2529 hd->pLocal = &hd->localReply;
2530 hd->pLocal->completion = MPT_SCANDV_DID_RESET;
2531 hd->scandv_wait_done = 1;
2532 wake_up(&hd->scandv_waitq);
2536 /* 7. Set flag to force DV and re-read IOC Page 3
2538 if (ioc->bus_type == SCSI) {
2539 ioc->spi_data.forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
2540 ddvtprintk(("Set reload IOC Pg3 Flag\n"));
2543 dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name));
2547 return 1; /* currently means nothing really */
2550 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2551 /* work queue thread to clear the persitency table */
2553 mptscsih_sas_persist_clear_table(void * arg)
2555 MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg;
2557 mptbase_sas_persist_operation(ioc, MPI_SAS_OP_CLEAR_NOT_PRESENT);
2560 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2562 mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2565 u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
2567 devtprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
2570 if (ioc->sh == NULL ||
2571 ((hd = (MPT_SCSI_HOST *)ioc->sh->hostdata) == NULL))
2575 case MPI_EVENT_UNIT_ATTENTION: /* 03 */
2578 case MPI_EVENT_IOC_BUS_RESET: /* 04 */
2579 case MPI_EVENT_EXT_BUS_RESET: /* 05 */
2580 if (hd && (ioc->bus_type == SCSI) && (hd->soft_resets < -1))
2583 case MPI_EVENT_LOGOUT: /* 09 */
2588 * CHECKME! Don't think we need to do
2589 * anything for these, but...
2591 case MPI_EVENT_RESCAN: /* 06 */
2592 case MPI_EVENT_LINK_STATUS_CHANGE: /* 07 */
2593 case MPI_EVENT_LOOP_STATE_CHANGE: /* 08 */
2595 * CHECKME! Falling thru...
2599 case MPI_EVENT_INTEGRATED_RAID: /* 0B */
2601 pMpiEventDataRaid_t pRaidEventData =
2602 (pMpiEventDataRaid_t) pEvReply->Data;
2603 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
2604 /* Domain Validation Needed */
2605 if (ioc->bus_type == SCSI &&
2606 pRaidEventData->ReasonCode ==
2607 MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED)
2608 mptscsih_set_dvflags_raid(hd, pRaidEventData->PhysDiskNum);
2613 /* Persistent table is full. */
2614 case MPI_EVENT_PERSISTENT_TABLE_FULL:
2615 INIT_WORK(&mptscsih_persistTask,
2616 mptscsih_sas_persist_clear_table,(void *)ioc);
2617 schedule_work(&mptscsih_persistTask);
2620 case MPI_EVENT_NONE: /* 00 */
2621 case MPI_EVENT_LOG_DATA: /* 01 */
2622 case MPI_EVENT_STATE_CHANGE: /* 02 */
2623 case MPI_EVENT_EVENT_CHANGE: /* 0A */
2625 dprintk((KERN_INFO " Ignoring event (=%02Xh)\n", event));
2629 return 1; /* currently means nothing really */
2632 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2634 * mptscsih_initTarget - Target, LUN alloc/free functionality.
2635 * @hd: Pointer to MPT_SCSI_HOST structure
2636 * @bus_id: Bus number (?)
2637 * @target_id: SCSI target id
2639 * @data: Pointer to data
2640 * @dlen: Number of INQUIRY bytes
2642 * NOTE: It's only SAFE to call this routine if data points to
2643 * sane & valid STANDARD INQUIRY data!
2645 * Allocate and initialize memory for this target.
2646 * Save inquiry data.
2650 mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *data, int dlen)
2652 int indexed_lun, lun_index;
2657 dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n",
2658 hd->ioc->name, bus_id, target_id, lun, hd));
2661 * If the peripheral qualifier filter is enabled then if the target reports a 0x1
2662 * (i.e. The targer is capable of supporting the specified peripheral device type
2663 * on this logical unit; however, the physical device is not currently connected
2664 * to this logical unit) it will be converted to a 0x3 (i.e. The target is not
2665 * capable of supporting a physical device on this logical unit). This is to work
2666 * around a bug in th emid-layer in some distributions in which the mid-layer will
2667 * continue to try to communicate to the LUN and evntually create a dummy LUN.
2669 if (hd->mpt_pq_filter && dlen && (data[0] & 0xE0))
2672 /* Is LUN supported? If so, upper 2 bits will be 0
2673 * in first byte of inquiry data.
2678 if ((vdev = hd->Targets[target_id]) == NULL) {
2682 lun_index = (lun >> 5); /* 32 luns per lun_index */
2683 indexed_lun = (lun % 32);
2684 vdev->luns[lun_index] |= (1 << indexed_lun);
2686 if (hd->ioc->bus_type == SCSI) {
2687 if ((data[0] == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) {
2688 /* Treat all Processors as SAF-TE if
2689 * command line option is set */
2690 vdev->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
2691 mptscsih_writeIOCPage4(hd, target_id, bus_id);
2692 }else if ((data[0] == TYPE_PROCESSOR) &&
2693 !(vdev->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) {
2695 vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
2696 if ( data[44] == 'S' &&
2702 vdev->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
2703 mptscsih_writeIOCPage4(hd, target_id, bus_id);
2707 if (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY)) {
2709 memcpy (vdev->inq_data, data, 8);
2711 memcpy (vdev->inq_data, data, dlen);
2714 /* If have not done DV, set the DV flag.
2716 pSpi = &hd->ioc->spi_data;
2717 if ((data[0] == TYPE_TAPE) || (data[0] == TYPE_PROCESSOR)) {
2718 if (pSpi->dvStatus[target_id] & MPT_SCSICFG_DV_NOT_DONE)
2719 pSpi->dvStatus[target_id] |= MPT_SCSICFG_NEED_DV;
2722 vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
2725 data_56 = 0x0F; /* Default to full capabilities if Inq data length is < 57 */
2727 if ( (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_56))) {
2728 /* Update the target capabilities
2731 vdev->tflags |= MPT_TARGET_FLAGS_VALID_56;
2734 mptscsih_setTargetNegoParms(hd, vdev, data_56);
2736 /* Initial Inquiry may not request enough data bytes to
2737 * obtain byte 57. DV will; if target doesn't return
2738 * at least 57 bytes, data[56] will be zero. */
2740 if ( (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_56))) {
2741 /* Update the target capabilities
2744 vdev->tflags |= MPT_TARGET_FLAGS_VALID_56;
2745 mptscsih_setTargetNegoParms(hd, vdev, data_56);
2752 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2754 * Update the target negotiation parameters based on the
2755 * the Inquiry data, adapter capabilities, and NVRAM settings.
2759 mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56)
2761 SpiCfgData *pspi_data = &hd->ioc->spi_data;
2762 int id = (int) target->target_id;
2766 u8 width = MPT_NARROW;
2767 u8 factor = MPT_ASYNC;
2769 u8 version, nfactor;
2772 target->negoFlags = pspi_data->noQas;
2774 /* noQas == 0 => device supports QAS. Need byte 56 of Inq to determine
2775 * support. If available, default QAS to off and allow enabling.
2776 * If not available, default QAS to on, turn off for non-disks.
2779 /* Set flags based on Inquiry data
2781 version = target->inq_data[2] & 0x07;
2784 factor = MPT_ULTRA2;
2785 offset = pspi_data->maxSyncOffset;
2786 target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
2788 if (target->inq_data[7] & 0x20) {
2792 if (target->inq_data[7] & 0x10) {
2793 factor = pspi_data->minSyncFactor;
2794 if (target->tflags & MPT_TARGET_FLAGS_VALID_56) {
2795 /* bits 2 & 3 show Clocking support */
2796 if ((byte56 & 0x0C) == 0)
2797 factor = MPT_ULTRA2;
2799 if ((byte56 & 0x03) == 0)
2800 factor = MPT_ULTRA160;
2802 factor = MPT_ULTRA320;
2805 ddvtprintk((KERN_INFO "Enabling QAS due to byte56=%02x on id=%d!\n", byte56, id));
2808 if (target->inq_data[0] == TYPE_TAPE) {
2810 target->negoFlags |= MPT_TAPE_NEGO_IDP;
2815 ddvtprintk((KERN_INFO "Enabling QAS on id=%d due to ~TARGET_FLAGS_VALID_56!\n", id));
2819 offset = pspi_data->maxSyncOffset;
2821 /* If RAID, never disable QAS
2822 * else if non RAID, do not disable
2823 * QAS if bit 1 is set
2824 * bit 1 QAS support, non-raid only
2827 if (target->raidVolume == 1) {
2836 if ( (target->inq_data[7] & 0x02) == 0) {
2837 target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
2840 /* Update tflags based on NVRAM settings. (SCSI only)
2842 if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
2843 nvram = pspi_data->nvram[id];
2844 nfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
2847 width = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
2850 /* Ensure factor is set to the
2851 * maximum of: adapter, nvram, inquiry
2854 if (nfactor < pspi_data->minSyncFactor )
2855 nfactor = pspi_data->minSyncFactor;
2857 factor = max(factor, nfactor);
2858 if (factor == MPT_ASYNC)
2869 /* Make sure data is consistent
2871 if ((!width) && (factor < MPT_ULTRA2)) {
2872 factor = MPT_ULTRA2;
2875 /* Save the data to the target structure.
2877 target->minSyncFactor = factor;
2878 target->maxOffset = offset;
2879 target->maxWidth = width;
2881 target->tflags |= MPT_TARGET_FLAGS_VALID_NEGO;
2883 /* Disable unused features.
2886 target->negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
2889 target->negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
2891 if ( factor > MPT_ULTRA320 )
2894 /* GEM, processor WORKAROUND
2896 if ((target->inq_data[0] == TYPE_PROCESSOR) || (target->inq_data[0] > 0x08)) {
2897 target->negoFlags |= (MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC);
2898 pspi_data->dvStatus[id] |= MPT_SCSICFG_BLK_NEGO;
2900 if (noQas && (pspi_data->noQas == 0)) {
2901 pspi_data->noQas |= MPT_TARGET_NO_NEGO_QAS;
2902 target->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
2904 /* Disable QAS in a mixed configuration case
2907 ddvtprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id));
2908 for (ii = 0; ii < id; ii++) {
2909 if ( (vdev = hd->Targets[ii]) ) {
2910 vdev->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
2911 mptscsih_writeSDP1(hd, 0, ii, vdev->negoFlags);
2917 /* Write SDP1 on this I/O to this target */
2918 if (pspi_data->dvStatus[id] & MPT_SCSICFG_NEGOTIATE) {
2919 ddvtprintk((KERN_INFO "MPT_SCSICFG_NEGOTIATE on id=%d!\n", id));
2920 mptscsih_writeSDP1(hd, 0, id, hd->negoNvram);
2921 pspi_data->dvStatus[id] &= ~MPT_SCSICFG_NEGOTIATE;
2922 } else if (pspi_data->dvStatus[id] & MPT_SCSICFG_BLK_NEGO) {
2923 ddvtprintk((KERN_INFO "MPT_SCSICFG_BLK_NEGO on id=%d!\n", id));
2924 mptscsih_writeSDP1(hd, 0, id, MPT_SCSICFG_BLK_NEGO);
2925 pspi_data->dvStatus[id] &= ~MPT_SCSICFG_BLK_NEGO;
2929 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2930 /* If DV disabled (negoNvram set to USE_NVARM) or if not LUN 0, return.
2931 * Else set the NEED_DV flag after Read Capacity Issued (disks)
2932 * or Mode Sense (cdroms).
2934 * Tapes, initTarget will set this flag on completion of Inquiry command.
2935 * Called only if DV_NOT_DONE flag is set
2938 mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq)
2940 MPT_ADAPTER *ioc = hd->ioc;
2944 ddvtprintk((MYIOC_s_NOTE_FMT
2945 " set_dvflags: id=%d lun=%d negoNvram=%x cmd=%x\n",
2946 hd->ioc->name, pReq->TargetID, pReq->LUN[1], hd->negoNvram, pReq->CDB[0]));
2948 if ((pReq->LUN[1] != 0) || (hd->negoNvram != 0))
2953 if ((cmd == READ_CAPACITY) || (cmd == MODE_SENSE)) {
2954 pSpi = &ioc->spi_data;
2955 if ((ioc->raid_data.isRaid & (1 << pReq->TargetID)) && ioc->raid_data.pIocPg3) {
2956 /* Set NEED_DV for all hidden disks
2958 Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
2959 int numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
2962 pSpi->dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV;
2963 ddvtprintk(("NEED_DV set for phys disk id %d\n", pPDisk->PhysDiskID));
2968 pSpi->dvStatus[pReq->TargetID] |= MPT_SCSICFG_NEED_DV;
2969 ddvtprintk(("NEED_DV set for visible disk id %d\n", pReq->TargetID));
2973 /* mptscsih_raid_set_dv_flags()
2975 * New or replaced disk. Set DV flag and schedule DV.
2978 mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id)
2980 MPT_ADAPTER *ioc = hd->ioc;
2981 SpiCfgData *pSpi = &ioc->spi_data;
2982 Ioc3PhysDisk_t *pPDisk;
2985 if (hd->negoNvram != 0)
2988 ddvtprintk(("DV requested for phys disk id %d\n", id));
2989 if (ioc->raid_data.pIocPg3) {
2990 pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
2991 numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
2993 if (id == pPDisk->PhysDiskNum) {
2994 pSpi->dvStatus[pPDisk->PhysDiskID] =
2995 (MPT_SCSICFG_NEED_DV | MPT_SCSICFG_DV_NOT_DONE);
2996 pSpi->forceDv = MPT_SCSICFG_NEED_DV;
2997 ddvtprintk(("NEED_DV set for phys disk id %d\n",
2998 pPDisk->PhysDiskID));
3005 if (numPDisk == 0) {
3006 /* The physical disk that needs DV was not found
3007 * in the stored IOC Page 3. The driver must reload
3008 * this page. DV routine will set the NEED_DV flag for
3009 * all phys disks that have DV_NOT_DONE set.
3011 pSpi->forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
3012 ddvtprintk(("phys disk %d not found. Setting reload IOC Pg3 Flag\n",id));
3017 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3019 * If no Target, bus reset on 1st I/O. Set the flag to
3020 * prevent any future negotiations to this device.
3023 mptscsih_no_negotiate(MPT_SCSI_HOST *hd, int target_id)
3026 if ((hd->Targets) && (hd->Targets[target_id] == NULL))
3027 hd->ioc->spi_data.dvStatus[target_id] |= MPT_SCSICFG_BLK_NEGO;
3032 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3034 * SCSI Config Page functionality ...
3036 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3037 /* mptscsih_setDevicePage1Flags - add Requested and Configuration fields flags
3038 * based on width, factor and offset parameters.
3040 * @factor: sync factor
3041 * @offset: sync offset
3042 * @requestedPtr: pointer to requested values (updated)
3043 * @configurationPtr: pointer to configuration values (updated)
3044 * @flags: flags to block WDTR or SDTR negotiation
3048 * Remark: Called by writeSDP1 and _dv_params
3051 mptscsih_setDevicePage1Flags (u8 width, u8 factor, u8 offset, int *requestedPtr, int *configurationPtr, u8 flags)
3053 u8 nowide = flags & MPT_TARGET_NO_NEGO_WIDE;
3054 u8 nosync = flags & MPT_TARGET_NO_NEGO_SYNC;
3056 *configurationPtr = 0;
3057 *requestedPtr = width ? MPI_SCSIDEVPAGE1_RP_WIDE : 0;
3058 *requestedPtr |= (offset << 16) | (factor << 8);
3060 if (width && offset && !nowide && !nosync) {
3061 if (factor < MPT_ULTRA160) {
3062 *requestedPtr |= (MPI_SCSIDEVPAGE1_RP_IU + MPI_SCSIDEVPAGE1_RP_DT);
3063 if ((flags & MPT_TARGET_NO_NEGO_QAS) == 0)
3064 *requestedPtr |= MPI_SCSIDEVPAGE1_RP_QAS;
3065 if (flags & MPT_TAPE_NEGO_IDP)
3066 *requestedPtr |= 0x08000000;
3067 } else if (factor < MPT_ULTRA2) {
3068 *requestedPtr |= MPI_SCSIDEVPAGE1_RP_DT;
3073 *configurationPtr |= MPI_SCSIDEVPAGE1_CONF_WDTR_DISALLOWED;
3076 *configurationPtr |= MPI_SCSIDEVPAGE1_CONF_SDTR_DISALLOWED;
3081 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3082 /* mptscsih_writeSDP1 - write SCSI Device Page 1
3083 * @hd: Pointer to a SCSI Host Strucutre
3084 * @portnum: IOC port number
3085 * @target_id: writeSDP1 for single ID
3086 * @flags: MPT_SCSICFG_ALL_IDS, MPT_SCSICFG_USE_NVRAM, MPT_SCSICFG_BLK_NEGO
3088 * Return: -EFAULT if read of config page header fails
3091 * Remark: If a target has been found, the settings from the
3092 * target structure are used, else the device is set
3095 * Remark: Called during init and after a FW reload.
3096 * Remark: We do not wait for a return, write pages sequentially.
3099 mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
3101 MPT_ADAPTER *ioc = hd->ioc;
3103 SCSIDevicePage1_t *pData;
3104 VirtDevice *pTarget=NULL;
3109 u32 requested, configuration, flagsLength;
3111 int id = 0, maxid = 0;
3117 u8 maxwidth, maxoffset, maxfactor;
3119 if (ioc->spi_data.sdp1length == 0)
3122 if (flags & MPT_SCSICFG_ALL_IDS) {
3124 maxid = ioc->sh->max_id - 1;
3125 } else if (ioc->sh) {
3127 maxid = min_t(int, id, ioc->sh->max_id - 1);
3130 for (; id <= maxid; id++) {
3132 if (id == ioc->pfacts[portnum].PortSCSIID)
3135 /* Use NVRAM to get adapter and target maximums
3136 * Data over-riden by target structure information, if present
3138 maxwidth = ioc->spi_data.maxBusWidth;
3139 maxoffset = ioc->spi_data.maxSyncOffset;
3140 maxfactor = ioc->spi_data.minSyncFactor;
3141 if (ioc->spi_data.nvram && (ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
3142 nvram = ioc->spi_data.nvram[id];
3145 maxwidth = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
3147 if (maxoffset > 0) {
3148 maxfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
3149 if (maxfactor == 0) {
3151 maxfactor = MPT_ASYNC;
3153 } else if (maxfactor < ioc->spi_data.minSyncFactor) {
3154 maxfactor = ioc->spi_data.minSyncFactor;
3157 maxfactor = MPT_ASYNC;
3160 /* Set the negotiation flags.
3162 negoFlags = ioc->spi_data.noQas;
3164 negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
3167 negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
3169 if (flags & MPT_SCSICFG_USE_NVRAM) {
3178 //negoFlags = MPT_TARGET_NO_NEGO_SYNC;
3181 /* If id is not a raid volume, get the updated
3182 * transmission settings from the target structure.
3184 if (hd->Targets && (pTarget = hd->Targets[id]) && !pTarget->raidVolume) {
3185 width = pTarget->maxWidth;
3186 factor = pTarget->minSyncFactor;
3187 offset = pTarget->maxOffset;
3188 negoFlags = pTarget->negoFlags;
3191 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
3192 /* Force to async and narrow if DV has not been executed
3195 if ((hd->ioc->spi_data.dvStatus[id] & MPT_SCSICFG_DV_NOT_DONE) != 0) {
3202 if (flags & MPT_SCSICFG_BLK_NEGO)
3203 negoFlags |= MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC;
3205 mptscsih_setDevicePage1Flags(width, factor, offset,
3206 &requested, &configuration, negoFlags);
3207 dnegoprintk(("writeSDP1: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
3208 target_id, width, factor, offset, negoFlags, requested, configuration));
3210 /* Get a MF for this command.
3212 if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
3213 dfailprintk((MYIOC_s_WARN_FMT "write SDP1: no msg frames!\n",
3218 ddvprintk((MYIOC_s_INFO_FMT "WriteSDP1 (mf=%p, id=%d, req=0x%x, cfg=0x%x)\n",
3219 hd->ioc->name, mf, id, requested, configuration));
3222 /* Set the request and the data pointers.
3223 * Request takes: 36 bytes (32 bit SGE)
3224 * SCSI Device Page 1 requires 16 bytes
3225 * 40 + 16 <= size of SCSI IO Request = 56 bytes
3226 * and MF size >= 64 bytes.
3227 * Place data at end of MF.
3229 pReq = (Config_t *)mf;
3231 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3232 frameOffset = ioc->req_sz - sizeof(SCSIDevicePage1_t);
3234 pData = (SCSIDevicePage1_t *)((u8 *) mf + frameOffset);
3235 dataDma = ioc->req_frames_dma + (req_idx * ioc->req_sz) + frameOffset;
3237 /* Complete the request frame (same for all requests).
3239 pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
3241 pReq->ChainOffset = 0;
3242 pReq->Function = MPI_FUNCTION_CONFIG;
3243 pReq->ExtPageLength = 0;
3244 pReq->ExtPageType = 0;
3246 for (ii=0; ii < 8; ii++) {
3247 pReq->Reserved2[ii] = 0;
3249 pReq->Header.PageVersion = ioc->spi_data.sdp1version;
3250 pReq->Header.PageLength = ioc->spi_data.sdp1length;
3251 pReq->Header.PageNumber = 1;
3252 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
3253 pReq->PageAddress = cpu_to_le32(id | (bus << 8 ));
3255 /* Add a SGE to the config request.
3257 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE | ioc->spi_data.sdp1length * 4;
3259 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma);
3261 /* Set up the common data portion
3263 pData->Header.PageVersion = pReq->Header.PageVersion;
3264 pData->Header.PageLength = pReq->Header.PageLength;
3265 pData->Header.PageNumber = pReq->Header.PageNumber;
3266 pData->Header.PageType = pReq->Header.PageType;
3267 pData->RequestedParameters = cpu_to_le32(requested);
3268 pData->Reserved = 0;
3269 pData->Configuration = cpu_to_le32(configuration);
3271 dprintk((MYIOC_s_INFO_FMT
3272 "write SDP1: id %d pgaddr 0x%x req 0x%x config 0x%x\n",
3273 ioc->name, id, (id | (bus<<8)),
3274 requested, configuration));
3276 mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
3282 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3283 /* mptscsih_writeIOCPage4 - write IOC Page 4
3284 * @hd: Pointer to a SCSI Host Structure
3285 * @target_id: write IOC Page4 for this ID & Bus
3287 * Return: -EAGAIN if unable to obtain a Message Frame
3290 * Remark: We do not wait for a return, write pages sequentially.
3293 mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus)
3295 MPT_ADAPTER *ioc = hd->ioc;
3297 IOCPage4_t *IOCPage4Ptr;
3305 /* Get a MF for this command.
3307 if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
3308 dfailprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n",
3313 /* Set the request and the data pointers.
3314 * Place data at end of MF.
3316 pReq = (Config_t *)mf;
3318 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3319 frameOffset = ioc->req_sz - sizeof(IOCPage4_t);
3321 /* Complete the request frame (same for all requests).
3323 pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
3325 pReq->ChainOffset = 0;
3326 pReq->Function = MPI_FUNCTION_CONFIG;
3327 pReq->ExtPageLength = 0;
3328 pReq->ExtPageType = 0;
3330 for (ii=0; ii < 8; ii++) {
3331 pReq->Reserved2[ii] = 0;
3334 IOCPage4Ptr = ioc->spi_data.pIocPg4;
3335 dataDma = ioc->spi_data.IocPg4_dma;
3336 ii = IOCPage4Ptr->ActiveSEP++;
3337 IOCPage4Ptr->SEP[ii].SEPTargetID = target_id;
3338 IOCPage4Ptr->SEP[ii].SEPBus = bus;
3339 pReq->Header = IOCPage4Ptr->Header;
3340 pReq->PageAddress = cpu_to_le32(target_id | (bus << 8 ));
3342 /* Add a SGE to the config request.
3344 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE |
3345 (IOCPage4Ptr->Header.PageLength + ii) * 4;
3347 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma);
3349 dinitprintk((MYIOC_s_INFO_FMT
3350 "writeIOCPage4: MaxSEP=%d ActiveSEP=%d id=%d bus=%d\n",
3351 ioc->name, IOCPage4Ptr->MaxSEP, IOCPage4Ptr->ActiveSEP, target_id, bus));
3353 mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
3358 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3360 * Bus Scan and Domain Validation functionality ...
3363 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3365 * mptscsih_scandv_complete - Scan and DV callback routine registered
3366 * to Fustion MPT (base) driver.
3368 * @ioc: Pointer to MPT_ADAPTER structure
3369 * @mf: Pointer to original MPT request frame
3370 * @mr: Pointer to MPT reply frame (NULL if TurboReply)
3372 * This routine is called from mpt.c::mpt_interrupt() at the completion
3373 * of any SCSI IO request.
3374 * This routine is registered with the Fusion MPT (base) driver at driver
3375 * load/init time via the mpt_register() API call.
3377 * Returns 1 indicating alloc'd request frame ptr should be freed.
3379 * Remark: Sets a completion code and (possibly) saves sense data
3380 * in the IOC member localReply structure.
3381 * Used ONLY for DV and other internal commands.
3384 mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
3387 SCSIIORequest_t *pReq;
3391 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
3394 (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) {
3395 printk(MYIOC_s_ERR_FMT
3396 "ScanDvComplete, %s req frame ptr! (=%p)\n",
3397 ioc->name, mf?"BAD":"NULL", (void *) mf);
3401 del_timer(&hd->timer);
3402 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3403 hd->ScsiLookup[req_idx] = NULL;
3404 pReq = (SCSIIORequest_t *) mf;
3406 if (mf != hd->cmdPtr) {
3407 printk(MYIOC_s_WARN_FMT "ScanDvComplete (mf=%p, cmdPtr=%p, idx=%d)\n",
3408 hd->ioc->name, (void *)mf, (void *) hd->cmdPtr, req_idx);
3412 ddvprintk((MYIOC_s_INFO_FMT "ScanDvComplete (mf=%p,mr=%p,idx=%d)\n",
3413 hd->ioc->name, mf, mr, req_idx));
3415 hd->pLocal = &hd->localReply;
3416 hd->pLocal->scsiStatus = 0;
3418 /* If target struct exists, clear sense valid flag.
3421 completionCode = MPT_SCANDV_GOOD;
3423 SCSIIOReply_t *pReply;
3427 pReply = (SCSIIOReply_t *) mr;
3429 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
3430 scsi_status = pReply->SCSIStatus;
3432 ddvtprintk((KERN_NOTICE " IOCStatus=%04xh, SCSIState=%02xh, SCSIStatus=%02xh, IOCLogInfo=%08xh\n",
3433 status, pReply->SCSIState, scsi_status,
3434 le32_to_cpu(pReply->IOCLogInfo)));
3438 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
3439 completionCode = MPT_SCANDV_SELECTION_TIMEOUT;
3442 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
3443 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
3444 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
3445 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
3446 completionCode = MPT_SCANDV_DID_RESET;
3449 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
3450 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
3451 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
3452 if (pReply->Function == MPI_FUNCTION_CONFIG) {
3453 ConfigReply_t *pr = (ConfigReply_t *)mr;
3454 completionCode = MPT_SCANDV_GOOD;
3455 hd->pLocal->header.PageVersion = pr->Header.PageVersion;
3456 hd->pLocal->header.PageLength = pr->Header.PageLength;
3457 hd->pLocal->header.PageNumber = pr->Header.PageNumber;
3458 hd->pLocal->header.PageType = pr->Header.PageType;
3460 } else if (pReply->Function == MPI_FUNCTION_RAID_ACTION) {
3461 /* If the RAID Volume request is successful,
3462 * return GOOD, else indicate that
3463 * some type of error occurred.
3465 MpiRaidActionReply_t *pr = (MpiRaidActionReply_t *)mr;
3466 if (le16_to_cpu(pr->ActionStatus) == MPI_RAID_ACTION_ASTATUS_SUCCESS)
3467 completionCode = MPT_SCANDV_GOOD;
3469 completionCode = MPT_SCANDV_SOME_ERROR;
3471 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID) {
3475 /* save sense data in global structure
3477 completionCode = MPT_SCANDV_SENSE;
3478 hd->pLocal->scsiStatus = scsi_status;
3479 sense_data = ((u8 *)hd->ioc->sense_buf_pool +
3480 (req_idx * MPT_SENSE_BUFFER_ALLOC));
3482 sz = min_t(int, pReq->SenseBufferLength,
3483 SCSI_STD_SENSE_BYTES);
3484 memcpy(hd->pLocal->sense, sense_data, sz);
3486 ddvprintk((KERN_NOTICE " Check Condition, sense ptr %p\n",
3488 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_FAILED) {
3489 if (pReq->CDB[0] == INQUIRY)
3490 completionCode = MPT_SCANDV_ISSUE_SENSE;
3492 completionCode = MPT_SCANDV_DID_RESET;
3494 else if (pReply->SCSIState & MPI_SCSI_STATE_NO_SCSI_STATUS)
3495 completionCode = MPT_SCANDV_DID_RESET;
3496 else if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
3497 completionCode = MPT_SCANDV_DID_RESET;
3499 completionCode = MPT_SCANDV_GOOD;
3500 hd->pLocal->scsiStatus = scsi_status;
3504 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
3505 if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
3506 completionCode = MPT_SCANDV_DID_RESET;
3508 completionCode = MPT_SCANDV_SOME_ERROR;
3512 completionCode = MPT_SCANDV_SOME_ERROR;
3515 } /* switch(status) */
3517 ddvtprintk((KERN_NOTICE " completionCode set to %08xh\n",
3519 } /* end of address reply case */
3521 hd->pLocal->completion = completionCode;
3523 /* MF and RF are freed in mpt_interrupt
3526 /* Free Chain buffers (will never chain) in scan or dv */
3527 //mptscsih_freeChainBuffers(ioc, req_idx);
3530 * Wake up the original calling thread
3532 hd->scandv_wait_done = 1;
3533 wake_up(&hd->scandv_waitq);
3538 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3539 /* mptscsih_timer_expired - Call back for timer process.
3540 * Used only for dv functionality.
3541 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
3545 mptscsih_timer_expired(unsigned long data)
3547 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) data;
3549 ddvprintk((MYIOC_s_WARN_FMT "Timer Expired! Cmd %p\n", hd->ioc->name, hd->cmdPtr));
3552 MPIHeader_t *cmd = (MPIHeader_t *)hd->cmdPtr;
3554 if (cmd->Function == MPI_FUNCTION_SCSI_IO_REQUEST) {
3555 /* Desire to issue a task management request here.
3556 * TM requests MUST be single threaded.
3557 * If old eh code and no TM current, issue request.
3558 * If new eh code, do nothing. Wait for OS cmd timeout
3561 ddvtprintk((MYIOC_s_NOTE_FMT "DV Cmd Timeout: NoOp\n", hd->ioc->name));
3563 /* Perform a FW reload */
3564 if (mpt_HardResetHandler(hd->ioc, NO_SLEEP) < 0) {
3565 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", hd->ioc->name);
3569 /* This should NEVER happen */
3570 printk(MYIOC_s_WARN_FMT "Null cmdPtr!!!!\n", hd->ioc->name);
3573 /* No more processing.
3574 * TM call will generate an interrupt for SCSI TM Management.
3575 * The FW will reply to all outstanding commands, callback will finish cleanup.
3576 * Hard reset clean-up will free all resources.
3578 ddvprintk((MYIOC_s_WARN_FMT "Timer Expired Complete!\n", hd->ioc->name));
3583 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
3584 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3585 /* mptscsih_do_raid - Format and Issue a RAID volume request message.
3586 * @hd: Pointer to scsi host structure
3587 * @action: What do be done.
3588 * @id: Logical target id.
3589 * @bus: Target locations bus.
3591 * Returns: < 0 on a fatal error
3594 * Remark: Wait to return until reply processed by the ISR.
3597 mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io)
3599 MpiRaidActionRequest_t *pReq;
3603 in_isr = in_interrupt();
3605 dprintk((MYIOC_s_WARN_FMT "Internal raid request not allowed in ISR context!\n",
3610 /* Get and Populate a free Frame
3612 if ((mf = mpt_get_msg_frame(hd->ioc->InternalCtx, hd->ioc)) == NULL) {
3613 ddvprintk((MYIOC_s_WARN_FMT "_do_raid: no msg frames!\n",
3617 pReq = (MpiRaidActionRequest_t *)mf;
3618 pReq->Action = action;
3619 pReq->Reserved1 = 0;
3620 pReq->ChainOffset = 0;
3621 pReq->Function = MPI_FUNCTION_RAID_ACTION;
3622 pReq->VolumeID = io->id;
3623 pReq->VolumeBus = io->bus;
3624 pReq->PhysDiskNum = io->physDiskNum;
3626 pReq->Reserved2 = 0;
3627 pReq->ActionDataWord = 0; /* Reserved for this action */
3628 //pReq->ActionDataSGE = 0;
3630 mpt_add_sge((char *)&pReq->ActionDataSGE,
3631 MPT_SGE_FLAGS_SSIMPLE_READ | 0, (dma_addr_t) -1);
3633 ddvprintk((MYIOC_s_INFO_FMT "RAID Volume action %x id %d\n",
3634 hd->ioc->name, action, io->id));
3637 hd->timer.expires = jiffies + HZ*10; /* 10 second timeout */
3638 hd->scandv_wait_done = 0;
3640 /* Save cmd pointer, for resource free if timeout or
3645 add_timer(&hd->timer);
3646 mpt_put_msg_frame(hd->ioc->InternalCtx, hd->ioc, mf);
3647 wait_event(hd->scandv_waitq, hd->scandv_wait_done);
3649 if ((hd->pLocal == NULL) || (hd->pLocal->completion != MPT_SCANDV_GOOD))
3654 #endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */
3656 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3658 * mptscsih_do_cmd - Do internal command.
3659 * @hd: MPT_SCSI_HOST pointer
3660 * @io: INTERNAL_CMD pointer.
3662 * Issue the specified internally generated command and do command
3663 * specific cleanup. For bus scan / DV only.
3664 * NOTES: If command is Inquiry and status is good,
3665 * initialize a target structure, save the data
3667 * Remark: Single threaded access only.
3670 * < 0 if an illegal command or no resources
3674 * > 0 if command complete but some type of completion error.
3677 mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
3680 SCSIIORequest_t *pScsiReq;
3681 SCSIIORequest_t ReqCopy;
3682 int my_idx, ii, dir;
3686 char CDB[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
3689 in_isr = in_interrupt();
3691 dprintk((MYIOC_s_WARN_FMT "Internal SCSI IO request not allowed in ISR context!\n",
3697 /* Set command specific information
3702 dir = MPI_SCSIIO_CONTROL_READ;
3708 case TEST_UNIT_READY:
3710 dir = MPI_SCSIIO_CONTROL_READ;
3716 dir = MPI_SCSIIO_CONTROL_READ;
3718 CDB[4] = 1; /*Spin up the disk */
3726 dir = MPI_SCSIIO_CONTROL_READ;
3732 dir = MPI_SCSIIO_CONTROL_READ;
3734 if (io->flags & MPT_ICFLAG_ECHO) {
3740 if (io->flags & MPT_ICFLAG_BUF_CAP) {
3743 CDB[6] = (io->size >> 16) & 0xFF;
3744 CDB[7] = (io->size >> 8) & 0xFF;
3745 CDB[8] = io->size & 0xFF;
3751 dir = MPI_SCSIIO_CONTROL_WRITE;
3753 if (io->flags & MPT_ICFLAG_ECHO) {
3758 CDB[6] = (io->size >> 16) & 0xFF;
3759 CDB[7] = (io->size >> 8) & 0xFF;
3760 CDB[8] = io->size & 0xFF;
3766 dir = MPI_SCSIIO_CONTROL_READ;
3773 dir = MPI_SCSIIO_CONTROL_READ;
3778 case SYNCHRONIZE_CACHE:
3780 dir = MPI_SCSIIO_CONTROL_READ;
3782 // CDB[1] = 0x02; /* set immediate bit */
3791 /* Get and Populate a free Frame
3793 if ((mf = mpt_get_msg_frame(hd->ioc->InternalCtx, hd->ioc)) == NULL) {
3794 ddvprintk((MYIOC_s_WARN_FMT "No msg frames!\n",
3799 pScsiReq = (SCSIIORequest_t *) mf;
3801 /* Get the request index */
3802 my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3803 ADD_INDEX_LOG(my_idx); /* for debug */
3805 if (io->flags & MPT_ICFLAG_PHYS_DISK) {
3806 pScsiReq->TargetID = io->physDiskNum;
3808 pScsiReq->ChainOffset = 0;
3809 pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
3811 pScsiReq->TargetID = io->id;
3812 pScsiReq->Bus = io->bus;
3813 pScsiReq->ChainOffset = 0;
3814 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
3817 pScsiReq->CDBLength = cmdLen;
3818 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
3820 pScsiReq->Reserved = 0;
3822 pScsiReq->MsgFlags = mpt_msg_flags();
3823 /* MsgContext set in mpt_get_msg_fram call */
3825 for (ii=0; ii < 8; ii++)
3826 pScsiReq->LUN[ii] = 0;
3827 pScsiReq->LUN[1] = io->lun;
3829 if (io->flags & MPT_ICFLAG_TAGGED_CMD)
3830 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ);
3832 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3834 if (cmd == REQUEST_SENSE) {
3835 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3836 ddvprintk((MYIOC_s_INFO_FMT "Untagged! 0x%2x\n",
3837 hd->ioc->name, cmd));
3840 for (ii=0; ii < 16; ii++)
3841 pScsiReq->CDB[ii] = CDB[ii];
3843 pScsiReq->DataLength = cpu_to_le32(io->size);
3844 pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
3845 + (my_idx * MPT_SENSE_BUFFER_ALLOC));
3847 ddvprintk((MYIOC_s_INFO_FMT "Sending Command 0x%x for (%d:%d:%d)\n",
3848 hd->ioc->name, cmd, io->bus, io->id, io->lun));
3850 if (dir == MPI_SCSIIO_CONTROL_READ) {
3851 mpt_add_sge((char *) &pScsiReq->SGL,
3852 MPT_SGE_FLAGS_SSIMPLE_READ | io->size,
3855 mpt_add_sge((char *) &pScsiReq->SGL,
3856 MPT_SGE_FLAGS_SSIMPLE_WRITE | io->size,
3860 /* The ISR will free the request frame, but we need
3861 * the information to initialize the target. Duplicate.
3863 memcpy(&ReqCopy, pScsiReq, sizeof(SCSIIORequest_t));
3865 /* Issue this command after:
3868 * Wait until the reply has been received
3869 * ScsiScanDvCtx callback function will
3871 * set scandv_wait_done and call wake_up
3874 hd->timer.expires = jiffies + HZ*cmdTimeout;
3875 hd->scandv_wait_done = 0;
3877 /* Save cmd pointer, for resource free if timeout or
3882 add_timer(&hd->timer);
3883 mpt_put_msg_frame(hd->ioc->InternalCtx, hd->ioc, mf);
3884 wait_event(hd->scandv_waitq, hd->scandv_wait_done);
3887 rc = hd->pLocal->completion;
3888 hd->pLocal->skip = 0;
3890 /* Always set fatal error codes in some cases.
3892 if (rc == MPT_SCANDV_SELECTION_TIMEOUT)
3894 else if (rc == MPT_SCANDV_SOME_ERROR)
3898 /* This should never happen. */
3899 ddvprintk((MYIOC_s_INFO_FMT "_do_cmd: Null pLocal!!!\n",
3906 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3908 * mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
3909 * @hd: Pointer to MPT_SCSI_HOST structure
3910 * @portnum: IOC port number
3912 * Uses the ISR, but with special processing.
3913 * MUST be single-threaded.
3915 * Return: 0 on completion
3918 mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum)
3920 MPT_ADAPTER *ioc= hd->ioc;
3921 VirtDevice *pTarget;
3922 SCSIDevicePage1_t *pcfg1Data = NULL;
3925 dma_addr_t cfg1_dma_addr = -1;
3926 ConfigPageHeader_t header1;
3930 int indexed_lun, lun_index;
3931 int hostId = ioc->pfacts[portnum].PortSCSIID;
3933 int requested, configuration, data;
3937 max_id = ioc->sh->max_id - 1;
3939 /* Following parameters will not change
3942 iocmd.cmd = SYNCHRONIZE_CACHE;
3944 iocmd.physDiskNum = -1;
3946 iocmd.data_dma = -1;
3948 iocmd.rsvd = iocmd.rsvd2 = 0;
3952 if (hd->Targets == NULL)
3960 /* Write SDP1 for all SCSI devices
3961 * Alloc memory and set up config buffer
3963 if (ioc->bus_type == SCSI) {
3964 if (ioc->spi_data.sdp1length > 0) {
3965 pcfg1Data = (SCSIDevicePage1_t *)pci_alloc_consistent(ioc->pcidev,
3966 ioc->spi_data.sdp1length * 4, &cfg1_dma_addr);
3968 if (pcfg1Data != NULL) {
3970 header1.PageVersion = ioc->spi_data.sdp1version;
3971 header1.PageLength = ioc->spi_data.sdp1length;
3972 header1.PageNumber = 1;
3973 header1.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
3974 cfg.cfghdr.hdr = &header1;
3975 cfg.physAddr = cfg1_dma_addr;
3976 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
3983 /* loop through all devices on this port
3985 while (bus < MPT_MAX_BUS) {
3988 pTarget = hd->Targets[(int)id];
3992 /* Set the negotiation flags */
3993 if (pTarget && (pTarget = hd->Targets[id]) && !pTarget->raidVolume) {
3994 flags = pTarget->negoFlags;
3996 flags = hd->ioc->spi_data.noQas;
3997 if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
3998 data = hd->ioc->spi_data.nvram[id];
4000 if (data & MPT_NVRAM_WIDE_DISABLE)
4001 flags |= MPT_TARGET_NO_NEGO_WIDE;
4003 factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT;
4004 if ((factor == 0) || (factor == MPT_ASYNC))
4005 flags |= MPT_TARGET_NO_NEGO_SYNC;
4009 /* Force to async, narrow */
4010 mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested,
4011 &configuration, flags);
4012 dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC "
4013 "offset=0 negoFlags=%x request=%x config=%x\n",
4014 id, flags, requested, configuration));
4015 pcfg1Data->RequestedParameters = cpu_to_le32(requested);
4016 pcfg1Data->Reserved = 0;
4017 pcfg1Data->Configuration = cpu_to_le32(configuration);
4018 cfg.pageAddr = (bus<<8) | id;
4019 mpt_config(hd->ioc, &cfg);
4022 /* If target Ptr NULL or if this target is NOT a disk, skip.
4024 if ((pTarget) && (pTarget->inq_data[0] == TYPE_DISK)){
4025 for (lun=0; lun <= MPT_LAST_LUN; lun++) {
4026 /* If LUN present, issue the command
4028 lun_index = (lun >> 5); /* 32 luns per lun_index */
4029 indexed_lun = (lun % 32);
4030 if (pTarget->luns[lun_index] & (1<<indexed_lun)) {
4032 (void) mptscsih_do_cmd(hd, &iocmd);
4037 /* get next relevant device */
4050 pci_free_consistent(ioc->pcidev, header1.PageLength * 4, pcfg1Data, cfg1_dma_addr);
4056 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
4057 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4059 * mptscsih_domainValidation - Top level handler for domain validation.
4060 * @hd: Pointer to MPT_SCSI_HOST structure.
4062 * Uses the ISR, but with special processing.
4063 * Called from schedule, should not be in interrupt mode.
4064 * While thread alive, do dv for all devices needing dv
4069 mptscsih_domainValidation(void *arg)
4073 unsigned long flags;
4074 int id, maxid, dvStatus, did;
4077 spin_lock_irqsave(&dvtaskQ_lock, flags);
4079 if (dvtaskQ_release) {
4081 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4084 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4086 /* For this ioc, loop through all devices and do dv to each device.
4087 * When complete with this ioc, search through the ioc list, and
4088 * for each scsi ioc found, do dv for all devices. Exit when no
4094 list_for_each_entry(ioc, &ioc_list, list) {
4095 spin_lock_irqsave(&dvtaskQ_lock, flags);
4096 if (dvtaskQ_release) {
4098 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4101 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4105 /* DV only to SCSI adapters */
4106 if (ioc->bus_type != SCSI)
4109 /* Make sure everything looks ok */
4110 if (ioc->sh == NULL)
4113 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
4117 if ((ioc->spi_data.forceDv & MPT_SCSICFG_RELOAD_IOC_PG3) != 0) {
4118 mpt_read_ioc_pg_3(ioc);
4119 if (ioc->raid_data.pIocPg3) {
4120 Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
4121 int numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
4124 if (ioc->spi_data.dvStatus[pPDisk->PhysDiskID] & MPT_SCSICFG_DV_NOT_DONE)
4125 ioc->spi_data.dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV;
4131 ioc->spi_data.forceDv &= ~MPT_SCSICFG_RELOAD_IOC_PG3;
4134 maxid = min_t(int, ioc->sh->max_id, MPT_MAX_SCSI_DEVICES);
4136 for (id = 0; id < maxid; id++) {
4137 spin_lock_irqsave(&dvtaskQ_lock, flags);
4138 if (dvtaskQ_release) {
4140 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4143 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4144 dvStatus = hd->ioc->spi_data.dvStatus[id];
4146 if (dvStatus & MPT_SCSICFG_NEED_DV) {
4148 hd->ioc->spi_data.dvStatus[id] |= MPT_SCSICFG_DV_PENDING;
4149 hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_NEED_DV;
4153 /* If hidden phys disk, block IO's to all
4155 * else, process normally
4157 isPhysDisk = mptscsih_is_phys_disk(ioc, id);
4159 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4160 if (hd->ioc->raid_data.isRaid & (1 << ii)) {
4161 hd->ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_DV_PENDING;
4166 if (mptscsih_doDv(hd, 0, id) == 1) {
4167 /* Untagged device was busy, try again
4169 hd->ioc->spi_data.dvStatus[id] |= MPT_SCSICFG_NEED_DV;
4170 hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_PENDING;
4172 /* DV is complete. Clear flags.
4174 hd->ioc->spi_data.dvStatus[id] &= ~(MPT_SCSICFG_DV_NOT_DONE | MPT_SCSICFG_DV_PENDING);
4178 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4179 if (hd->ioc->raid_data.isRaid & (1 << ii)) {
4180 hd->ioc->spi_data.dvStatus[ii] &= ~MPT_SCSICFG_DV_PENDING;
4185 if (hd->ioc->spi_data.noQas)
4186 mptscsih_qas_check(hd, id);
4192 spin_lock_irqsave(&dvtaskQ_lock, flags);
4194 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4199 /* Search IOC page 3 to determine if this is hidden physical disk
4201 /* Search IOC page 3 to determine if this is hidden physical disk
4204 mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id)
4208 if (!ioc->raid_data.isRaid || !ioc->raid_data.pIocPg3)
4211 for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
4212 if (id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID)
4219 /* Write SDP1 if no QAS has been enabled
4222 mptscsih_qas_check(MPT_SCSI_HOST *hd, int id)
4224 VirtDevice *pTarget;
4227 if (hd->Targets == NULL)
4230 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4234 if ((hd->ioc->spi_data.dvStatus[ii] & MPT_SCSICFG_DV_NOT_DONE) != 0)
4237 pTarget = hd->Targets[ii];
4239 if ((pTarget != NULL) && (!pTarget->raidVolume)) {
4240 if ((pTarget->negoFlags & hd->ioc->spi_data.noQas) == 0) {
4241 pTarget->negoFlags |= hd->ioc->spi_data.noQas;
4242 dnegoprintk(("writeSDP1: id=%d flags=0\n", id));
4243 mptscsih_writeSDP1(hd, 0, ii, 0);
4246 if (mptscsih_is_phys_disk(hd->ioc, ii) == 1) {
4247 dnegoprintk(("writeSDP1: id=%d SCSICFG_USE_NVRAM\n", id));
4248 mptscsih_writeSDP1(hd, 0, ii, MPT_SCSICFG_USE_NVRAM);
4257 #define MPT_GET_NVRAM_VALS 0x01
4258 #define MPT_UPDATE_MAX 0x02
4259 #define MPT_SET_MAX 0x04
4260 #define MPT_SET_MIN 0x08
4261 #define MPT_FALLBACK 0x10
4262 #define MPT_SAVE 0x20
4264 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4266 * mptscsih_doDv - Perform domain validation to a target.
4267 * @hd: Pointer to MPT_SCSI_HOST structure.
4268 * @portnum: IOC port number.
4269 * @target: Physical ID of this target
4271 * Uses the ISR, but with special processing.
4272 * MUST be single-threaded.
4273 * Test will exit if target is at async & narrow.
4278 mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
4280 MPT_ADAPTER *ioc = hd->ioc;
4281 VirtDevice *pTarget;
4282 SCSIDevicePage1_t *pcfg1Data;
4283 SCSIDevicePage0_t *pcfg0Data;
4287 dma_addr_t dvbuf_dma = -1;
4288 dma_addr_t buf1_dma = -1;
4289 dma_addr_t buf2_dma = -1;
4290 dma_addr_t cfg1_dma_addr = -1;
4291 dma_addr_t cfg0_dma_addr = -1;
4292 ConfigPageHeader_t header1;
4293 ConfigPageHeader_t header0;
4300 int dataBufSize = 0;
4301 int echoBufSize = 0;
4306 int nfactor = MPT_ULTRA320;
4308 char doFallback = 0;
4313 if (ioc->spi_data.sdp1length == 0)
4316 if (ioc->spi_data.sdp0length == 0)
4319 /* If multiple buses are used, require that the initiator
4320 * id be the same on all buses.
4322 if (id == ioc->pfacts[0].PortSCSIID)
4326 bus = (u8) bus_number;
4327 ddvtprintk((MYIOC_s_NOTE_FMT
4328 "DV started: bus=%d, id=%d dv @ %p\n",
4329 ioc->name, bus, id, &dv));
4331 /* Prep DV structure
4333 memset (&dv, 0, sizeof(DVPARAMETERS));
4336 /* Populate tmax with the current maximum
4337 * transfer parameters for this target.
4338 * Exit if narrow and async.
4340 dv.cmd = MPT_GET_NVRAM_VALS;
4341 mptscsih_dv_parms(hd, &dv, NULL);
4343 /* Prep SCSI IO structure
4349 iocmd.physDiskNum = -1;
4350 iocmd.rsvd = iocmd.rsvd2 = 0;
4352 pTarget = hd->Targets[id];
4354 /* Use tagged commands if possible.
4357 if (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)
4358 iocmd.flags |= MPT_ICFLAG_TAGGED_CMD;
4360 if (hd->ioc->facts.FWVersion.Word < 0x01000600)
4363 if ((hd->ioc->facts.FWVersion.Word >= 0x01010000) &&
4364 (hd->ioc->facts.FWVersion.Word < 0x01010B00))
4369 /* Prep cfg structure
4371 cfg.pageAddr = (bus<<8) | id;
4372 cfg.cfghdr.hdr = NULL;
4376 header0.PageVersion = ioc->spi_data.sdp0version;
4377 header0.PageLength = ioc->spi_data.sdp0length;
4378 header0.PageNumber = 0;
4379 header0.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4383 header1.PageVersion = ioc->spi_data.sdp1version;
4384 header1.PageLength = ioc->spi_data.sdp1length;
4385 header1.PageNumber = 1;
4386 header1.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4388 if (header0.PageLength & 1)
4389 dv_alloc = (header0.PageLength * 4) + 4;
4391 dv_alloc += (2048 + (header1.PageLength * 4));
4393 pDvBuf = pci_alloc_consistent(ioc->pcidev, dv_alloc, &dvbuf_dma);
4398 pbuf1 = (u8 *)pDvBuf;
4399 buf1_dma = dvbuf_dma;
4402 pbuf2 = (u8 *) (pDvBuf + sz);
4403 buf2_dma = dvbuf_dma + sz;
4406 pcfg0Data = (SCSIDevicePage0_t *) (pDvBuf + sz);
4407 cfg0_dma_addr = dvbuf_dma + sz;
4408 sz += header0.PageLength * 4;
4412 if (header0.PageLength & 1)
4415 pcfg1Data = (SCSIDevicePage1_t *) (pDvBuf + sz);
4416 cfg1_dma_addr = dvbuf_dma + sz;
4418 /* Skip this ID? Set cfg.cfghdr.hdr to force config page write
4421 SpiCfgData *pspi_data = &hd->ioc->spi_data;
4422 if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
4423 /* Set the factor from nvram */
4424 nfactor = (pspi_data->nvram[id] & MPT_NVRAM_SYNC_MASK) >> 8;
4425 if (nfactor < pspi_data->minSyncFactor )
4426 nfactor = pspi_data->minSyncFactor;
4428 if (!(pspi_data->nvram[id] & MPT_NVRAM_ID_SCAN_ENABLE) ||
4429 (pspi_data->PortFlags == MPI_SCSIPORTPAGE2_PORT_FLAGS_OFF_DV) ) {
4431 ddvprintk((MYIOC_s_NOTE_FMT "DV Skipped: bus, id, lun (%d, %d, %d)\n",
4432 ioc->name, bus, id, lun));
4434 dv.cmd = MPT_SET_MAX;
4435 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
4436 cfg.cfghdr.hdr = &header1;
4438 /* Save the final negotiated settings to
4439 * SCSI device page 1.
4441 cfg.physAddr = cfg1_dma_addr;
4442 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4444 mpt_config(hd->ioc, &cfg);
4450 /* Finish iocmd inititialization - hidden or visible disk? */
4451 if (ioc->raid_data.pIocPg3) {
4452 /* Search IOC page 3 for matching id
4454 Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
4455 int numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
4458 if (pPDisk->PhysDiskID == id) {
4460 iocmd.flags |= MPT_ICFLAG_PHYS_DISK;
4461 iocmd.physDiskNum = pPDisk->PhysDiskNum;
4465 if (mptscsih_do_raid(hd, MPI_RAID_ACTION_QUIESCE_PHYS_IO, &iocmd) < 0) {
4466 ddvprintk((MYIOC_s_ERR_FMT "RAID Queisce FAILED!\n", ioc->name));
4476 /* RAID Volume ID's may double for a physical device. If RAID but
4477 * not a physical ID as well, skip DV.
4479 if ((hd->ioc->raid_data.isRaid & (1 << id)) && !(iocmd.flags & MPT_ICFLAG_PHYS_DISK))
4484 * Async & Narrow - Inquiry
4485 * Async & Narrow - Inquiry
4486 * Maximum transfer rate - Inquiry
4488 * If compare, test complete.
4489 * If miscompare and first pass, repeat
4490 * If miscompare and not first pass, fall back and repeat
4494 sz = SCSI_MAX_INQUIRY_BYTES;
4495 rc = MPT_SCANDV_GOOD;
4497 ddvprintk((MYIOC_s_NOTE_FMT "DV: Start Basic test on id=%d\n", ioc->name, id));
4499 dv.cmd = MPT_SET_MIN;
4500 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
4502 cfg.cfghdr.hdr = &header1;
4503 cfg.physAddr = cfg1_dma_addr;
4504 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4506 if (mpt_config(hd->ioc, &cfg) != 0)
4509 /* Wide - narrow - wide workaround case
4511 if ((rc == MPT_SCANDV_ISSUE_SENSE) && dv.max.width) {
4512 /* Send an untagged command to reset disk Qs corrupted
4513 * when a parity error occurs on a Request Sense.
4515 if ((hd->ioc->facts.FWVersion.Word >= 0x01000600) ||
4516 ((hd->ioc->facts.FWVersion.Word >= 0x01010000) &&
4517 (hd->ioc->facts.FWVersion.Word < 0x01010B00)) ) {
4519 iocmd.cmd = REQUEST_SENSE;
4520 iocmd.data_dma = buf1_dma;
4523 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4526 if (hd->pLocal == NULL)
4528 rc = hd->pLocal->completion;
4529 if ((rc == MPT_SCANDV_GOOD) || (rc == MPT_SCANDV_SENSE)) {
4539 iocmd.cmd = INQUIRY;
4540 iocmd.data_dma = buf1_dma;
4543 memset(pbuf1, 0x00, sz);
4544 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4547 if (hd->pLocal == NULL)
4549 rc = hd->pLocal->completion;
4550 if (rc == MPT_SCANDV_GOOD) {
4551 if (hd->pLocal->scsiStatus == SAM_STAT_BUSY) {
4552 if ((iocmd.flags & MPT_ICFLAG_TAGGED_CMD) == 0)
4559 } else if (rc == MPT_SCANDV_SENSE) {
4562 /* If first command doesn't complete
4563 * with a good status or with a check condition,
4570 /* Reset the size for disks
4572 inq0 = (*pbuf1) & 0x1F;
4573 if ((inq0 == 0) && pTarget && !pTarget->raidVolume) {
4578 /* Another GEM workaround. Check peripheral device type,
4579 * if PROCESSOR, quit DV.
4581 if (inq0 == TYPE_PROCESSOR) {
4582 mptscsih_initTarget(hd,
4594 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4598 if ((pTarget->maxWidth == 1) && (pTarget->maxOffset) && (nfactor < 0x0A)
4599 && (pTarget->minSyncFactor > 0x09)) {
4600 if ((pbuf1[56] & 0x04) == 0)
4602 else if ((pbuf1[56] & 0x01) == 1) {
4603 pTarget->minSyncFactor =
4604 nfactor > MPT_ULTRA320 ? nfactor : MPT_ULTRA320;
4606 pTarget->minSyncFactor =
4607 nfactor > MPT_ULTRA160 ? nfactor : MPT_ULTRA160;
4610 dv.max.factor = pTarget->minSyncFactor;
4612 if ((pbuf1[56] & 0x02) == 0) {
4613 pTarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
4614 hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS;
4615 ddvprintk((MYIOC_s_NOTE_FMT
4616 "DV: Start Basic noQas on id=%d due to pbuf1[56]=%x\n",
4617 ioc->name, id, pbuf1[56]));
4623 dv.cmd = MPT_FALLBACK;
4625 dv.cmd = MPT_SET_MAX;
4627 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
4628 if (mpt_config(hd->ioc, &cfg) != 0)
4631 if ((!dv.now.width) && (!dv.now.offset))
4634 iocmd.cmd = INQUIRY;
4635 iocmd.data_dma = buf2_dma;
4638 memset(pbuf2, 0x00, sz);
4639 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4641 else if (hd->pLocal == NULL)
4644 /* Save the return code.
4645 * If this is the first pass,
4646 * read SCSI Device Page 0
4647 * and update the target max parameters.
4649 rc = hd->pLocal->completion;
4651 if (rc == MPT_SCANDV_GOOD) {
4656 cfg.cfghdr.hdr = &header0;
4657 cfg.physAddr = cfg0_dma_addr;
4658 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4661 if (mpt_config(hd->ioc, &cfg) != 0)
4664 sdp0_info = le32_to_cpu(pcfg0Data->Information) & 0x0E;
4665 sdp0_nego = (le32_to_cpu(pcfg0Data->NegotiatedParameters) & 0xFF00 ) >> 8;
4667 /* Quantum and Fujitsu workarounds.
4668 * Quantum: PPR U320 -> PPR reply with Ultra2 and wide
4669 * Fujitsu: PPR U320 -> Msg Reject and Ultra2 and wide
4670 * Resetart with a request for U160.
4672 if ((dv.now.factor == MPT_ULTRA320) && (sdp0_nego == MPT_ULTRA2)) {
4675 dv.cmd = MPT_UPDATE_MAX;
4676 mptscsih_dv_parms(hd, &dv, (void *)pcfg0Data);
4677 /* Update the SCSI device page 1 area
4679 pcfg1Data->RequestedParameters = pcfg0Data->NegotiatedParameters;
4684 /* Quantum workaround. Restart this test will the fallback
4687 if (doFallback == 0) {
4688 if (memcmp(pbuf1, pbuf2, sz) != 0) {
4692 ddvprintk((MYIOC_s_NOTE_FMT
4693 "DV:Inquiry compared id=%d, calling initTarget\n", ioc->name, id));
4694 hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_NOT_DONE;
4695 mptscsih_initTarget(hd,
4701 break; /* test complete */
4706 } else if (rc == MPT_SCANDV_ISSUE_SENSE)
4707 doFallback = 1; /* set fallback flag */
4708 else if ((rc == MPT_SCANDV_DID_RESET) ||
4709 (rc == MPT_SCANDV_SENSE) ||
4710 (rc == MPT_SCANDV_FALLBACK))
4711 doFallback = 1; /* set fallback flag */
4718 ddvprintk((MYIOC_s_NOTE_FMT "DV: Basic test on id=%d completed OK.\n", ioc->name, id));
4720 if (ioc->spi_data.mpt_dv == 0)
4723 inq0 = (*pbuf1) & 0x1F;
4725 /* Continue only for disks
4730 if ( ioc->spi_data.PortFlags == MPI_SCSIPORTPAGE2_PORT_FLAGS_BASIC_DV_ONLY )
4733 /* Start the Enhanced Test.
4734 * 0) issue TUR to clear out check conditions
4735 * 1) read capacity of echo (regular) buffer
4737 * 3) do write-read-compare data pattern test
4739 * 5) update nego parms to target struct
4741 cfg.cfghdr.hdr = &header1;
4742 cfg.physAddr = cfg1_dma_addr;
4743 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4746 iocmd.cmd = TEST_UNIT_READY;
4747 iocmd.data_dma = -1;
4752 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4755 if (hd->pLocal == NULL)
4758 rc = hd->pLocal->completion;
4759 if (rc == MPT_SCANDV_GOOD)
4761 else if (rc == MPT_SCANDV_SENSE) {
4762 u8 skey = hd->pLocal->sense[2] & 0x0F;
4763 u8 asc = hd->pLocal->sense[12];
4764 u8 ascq = hd->pLocal->sense[13];
4765 ddvprintk((MYIOC_s_INFO_FMT
4766 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
4767 ioc->name, skey, asc, ascq));
4769 if (skey == UNIT_ATTENTION)
4770 notDone++; /* repeat */
4771 else if ((skey == NOT_READY) &&
4772 (asc == 0x04)&&(ascq == 0x01)) {
4773 /* wait then repeat */
4776 } else if ((skey == NOT_READY) && (asc == 0x3A)) {
4777 /* no medium, try read test anyway */
4780 /* All other errors are fatal.
4782 ddvprintk((MYIOC_s_INFO_FMT "DV: fatal error.",
4790 iocmd.cmd = READ_BUFFER;
4791 iocmd.data_dma = buf1_dma;
4794 iocmd.flags |= MPT_ICFLAG_BUF_CAP;
4798 for (patt = 0; patt < 2; patt++) {
4800 iocmd.flags |= MPT_ICFLAG_ECHO;
4802 iocmd.flags &= ~MPT_ICFLAG_ECHO;
4808 /* If not ready after 8 trials,
4809 * give up on this device.
4814 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4816 else if (hd->pLocal == NULL)
4819 rc = hd->pLocal->completion;
4820 ddvprintk(("ReadBuffer Comp Code %d", rc));
4821 ddvprintk((" buff: %0x %0x %0x %0x\n",
4822 pbuf1[0], pbuf1[1], pbuf1[2], pbuf1[3]));
4824 if (rc == MPT_SCANDV_GOOD) {
4826 if (iocmd.flags & MPT_ICFLAG_ECHO) {
4827 bufsize = ((pbuf1[2] & 0x1F) <<8) | pbuf1[3];
4828 if (pbuf1[0] & 0x01)
4829 iocmd.flags |= MPT_ICFLAG_EBOS;
4831 bufsize = pbuf1[1]<<16 | pbuf1[2]<<8 | pbuf1[3];
4833 } else if (rc == MPT_SCANDV_SENSE) {
4834 u8 skey = hd->pLocal->sense[2] & 0x0F;
4835 u8 asc = hd->pLocal->sense[12];
4836 u8 ascq = hd->pLocal->sense[13];
4837 ddvprintk((MYIOC_s_INFO_FMT
4838 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
4839 ioc->name, skey, asc, ascq));
4840 if (skey == ILLEGAL_REQUEST) {
4842 } else if (skey == UNIT_ATTENTION) {
4843 notDone++; /* repeat */
4844 } else if ((skey == NOT_READY) &&
4845 (asc == 0x04)&&(ascq == 0x01)) {
4846 /* wait then repeat */
4850 /* All other errors are fatal.
4852 ddvprintk((MYIOC_s_INFO_FMT "DV: fatal error.",
4857 /* All other errors are fatal
4864 if (iocmd.flags & MPT_ICFLAG_ECHO)
4865 echoBufSize = bufsize;
4867 dataBufSize = bufsize;
4870 iocmd.flags &= ~MPT_ICFLAG_BUF_CAP;
4872 /* Use echo buffers if possible,
4873 * Exit if both buffers are 0.
4875 if (echoBufSize > 0) {
4876 iocmd.flags |= MPT_ICFLAG_ECHO;
4877 if (dataBufSize > 0)
4878 bufsize = min(echoBufSize, dataBufSize);
4880 bufsize = echoBufSize;
4881 } else if (dataBufSize == 0)
4884 ddvprintk((MYIOC_s_INFO_FMT "%s Buffer Capacity %d\n", ioc->name,
4885 (iocmd.flags & MPT_ICFLAG_ECHO) ? "Echo" : " ", bufsize));
4887 /* Data buffers for write-read-compare test max 1K.
4889 sz = min(bufsize, 1024);
4892 * On first pass, always issue a reserve.
4893 * On additional loops, only if a reset has occurred.
4894 * iocmd.flags indicates if echo or regular buffer
4896 for (patt = 0; patt < 4; patt++) {
4897 ddvprintk(("Pattern %d\n", patt));
4898 if ((iocmd.flags & MPT_ICFLAG_RESERVED) && (iocmd.flags & MPT_ICFLAG_DID_RESET)) {
4899 iocmd.cmd = TEST_UNIT_READY;
4900 iocmd.data_dma = -1;
4903 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4906 iocmd.cmd = RELEASE;
4907 iocmd.data_dma = -1;
4910 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4912 else if (hd->pLocal == NULL)
4915 rc = hd->pLocal->completion;
4916 ddvprintk(("Release rc %d\n", rc));
4917 if (rc == MPT_SCANDV_GOOD)
4918 iocmd.flags &= ~MPT_ICFLAG_RESERVED;
4922 iocmd.flags &= ~MPT_ICFLAG_RESERVED;
4924 iocmd.flags &= ~MPT_ICFLAG_DID_RESET;
4926 if (iocmd.flags & MPT_ICFLAG_EBOS)
4930 while (repeat && (!(iocmd.flags & MPT_ICFLAG_RESERVED))) {
4931 iocmd.cmd = RESERVE;
4932 iocmd.data_dma = -1;
4935 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4937 else if (hd->pLocal == NULL)
4940 rc = hd->pLocal->completion;
4941 if (rc == MPT_SCANDV_GOOD) {
4942 iocmd.flags |= MPT_ICFLAG_RESERVED;
4943 } else if (rc == MPT_SCANDV_SENSE) {
4944 /* Wait if coming ready
4946 u8 skey = hd->pLocal->sense[2] & 0x0F;
4947 u8 asc = hd->pLocal->sense[12];
4948 u8 ascq = hd->pLocal->sense[13];
4949 ddvprintk((MYIOC_s_INFO_FMT
4950 "DV: Reserve Failed: ", ioc->name));
4951 ddvprintk(("SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
4954 if ((skey == NOT_READY) && (asc == 0x04)&&
4956 /* wait then repeat */
4960 ddvprintk((MYIOC_s_INFO_FMT
4961 "DV: Reserved Failed.", ioc->name));
4965 ddvprintk((MYIOC_s_INFO_FMT "DV: Reserved Failed.",
4973 mptscsih_fillbuf(pbuf1, sz, patt, 1);
4974 iocmd.cmd = WRITE_BUFFER;
4975 iocmd.data_dma = buf1_dma;
4978 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4980 else if (hd->pLocal == NULL)
4983 rc = hd->pLocal->completion;
4984 if (rc == MPT_SCANDV_GOOD)
4985 ; /* Issue read buffer */
4986 else if (rc == MPT_SCANDV_DID_RESET) {
4987 /* If using echo buffers, reset to data buffers.
4988 * Else do Fallback and restart
4989 * this test (re-issue reserve
4990 * because of bus reset).
4992 if ((iocmd.flags & MPT_ICFLAG_ECHO) && (dataBufSize >= bufsize)) {
4993 iocmd.flags &= ~MPT_ICFLAG_ECHO;
4995 dv.cmd = MPT_FALLBACK;
4996 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
4998 if (mpt_config(hd->ioc, &cfg) != 0)
5001 if ((!dv.now.width) && (!dv.now.offset))
5005 iocmd.flags |= MPT_ICFLAG_DID_RESET;
5008 } else if (rc == MPT_SCANDV_SENSE) {
5009 /* Restart data test if UA, else quit.
5011 u8 skey = hd->pLocal->sense[2] & 0x0F;
5012 ddvprintk((MYIOC_s_INFO_FMT
5013 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n", ioc->name, skey,
5014 hd->pLocal->sense[12], hd->pLocal->sense[13]));
5015 if (skey == UNIT_ATTENTION) {
5018 } else if (skey == ILLEGAL_REQUEST) {
5019 if (iocmd.flags & MPT_ICFLAG_ECHO) {
5020 if (dataBufSize >= bufsize) {
5021 iocmd.flags &= ~MPT_ICFLAG_ECHO;
5036 iocmd.cmd = READ_BUFFER;
5037 iocmd.data_dma = buf2_dma;
5040 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5042 else if (hd->pLocal == NULL)
5045 rc = hd->pLocal->completion;
5046 if (rc == MPT_SCANDV_GOOD) {
5047 /* If buffers compare,
5048 * go to next pattern,
5049 * else, do a fallback and restart
5050 * data transfer test.
5052 if (memcmp (pbuf1, pbuf2, sz) == 0) {
5053 ; /* goto next pattern */
5055 /* Miscompare with Echo buffer, go to data buffer,
5056 * if that buffer exists.
5057 * Miscompare with Data buffer, check first 4 bytes,
5058 * some devices return capacity. Exit in this case.
5060 if (iocmd.flags & MPT_ICFLAG_ECHO) {
5061 if (dataBufSize >= bufsize)
5062 iocmd.flags &= ~MPT_ICFLAG_ECHO;
5066 if (dataBufSize == (pbuf2[1]<<16 | pbuf2[2]<<8 | pbuf2[3])) {
5067 /* Argh. Device returning wrong data.
5068 * Quit DV for this device.
5073 /* Had an actual miscompare. Slow down.*/
5074 dv.cmd = MPT_FALLBACK;
5075 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5077 if (mpt_config(hd->ioc, &cfg) != 0)
5080 if ((!dv.now.width) && (!dv.now.offset))
5087 } else if (rc == MPT_SCANDV_DID_RESET) {
5088 /* Do Fallback and restart
5089 * this test (re-issue reserve
5090 * because of bus reset).
5092 dv.cmd = MPT_FALLBACK;
5093 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5095 if (mpt_config(hd->ioc, &cfg) != 0)
5098 if ((!dv.now.width) && (!dv.now.offset))
5101 iocmd.flags |= MPT_ICFLAG_DID_RESET;
5104 } else if (rc == MPT_SCANDV_SENSE) {
5105 /* Restart data test if UA, else quit.
5107 u8 skey = hd->pLocal->sense[2] & 0x0F;
5108 ddvprintk((MYIOC_s_INFO_FMT
5109 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n", ioc->name, skey,
5110 hd->pLocal->sense[12], hd->pLocal->sense[13]));
5111 if (skey == UNIT_ATTENTION) {
5123 } /* --- end of patt loop ---- */
5126 if (iocmd.flags & MPT_ICFLAG_RESERVED) {
5127 iocmd.cmd = RELEASE;
5128 iocmd.data_dma = -1;
5131 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5132 printk(MYIOC_s_INFO_FMT "DV: Release failed. id %d",
5134 else if (hd->pLocal) {
5135 if (hd->pLocal->completion == MPT_SCANDV_GOOD)
5136 iocmd.flags &= ~MPT_ICFLAG_RESERVED;
5138 printk(MYIOC_s_INFO_FMT "DV: Release failed. id %d",
5144 /* Set if cfg1_dma_addr contents is valid
5146 if ((cfg.cfghdr.hdr != NULL) && (retcode == 0)){
5147 /* If disk, not U320, disable QAS
5149 if ((inq0 == 0) && (dv.now.factor > MPT_ULTRA320)) {
5150 hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS;
5151 ddvprintk((MYIOC_s_NOTE_FMT
5152 "noQas set due to id=%d has factor=%x\n", ioc->name, id, dv.now.factor));
5156 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5158 /* Double writes to SDP1 can cause problems,
5159 * skip save of the final negotiated settings to
5160 * SCSI device page 1.
5162 cfg.cfghdr.hdr = &header1;
5163 cfg.physAddr = cfg1_dma_addr;
5164 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5166 mpt_config(hd->ioc, &cfg);
5170 /* If this is a RAID Passthrough, enable internal IOs
5172 if (iocmd.flags & MPT_ICFLAG_PHYS_DISK) {
5173 if (mptscsih_do_raid(hd, MPI_RAID_ACTION_ENABLE_PHYS_IO, &iocmd) < 0)
5174 ddvprintk((MYIOC_s_ERR_FMT "RAID Enable FAILED!\n", ioc->name));
5177 /* Done with the DV scan of the current target
5180 pci_free_consistent(ioc->pcidev, dv_alloc, pDvBuf, dvbuf_dma);
5182 ddvtprintk((MYIOC_s_INFO_FMT "DV Done id=%d\n",
5188 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5189 /* mptscsih_dv_parms - perform a variety of operations on the
5190 * parameters used for negotiation.
5191 * @hd: Pointer to a SCSI host.
5192 * @dv: Pointer to a structure that contains the maximum and current
5193 * negotiated parameters.
5196 mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
5198 VirtDevice *pTarget;
5199 SCSIDevicePage0_t *pPage0;
5200 SCSIDevicePage1_t *pPage1;
5201 int val = 0, data, configuration;
5210 case MPT_GET_NVRAM_VALS:
5211 ddvprintk((MYIOC_s_NOTE_FMT "Getting NVRAM: ",
5213 /* Get the NVRAM values and save in tmax
5214 * If not an LVD bus, the adapter minSyncFactor has been
5215 * already throttled back.
5217 negoFlags = hd->ioc->spi_data.noQas;
5218 if ((hd->Targets)&&((pTarget = hd->Targets[(int)id]) != NULL) && !pTarget->raidVolume) {
5219 width = pTarget->maxWidth;
5220 offset = pTarget->maxOffset;
5221 factor = pTarget->minSyncFactor;
5222 negoFlags |= pTarget->negoFlags;
5224 if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
5225 data = hd->ioc->spi_data.nvram[id];
5226 width = data & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
5227 if ((offset = hd->ioc->spi_data.maxSyncOffset) == 0)
5230 factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT;
5231 if ((factor == 0) || (factor == MPT_ASYNC)){
5242 /* Set the negotiation flags */
5244 negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
5247 negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
5250 /* limit by adapter capabilities */
5251 width = min(width, hd->ioc->spi_data.maxBusWidth);
5252 offset = min(offset, hd->ioc->spi_data.maxSyncOffset);
5253 factor = max(factor, hd->ioc->spi_data.minSyncFactor);
5255 /* Check Consistency */
5256 if (offset && (factor < MPT_ULTRA2) && !width)
5257 factor = MPT_ULTRA2;
5259 dv->max.width = width;
5260 dv->max.offset = offset;
5261 dv->max.factor = factor;
5262 dv->max.flags = negoFlags;
5263 ddvprintk((" id=%d width=%d factor=%x offset=%x flags=%x\n",
5264 id, width, factor, offset, negoFlags));
5267 case MPT_UPDATE_MAX:
5268 ddvprintk((MYIOC_s_NOTE_FMT
5269 "Updating with SDP0 Data: ", hd->ioc->name));
5270 /* Update tmax values with those from Device Page 0.*/
5271 pPage0 = (SCSIDevicePage0_t *) pPage;
5273 val = le32_to_cpu(pPage0->NegotiatedParameters);
5274 dv->max.width = val & MPI_SCSIDEVPAGE0_NP_WIDE ? 1 : 0;
5275 dv->max.offset = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK) >> 16;
5276 dv->max.factor = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK) >> 8;
5279 dv->now.width = dv->max.width;
5280 dv->now.offset = dv->max.offset;
5281 dv->now.factor = dv->max.factor;
5282 ddvprintk(("id=%d width=%d factor=%x offset=%x flags=%x\n",
5283 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags));
5287 ddvprintk((MYIOC_s_NOTE_FMT "Setting Max: ",
5289 /* Set current to the max values. Update the config page.*/
5290 dv->now.width = dv->max.width;
5291 dv->now.offset = dv->max.offset;
5292 dv->now.factor = dv->max.factor;
5293 dv->now.flags = dv->max.flags;
5295 pPage1 = (SCSIDevicePage1_t *)pPage;
5297 mptscsih_setDevicePage1Flags (dv->now.width, dv->now.factor,
5298 dv->now.offset, &val, &configuration, dv->now.flags);
5299 dnegoprintk(("Setting Max: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
5300 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags, val, configuration));
5301 pPage1->RequestedParameters = cpu_to_le32(val);
5302 pPage1->Reserved = 0;
5303 pPage1->Configuration = cpu_to_le32(configuration);
5306 ddvprintk(("id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x configuration=%x\n",
5307 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags, val, configuration));
5311 ddvprintk((MYIOC_s_NOTE_FMT "Setting Min: ",
5313 /* Set page to asynchronous and narrow
5314 * Do not update now, breaks fallback routine. */
5318 negoFlags = dv->max.flags;
5320 pPage1 = (SCSIDevicePage1_t *)pPage;
5322 mptscsih_setDevicePage1Flags (width, factor,
5323 offset, &val, &configuration, negoFlags);
5324 dnegoprintk(("Setting Min: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
5325 id, width, factor, offset, negoFlags, val, configuration));
5326 pPage1->RequestedParameters = cpu_to_le32(val);
5327 pPage1->Reserved = 0;
5328 pPage1->Configuration = cpu_to_le32(configuration);
5330 ddvprintk(("id=%d width=%d factor=%x offset=%x request=%x config=%x negoFlags=%x\n",
5331 id, width, factor, offset, val, configuration, negoFlags));
5335 ddvprintk((MYIOC_s_NOTE_FMT
5336 "Fallback: Start: offset %d, factor %x, width %d \n",
5337 hd->ioc->name, dv->now.offset,
5338 dv->now.factor, dv->now.width));
5339 width = dv->now.width;
5340 offset = dv->now.offset;
5341 factor = dv->now.factor;
5342 if ((offset) && (dv->max.width)) {
5343 if (factor < MPT_ULTRA160)
5344 factor = MPT_ULTRA160;
5345 else if (factor < MPT_ULTRA2) {
5346 factor = MPT_ULTRA2;
5348 } else if ((factor == MPT_ULTRA2) && width) {
5349 factor = MPT_ULTRA2;
5351 } else if (factor < MPT_ULTRA) {
5354 } else if ((factor == MPT_ULTRA) && width) {
5356 } else if (factor < MPT_FAST) {
5359 } else if ((factor == MPT_FAST) && width) {
5362 } else if (factor < MPT_SCSI) {
5365 } else if ((factor == MPT_SCSI) && width) {
5373 } else if (offset) {
5375 if (factor < MPT_ULTRA)
5377 else if (factor < MPT_FAST)
5379 else if (factor < MPT_SCSI)
5390 dv->max.flags |= MPT_TARGET_NO_NEGO_QAS;
5391 dv->max.flags &= ~MPT_TAPE_NEGO_IDP;
5393 dv->now.width = width;
5394 dv->now.offset = offset;
5395 dv->now.factor = factor;
5396 dv->now.flags = dv->max.flags;
5398 pPage1 = (SCSIDevicePage1_t *)pPage;
5400 mptscsih_setDevicePage1Flags (width, factor, offset, &val,
5401 &configuration, dv->now.flags);
5402 dnegoprintk(("Finish: id=%d width=%d offset=%d factor=%x negoFlags=%x request=%x config=%x\n",
5403 id, width, offset, factor, dv->now.flags, val, configuration));
5405 pPage1->RequestedParameters = cpu_to_le32(val);
5406 pPage1->Reserved = 0;
5407 pPage1->Configuration = cpu_to_le32(configuration);
5410 ddvprintk(("Finish: id=%d offset=%d factor=%x width=%d request=%x config=%x\n",
5411 id, dv->now.offset, dv->now.factor, dv->now.width, val, configuration));
5415 ddvprintk((MYIOC_s_NOTE_FMT
5416 "Saving to Target structure: ", hd->ioc->name));
5417 ddvprintk(("id=%d width=%x factor=%x offset=%d flags=%x\n",
5418 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags));
5420 /* Save these values to target structures
5421 * or overwrite nvram (phys disks only).
5424 if ((hd->Targets)&&((pTarget = hd->Targets[(int)id]) != NULL) && !pTarget->raidVolume ) {
5425 pTarget->maxWidth = dv->now.width;
5426 pTarget->maxOffset = dv->now.offset;
5427 pTarget->minSyncFactor = dv->now.factor;
5428 pTarget->negoFlags = dv->now.flags;
5430 /* Preserv all flags, use
5431 * read-modify-write algorithm
5433 if (hd->ioc->spi_data.nvram) {
5434 data = hd->ioc->spi_data.nvram[id];
5437 data &= ~MPT_NVRAM_WIDE_DISABLE;
5439 data |= MPT_NVRAM_WIDE_DISABLE;
5441 if (!dv->now.offset)
5444 data &= ~MPT_NVRAM_SYNC_MASK;
5445 data |= (dv->now.factor << MPT_NVRAM_SYNC_SHIFT) & MPT_NVRAM_SYNC_MASK;
5447 hd->ioc->spi_data.nvram[id] = data;
5454 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5455 /* mptscsih_fillbuf - fill a buffer with a special data pattern
5456 * cleanup. For bus scan only.
5458 * @buffer: Pointer to data buffer to be filled.
5459 * @size: Number of bytes to fill
5460 * @index: Pattern index
5461 * @width: bus width, 0 (8 bits) or 1 (16 bits)
5464 mptscsih_fillbuf(char *buffer, int size, int index, int width)
5475 /* Pattern: 0000 FFFF 0000 FFFF
5477 for (ii=0; ii < size; ii++, ptr++) {
5484 /* Pattern: 00 FF 00 FF
5486 for (ii=0; ii < size; ii++, ptr++) {
5497 /* Pattern: 5555 AAAA 5555 AAAA 5555
5499 for (ii=0; ii < size; ii++, ptr++) {
5506 /* Pattern: 55 AA 55 AA 55
5508 for (ii=0; ii < size; ii++, ptr++) {
5518 /* Pattern: 00 01 02 03 04 05
5521 for (ii=0; ii < size; ii++, ptr++)
5527 /* Wide Pattern: FFFE 0001 FFFD 0002
5528 * ... 4000 DFFF 8000 EFFF
5531 for (ii=0; ii < size/2; ii++) {
5532 /* Create the base pattern
5535 /* every 64 (0x40) bytes flip the pattern
5536 * since we fill 2 bytes / iteration,
5537 * test for ii = 0x20
5543 *ptr = (char)( (val & 0xFF00) >> 8);
5545 *ptr = (char)(val & 0xFF);
5550 *ptr = (char)( (val & 0xFF00) >> 8);
5552 *ptr = (char)(val & 0xFF);
5558 /* Narrow Pattern: FE 01 FD 02 FB 04
5559 * .. 7F 80 01 FE 02 FD ... 80 7F
5562 for (ii=0; ii < size; ii++, ptr++) {
5563 /* Base pattern - first 32 bytes
5570 *ptr = (char) (~(1 << byte));
5573 /* Flip the pattern every 32 bytes
5582 #endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */
5584 EXPORT_SYMBOL(mptscsih_remove);
5585 EXPORT_SYMBOL(mptscsih_shutdown);
5587 EXPORT_SYMBOL(mptscsih_suspend);
5588 EXPORT_SYMBOL(mptscsih_resume);
5590 EXPORT_SYMBOL(mptscsih_proc_info);
5591 EXPORT_SYMBOL(mptscsih_info);
5592 EXPORT_SYMBOL(mptscsih_qcmd);
5593 EXPORT_SYMBOL(mptscsih_slave_alloc);
5594 EXPORT_SYMBOL(mptscsih_slave_destroy);
5595 EXPORT_SYMBOL(mptscsih_slave_configure);
5596 EXPORT_SYMBOL(mptscsih_abort);
5597 EXPORT_SYMBOL(mptscsih_dev_reset);
5598 EXPORT_SYMBOL(mptscsih_bus_reset);
5599 EXPORT_SYMBOL(mptscsih_host_reset);
5600 EXPORT_SYMBOL(mptscsih_bios_param);
5601 EXPORT_SYMBOL(mptscsih_io_done);
5602 EXPORT_SYMBOL(mptscsih_taskmgmt_complete);
5603 EXPORT_SYMBOL(mptscsih_scandv_complete);
5604 EXPORT_SYMBOL(mptscsih_event_process);
5605 EXPORT_SYMBOL(mptscsih_ioc_reset);
5606 EXPORT_SYMBOL(mptscsih_change_queue_depth);
5607 EXPORT_SYMBOL(mptscsih_timer_expired);
5609 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/