2 * linux/drivers/message/fusion/mptscsih.c
3 * For use with LSI Logic PCI chip/adapter(s)
4 * running LSI Logic Fusion MPT (Message Passing Technology) firmware.
6 * Copyright (c) 1999-2005 LSI Logic Corporation
7 * (mailto:mpt_linux_developer@lsil.com)
10 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; version 2 of the License.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
22 THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
23 CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
24 LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
25 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
26 solely responsible for determining the appropriateness of using and
27 distributing the Program and assumes all risks associated with its
28 exercise of rights under this Agreement, including but not limited to
29 the risks and costs of program errors, damage to or loss of data,
30 programs or equipment, and unavailability or interruption of operations.
32 DISCLAIMER OF LIABILITY
33 NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
34 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
35 DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
36 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
37 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
38 USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
39 HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
41 You should have received a copy of the GNU General Public License
42 along with this program; if not, write to the Free Software
43 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
45 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
47 #include "linux_compat.h" /* linux-2.6 tweaks */
48 #include <linux/module.h>
49 #include <linux/kernel.h>
50 #include <linux/init.h>
51 #include <linux/errno.h>
52 #include <linux/kdev_t.h>
53 #include <linux/blkdev.h>
54 #include <linux/delay.h> /* for mdelay */
55 #include <linux/interrupt.h> /* needed for in_interrupt() proto */
56 #include <linux/reboot.h> /* notifier code */
57 #include <linux/sched.h>
58 #include <linux/workqueue.h>
60 #include <scsi/scsi.h>
61 #include <scsi/scsi_cmnd.h>
62 #include <scsi/scsi_device.h>
63 #include <scsi/scsi_host.h>
64 #include <scsi/scsi_tcq.h>
65 #include <scsi/scsi_dbg.h>
70 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
71 #define my_NAME "Fusion MPT SCSI Host driver"
72 #define my_VERSION MPT_LINUX_VERSION_COMMON
73 #define MYNAM "mptscsih"
75 MODULE_AUTHOR(MODULEAUTHOR);
76 MODULE_DESCRIPTION(my_NAME);
77 MODULE_LICENSE("GPL");
79 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
81 typedef struct _BIG_SENSE_BUF {
82 u8 data[MPT_SENSE_BUFFER_ALLOC];
85 #define MPT_SCANDV_GOOD (0x00000000) /* must be 0 */
86 #define MPT_SCANDV_DID_RESET (0x00000001)
87 #define MPT_SCANDV_SENSE (0x00000002)
88 #define MPT_SCANDV_SOME_ERROR (0x00000004)
89 #define MPT_SCANDV_SELECTION_TIMEOUT (0x00000008)
90 #define MPT_SCANDV_ISSUE_SENSE (0x00000010)
91 #define MPT_SCANDV_FALLBACK (0x00000020)
93 #define MPT_SCANDV_MAX_RETRIES (10)
95 #define MPT_ICFLAG_BUF_CAP 0x01 /* ReadBuffer Read Capacity format */
96 #define MPT_ICFLAG_ECHO 0x02 /* ReadBuffer Echo buffer format */
97 #define MPT_ICFLAG_EBOS 0x04 /* ReadBuffer Echo buffer has EBOS */
98 #define MPT_ICFLAG_PHYS_DISK 0x08 /* Any SCSI IO but do Phys Disk Format */
99 #define MPT_ICFLAG_TAGGED_CMD 0x10 /* Do tagged IO */
100 #define MPT_ICFLAG_DID_RESET 0x20 /* Bus Reset occurred with this command */
101 #define MPT_ICFLAG_RESERVED 0x40 /* Reserved has been issued */
103 typedef struct _internal_cmd {
104 char *data; /* data pointer */
105 dma_addr_t data_dma; /* data dma address */
106 int size; /* transfer size */
107 u8 cmd; /* SCSI Op Code */
108 u8 bus; /* bus number */
109 u8 id; /* SCSI ID (virtual) */
111 u8 flags; /* Bit Field - See above */
112 u8 physDiskNum; /* Phys disk number, -1 else */
117 typedef struct _negoparms {
124 typedef struct _dv_parameters {
133 * Other private/forward protos...
135 int mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
136 static void mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq);
137 int mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
139 static int mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
140 SCSIIORequest_t *pReq, int req_idx);
141 static void mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx);
142 static void mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply);
143 static int mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd);
144 static int mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout );
145 static u32 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc);
147 static int mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout);
148 static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout);
150 int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
151 int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
153 static void mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, u8 lun, char *data, int dlen);
154 static void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *vtarget, char byte56);
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, struct scsi_cmnd *sc);
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 void mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice);
162 static void mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtTarget *vtarget);
163 static int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id);
165 static struct work_struct mptscsih_persistTask;
167 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
168 static int mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io);
169 static void mptscsih_domainValidation(void *hd);
170 static void mptscsih_qas_check(MPT_SCSI_HOST *hd, int id);
171 static int mptscsih_doDv(MPT_SCSI_HOST *hd, int channel, int target);
172 static void mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage);
173 static void mptscsih_fillbuf(char *buffer, int size, int index, int width);
174 static void mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id);
175 static void mptscsih_set_dvflags(MPT_SCSI_HOST *hd, struct scsi_cmnd *sc);
178 void mptscsih_remove(struct pci_dev *);
179 void mptscsih_shutdown(struct pci_dev *);
181 int mptscsih_suspend(struct pci_dev *pdev, pm_message_t state);
182 int mptscsih_resume(struct pci_dev *pdev);
185 #define SNS_LEN(scp) sizeof((scp)->sense_buffer)
187 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
189 * Domain Validation task structure
191 static DEFINE_SPINLOCK(dvtaskQ_lock);
192 static int dvtaskQ_active = 0;
193 static int dvtaskQ_release = 0;
194 static struct work_struct dvTaskQ_task;
197 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
199 * mptscsih_add_sge - Place a simple SGE at address pAddr.
200 * @pAddr: virtual address for SGE
201 * @flagslength: SGE flags and data transfer length
202 * @dma_addr: Physical address
204 * This routine places a MPT request frame back on the MPT adapter's
208 mptscsih_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
210 if (sizeof(dma_addr_t) == sizeof(u64)) {
211 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
212 u32 tmp = dma_addr & 0xFFFFFFFF;
214 pSge->FlagsLength = cpu_to_le32(flagslength);
215 pSge->Address.Low = cpu_to_le32(tmp);
216 tmp = (u32) ((u64)dma_addr >> 32);
217 pSge->Address.High = cpu_to_le32(tmp);
220 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
221 pSge->FlagsLength = cpu_to_le32(flagslength);
222 pSge->Address = cpu_to_le32(dma_addr);
224 } /* mptscsih_add_sge() */
226 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
228 * mptscsih_add_chain - Place a chain SGE at address pAddr.
229 * @pAddr: virtual address for SGE
230 * @next: nextChainOffset value (u32's)
231 * @length: length of next SGL segment
232 * @dma_addr: Physical address
234 * This routine places a MPT request frame back on the MPT adapter's
238 mptscsih_add_chain(char *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
240 if (sizeof(dma_addr_t) == sizeof(u64)) {
241 SGEChain64_t *pChain = (SGEChain64_t *) pAddr;
242 u32 tmp = dma_addr & 0xFFFFFFFF;
244 pChain->Length = cpu_to_le16(length);
245 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size();
247 pChain->NextChainOffset = next;
249 pChain->Address.Low = cpu_to_le32(tmp);
250 tmp = (u32) ((u64)dma_addr >> 32);
251 pChain->Address.High = cpu_to_le32(tmp);
253 SGEChain32_t *pChain = (SGEChain32_t *) pAddr;
254 pChain->Length = cpu_to_le16(length);
255 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size();
256 pChain->NextChainOffset = next;
257 pChain->Address = cpu_to_le32(dma_addr);
259 } /* mptscsih_add_chain() */
261 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
263 * mptscsih_getFreeChainBuffer - Function to get a free chain
264 * from the MPT_SCSI_HOST FreeChainQ.
265 * @ioc: Pointer to MPT_ADAPTER structure
266 * @req_idx: Index of the SCSI IO request frame. (output)
268 * return SUCCESS or FAILED
271 mptscsih_getFreeChainBuffer(MPT_ADAPTER *ioc, int *retIndex)
273 MPT_FRAME_HDR *chainBuf;
278 dsgprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer called\n",
280 spin_lock_irqsave(&ioc->FreeQlock, flags);
281 if (!list_empty(&ioc->FreeChainQ)) {
284 chainBuf = list_entry(ioc->FreeChainQ.next, MPT_FRAME_HDR,
285 u.frame.linkage.list);
286 list_del(&chainBuf->u.frame.linkage.list);
287 offset = (u8 *)chainBuf - (u8 *)ioc->ChainBuffer;
288 chain_idx = offset / ioc->req_sz;
290 dsgprintk((MYIOC_s_ERR_FMT "getFreeChainBuffer chainBuf=%p ChainBuffer=%p offset=%d chain_idx=%d\n",
291 ioc->name, chainBuf, ioc->ChainBuffer, offset, chain_idx));
294 chain_idx = MPT_HOST_NO_CHAIN;
295 dfailprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer failed\n",
298 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
300 *retIndex = chain_idx;
302 } /* mptscsih_getFreeChainBuffer() */
304 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
306 * mptscsih_AddSGE - Add a SGE (plus chain buffers) to the
307 * SCSIIORequest_t Message Frame.
308 * @ioc: Pointer to MPT_ADAPTER structure
309 * @SCpnt: Pointer to scsi_cmnd structure
310 * @pReq: Pointer to SCSIIORequest_t structure
315 mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
316 SCSIIORequest_t *pReq, int req_idx)
320 struct scatterlist *sg;
322 int sges_left, sg_done;
323 int chain_idx = MPT_HOST_NO_CHAIN;
325 int numSgeSlots, numSgeThisFrame;
326 u32 sgflags, sgdir, thisxfer = 0;
327 int chain_dma_off = 0;
333 sgdir = le32_to_cpu(pReq->Control) & MPI_SCSIIO_CONTROL_DATADIRECTION_MASK;
334 if (sgdir == MPI_SCSIIO_CONTROL_WRITE) {
335 sgdir = MPT_TRANSFER_HOST_TO_IOC;
337 sgdir = MPT_TRANSFER_IOC_TO_HOST;
340 psge = (char *) &pReq->SGL;
341 frm_sz = ioc->req_sz;
343 /* Map the data portion, if any.
344 * sges_left = 0 if no data transfer.
346 if ( (sges_left = SCpnt->use_sg) ) {
347 sges_left = pci_map_sg(ioc->pcidev,
348 (struct scatterlist *) SCpnt->request_buffer,
350 SCpnt->sc_data_direction);
353 } else if (SCpnt->request_bufflen) {
354 SCpnt->SCp.dma_handle = pci_map_single(ioc->pcidev,
355 SCpnt->request_buffer,
356 SCpnt->request_bufflen,
357 SCpnt->sc_data_direction);
358 dsgprintk((MYIOC_s_INFO_FMT "SG: non-SG for %p, len=%d\n",
359 ioc->name, SCpnt, SCpnt->request_bufflen));
360 mptscsih_add_sge((char *) &pReq->SGL,
361 0xD1000000|MPT_SGE_FLAGS_ADDRESSING|sgdir|SCpnt->request_bufflen,
362 SCpnt->SCp.dma_handle);
367 /* Handle the SG case.
369 sg = (struct scatterlist *) SCpnt->request_buffer;
371 sgeOffset = sizeof(SCSIIORequest_t) - sizeof(SGE_IO_UNION);
374 /* Prior to entering this loop - the following must be set
375 * current MF: sgeOffset (bytes)
376 * chainSge (Null if original MF is not a chain buffer)
377 * sg_done (num SGE done for this MF)
381 numSgeSlots = ((frm_sz - sgeOffset) / (sizeof(u32) + sizeof(dma_addr_t)) );
382 numSgeThisFrame = (sges_left < numSgeSlots) ? sges_left : numSgeSlots;
384 sgflags = MPT_SGE_FLAGS_SIMPLE_ELEMENT | MPT_SGE_FLAGS_ADDRESSING | sgdir;
386 /* Get first (num - 1) SG elements
387 * Skip any SG entries with a length of 0
388 * NOTE: at finish, sg and psge pointed to NEXT data/location positions
390 for (ii=0; ii < (numSgeThisFrame-1); ii++) {
391 thisxfer = sg_dma_len(sg);
393 sg ++; /* Get next SG element from the OS */
398 v2 = sg_dma_address(sg);
399 mptscsih_add_sge(psge, sgflags | thisxfer, v2);
401 sg++; /* Get next SG element from the OS */
402 psge += (sizeof(u32) + sizeof(dma_addr_t));
403 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
407 if (numSgeThisFrame == sges_left) {
408 /* Add last element, end of buffer and end of list flags.
410 sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT |
411 MPT_SGE_FLAGS_END_OF_BUFFER |
412 MPT_SGE_FLAGS_END_OF_LIST;
414 /* Add last SGE and set termination flags.
415 * Note: Last SGE may have a length of 0 - which should be ok.
417 thisxfer = sg_dma_len(sg);
419 v2 = sg_dma_address(sg);
420 mptscsih_add_sge(psge, sgflags | thisxfer, v2);
423 psge += (sizeof(u32) + sizeof(dma_addr_t));
425 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
429 /* The current buffer is a chain buffer,
430 * but there is not another one.
431 * Update the chain element
432 * Offset and Length fields.
434 mptscsih_add_chain((char *)chainSge, 0, sgeOffset, ioc->ChainBufferDMA + chain_dma_off);
436 /* The current buffer is the original MF
437 * and there is no Chain buffer.
439 pReq->ChainOffset = 0;
440 RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor) + 1) & 0x03;
441 dsgprintk((MYIOC_s_INFO_FMT
442 "Single Buffer RequestNB=%x, sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
443 ioc->RequestNB[req_idx] = RequestNB;
446 /* At least one chain buffer is needed.
447 * Complete the first MF
448 * - last SGE element, set the LastElement bit
449 * - set ChainOffset (words) for orig MF
450 * (OR finish previous MF chain buffer)
451 * - update MFStructPtr ChainIndex
452 * - Populate chain element
457 dsgprintk((MYIOC_s_INFO_FMT "SG: Chain Required! sg done %d\n",
458 ioc->name, sg_done));
460 /* Set LAST_ELEMENT flag for last non-chain element
461 * in the buffer. Since psge points at the NEXT
462 * SGE element, go back one SGE element, update the flags
463 * and reset the pointer. (Note: sgflags & thisxfer are already
467 u32 *ptmp = (u32 *) (psge - (sizeof(u32) + sizeof(dma_addr_t)));
468 sgflags = le32_to_cpu(*ptmp);
469 sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT;
470 *ptmp = cpu_to_le32(sgflags);
474 /* The current buffer is a chain buffer.
475 * chainSge points to the previous Chain Element.
476 * Update its chain element Offset and Length (must
477 * include chain element size) fields.
478 * Old chain element is now complete.
480 u8 nextChain = (u8) (sgeOffset >> 2);
481 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
482 mptscsih_add_chain((char *)chainSge, nextChain, sgeOffset, ioc->ChainBufferDMA + chain_dma_off);
484 /* The original MF buffer requires a chain buffer -
486 * Last element in this MF is a chain element.
488 pReq->ChainOffset = (u8) (sgeOffset >> 2);
489 RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor) + 1) & 0x03;
490 dsgprintk((MYIOC_s_ERR_FMT "Chain Buffer Needed, RequestNB=%x sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
491 ioc->RequestNB[req_idx] = RequestNB;
494 sges_left -= sg_done;
497 /* NOTE: psge points to the beginning of the chain element
498 * in current buffer. Get a chain buffer.
500 if ((mptscsih_getFreeChainBuffer(ioc, &newIndex)) == FAILED) {
501 dfailprintk((MYIOC_s_INFO_FMT
502 "getFreeChainBuffer FAILED SCSI cmd=%02x (%p)\n",
503 ioc->name, pReq->CDB[0], SCpnt));
507 /* Update the tracking arrays.
508 * If chainSge == NULL, update ReqToChain, else ChainToChain
511 ioc->ChainToChain[chain_idx] = newIndex;
513 ioc->ReqToChain[req_idx] = newIndex;
515 chain_idx = newIndex;
516 chain_dma_off = ioc->req_sz * chain_idx;
518 /* Populate the chainSGE for the current buffer.
519 * - Set chain buffer pointer to psge and fill
520 * out the Address and Flags fields.
522 chainSge = (char *) psge;
523 dsgprintk((KERN_INFO " Current buff @ %p (index 0x%x)",
526 /* Start the SGE for the next buffer
528 psge = (char *) (ioc->ChainBuffer + chain_dma_off);
532 dsgprintk((KERN_INFO " Chain buff @ %p (index 0x%x)\n",
535 /* Start the SGE for the next buffer
542 } /* mptscsih_AddSGE() */
544 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
546 * mptscsih_io_done - Main SCSI IO callback routine registered to
547 * Fusion MPT (base) driver
548 * @ioc: Pointer to MPT_ADAPTER structure
549 * @mf: Pointer to original MPT request frame
550 * @r: Pointer to MPT reply frame (NULL if TurboReply)
552 * This routine is called from mpt.c::mpt_interrupt() at the completion
553 * of any SCSI IO request.
554 * This routine is registered with the Fusion MPT (base) driver at driver
555 * load/init time via the mpt_register() API call.
557 * Returns 1 indicating alloc'd request frame ptr should be freed.
560 mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
562 struct scsi_cmnd *sc;
564 SCSIIORequest_t *pScsiReq;
565 SCSIIOReply_t *pScsiReply;
568 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
570 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
571 sc = hd->ScsiLookup[req_idx];
573 MPIHeader_t *hdr = (MPIHeader_t *)mf;
575 /* Remark: writeSDP1 will use the ScsiDoneCtx
576 * If a SCSI I/O cmd, device disabled by OS and
577 * completion done. Cannot touch sc struct. Just free mem.
579 if (hdr->Function == MPI_FUNCTION_SCSI_IO_REQUEST)
580 printk(MYIOC_s_ERR_FMT "NULL ScsiCmd ptr!\n",
583 mptscsih_freeChainBuffers(ioc, req_idx);
587 sc->result = DID_OK << 16; /* Set default reply as OK */
588 pScsiReq = (SCSIIORequest_t *) mf;
589 pScsiReply = (SCSIIOReply_t *) mr;
591 if((ioc->facts.MsgVersion >= MPI_VERSION_01_05) && pScsiReply){
592 dmfprintk((MYIOC_s_INFO_FMT
593 "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d,task-tag=%d)\n",
594 ioc->name, mf, mr, sc, req_idx, pScsiReply->TaskTag));
596 dmfprintk((MYIOC_s_INFO_FMT
597 "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n",
598 ioc->name, mf, mr, sc, req_idx));
601 if (pScsiReply == NULL) {
602 /* special context reply handling */
607 u8 scsi_state, scsi_status;
609 status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK;
610 scsi_state = pScsiReply->SCSIState;
611 scsi_status = pScsiReply->SCSIStatus;
612 xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
613 sc->resid = sc->request_bufflen - xfer_cnt;
616 * if we get a data underrun indication, yet no data was
617 * transferred and the SCSI status indicates that the
618 * command was never started, change the data underrun
621 if (status == MPI_IOCSTATUS_SCSI_DATA_UNDERRUN && xfer_cnt == 0 &&
622 (scsi_status == MPI_SCSI_STATUS_BUSY ||
623 scsi_status == MPI_SCSI_STATUS_RESERVATION_CONFLICT ||
624 scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)) {
625 status = MPI_IOCSTATUS_SUCCESS;
628 dreplyprintk((KERN_NOTICE "Reply ha=%d id=%d lun=%d:\n"
629 "IOCStatus=%04xh SCSIState=%02xh SCSIStatus=%02xh\n"
630 "resid=%d bufflen=%d xfer_cnt=%d\n",
631 ioc->id, sc->device->id, sc->device->lun,
632 status, scsi_state, scsi_status, sc->resid,
633 sc->request_bufflen, xfer_cnt));
635 if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)
636 mptscsih_copy_sense_data(sc, hd, mf, pScsiReply);
639 * Look for + dump FCP ResponseInfo[]!
641 if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID &&
642 pScsiReply->ResponseInfo) {
643 printk(KERN_NOTICE "ha=%d id=%d lun=%d: "
644 "FCP_ResponseInfo=%08xh\n",
645 ioc->id, sc->device->id, sc->device->lun,
646 le32_to_cpu(pScsiReply->ResponseInfo));
650 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
652 * Maybe: DRIVER_BUSY | SUGGEST_RETRY | DID_SOFT_ERROR (retry)
653 * But not: DID_BUS_BUSY lest one risk
654 * killing interrupt handler:-(
656 sc->result = SAM_STAT_BUSY;
659 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
660 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
661 sc->result = DID_BAD_TARGET << 16;
664 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
665 /* Spoof to SCSI Selection Timeout! */
666 sc->result = DID_NO_CONNECT << 16;
668 if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF)
669 hd->sel_timeout[pScsiReq->TargetID]++;
672 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
673 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
674 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
675 /* Linux handles an unsolicited DID_RESET better
676 * than an unsolicited DID_ABORT.
678 sc->result = DID_RESET << 16;
680 /* GEM Workaround. */
681 if (ioc->bus_type == SPI)
682 mptscsih_no_negotiate(hd, sc);
685 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
686 sc->resid = sc->request_bufflen - xfer_cnt;
687 if((xfer_cnt==0)||(sc->underflow > xfer_cnt))
688 sc->result=DID_SOFT_ERROR << 16;
689 else /* Sufficient data transfer occurred */
690 sc->result = (DID_OK << 16) | scsi_status;
691 dreplyprintk((KERN_NOTICE
692 "RESIDUAL_MISMATCH: result=%x on id=%d\n", sc->result, sc->device->id));
695 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
697 * Do upfront check for valid SenseData and give it
700 sc->result = (DID_OK << 16) | scsi_status;
701 if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
702 /* Have already saved the status and sense data
706 if (xfer_cnt < sc->underflow) {
707 if (scsi_status == SAM_STAT_BUSY)
708 sc->result = SAM_STAT_BUSY;
710 sc->result = DID_SOFT_ERROR << 16;
712 if (scsi_state & (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)) {
715 sc->result = DID_SOFT_ERROR << 16;
717 else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
718 /* Not real sure here either... */
719 sc->result = DID_RESET << 16;
723 dreplyprintk((KERN_NOTICE " sc->underflow={report ERR if < %02xh bytes xfer'd}\n",
725 dreplyprintk((KERN_NOTICE " ActBytesXferd=%02xh\n", xfer_cnt));
728 if (scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)
729 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
733 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
734 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
735 if (scsi_status == MPI_SCSI_STATUS_BUSY)
736 sc->result = (DID_BUS_BUSY << 16) | scsi_status;
738 sc->result = (DID_OK << 16) | scsi_status;
739 if (scsi_state == 0) {
741 } else if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
743 * If running against circa 200003dd 909 MPT f/w,
744 * may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL
745 * (QUEUE_FULL) returned from device! --> get 0x0000?128
746 * and with SenseBytes set to 0.
748 if (pScsiReply->SCSIStatus == MPI_SCSI_STATUS_TASK_SET_FULL)
749 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
752 else if (scsi_state &
753 (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)
758 sc->result = DID_SOFT_ERROR << 16;
760 else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
761 /* Not real sure here either... */
762 sc->result = DID_RESET << 16;
764 else if (scsi_state & MPI_SCSI_STATE_QUEUE_TAG_REJECTED) {
765 /* Device Inq. data indicates that it supports
766 * QTags, but rejects QTag messages.
767 * This command completed OK.
769 * Not real sure here either so do nothing... */
772 if (sc->result == MPI_SCSI_STATUS_TASK_SET_FULL)
773 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
776 * Reservation Conflict, Busy,
777 * Command Terminated, CHECK
781 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
782 sc->result = DID_SOFT_ERROR << 16;
785 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
786 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
787 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
788 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
789 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
790 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
791 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
792 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
793 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
794 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
799 sc->result = DID_SOFT_ERROR << 16;
802 } /* switch(status) */
804 dreplyprintk((KERN_NOTICE " sc->result is %08xh\n", sc->result));
805 } /* end of address reply case */
807 /* Unmap the DMA buffers, if any. */
809 pci_unmap_sg(ioc->pcidev, (struct scatterlist *) sc->request_buffer,
810 sc->use_sg, sc->sc_data_direction);
811 } else if (sc->request_bufflen) {
812 pci_unmap_single(ioc->pcidev, sc->SCp.dma_handle,
813 sc->request_bufflen, sc->sc_data_direction);
816 hd->ScsiLookup[req_idx] = NULL;
818 sc->scsi_done(sc); /* Issue the command callback */
820 /* Free Chain buffers */
821 mptscsih_freeChainBuffers(ioc, req_idx);
826 * mptscsih_flush_running_cmds - For each command found, search
827 * Scsi_Host instance taskQ and reply to OS.
828 * Called only if recovering from a FW reload.
829 * @hd: Pointer to a SCSI HOST structure
833 * Must be called while new I/Os are being queued.
836 mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
838 MPT_ADAPTER *ioc = hd->ioc;
839 struct scsi_cmnd *SCpnt;
842 int max = ioc->req_depth;
844 dprintk((KERN_INFO MYNAM ": flush_ScsiLookup called\n"));
845 for (ii= 0; ii < max; ii++) {
846 if ((SCpnt = hd->ScsiLookup[ii]) != NULL) {
851 /* Null ScsiLookup index
853 hd->ScsiLookup[ii] = NULL;
855 mf = MPT_INDEX_2_MFPTR(ioc, ii);
856 dmfprintk(( "flush: ScsiDone (mf=%p,sc=%p)\n",
859 /* Set status, free OS resources (SG DMA buffers)
861 * Free driver resources (chain, msg buffers)
864 pci_unmap_sg(ioc->pcidev,
865 (struct scatterlist *) SCpnt->request_buffer,
867 SCpnt->sc_data_direction);
868 } else if (SCpnt->request_bufflen) {
869 pci_unmap_single(ioc->pcidev,
870 SCpnt->SCp.dma_handle,
871 SCpnt->request_bufflen,
872 SCpnt->sc_data_direction);
874 SCpnt->result = DID_RESET << 16;
875 SCpnt->host_scribble = NULL;
877 /* Free Chain buffers */
878 mptscsih_freeChainBuffers(ioc, ii);
880 /* Free Message frames */
881 mpt_free_msg_frame(ioc, mf);
883 SCpnt->scsi_done(SCpnt); /* Issue the command callback */
891 * mptscsih_search_running_cmds - Delete any commands associated
892 * with the specified target and lun. Function called only
893 * when a lun is disable by mid-layer.
894 * Do NOT access the referenced scsi_cmnd structure or
895 * members. Will cause either a paging or NULL ptr error.
896 * @hd: Pointer to a SCSI HOST structure
897 * @vdevice: per device private data
901 * Called from slave_destroy.
904 mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
906 SCSIIORequest_t *mf = NULL;
908 int max = hd->ioc->req_depth;
909 struct scsi_cmnd *sc;
911 dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n",
912 vdevice->target_id, vdevice->lun, max));
914 for (ii=0; ii < max; ii++) {
915 if ((sc = hd->ScsiLookup[ii]) != NULL) {
917 mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii);
919 dsprintk(( "search_running: found (sc=%p, mf = %p) target %d, lun %d \n",
920 hd->ScsiLookup[ii], mf, mf->TargetID, mf->LUN[1]));
922 if ((mf->TargetID != ((u8)vdevice->target_id)) || (mf->LUN[1] != ((u8) vdevice->lun)))
927 hd->ScsiLookup[ii] = NULL;
928 mptscsih_freeChainBuffers(hd->ioc, ii);
929 mpt_free_msg_frame(hd->ioc, (MPT_FRAME_HDR *)mf);
931 pci_unmap_sg(hd->ioc->pcidev,
932 (struct scatterlist *) sc->request_buffer,
934 sc->sc_data_direction);
935 } else if (sc->request_bufflen) {
936 pci_unmap_single(hd->ioc->pcidev,
939 sc->sc_data_direction);
941 sc->host_scribble = NULL;
942 sc->result = DID_NO_CONNECT << 16;
949 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
951 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
953 * mptscsih_report_queue_full - Report QUEUE_FULL status returned
954 * from a SCSI target device.
955 * @sc: Pointer to scsi_cmnd structure
956 * @pScsiReply: Pointer to SCSIIOReply_t
957 * @pScsiReq: Pointer to original SCSI request
959 * This routine periodically reports QUEUE_FULL status returned from a
960 * SCSI target device. It reports this to the console via kernel
961 * printk() API call, not more than once every 10 seconds.
964 mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq)
969 if (sc->device == NULL)
971 if (sc->device->host == NULL)
973 if ((hd = (MPT_SCSI_HOST *)sc->device->host->hostdata) == NULL)
976 if (time - hd->last_queue_full > 10 * HZ) {
977 dprintk((MYIOC_s_WARN_FMT "Device (%d:%d:%d) reported QUEUE_FULL!\n",
978 hd->ioc->name, 0, sc->device->id, sc->device->lun));
979 hd->last_queue_full = time;
983 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
985 * mptscsih_remove - Removed scsi devices
986 * @pdev: Pointer to pci_dev structure
991 mptscsih_remove(struct pci_dev *pdev)
993 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
994 struct Scsi_Host *host = ioc->sh;
996 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1007 scsi_remove_host(host);
1009 if((hd = (MPT_SCSI_HOST *)host->hostdata) == NULL)
1012 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1013 /* Check DV thread active */
1015 spin_lock_irqsave(&dvtaskQ_lock, flags);
1016 if (dvtaskQ_active) {
1017 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
1018 while(dvtaskQ_active && --count)
1019 schedule_timeout_interruptible(1);
1021 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
1024 printk(KERN_ERR MYNAM ": ERROR - DV thread still active!\n");
1025 #if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY)
1027 printk(KERN_ERR MYNAM ": DV thread orig %d, count %d\n", 10 * HZ, count);
1031 mptscsih_shutdown(pdev);
1035 if (hd->ScsiLookup != NULL) {
1036 sz1 = hd->ioc->req_depth * sizeof(void *);
1037 kfree(hd->ScsiLookup);
1038 hd->ScsiLookup = NULL;
1042 * Free pointer array.
1047 dprintk((MYIOC_s_INFO_FMT
1048 "Free'd ScsiLookup (%d) memory\n",
1049 hd->ioc->name, sz1));
1051 kfree(hd->info_kbuf);
1053 /* NULL the Scsi_Host pointer
1057 scsi_host_put(host);
1063 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1065 * mptscsih_shutdown - reboot notifier
1069 mptscsih_shutdown(struct pci_dev *pdev)
1071 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1072 struct Scsi_Host *host = ioc->sh;
1078 hd = (MPT_SCSI_HOST *)host->hostdata;
1083 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1085 * mptscsih_suspend - Fusion MPT scsi driver suspend routine.
1090 mptscsih_suspend(struct pci_dev *pdev, pm_message_t state)
1092 mptscsih_shutdown(pdev);
1093 return mpt_suspend(pdev,state);
1096 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1098 * mptscsih_resume - Fusion MPT scsi driver resume routine.
1103 mptscsih_resume(struct pci_dev *pdev)
1105 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1106 struct Scsi_Host *host = ioc->sh;
1114 hd = (MPT_SCSI_HOST *)host->hostdata;
1118 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1120 unsigned long lflags;
1121 spin_lock_irqsave(&dvtaskQ_lock, lflags);
1122 if (!dvtaskQ_active) {
1124 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1125 INIT_WORK(&dvTaskQ_task,
1126 mptscsih_domainValidation, (void *) hd);
1127 schedule_work(&dvTaskQ_task);
1129 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1138 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1140 * mptscsih_info - Return information about MPT adapter
1141 * @SChost: Pointer to Scsi_Host structure
1143 * (linux scsi_host_template.info routine)
1145 * Returns pointer to buffer where information was written.
1148 mptscsih_info(struct Scsi_Host *SChost)
1153 h = (MPT_SCSI_HOST *)SChost->hostdata;
1156 if (h->info_kbuf == NULL)
1157 if ((h->info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)
1158 return h->info_kbuf;
1159 h->info_kbuf[0] = '\0';
1161 mpt_print_ioc_summary(h->ioc, h->info_kbuf, &size, 0, 0);
1162 h->info_kbuf[size-1] = '\0';
1165 return h->info_kbuf;
1176 mptscsih_copy_mem_info(struct info_str *info, char *data, int len)
1178 if (info->pos + len > info->length)
1179 len = info->length - info->pos;
1181 if (info->pos + len < info->offset) {
1186 if (info->pos < info->offset) {
1187 data += (info->offset - info->pos);
1188 len -= (info->offset - info->pos);
1192 memcpy(info->buffer + info->pos, data, len);
1198 mptscsih_copy_info(struct info_str *info, char *fmt, ...)
1204 va_start(args, fmt);
1205 len = vsprintf(buf, fmt, args);
1208 mptscsih_copy_mem_info(info, buf, len);
1213 mptscsih_host_info(MPT_ADAPTER *ioc, char *pbuf, off_t offset, int len)
1215 struct info_str info;
1219 info.offset = offset;
1222 mptscsih_copy_info(&info, "%s: %s, ", ioc->name, ioc->prod_name);
1223 mptscsih_copy_info(&info, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING, ioc->facts.FWVersion.Word);
1224 mptscsih_copy_info(&info, "Ports=%d, ", ioc->facts.NumberOfPorts);
1225 mptscsih_copy_info(&info, "MaxQ=%d\n", ioc->req_depth);
1227 return ((info.pos > info.offset) ? info.pos - info.offset : 0);
1230 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1232 * mptscsih_proc_info - Return information about MPT adapter
1234 * (linux scsi_host_template.info routine)
1236 * buffer: if write, user data; if read, buffer for user
1237 * length: if write, return length;
1238 * offset: if write, 0; if read, the current offset into the buffer from
1239 * the previous read.
1240 * hostno: scsi host number
1241 * func: if write = 1; if read = 0
1244 mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
1245 int length, int func)
1247 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
1248 MPT_ADAPTER *ioc = hd->ioc;
1253 * write is not supported
1259 size = mptscsih_host_info(ioc, buffer, offset, length);
1265 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1266 #define ADD_INDEX_LOG(req_ent) do { } while(0)
1268 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1270 * mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine.
1271 * @SCpnt: Pointer to scsi_cmnd structure
1272 * @done: Pointer SCSI mid-layer IO completion function
1274 * (linux scsi_host_template.queuecommand routine)
1275 * This is the primary SCSI IO start routine. Create a MPI SCSIIORequest
1276 * from a linux scsi_cmnd request and send it to the IOC.
1278 * Returns 0. (rtn value discarded by linux scsi mid-layer)
1281 mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1285 SCSIIORequest_t *pScsiReq;
1286 VirtDevice *vdev = SCpnt->device->hostdata;
1295 hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata;
1296 lun = SCpnt->device->lun;
1297 SCpnt->scsi_done = done;
1299 dmfprintk((MYIOC_s_INFO_FMT "qcmd: SCpnt=%p, done()=%p\n",
1300 (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt, done));
1302 if (hd->resetPending) {
1303 dtmprintk((MYIOC_s_WARN_FMT "qcmd: SCpnt=%p timeout + 60HZ\n",
1304 (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt));
1305 return SCSI_MLQUEUE_HOST_BUSY;
1309 * Put together a MPT SCSI request...
1311 if ((mf = mpt_get_msg_frame(hd->ioc->DoneCtx, hd->ioc)) == NULL) {
1312 dprintk((MYIOC_s_WARN_FMT "QueueCmd, no msg frames!!\n",
1314 return SCSI_MLQUEUE_HOST_BUSY;
1317 pScsiReq = (SCSIIORequest_t *) mf;
1319 my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
1321 ADD_INDEX_LOG(my_idx);
1323 /* TUR's being issued with scsictl=0x02000000 (DATA_IN)!
1324 * Seems we may receive a buffer (datalen>0) even when there
1325 * will be no data transfer! GRRRRR...
1327 if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
1328 datalen = SCpnt->request_bufflen;
1329 scsidir = MPI_SCSIIO_CONTROL_READ; /* DATA IN (host<--ioc<--dev) */
1330 } else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
1331 datalen = SCpnt->request_bufflen;
1332 scsidir = MPI_SCSIIO_CONTROL_WRITE; /* DATA OUT (host-->ioc-->dev) */
1335 scsidir = MPI_SCSIIO_CONTROL_NODATATRANSFER;
1338 /* Default to untagged. Once a target structure has been allocated,
1339 * use the Inquiry data to determine if device supports tagged.
1342 && (vdev->vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)
1343 && (SCpnt->device->tagged_supported)) {
1344 scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
1346 scsictl = scsidir | MPI_SCSIIO_CONTROL_UNTAGGED;
1349 /* Use the above information to set up the message frame
1351 pScsiReq->TargetID = (u8) vdev->target_id;
1352 pScsiReq->Bus = vdev->bus_id;
1353 pScsiReq->ChainOffset = 0;
1354 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
1355 pScsiReq->CDBLength = SCpnt->cmd_len;
1356 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
1357 pScsiReq->Reserved = 0;
1358 pScsiReq->MsgFlags = mpt_msg_flags();
1359 pScsiReq->LUN[0] = 0;
1360 pScsiReq->LUN[1] = lun;
1361 pScsiReq->LUN[2] = 0;
1362 pScsiReq->LUN[3] = 0;
1363 pScsiReq->LUN[4] = 0;
1364 pScsiReq->LUN[5] = 0;
1365 pScsiReq->LUN[6] = 0;
1366 pScsiReq->LUN[7] = 0;
1367 pScsiReq->Control = cpu_to_le32(scsictl);
1370 * Write SCSI CDB into the message
1372 cmd_len = SCpnt->cmd_len;
1373 for (ii=0; ii < cmd_len; ii++)
1374 pScsiReq->CDB[ii] = SCpnt->cmnd[ii];
1376 for (ii=cmd_len; ii < 16; ii++)
1377 pScsiReq->CDB[ii] = 0;
1380 pScsiReq->DataLength = cpu_to_le32(datalen);
1382 /* SenseBuffer low address */
1383 pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
1384 + (my_idx * MPT_SENSE_BUFFER_ALLOC));
1386 /* Now add the SG list
1387 * Always have a SGE even if null length.
1390 /* Add a NULL SGE */
1391 mptscsih_add_sge((char *)&pScsiReq->SGL, MPT_SGE_FLAGS_SSIMPLE_READ | 0,
1394 /* Add a 32 or 64 bit SGE */
1395 if (mptscsih_AddSGE(hd->ioc, SCpnt, pScsiReq, my_idx) != SUCCESS)
1399 hd->ScsiLookup[my_idx] = SCpnt;
1400 SCpnt->host_scribble = NULL;
1402 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1403 if (hd->ioc->bus_type == SPI) {
1404 int dvStatus = hd->ioc->spi_data.dvStatus[vdev->target_id];
1407 if (dvStatus || hd->ioc->spi_data.forceDv) {
1409 if ((dvStatus & MPT_SCSICFG_NEED_DV) ||
1410 (hd->ioc->spi_data.forceDv & MPT_SCSICFG_NEED_DV)) {
1411 unsigned long lflags;
1412 /* Schedule DV if necessary */
1413 spin_lock_irqsave(&dvtaskQ_lock, lflags);
1414 if (!dvtaskQ_active) {
1416 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1417 INIT_WORK(&dvTaskQ_task, mptscsih_domainValidation, (void *) hd);
1419 schedule_work(&dvTaskQ_task);
1421 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1423 hd->ioc->spi_data.forceDv &= ~MPT_SCSICFG_NEED_DV;
1426 /* Trying to do DV to this target, extend timeout.
1427 * Wait to issue until flag is clear
1429 if (dvStatus & MPT_SCSICFG_DV_PENDING) {
1430 mod_timer(&SCpnt->eh_timeout, jiffies + 40 * HZ);
1434 /* Set the DV flags.
1436 if (dvStatus & MPT_SCSICFG_DV_NOT_DONE)
1437 mptscsih_set_dvflags(hd, SCpnt);
1445 mpt_put_msg_frame(hd->ioc->DoneCtx, hd->ioc, mf);
1446 dmfprintk((MYIOC_s_INFO_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n",
1447 hd->ioc->name, SCpnt, mf, my_idx));
1448 DBG_DUMP_REQUEST_FRAME(mf)
1452 hd->ScsiLookup[my_idx] = NULL;
1453 mptscsih_freeChainBuffers(hd->ioc, my_idx);
1454 mpt_free_msg_frame(hd->ioc, mf);
1455 return SCSI_MLQUEUE_HOST_BUSY;
1458 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1460 * mptscsih_freeChainBuffers - Function to free chain buffers associated
1461 * with a SCSI IO request
1462 * @hd: Pointer to the MPT_SCSI_HOST instance
1463 * @req_idx: Index of the SCSI IO request frame.
1465 * Called if SG chain buffer allocation fails and mptscsih callbacks.
1469 mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
1471 MPT_FRAME_HDR *chain;
1472 unsigned long flags;
1476 /* Get the first chain index and reset
1479 chain_idx = ioc->ReqToChain[req_idx];
1480 ioc->ReqToChain[req_idx] = MPT_HOST_NO_CHAIN;
1482 while (chain_idx != MPT_HOST_NO_CHAIN) {
1484 /* Save the next chain buffer index */
1485 next = ioc->ChainToChain[chain_idx];
1487 /* Free this chain buffer and reset
1490 ioc->ChainToChain[chain_idx] = MPT_HOST_NO_CHAIN;
1492 chain = (MPT_FRAME_HDR *) (ioc->ChainBuffer
1493 + (chain_idx * ioc->req_sz));
1495 spin_lock_irqsave(&ioc->FreeQlock, flags);
1496 list_add_tail(&chain->u.frame.linkage.list, &ioc->FreeChainQ);
1497 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1499 dmfprintk((MYIOC_s_INFO_FMT "FreeChainBuffers (index %d)\n",
1500 ioc->name, chain_idx));
1508 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1513 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1515 * mptscsih_TMHandler - Generic handler for SCSI Task Management.
1516 * Fall through to mpt_HardResetHandler if: not operational, too many
1517 * failed TM requests or handshake failure.
1519 * @ioc: Pointer to MPT_ADAPTER structure
1520 * @type: Task Management type
1521 * @target: Logical Target ID for reset (if appropriate)
1522 * @lun: Logical Unit for reset (if appropriate)
1523 * @ctx2abort: Context for the task to be aborted (if appropriate)
1525 * Remark: Currently invoked from a non-interrupt thread (_bh).
1527 * Remark: With old EH code, at most 1 SCSI TaskMgmt function per IOC
1530 * Returns 0 for SUCCESS or -1 if FAILED.
1533 mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout)
1539 unsigned long flags;
1541 /* If FW is being reloaded currently, return success to
1542 * the calling function.
1549 printk(KERN_ERR MYNAM " TMHandler" " NULL ioc!\n");
1552 dtmprintk((MYIOC_s_INFO_FMT "TMHandler Entered!\n", ioc->name));
1554 // SJR - CHECKME - Can we avoid this here?
1555 // (mpt_HardResetHandler has this check...)
1556 spin_lock_irqsave(&ioc->diagLock, flags);
1557 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)) {
1558 spin_unlock_irqrestore(&ioc->diagLock, flags);
1561 spin_unlock_irqrestore(&ioc->diagLock, flags);
1563 /* Wait a fixed amount of time for the TM pending flag to be cleared.
1564 * If we time out and not bus reset, then we return a FAILED status to the caller.
1565 * The call to mptscsih_tm_pending_wait() will set the pending flag if we are
1566 * successful. Otherwise, reload the FW.
1568 if (mptscsih_tm_pending_wait(hd) == FAILED) {
1569 if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
1570 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler abort: "
1571 "Timed out waiting for last TM (%d) to complete! \n",
1572 hd->ioc->name, hd->tmPending));
1574 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) {
1575 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler target reset: "
1576 "Timed out waiting for last TM (%d) to complete! \n",
1577 hd->ioc->name, hd->tmPending));
1579 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
1580 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler bus reset: "
1581 "Timed out waiting for last TM (%d) to complete! \n",
1582 hd->ioc->name, hd->tmPending));
1583 if (hd->tmPending & (1 << MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS))
1589 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
1590 hd->tmPending |= (1 << type);
1591 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1596 ioc_raw_state = mpt_GetIocState(hd->ioc, 0);
1598 #ifdef MPT_DEBUG_RESET
1599 if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) {
1600 printk(MYIOC_s_WARN_FMT
1601 "TM Handler: IOC Not operational(0x%x)!\n",
1602 hd->ioc->name, ioc_raw_state);
1606 if (doTask && ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL)
1607 && !(ioc_raw_state & MPI_DOORBELL_ACTIVE)) {
1609 /* Isse the Task Mgmt request.
1611 if (hd->hard_resets < -1)
1613 rc = mptscsih_IssueTaskMgmt(hd, type, channel, target, lun, ctx2abort, timeout);
1615 printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n", hd->ioc->name);
1617 dtmprintk((MYIOC_s_INFO_FMT "Issue of TaskMgmt Successful!\n", hd->ioc->name));
1621 /* Only fall through to the HRH if this is a bus reset
1623 if ((type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) && (rc ||
1624 ioc->reload_fw || (ioc->alt_ioc && ioc->alt_ioc->reload_fw))) {
1625 dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
1627 rc = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
1630 dtmprintk((MYIOC_s_INFO_FMT "TMHandler rc = %d!\n", hd->ioc->name, rc));
1636 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1638 * mptscsih_IssueTaskMgmt - Generic send Task Management function.
1639 * @hd: Pointer to MPT_SCSI_HOST structure
1640 * @type: Task Management type
1641 * @target: Logical Target ID for reset (if appropriate)
1642 * @lun: Logical Unit for reset (if appropriate)
1643 * @ctx2abort: Context for the task to be aborted (if appropriate)
1645 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
1646 * or a non-interrupt thread. In the former, must not call schedule().
1648 * Not all fields are meaningfull for all task types.
1650 * Returns 0 for SUCCESS, -999 for "no msg frames",
1651 * else other non-zero value returned.
1654 mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout)
1657 SCSITaskMgmt_t *pScsiTm;
1661 /* Return Fail to calling function if no message frames available.
1663 if ((mf = mpt_get_msg_frame(hd->ioc->TaskCtx, hd->ioc)) == NULL) {
1664 dfailprintk((MYIOC_s_ERR_FMT "IssueTaskMgmt, no msg frames!!\n",
1668 dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt request @ %p\n",
1669 hd->ioc->name, mf));
1671 /* Format the Request
1673 pScsiTm = (SCSITaskMgmt_t *) mf;
1674 pScsiTm->TargetID = target;
1675 pScsiTm->Bus = channel;
1676 pScsiTm->ChainOffset = 0;
1677 pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
1679 pScsiTm->Reserved = 0;
1680 pScsiTm->TaskType = type;
1681 pScsiTm->Reserved1 = 0;
1682 pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)
1683 ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0;
1685 for (ii= 0; ii < 8; ii++) {
1686 pScsiTm->LUN[ii] = 0;
1688 pScsiTm->LUN[1] = lun;
1690 for (ii=0; ii < 7; ii++)
1691 pScsiTm->Reserved2[ii] = 0;
1693 pScsiTm->TaskMsgContext = ctx2abort;
1695 dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt: ctx2abort (0x%08x) type=%d\n",
1696 hd->ioc->name, ctx2abort, type));
1698 DBG_DUMP_TM_REQUEST_FRAME((u32 *)pScsiTm);
1700 if ((retval = mpt_send_handshake_request(hd->ioc->TaskCtx, hd->ioc,
1701 sizeof(SCSITaskMgmt_t), (u32*)pScsiTm,
1703 dfailprintk((MYIOC_s_ERR_FMT "_send_handshake FAILED!"
1704 " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
1706 mpt_free_msg_frame(hd->ioc, mf);
1710 if(mptscsih_tm_wait_for_completion(hd, timeout) == FAILED) {
1711 dfailprintk((MYIOC_s_ERR_FMT "_wait_for_completion FAILED!"
1712 " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
1714 mpt_free_msg_frame(hd->ioc, mf);
1715 dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
1717 retval = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
1723 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1725 * mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant
1726 * @SCpnt: Pointer to scsi_cmnd structure, IO to be aborted
1728 * (linux scsi_host_template.eh_abort_handler routine)
1730 * Returns SUCCESS or FAILED.
1733 mptscsih_abort(struct scsi_cmnd * SCpnt)
1743 /* If we can't locate our host adapter structure, return FAILED status.
1745 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL) {
1746 SCpnt->result = DID_RESET << 16;
1747 SCpnt->scsi_done(SCpnt);
1748 dfailprintk((KERN_INFO MYNAM ": mptscsih_abort: "
1749 "Can't locate host! (sc=%p)\n",
1755 if (hd->resetPending) {
1759 if (hd->timeouts < -1)
1762 /* Find this command
1764 if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) {
1765 /* Cmd not found in ScsiLookup.
1768 SCpnt->result = DID_RESET << 16;
1769 dtmprintk((KERN_INFO MYNAM ": %s: mptscsih_abort: "
1770 "Command not in the active list! (sc=%p)\n",
1771 hd->ioc->name, SCpnt));
1775 printk(KERN_WARNING MYNAM ": %s: attempting task abort! (sc=%p)\n",
1776 hd->ioc->name, SCpnt);
1777 scsi_print_command(SCpnt);
1779 /* Most important! Set TaskMsgContext to SCpnt's MsgContext!
1780 * (the IO to be ABORT'd)
1782 * NOTE: Since we do not byteswap MsgContext, we do not
1783 * swap it here either. It is an opaque cookie to
1784 * the controller, so it does not matter. -DaveM
1786 mf = MPT_INDEX_2_MFPTR(hd->ioc, scpnt_idx);
1787 ctx2abort = mf->u.frame.hwhdr.msgctxu.MsgContext;
1789 hd->abortSCpnt = SCpnt;
1791 vdev = SCpnt->device->hostdata;
1792 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
1793 vdev->bus_id, vdev->target_id, vdev->lun,
1794 ctx2abort, 2 /* 2 second timeout */);
1796 printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n",
1798 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1803 if(retval != FAILED ) {
1805 hd->tmState = TM_STATE_NONE;
1810 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1812 * mptscsih_dev_reset - Perform a SCSI TARGET_RESET! new_eh variant
1813 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1815 * (linux scsi_host_template.eh_dev_reset_handler routine)
1817 * Returns SUCCESS or FAILED.
1820 mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
1826 /* If we can't locate our host adapter structure, return FAILED status.
1828 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1829 dtmprintk((KERN_INFO MYNAM ": mptscsih_dev_reset: "
1830 "Can't locate host! (sc=%p)\n",
1835 if (hd->resetPending)
1838 printk(KERN_WARNING MYNAM ": %s: attempting target reset! (sc=%p)\n",
1839 hd->ioc->name, SCpnt);
1840 scsi_print_command(SCpnt);
1842 vdev = SCpnt->device->hostdata;
1843 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
1844 vdev->bus_id, vdev->target_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)
1877 /* If we can't locate our host adapter structure, return FAILED status.
1879 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1880 dtmprintk((KERN_INFO MYNAM ": mptscsih_bus_reset: "
1881 "Can't locate host! (sc=%p)\n",
1886 printk(KERN_WARNING MYNAM ": %s: attempting bus reset! (sc=%p)\n",
1887 hd->ioc->name, SCpnt);
1888 scsi_print_command(SCpnt);
1890 if (hd->timeouts < -1)
1893 vdev = SCpnt->device->hostdata;
1894 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
1895 vdev->bus_id, 0, 0, 0, 5 /* 5 second timeout */);
1897 printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n",
1899 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1904 if(retval != FAILED ) {
1906 hd->tmState = TM_STATE_NONE;
1911 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1913 * mptscsih_host_reset - Perform a SCSI host adapter RESET!
1915 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1917 * (linux scsi_host_template.eh_host_reset_handler routine)
1919 * Returns SUCCESS or FAILED.
1922 mptscsih_host_reset(struct scsi_cmnd *SCpnt)
1925 int status = SUCCESS;
1927 /* If we can't locate the host to reset, then we failed. */
1928 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1929 dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
1930 "Can't locate host! (sc=%p)\n",
1935 printk(KERN_WARNING MYNAM ": %s: Attempting host reset! (sc=%p)\n",
1936 hd->ioc->name, SCpnt);
1938 /* If our attempts to reset the host failed, then return a failed
1939 * status. The host will be taken off line by the SCSI mid-layer.
1941 if (mpt_HardResetHandler(hd->ioc, CAN_SLEEP) < 0){
1944 /* Make sure TM pending is cleared and TM state is set to
1948 hd->tmState = TM_STATE_NONE;
1951 dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
1953 (status == SUCCESS) ? "SUCCESS" : "FAILED" ) );
1958 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1960 * mptscsih_tm_pending_wait - wait for pending task management request to
1962 * @hd: Pointer to MPT host structure.
1964 * Returns {SUCCESS,FAILED}.
1967 mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd)
1969 unsigned long flags;
1970 int loop_count = 4 * 10; /* Wait 10 seconds */
1971 int status = FAILED;
1974 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
1975 if (hd->tmState == TM_STATE_NONE) {
1976 hd->tmState = TM_STATE_IN_PROGRESS;
1978 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1982 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1984 } while (--loop_count);
1989 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1991 * mptscsih_tm_wait_for_completion - wait for completion of TM task
1992 * @hd: Pointer to MPT host structure.
1994 * Returns {SUCCESS,FAILED}.
1997 mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout )
1999 unsigned long flags;
2000 int loop_count = 4 * timeout;
2001 int status = FAILED;
2004 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
2005 if(hd->tmPending == 0) {
2007 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2010 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2011 msleep_interruptible(250);
2012 } while (--loop_count);
2017 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2019 * mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
2020 * @ioc: Pointer to MPT_ADAPTER structure
2021 * @mf: Pointer to SCSI task mgmt request frame
2022 * @mr: Pointer to SCSI task mgmt reply frame
2024 * This routine is called from mptbase.c::mpt_interrupt() at the completion
2025 * of any SCSI task management request.
2026 * This routine is registered with the MPT (base) driver at driver
2027 * load/init time via the mpt_register() API call.
2029 * Returns 1 indicating alloc'd request frame ptr should be freed.
2032 mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
2034 SCSITaskMgmtReply_t *pScsiTmReply;
2035 SCSITaskMgmt_t *pScsiTmReq;
2037 unsigned long flags;
2041 dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt completed (mf=%p,mr=%p)\n",
2042 ioc->name, mf, mr));
2044 /* Depending on the thread, a timer is activated for
2045 * the TM request. Delete this timer on completion of TM.
2046 * Decrement count of outstanding TM requests.
2048 hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
2050 dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt Complete: NULL Scsi Host Ptr\n",
2056 dtmprintk((MYIOC_s_WARN_FMT "ERROR! TaskMgmt Reply: NULL Request %p\n",
2060 pScsiTmReply = (SCSITaskMgmtReply_t*)mr;
2061 pScsiTmReq = (SCSITaskMgmt_t*)mf;
2063 /* Figure out if this was ABORT_TASK, TARGET_RESET, or BUS_RESET! */
2064 tmType = pScsiTmReq->TaskType;
2066 dtmprintk((MYIOC_s_WARN_FMT " TaskType = %d, TerminationCount=%d\n",
2067 ioc->name, tmType, le32_to_cpu(pScsiTmReply->TerminationCount)));
2068 DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply);
2070 iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2071 dtmprintk((MYIOC_s_WARN_FMT " SCSI TaskMgmt (%d) IOCStatus=%04x IOCLogInfo=%08x\n",
2072 ioc->name, tmType, iocstatus, le32_to_cpu(pScsiTmReply->IOCLogInfo)));
2073 /* Error? (anything non-zero?) */
2076 /* clear flags and continue.
2078 if (tmType == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK)
2079 hd->abortSCpnt = NULL;
2081 /* If an internal command is present
2082 * or the TM failed - reload the FW.
2083 * FC FW may respond FAILED to an ABORT
2085 if (tmType == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
2087 (iocstatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED)) {
2088 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0) {
2089 printk((KERN_WARNING
2090 " Firmware Reload FAILED!!\n"));
2095 dtmprintk((MYIOC_s_WARN_FMT " TaskMgmt SUCCESS\n", ioc->name));
2097 hd->abortSCpnt = NULL;
2102 spin_lock_irqsave(&ioc->FreeQlock, flags);
2104 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2105 hd->tmState = TM_STATE_NONE;
2110 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2112 * This is anyones guess quite frankly.
2115 mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
2116 sector_t capacity, int geom[])
2126 dummy = heads * sectors;
2127 cylinders = capacity;
2128 sector_div(cylinders,dummy);
2131 * Handle extended translation size for logical drives
2134 if ((ulong)capacity >= 0x200000) {
2137 dummy = heads * sectors;
2138 cylinders = capacity;
2139 sector_div(cylinders,dummy);
2145 geom[2] = cylinders;
2147 dprintk((KERN_NOTICE
2148 ": bios_param: Id=%i Lun=%i Channel=%i CHS=%i/%i/%i\n",
2149 sdev->id, sdev->lun,sdev->channel,(int)cylinders,heads,sectors));
2154 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2156 * OS entry point to allow host driver to alloc memory
2157 * for each scsi target. Called once per device the bus scan.
2158 * Return non-zero if allocation fails.
2161 mptscsih_target_alloc(struct scsi_target *starget)
2163 VirtTarget *vtarget;
2165 vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
2168 starget->hostdata = vtarget;
2172 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2174 * OS entry point to allow host driver to alloc memory
2175 * for each scsi device. Called once per device the bus scan.
2176 * Return non-zero if allocation fails.
2179 mptscsih_slave_alloc(struct scsi_device *sdev)
2181 struct Scsi_Host *host = sdev->host;
2182 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
2183 VirtTarget *vtarget;
2185 struct scsi_target *starget;
2187 vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
2189 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
2190 hd->ioc->name, sizeof(VirtDevice));
2194 vdev->ioc_id = hd->ioc->id;
2195 vdev->target_id = sdev->id;
2196 vdev->bus_id = sdev->channel;
2197 vdev->lun = sdev->lun;
2198 sdev->hostdata = vdev;
2200 starget = scsi_target(sdev);
2201 vtarget = starget->hostdata;
2202 vdev->vtarget = vtarget;
2204 if (vtarget->num_luns == 0) {
2205 hd->Targets[sdev->id] = vtarget;
2206 vtarget->ioc_id = hd->ioc->id;
2207 vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
2208 vtarget->target_id = sdev->id;
2209 vtarget->bus_id = sdev->channel;
2210 if (hd->ioc->bus_type == SPI) {
2211 if (hd->ioc->raid_data.isRaid & (1 << sdev->id)) {
2212 vtarget->raidVolume = 1;
2213 ddvtprintk((KERN_INFO
2214 "RAID Volume @ id %d\n", sdev->id));
2217 vtarget->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
2220 vtarget->num_luns++;
2225 * OS entry point to allow for host driver to free allocated memory
2226 * Called if no device present or device being unloaded
2229 mptscsih_target_destroy(struct scsi_target *starget)
2231 if (starget->hostdata)
2232 kfree(starget->hostdata);
2233 starget->hostdata = NULL;
2237 * OS entry point to allow for host driver to free allocated memory
2238 * Called if no device present or device being unloaded
2241 mptscsih_slave_destroy(struct scsi_device *sdev)
2243 struct Scsi_Host *host = sdev->host;
2244 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
2245 VirtTarget *vtarget;
2246 VirtDevice *vdevice;
2247 struct scsi_target *starget;
2249 starget = scsi_target(sdev);
2250 vtarget = starget->hostdata;
2251 vdevice = sdev->hostdata;
2253 mptscsih_search_running_cmds(hd, vdevice);
2254 vtarget->luns[0] &= ~(1 << vdevice->lun);
2255 vtarget->num_luns--;
2256 if (vtarget->num_luns == 0) {
2257 mptscsih_negotiate_to_asyn_narrow(hd, vtarget);
2258 if (hd->ioc->bus_type == SPI) {
2259 if (mptscsih_is_phys_disk(hd->ioc, vtarget->target_id)) {
2260 hd->ioc->spi_data.forceDv |= MPT_SCSICFG_RELOAD_IOC_PG3;
2262 hd->ioc->spi_data.dvStatus[vtarget->target_id] =
2263 MPT_SCSICFG_NEGOTIATE;
2264 if (!hd->negoNvram) {
2265 hd->ioc->spi_data.dvStatus[vtarget->target_id] |=
2266 MPT_SCSICFG_DV_NOT_DONE;
2270 hd->Targets[sdev->id] = NULL;
2272 mptscsih_synchronize_cache(hd, vdevice);
2274 sdev->hostdata = NULL;
2277 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2279 * mptscsih_change_queue_depth - This function will set a devices queue depth
2280 * @sdev: per scsi_device pointer
2281 * @qdepth: requested queue depth
2283 * Adding support for new 'change_queue_depth' api.
2286 mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
2288 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sdev->host->hostdata;
2289 VirtTarget *vtarget;
2290 struct scsi_target *starget;
2294 starget = scsi_target(sdev);
2295 vtarget = starget->hostdata;
2297 if (hd->ioc->bus_type == SPI) {
2298 if (vtarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) {
2299 if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
2301 else if (((vtarget->inq_data[0] & 0x1f) == 0x00) &&
2302 (vtarget->minSyncFactor <= MPT_ULTRA160 ))
2303 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2305 max_depth = MPT_SCSI_CMD_PER_DEV_LOW;
2307 /* error case - No Inq. Data */
2311 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2313 if (qdepth > max_depth)
2318 tagged = MSG_SIMPLE_TAG;
2320 scsi_adjust_queue_depth(sdev, tagged, qdepth);
2321 return sdev->queue_depth;
2325 * OS entry point to adjust the queue_depths on a per-device basis.
2326 * Called once per device the bus scan. Use it to force the queue_depth
2327 * member to 1 if a device does not support Q tags.
2328 * Return non-zero if fails.
2331 mptscsih_slave_configure(struct scsi_device *sdev)
2333 struct Scsi_Host *sh = sdev->host;
2334 VirtTarget *vtarget;
2335 VirtDevice *vdevice;
2336 struct scsi_target *starget;
2337 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sh->hostdata;
2338 int indexed_lun, lun_index;
2340 starget = scsi_target(sdev);
2341 vtarget = starget->hostdata;
2342 vdevice = sdev->hostdata;
2344 dsprintk((MYIOC_s_INFO_FMT
2345 "device @ %p, id=%d, LUN=%d, channel=%d\n",
2346 hd->ioc->name, sdev, sdev->id, sdev->lun, sdev->channel));
2347 if (hd->ioc->bus_type == SPI)
2348 dsprintk((MYIOC_s_INFO_FMT
2349 "sdtr %d wdtr %d ppr %d inq length=%d\n",
2350 hd->ioc->name, sdev->sdtr, sdev->wdtr,
2351 sdev->ppr, sdev->inquiry_len));
2353 if (sdev->id > sh->max_id) {
2354 /* error case, should never happen */
2355 scsi_adjust_queue_depth(sdev, 0, 1);
2356 goto slave_configure_exit;
2359 vdevice->configured_lun=1;
2360 lun_index = (vdevice->lun >> 5); /* 32 luns per lun_index */
2361 indexed_lun = (vdevice->lun % 32);
2362 vtarget->luns[lun_index] |= (1 << indexed_lun);
2363 mptscsih_initTarget(hd, vtarget, sdev->lun, sdev->inquiry,
2364 sdev->inquiry_len );
2365 mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH);
2367 dsprintk((MYIOC_s_INFO_FMT
2368 "Queue depth=%d, tflags=%x\n",
2369 hd->ioc->name, sdev->queue_depth, vtarget->tflags));
2371 if (hd->ioc->bus_type == SPI)
2372 dsprintk((MYIOC_s_INFO_FMT
2373 "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
2374 hd->ioc->name, vtarget->negoFlags, vtarget->maxOffset,
2375 vtarget->minSyncFactor));
2377 slave_configure_exit:
2379 dsprintk((MYIOC_s_INFO_FMT
2380 "tagged %d, simple %d, ordered %d\n",
2381 hd->ioc->name,sdev->tagged_supported, sdev->simple_tags,
2382 sdev->ordered_tags));
2387 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2389 * Private routines...
2392 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2393 /* Utility function to copy sense data from the scsi_cmnd buffer
2394 * to the FC and SCSI target structures.
2398 mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
2401 SCSIIORequest_t *pReq;
2402 u32 sense_count = le32_to_cpu(pScsiReply->SenseCount);
2404 /* Get target structure
2406 pReq = (SCSIIORequest_t *) mf;
2407 vdev = sc->device->hostdata;
2413 /* Copy the sense received into the scsi command block. */
2414 req_index = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2415 sense_data = ((u8 *)hd->ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC));
2416 memcpy(sc->sense_buffer, sense_data, SNS_LEN(sc));
2418 /* Log SMART data (asc = 0x5D, non-IM case only) if required.
2420 if ((hd->ioc->events) && (hd->ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) {
2421 if ((sense_data[12] == 0x5D) && (vdev->vtarget->raidVolume == 0)) {
2423 MPT_ADAPTER *ioc = hd->ioc;
2425 idx = ioc->eventContext % ioc->eventLogSize;
2426 ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
2427 ioc->events[idx].eventContext = ioc->eventContext;
2429 ioc->events[idx].data[0] = (pReq->LUN[1] << 24) ||
2430 (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) ||
2431 (sc->device->channel << 8) || sc->device->id;
2433 ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12];
2435 ioc->eventContext++;
2439 dprintk((MYIOC_s_INFO_FMT "Hmmm... SenseData len=0! (?)\n",
2445 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc)
2450 hd = (MPT_SCSI_HOST *) sc->device->host->hostdata;
2452 for (i = 0; i < hd->ioc->req_depth; i++) {
2453 if (hd->ScsiLookup[i] == sc) {
2461 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2463 mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2466 unsigned long flags;
2469 dtmprintk((KERN_WARNING MYNAM
2470 ": IOC %s_reset routed to SCSI host driver!\n",
2471 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
2472 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
2474 /* If a FW reload request arrives after base installed but
2475 * before all scsi hosts have been attached, then an alt_ioc
2476 * may have a NULL sh pointer.
2478 if ((ioc->sh == NULL) || (ioc->sh->hostdata == NULL))
2481 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2483 if (reset_phase == MPT_IOC_SETUP_RESET) {
2484 dtmprintk((MYIOC_s_WARN_FMT "Setup-Diag Reset\n", ioc->name));
2487 * 1. Set Hard Reset Pending Flag
2488 * All new commands go to doneQ
2490 hd->resetPending = 1;
2492 } else if (reset_phase == MPT_IOC_PRE_RESET) {
2493 dtmprintk((MYIOC_s_WARN_FMT "Pre-Diag Reset\n", ioc->name));
2495 /* 2. Flush running commands
2496 * Clean ScsiLookup (and associated memory)
2500 /* 2b. Reply to OS all known outstanding I/O commands.
2502 mptscsih_flush_running_cmds(hd);
2504 /* 2c. If there was an internal command that
2505 * has not completed, configuration or io request,
2506 * free these resources.
2509 del_timer(&hd->timer);
2510 mpt_free_msg_frame(ioc, hd->cmdPtr);
2513 dtmprintk((MYIOC_s_WARN_FMT "Pre-Reset complete.\n", ioc->name));
2516 dtmprintk((MYIOC_s_WARN_FMT "Post-Diag Reset\n", ioc->name));
2518 /* Once a FW reload begins, all new OS commands are
2519 * redirected to the doneQ w/ a reset status.
2520 * Init all control structures.
2523 /* ScsiLookup initialization
2525 for (ii=0; ii < hd->ioc->req_depth; ii++)
2526 hd->ScsiLookup[ii] = NULL;
2528 /* 2. Chain Buffer initialization
2531 /* 4. Renegotiate to all devices, if SPI
2533 if (ioc->bus_type == SPI) {
2534 dnegoprintk(("writeSDP1: ALL_IDS USE_NVRAM\n"));
2535 mptscsih_writeSDP1(hd, 0, 0, MPT_SCSICFG_ALL_IDS | MPT_SCSICFG_USE_NVRAM);
2538 /* 5. Enable new commands to be posted
2540 spin_lock_irqsave(&ioc->FreeQlock, flags);
2542 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2543 hd->resetPending = 0;
2544 hd->tmState = TM_STATE_NONE;
2546 /* 6. If there was an internal command,
2547 * wake this process up.
2551 * Wake up the original calling thread
2553 hd->pLocal = &hd->localReply;
2554 hd->pLocal->completion = MPT_SCANDV_DID_RESET;
2555 hd->scandv_wait_done = 1;
2556 wake_up(&hd->scandv_waitq);
2560 /* 7. Set flag to force DV and re-read IOC Page 3
2562 if (ioc->bus_type == SPI) {
2563 ioc->spi_data.forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
2564 ddvtprintk(("Set reload IOC Pg3 Flag\n"));
2567 dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name));
2571 return 1; /* currently means nothing really */
2574 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2575 /* work queue thread to clear the persitency table */
2577 mptscsih_sas_persist_clear_table(void * arg)
2579 MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg;
2581 mptbase_sas_persist_operation(ioc, MPI_SAS_OP_CLEAR_NOT_PRESENT);
2584 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2586 mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2589 u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
2591 devtprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
2594 if (ioc->sh == NULL ||
2595 ((hd = (MPT_SCSI_HOST *)ioc->sh->hostdata) == NULL))
2599 case MPI_EVENT_UNIT_ATTENTION: /* 03 */
2602 case MPI_EVENT_IOC_BUS_RESET: /* 04 */
2603 case MPI_EVENT_EXT_BUS_RESET: /* 05 */
2604 if (hd && (ioc->bus_type == SPI) && (hd->soft_resets < -1))
2607 case MPI_EVENT_LOGOUT: /* 09 */
2612 * CHECKME! Don't think we need to do
2613 * anything for these, but...
2615 case MPI_EVENT_RESCAN: /* 06 */
2616 case MPI_EVENT_LINK_STATUS_CHANGE: /* 07 */
2617 case MPI_EVENT_LOOP_STATE_CHANGE: /* 08 */
2619 * CHECKME! Falling thru...
2623 case MPI_EVENT_INTEGRATED_RAID: /* 0B */
2625 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
2626 pMpiEventDataRaid_t pRaidEventData =
2627 (pMpiEventDataRaid_t) pEvReply->Data;
2628 /* Domain Validation Needed */
2629 if (ioc->bus_type == SPI &&
2630 pRaidEventData->ReasonCode ==
2631 MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED)
2632 mptscsih_set_dvflags_raid(hd, pRaidEventData->PhysDiskNum);
2637 /* Persistent table is full. */
2638 case MPI_EVENT_PERSISTENT_TABLE_FULL:
2639 INIT_WORK(&mptscsih_persistTask,
2640 mptscsih_sas_persist_clear_table,(void *)ioc);
2641 schedule_work(&mptscsih_persistTask);
2644 case MPI_EVENT_NONE: /* 00 */
2645 case MPI_EVENT_LOG_DATA: /* 01 */
2646 case MPI_EVENT_STATE_CHANGE: /* 02 */
2647 case MPI_EVENT_EVENT_CHANGE: /* 0A */
2649 dprintk((KERN_INFO " Ignoring event (=%02Xh)\n", event));
2653 return 1; /* currently means nothing really */
2656 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2658 * mptscsih_initTarget - Target, LUN alloc/free functionality.
2659 * @hd: Pointer to MPT_SCSI_HOST structure
2660 * @vtarget: per target private data
2662 * @data: Pointer to data
2663 * @dlen: Number of INQUIRY bytes
2665 * NOTE: It's only SAFE to call this routine if data points to
2666 * sane & valid STANDARD INQUIRY data!
2668 * Allocate and initialize memory for this target.
2669 * Save inquiry data.
2673 mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, u8 lun, char *data, int dlen)
2679 dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n",
2680 hd->ioc->name, vtarget->bus_id, vtarget->target_id, lun, hd));
2683 * If the peripheral qualifier filter is enabled then if the target reports a 0x1
2684 * (i.e. The targer is capable of supporting the specified peripheral device type
2685 * on this logical unit; however, the physical device is not currently connected
2686 * to this logical unit) it will be converted to a 0x3 (i.e. The target is not
2687 * capable of supporting a physical device on this logical unit). This is to work
2688 * around a bug in th emid-layer in some distributions in which the mid-layer will
2689 * continue to try to communicate to the LUN and evntually create a dummy LUN.
2691 if (hd->mpt_pq_filter && dlen && (data[0] & 0xE0))
2694 /* Is LUN supported? If so, upper 2 bits will be 0
2695 * in first byte of inquiry data.
2700 if (vtarget == NULL)
2704 vtarget->type = data[0];
2706 if (hd->ioc->bus_type != SPI)
2709 if ((data[0] == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) {
2710 /* Treat all Processors as SAF-TE if
2711 * command line option is set */
2712 vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
2713 mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id);
2714 }else if ((data[0] == TYPE_PROCESSOR) &&
2715 !(vtarget->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) {
2717 vtarget->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
2718 if ( data[44] == 'S' &&
2724 vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
2725 mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id);
2729 if (!(vtarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY)) {
2730 inq_len = dlen < 8 ? dlen : 8;
2731 memcpy (vtarget->inq_data, data, inq_len);
2732 /* If have not done DV, set the DV flag.
2734 pSpi = &hd->ioc->spi_data;
2735 if ((data[0] == TYPE_TAPE) || (data[0] == TYPE_PROCESSOR)) {
2736 if (pSpi->dvStatus[vtarget->target_id] & MPT_SCSICFG_DV_NOT_DONE)
2737 pSpi->dvStatus[vtarget->target_id] |= MPT_SCSICFG_NEED_DV;
2739 vtarget->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
2741 data_56 = 0x0F; /* Default to full capabilities if Inq data length is < 57 */
2743 if ( (!(vtarget->tflags & MPT_TARGET_FLAGS_VALID_56))) {
2744 /* Update the target capabilities
2747 vtarget->tflags |= MPT_TARGET_FLAGS_VALID_56;
2750 mptscsih_setTargetNegoParms(hd, vtarget, data_56);
2752 /* Initial Inquiry may not request enough data bytes to
2753 * obtain byte 57. DV will; if target doesn't return
2754 * at least 57 bytes, data[56] will be zero. */
2756 if ( (!(vtarget->tflags & MPT_TARGET_FLAGS_VALID_56))) {
2757 /* Update the target capabilities
2760 vtarget->tflags |= MPT_TARGET_FLAGS_VALID_56;
2761 mptscsih_setTargetNegoParms(hd, vtarget, data_56);
2767 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2769 * Update the target negotiation parameters based on the
2770 * the Inquiry data, adapter capabilities, and NVRAM settings.
2774 mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target, char byte56)
2776 SpiCfgData *pspi_data = &hd->ioc->spi_data;
2777 int id = (int) target->target_id;
2779 VirtTarget *vtarget;
2781 u8 width = MPT_NARROW;
2782 u8 factor = MPT_ASYNC;
2784 u8 version, nfactor;
2787 target->negoFlags = pspi_data->noQas;
2789 /* noQas == 0 => device supports QAS. Need byte 56 of Inq to determine
2790 * support. If available, default QAS to off and allow enabling.
2791 * If not available, default QAS to on, turn off for non-disks.
2794 /* Set flags based on Inquiry data
2796 version = target->inq_data[2] & 0x07;
2799 factor = MPT_ULTRA2;
2800 offset = pspi_data->maxSyncOffset;
2801 target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
2803 if (target->inq_data[7] & 0x20) {
2807 if (target->inq_data[7] & 0x10) {
2808 factor = pspi_data->minSyncFactor;
2809 if (target->tflags & MPT_TARGET_FLAGS_VALID_56) {
2810 /* bits 2 & 3 show Clocking support */
2811 if ((byte56 & 0x0C) == 0)
2812 factor = MPT_ULTRA2;
2814 if ((byte56 & 0x03) == 0)
2815 factor = MPT_ULTRA160;
2817 factor = MPT_ULTRA320;
2820 ddvtprintk((KERN_INFO "Enabling QAS due to byte56=%02x on id=%d!\n", byte56, id));
2823 if (target->inq_data[0] == TYPE_TAPE) {
2825 target->negoFlags |= MPT_TAPE_NEGO_IDP;
2830 ddvtprintk((KERN_INFO "Enabling QAS on id=%d due to ~TARGET_FLAGS_VALID_56!\n", id));
2834 offset = pspi_data->maxSyncOffset;
2836 /* If RAID, never disable QAS
2837 * else if non RAID, do not disable
2838 * QAS if bit 1 is set
2839 * bit 1 QAS support, non-raid only
2842 if (target->raidVolume == 1) {
2851 if ( (target->inq_data[7] & 0x02) == 0) {
2852 target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
2855 /* Update tflags based on NVRAM settings. (SCSI only)
2857 if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
2858 nvram = pspi_data->nvram[id];
2859 nfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
2862 width = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
2865 /* Ensure factor is set to the
2866 * maximum of: adapter, nvram, inquiry
2869 if (nfactor < pspi_data->minSyncFactor )
2870 nfactor = pspi_data->minSyncFactor;
2872 factor = max(factor, nfactor);
2873 if (factor == MPT_ASYNC)
2884 /* Make sure data is consistent
2886 if ((!width) && (factor < MPT_ULTRA2)) {
2887 factor = MPT_ULTRA2;
2890 /* Save the data to the target structure.
2892 target->minSyncFactor = factor;
2893 target->maxOffset = offset;
2894 target->maxWidth = width;
2896 target->tflags |= MPT_TARGET_FLAGS_VALID_NEGO;
2898 /* Disable unused features.
2901 target->negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
2904 target->negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
2906 if ( factor > MPT_ULTRA320 )
2909 /* GEM, processor WORKAROUND
2911 if ((target->inq_data[0] == TYPE_PROCESSOR) || (target->inq_data[0] > 0x08)) {
2912 target->negoFlags |= (MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC);
2913 pspi_data->dvStatus[id] |= MPT_SCSICFG_BLK_NEGO;
2915 if (noQas && (pspi_data->noQas == 0)) {
2916 pspi_data->noQas |= MPT_TARGET_NO_NEGO_QAS;
2917 target->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
2919 /* Disable QAS in a mixed configuration case
2922 ddvtprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id));
2923 for (ii = 0; ii < id; ii++) {
2924 if ( (vtarget = hd->Targets[ii]) ) {
2925 vtarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
2926 mptscsih_writeSDP1(hd, 0, ii, vtarget->negoFlags);
2932 /* Write SDP1 on this I/O to this target */
2933 if (pspi_data->dvStatus[id] & MPT_SCSICFG_NEGOTIATE) {
2934 ddvtprintk((KERN_INFO "MPT_SCSICFG_NEGOTIATE on id=%d!\n", id));
2935 mptscsih_writeSDP1(hd, 0, id, hd->negoNvram);
2936 pspi_data->dvStatus[id] &= ~MPT_SCSICFG_NEGOTIATE;
2937 } else if (pspi_data->dvStatus[id] & MPT_SCSICFG_BLK_NEGO) {
2938 ddvtprintk((KERN_INFO "MPT_SCSICFG_BLK_NEGO on id=%d!\n", id));
2939 mptscsih_writeSDP1(hd, 0, id, MPT_SCSICFG_BLK_NEGO);
2940 pspi_data->dvStatus[id] &= ~MPT_SCSICFG_BLK_NEGO;
2944 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2946 * If no Target, bus reset on 1st I/O. Set the flag to
2947 * prevent any future negotiations to this device.
2950 mptscsih_no_negotiate(MPT_SCSI_HOST *hd, struct scsi_cmnd *sc)
2954 if ((vdev = sc->device->hostdata) != NULL)
2955 hd->ioc->spi_data.dvStatus[vdev->target_id] |= MPT_SCSICFG_BLK_NEGO;
2959 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2961 * SCSI Config Page functionality ...
2963 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2964 /* mptscsih_setDevicePage1Flags - add Requested and Configuration fields flags
2965 * based on width, factor and offset parameters.
2967 * @factor: sync factor
2968 * @offset: sync offset
2969 * @requestedPtr: pointer to requested values (updated)
2970 * @configurationPtr: pointer to configuration values (updated)
2971 * @flags: flags to block WDTR or SDTR negotiation
2975 * Remark: Called by writeSDP1 and _dv_params
2978 mptscsih_setDevicePage1Flags (u8 width, u8 factor, u8 offset, int *requestedPtr, int *configurationPtr, u8 flags)
2980 u8 nowide = flags & MPT_TARGET_NO_NEGO_WIDE;
2981 u8 nosync = flags & MPT_TARGET_NO_NEGO_SYNC;
2983 *configurationPtr = 0;
2984 *requestedPtr = width ? MPI_SCSIDEVPAGE1_RP_WIDE : 0;
2985 *requestedPtr |= (offset << 16) | (factor << 8);
2987 if (width && offset && !nowide && !nosync) {
2988 if (factor < MPT_ULTRA160) {
2989 *requestedPtr |= (MPI_SCSIDEVPAGE1_RP_IU + MPI_SCSIDEVPAGE1_RP_DT);
2990 if ((flags & MPT_TARGET_NO_NEGO_QAS) == 0)
2991 *requestedPtr |= MPI_SCSIDEVPAGE1_RP_QAS;
2992 if (flags & MPT_TAPE_NEGO_IDP)
2993 *requestedPtr |= 0x08000000;
2994 } else if (factor < MPT_ULTRA2) {
2995 *requestedPtr |= MPI_SCSIDEVPAGE1_RP_DT;
3000 *configurationPtr |= MPI_SCSIDEVPAGE1_CONF_WDTR_DISALLOWED;
3003 *configurationPtr |= MPI_SCSIDEVPAGE1_CONF_SDTR_DISALLOWED;
3008 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3009 /* mptscsih_writeSDP1 - write SCSI Device Page 1
3010 * @hd: Pointer to a SCSI Host Strucutre
3011 * @portnum: IOC port number
3012 * @target_id: writeSDP1 for single ID
3013 * @flags: MPT_SCSICFG_ALL_IDS, MPT_SCSICFG_USE_NVRAM, MPT_SCSICFG_BLK_NEGO
3015 * Return: -EFAULT if read of config page header fails
3018 * Remark: If a target has been found, the settings from the
3019 * target structure are used, else the device is set
3022 * Remark: Called during init and after a FW reload.
3023 * Remark: We do not wait for a return, write pages sequentially.
3026 mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
3028 MPT_ADAPTER *ioc = hd->ioc;
3030 SCSIDevicePage1_t *pData;
3031 VirtTarget *vtarget=NULL;
3036 u32 requested, configuration, flagsLength;
3038 int id = 0, maxid = 0;
3044 u8 maxwidth, maxoffset, maxfactor;
3046 if (ioc->spi_data.sdp1length == 0)
3049 if (flags & MPT_SCSICFG_ALL_IDS) {
3051 maxid = ioc->sh->max_id - 1;
3052 } else if (ioc->sh) {
3054 maxid = min_t(int, id, ioc->sh->max_id - 1);
3057 for (; id <= maxid; id++) {
3059 if (id == ioc->pfacts[portnum].PortSCSIID)
3062 /* Use NVRAM to get adapter and target maximums
3063 * Data over-riden by target structure information, if present
3065 maxwidth = ioc->spi_data.maxBusWidth;
3066 maxoffset = ioc->spi_data.maxSyncOffset;
3067 maxfactor = ioc->spi_data.minSyncFactor;
3068 if (ioc->spi_data.nvram && (ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
3069 nvram = ioc->spi_data.nvram[id];
3072 maxwidth = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
3074 if (maxoffset > 0) {
3075 maxfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
3076 if (maxfactor == 0) {
3078 maxfactor = MPT_ASYNC;
3080 } else if (maxfactor < ioc->spi_data.minSyncFactor) {
3081 maxfactor = ioc->spi_data.minSyncFactor;
3084 maxfactor = MPT_ASYNC;
3087 /* Set the negotiation flags.
3089 negoFlags = ioc->spi_data.noQas;
3091 negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
3094 negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
3096 if (flags & MPT_SCSICFG_USE_NVRAM) {
3105 //negoFlags = MPT_TARGET_NO_NEGO_SYNC;
3108 /* If id is not a raid volume, get the updated
3109 * transmission settings from the target structure.
3111 if (hd->Targets && (vtarget = hd->Targets[id]) && !vtarget->raidVolume) {
3112 width = vtarget->maxWidth;
3113 factor = vtarget->minSyncFactor;
3114 offset = vtarget->maxOffset;
3115 negoFlags = vtarget->negoFlags;
3118 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
3119 /* Force to async and narrow if DV has not been executed
3122 if ((hd->ioc->spi_data.dvStatus[id] & MPT_SCSICFG_DV_NOT_DONE) != 0) {
3129 if (flags & MPT_SCSICFG_BLK_NEGO)
3130 negoFlags |= MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC;
3132 mptscsih_setDevicePage1Flags(width, factor, offset,
3133 &requested, &configuration, negoFlags);
3134 dnegoprintk(("writeSDP1: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
3135 target_id, width, factor, offset, negoFlags, requested, configuration));
3137 /* Get a MF for this command.
3139 if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
3140 dfailprintk((MYIOC_s_WARN_FMT "write SDP1: no msg frames!\n",
3145 ddvprintk((MYIOC_s_INFO_FMT "WriteSDP1 (mf=%p, id=%d, req=0x%x, cfg=0x%x)\n",
3146 hd->ioc->name, mf, id, requested, configuration));
3149 /* Set the request and the data pointers.
3150 * Request takes: 36 bytes (32 bit SGE)
3151 * SCSI Device Page 1 requires 16 bytes
3152 * 40 + 16 <= size of SCSI IO Request = 56 bytes
3153 * and MF size >= 64 bytes.
3154 * Place data at end of MF.
3156 pReq = (Config_t *)mf;
3158 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3159 frameOffset = ioc->req_sz - sizeof(SCSIDevicePage1_t);
3161 pData = (SCSIDevicePage1_t *)((u8 *) mf + frameOffset);
3162 dataDma = ioc->req_frames_dma + (req_idx * ioc->req_sz) + frameOffset;
3164 /* Complete the request frame (same for all requests).
3166 pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
3168 pReq->ChainOffset = 0;
3169 pReq->Function = MPI_FUNCTION_CONFIG;
3170 pReq->ExtPageLength = 0;
3171 pReq->ExtPageType = 0;
3173 for (ii=0; ii < 8; ii++) {
3174 pReq->Reserved2[ii] = 0;
3176 pReq->Header.PageVersion = ioc->spi_data.sdp1version;
3177 pReq->Header.PageLength = ioc->spi_data.sdp1length;
3178 pReq->Header.PageNumber = 1;
3179 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
3180 pReq->PageAddress = cpu_to_le32(id | (bus << 8 ));
3182 /* Add a SGE to the config request.
3184 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE | ioc->spi_data.sdp1length * 4;
3186 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma);
3188 /* Set up the common data portion
3190 pData->Header.PageVersion = pReq->Header.PageVersion;
3191 pData->Header.PageLength = pReq->Header.PageLength;
3192 pData->Header.PageNumber = pReq->Header.PageNumber;
3193 pData->Header.PageType = pReq->Header.PageType;
3194 pData->RequestedParameters = cpu_to_le32(requested);
3195 pData->Reserved = 0;
3196 pData->Configuration = cpu_to_le32(configuration);
3198 dprintk((MYIOC_s_INFO_FMT
3199 "write SDP1: id %d pgaddr 0x%x req 0x%x config 0x%x\n",
3200 ioc->name, id, (id | (bus<<8)),
3201 requested, configuration));
3203 mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
3209 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3210 /* mptscsih_writeIOCPage4 - write IOC Page 4
3211 * @hd: Pointer to a SCSI Host Structure
3212 * @target_id: write IOC Page4 for this ID & Bus
3214 * Return: -EAGAIN if unable to obtain a Message Frame
3217 * Remark: We do not wait for a return, write pages sequentially.
3220 mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus)
3222 MPT_ADAPTER *ioc = hd->ioc;
3224 IOCPage4_t *IOCPage4Ptr;
3232 /* Get a MF for this command.
3234 if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
3235 dfailprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n",
3240 /* Set the request and the data pointers.
3241 * Place data at end of MF.
3243 pReq = (Config_t *)mf;
3245 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3246 frameOffset = ioc->req_sz - sizeof(IOCPage4_t);
3248 /* Complete the request frame (same for all requests).
3250 pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
3252 pReq->ChainOffset = 0;
3253 pReq->Function = MPI_FUNCTION_CONFIG;
3254 pReq->ExtPageLength = 0;
3255 pReq->ExtPageType = 0;
3257 for (ii=0; ii < 8; ii++) {
3258 pReq->Reserved2[ii] = 0;
3261 IOCPage4Ptr = ioc->spi_data.pIocPg4;
3262 dataDma = ioc->spi_data.IocPg4_dma;
3263 ii = IOCPage4Ptr->ActiveSEP++;
3264 IOCPage4Ptr->SEP[ii].SEPTargetID = target_id;
3265 IOCPage4Ptr->SEP[ii].SEPBus = bus;
3266 pReq->Header = IOCPage4Ptr->Header;
3267 pReq->PageAddress = cpu_to_le32(target_id | (bus << 8 ));
3269 /* Add a SGE to the config request.
3271 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE |
3272 (IOCPage4Ptr->Header.PageLength + ii) * 4;
3274 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma);
3276 dinitprintk((MYIOC_s_INFO_FMT
3277 "writeIOCPage4: MaxSEP=%d ActiveSEP=%d id=%d bus=%d\n",
3278 ioc->name, IOCPage4Ptr->MaxSEP, IOCPage4Ptr->ActiveSEP, target_id, bus));
3280 mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
3285 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3287 * Bus Scan and Domain Validation functionality ...
3290 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3292 * mptscsih_scandv_complete - Scan and DV callback routine registered
3293 * to Fustion MPT (base) driver.
3295 * @ioc: Pointer to MPT_ADAPTER structure
3296 * @mf: Pointer to original MPT request frame
3297 * @mr: Pointer to MPT reply frame (NULL if TurboReply)
3299 * This routine is called from mpt.c::mpt_interrupt() at the completion
3300 * of any SCSI IO request.
3301 * This routine is registered with the Fusion MPT (base) driver at driver
3302 * load/init time via the mpt_register() API call.
3304 * Returns 1 indicating alloc'd request frame ptr should be freed.
3306 * Remark: Sets a completion code and (possibly) saves sense data
3307 * in the IOC member localReply structure.
3308 * Used ONLY for DV and other internal commands.
3311 mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
3314 SCSIIORequest_t *pReq;
3318 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
3321 (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) {
3322 printk(MYIOC_s_ERR_FMT
3323 "ScanDvComplete, %s req frame ptr! (=%p)\n",
3324 ioc->name, mf?"BAD":"NULL", (void *) mf);
3328 del_timer(&hd->timer);
3329 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3330 hd->ScsiLookup[req_idx] = NULL;
3331 pReq = (SCSIIORequest_t *) mf;
3333 if (mf != hd->cmdPtr) {
3334 printk(MYIOC_s_WARN_FMT "ScanDvComplete (mf=%p, cmdPtr=%p, idx=%d)\n",
3335 hd->ioc->name, (void *)mf, (void *) hd->cmdPtr, req_idx);
3339 ddvprintk((MYIOC_s_INFO_FMT "ScanDvComplete (mf=%p,mr=%p,idx=%d)\n",
3340 hd->ioc->name, mf, mr, req_idx));
3342 hd->pLocal = &hd->localReply;
3343 hd->pLocal->scsiStatus = 0;
3345 /* If target struct exists, clear sense valid flag.
3348 completionCode = MPT_SCANDV_GOOD;
3350 SCSIIOReply_t *pReply;
3354 pReply = (SCSIIOReply_t *) mr;
3356 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
3357 scsi_status = pReply->SCSIStatus;
3359 ddvtprintk((KERN_NOTICE " IOCStatus=%04xh, SCSIState=%02xh, SCSIStatus=%02xh, IOCLogInfo=%08xh\n",
3360 status, pReply->SCSIState, scsi_status,
3361 le32_to_cpu(pReply->IOCLogInfo)));
3365 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
3366 completionCode = MPT_SCANDV_SELECTION_TIMEOUT;
3369 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
3370 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
3371 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
3372 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
3373 completionCode = MPT_SCANDV_DID_RESET;
3376 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
3377 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
3378 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
3379 if (pReply->Function == MPI_FUNCTION_CONFIG) {
3380 ConfigReply_t *pr = (ConfigReply_t *)mr;
3381 completionCode = MPT_SCANDV_GOOD;
3382 hd->pLocal->header.PageVersion = pr->Header.PageVersion;
3383 hd->pLocal->header.PageLength = pr->Header.PageLength;
3384 hd->pLocal->header.PageNumber = pr->Header.PageNumber;
3385 hd->pLocal->header.PageType = pr->Header.PageType;
3387 } else if (pReply->Function == MPI_FUNCTION_RAID_ACTION) {
3388 /* If the RAID Volume request is successful,
3389 * return GOOD, else indicate that
3390 * some type of error occurred.
3392 MpiRaidActionReply_t *pr = (MpiRaidActionReply_t *)mr;
3393 if (le16_to_cpu(pr->ActionStatus) == MPI_RAID_ACTION_ASTATUS_SUCCESS)
3394 completionCode = MPT_SCANDV_GOOD;
3396 completionCode = MPT_SCANDV_SOME_ERROR;
3398 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID) {
3402 /* save sense data in global structure
3404 completionCode = MPT_SCANDV_SENSE;
3405 hd->pLocal->scsiStatus = scsi_status;
3406 sense_data = ((u8 *)hd->ioc->sense_buf_pool +
3407 (req_idx * MPT_SENSE_BUFFER_ALLOC));
3409 sz = min_t(int, pReq->SenseBufferLength,
3410 SCSI_STD_SENSE_BYTES);
3411 memcpy(hd->pLocal->sense, sense_data, sz);
3413 ddvprintk((KERN_NOTICE " Check Condition, sense ptr %p\n",
3415 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_FAILED) {
3416 if (pReq->CDB[0] == INQUIRY)
3417 completionCode = MPT_SCANDV_ISSUE_SENSE;
3419 completionCode = MPT_SCANDV_DID_RESET;
3421 else if (pReply->SCSIState & MPI_SCSI_STATE_NO_SCSI_STATUS)
3422 completionCode = MPT_SCANDV_DID_RESET;
3423 else if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
3424 completionCode = MPT_SCANDV_DID_RESET;
3426 completionCode = MPT_SCANDV_GOOD;
3427 hd->pLocal->scsiStatus = scsi_status;
3431 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
3432 if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
3433 completionCode = MPT_SCANDV_DID_RESET;
3435 completionCode = MPT_SCANDV_SOME_ERROR;
3439 completionCode = MPT_SCANDV_SOME_ERROR;
3442 } /* switch(status) */
3444 ddvtprintk((KERN_NOTICE " completionCode set to %08xh\n",
3446 } /* end of address reply case */
3448 hd->pLocal->completion = completionCode;
3450 /* MF and RF are freed in mpt_interrupt
3453 /* Free Chain buffers (will never chain) in scan or dv */
3454 //mptscsih_freeChainBuffers(ioc, req_idx);
3457 * Wake up the original calling thread
3459 hd->scandv_wait_done = 1;
3460 wake_up(&hd->scandv_waitq);
3465 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3466 /* mptscsih_timer_expired - Call back for timer process.
3467 * Used only for dv functionality.
3468 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
3472 mptscsih_timer_expired(unsigned long data)
3474 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) data;
3476 ddvprintk((MYIOC_s_WARN_FMT "Timer Expired! Cmd %p\n", hd->ioc->name, hd->cmdPtr));
3479 MPIHeader_t *cmd = (MPIHeader_t *)hd->cmdPtr;
3481 if (cmd->Function == MPI_FUNCTION_SCSI_IO_REQUEST) {
3482 /* Desire to issue a task management request here.
3483 * TM requests MUST be single threaded.
3484 * If old eh code and no TM current, issue request.
3485 * If new eh code, do nothing. Wait for OS cmd timeout
3488 ddvtprintk((MYIOC_s_NOTE_FMT "DV Cmd Timeout: NoOp\n", hd->ioc->name));
3490 /* Perform a FW reload */
3491 if (mpt_HardResetHandler(hd->ioc, NO_SLEEP) < 0) {
3492 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", hd->ioc->name);
3496 /* This should NEVER happen */
3497 printk(MYIOC_s_WARN_FMT "Null cmdPtr!!!!\n", hd->ioc->name);
3500 /* No more processing.
3501 * TM call will generate an interrupt for SCSI TM Management.
3502 * The FW will reply to all outstanding commands, callback will finish cleanup.
3503 * Hard reset clean-up will free all resources.
3505 ddvprintk((MYIOC_s_WARN_FMT "Timer Expired Complete!\n", hd->ioc->name));
3510 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
3511 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3512 /* mptscsih_do_raid - Format and Issue a RAID volume request message.
3513 * @hd: Pointer to scsi host structure
3514 * @action: What do be done.
3515 * @id: Logical target id.
3516 * @bus: Target locations bus.
3518 * Returns: < 0 on a fatal error
3521 * Remark: Wait to return until reply processed by the ISR.
3524 mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io)
3526 MpiRaidActionRequest_t *pReq;
3530 in_isr = in_interrupt();
3532 dprintk((MYIOC_s_WARN_FMT "Internal raid request not allowed in ISR context!\n",
3537 /* Get and Populate a free Frame
3539 if ((mf = mpt_get_msg_frame(hd->ioc->InternalCtx, hd->ioc)) == NULL) {
3540 ddvprintk((MYIOC_s_WARN_FMT "_do_raid: no msg frames!\n",
3544 pReq = (MpiRaidActionRequest_t *)mf;
3545 pReq->Action = action;
3546 pReq->Reserved1 = 0;
3547 pReq->ChainOffset = 0;
3548 pReq->Function = MPI_FUNCTION_RAID_ACTION;
3549 pReq->VolumeID = io->id;
3550 pReq->VolumeBus = io->bus;
3551 pReq->PhysDiskNum = io->physDiskNum;
3553 pReq->Reserved2 = 0;
3554 pReq->ActionDataWord = 0; /* Reserved for this action */
3555 //pReq->ActionDataSGE = 0;
3557 mpt_add_sge((char *)&pReq->ActionDataSGE,
3558 MPT_SGE_FLAGS_SSIMPLE_READ | 0, (dma_addr_t) -1);
3560 ddvprintk((MYIOC_s_INFO_FMT "RAID Volume action %x id %d\n",
3561 hd->ioc->name, action, io->id));
3564 hd->timer.expires = jiffies + HZ*10; /* 10 second timeout */
3565 hd->scandv_wait_done = 0;
3567 /* Save cmd pointer, for resource free if timeout or
3572 add_timer(&hd->timer);
3573 mpt_put_msg_frame(hd->ioc->InternalCtx, hd->ioc, mf);
3574 wait_event(hd->scandv_waitq, hd->scandv_wait_done);
3576 if ((hd->pLocal == NULL) || (hd->pLocal->completion != MPT_SCANDV_GOOD))
3581 #endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */
3583 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3585 * mptscsih_do_cmd - Do internal command.
3586 * @hd: MPT_SCSI_HOST pointer
3587 * @io: INTERNAL_CMD pointer.
3589 * Issue the specified internally generated command and do command
3590 * specific cleanup. For bus scan / DV only.
3591 * NOTES: If command is Inquiry and status is good,
3592 * initialize a target structure, save the data
3594 * Remark: Single threaded access only.
3597 * < 0 if an illegal command or no resources
3601 * > 0 if command complete but some type of completion error.
3604 mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
3607 SCSIIORequest_t *pScsiReq;
3608 SCSIIORequest_t ReqCopy;
3609 int my_idx, ii, dir;
3613 char CDB[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
3616 in_isr = in_interrupt();
3618 dprintk((MYIOC_s_WARN_FMT "Internal SCSI IO request not allowed in ISR context!\n",
3624 /* Set command specific information
3629 dir = MPI_SCSIIO_CONTROL_READ;
3635 case TEST_UNIT_READY:
3637 dir = MPI_SCSIIO_CONTROL_READ;
3643 dir = MPI_SCSIIO_CONTROL_READ;
3645 CDB[4] = 1; /*Spin up the disk */
3653 dir = MPI_SCSIIO_CONTROL_READ;
3659 dir = MPI_SCSIIO_CONTROL_READ;
3661 if (io->flags & MPT_ICFLAG_ECHO) {
3667 if (io->flags & MPT_ICFLAG_BUF_CAP) {
3670 CDB[6] = (io->size >> 16) & 0xFF;
3671 CDB[7] = (io->size >> 8) & 0xFF;
3672 CDB[8] = io->size & 0xFF;
3678 dir = MPI_SCSIIO_CONTROL_WRITE;
3680 if (io->flags & MPT_ICFLAG_ECHO) {
3685 CDB[6] = (io->size >> 16) & 0xFF;
3686 CDB[7] = (io->size >> 8) & 0xFF;
3687 CDB[8] = io->size & 0xFF;
3693 dir = MPI_SCSIIO_CONTROL_READ;
3700 dir = MPI_SCSIIO_CONTROL_READ;
3705 case SYNCHRONIZE_CACHE:
3707 dir = MPI_SCSIIO_CONTROL_READ;
3709 // CDB[1] = 0x02; /* set immediate bit */
3718 /* Get and Populate a free Frame
3720 if ((mf = mpt_get_msg_frame(hd->ioc->InternalCtx, hd->ioc)) == NULL) {
3721 ddvprintk((MYIOC_s_WARN_FMT "No msg frames!\n",
3726 pScsiReq = (SCSIIORequest_t *) mf;
3728 /* Get the request index */
3729 my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3730 ADD_INDEX_LOG(my_idx); /* for debug */
3732 if (io->flags & MPT_ICFLAG_PHYS_DISK) {
3733 pScsiReq->TargetID = io->physDiskNum;
3735 pScsiReq->ChainOffset = 0;
3736 pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
3738 pScsiReq->TargetID = io->id;
3739 pScsiReq->Bus = io->bus;
3740 pScsiReq->ChainOffset = 0;
3741 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
3744 pScsiReq->CDBLength = cmdLen;
3745 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
3747 pScsiReq->Reserved = 0;
3749 pScsiReq->MsgFlags = mpt_msg_flags();
3750 /* MsgContext set in mpt_get_msg_fram call */
3752 for (ii=0; ii < 8; ii++)
3753 pScsiReq->LUN[ii] = 0;
3754 pScsiReq->LUN[1] = io->lun;
3756 if (io->flags & MPT_ICFLAG_TAGGED_CMD)
3757 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ);
3759 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3761 if (cmd == REQUEST_SENSE) {
3762 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3763 ddvprintk((MYIOC_s_INFO_FMT "Untagged! 0x%2x\n",
3764 hd->ioc->name, cmd));
3767 for (ii=0; ii < 16; ii++)
3768 pScsiReq->CDB[ii] = CDB[ii];
3770 pScsiReq->DataLength = cpu_to_le32(io->size);
3771 pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
3772 + (my_idx * MPT_SENSE_BUFFER_ALLOC));
3774 ddvprintk((MYIOC_s_INFO_FMT "Sending Command 0x%x for (%d:%d:%d)\n",
3775 hd->ioc->name, cmd, io->bus, io->id, io->lun));
3777 if (dir == MPI_SCSIIO_CONTROL_READ) {
3778 mpt_add_sge((char *) &pScsiReq->SGL,
3779 MPT_SGE_FLAGS_SSIMPLE_READ | io->size,
3782 mpt_add_sge((char *) &pScsiReq->SGL,
3783 MPT_SGE_FLAGS_SSIMPLE_WRITE | io->size,
3787 /* The ISR will free the request frame, but we need
3788 * the information to initialize the target. Duplicate.
3790 memcpy(&ReqCopy, pScsiReq, sizeof(SCSIIORequest_t));
3792 /* Issue this command after:
3795 * Wait until the reply has been received
3796 * ScsiScanDvCtx callback function will
3798 * set scandv_wait_done and call wake_up
3801 hd->timer.expires = jiffies + HZ*cmdTimeout;
3802 hd->scandv_wait_done = 0;
3804 /* Save cmd pointer, for resource free if timeout or
3809 add_timer(&hd->timer);
3810 mpt_put_msg_frame(hd->ioc->InternalCtx, hd->ioc, mf);
3811 wait_event(hd->scandv_waitq, hd->scandv_wait_done);
3814 rc = hd->pLocal->completion;
3815 hd->pLocal->skip = 0;
3817 /* Always set fatal error codes in some cases.
3819 if (rc == MPT_SCANDV_SELECTION_TIMEOUT)
3821 else if (rc == MPT_SCANDV_SOME_ERROR)
3825 /* This should never happen. */
3826 ddvprintk((MYIOC_s_INFO_FMT "_do_cmd: Null pLocal!!!\n",
3833 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3835 * mptscsih_negotiate_to_asyn_narrow - Restore devices to default state
3836 * @hd: Pointer to a SCSI HOST structure
3837 * @vtarget: per device private data
3839 * Uses the ISR, but with special processing.
3840 * MUST be single-threaded.
3844 mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtTarget *vtarget)
3846 MPT_ADAPTER *ioc= hd->ioc;
3847 SCSIDevicePage1_t *pcfg1Data;
3849 dma_addr_t cfg1_dma_addr;
3850 ConfigPageHeader_t header;
3852 int requested, configuration, data,i;
3855 if (ioc->bus_type != SPI)
3858 if (!ioc->spi_data.sdp1length)
3861 pcfg1Data = (SCSIDevicePage1_t *)pci_alloc_consistent(ioc->pcidev,
3862 ioc->spi_data.sdp1length * 4, &cfg1_dma_addr);
3864 if (pcfg1Data == NULL)
3867 header.PageVersion = ioc->spi_data.sdp1version;
3868 header.PageLength = ioc->spi_data.sdp1length;
3869 header.PageNumber = 1;
3870 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
3871 cfg.cfghdr.hdr = &header;
3872 cfg.physAddr = cfg1_dma_addr;
3873 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
3877 if (vtarget->raidVolume && ioc->raid_data.pIocPg3) {
3878 for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
3879 id = ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID;
3880 flags = hd->ioc->spi_data.noQas;
3881 if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
3882 data = hd->ioc->spi_data.nvram[id];
3883 if (data & MPT_NVRAM_WIDE_DISABLE)
3884 flags |= MPT_TARGET_NO_NEGO_WIDE;
3885 factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT;
3886 if ((factor == 0) || (factor == MPT_ASYNC))
3887 flags |= MPT_TARGET_NO_NEGO_SYNC;
3889 mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested,
3890 &configuration, flags);
3891 dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC "
3892 "offset=0 negoFlags=%x request=%x config=%x\n",
3893 id, flags, requested, configuration));
3894 pcfg1Data->RequestedParameters = cpu_to_le32(requested);
3895 pcfg1Data->Reserved = 0;
3896 pcfg1Data->Configuration = cpu_to_le32(configuration);
3897 cfg.pageAddr = (vtarget->bus_id<<8) | id;
3898 mpt_config(hd->ioc, &cfg);
3901 flags = vtarget->negoFlags;
3902 mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested,
3903 &configuration, flags);
3904 dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC "
3905 "offset=0 negoFlags=%x request=%x config=%x\n",
3906 vtarget->target_id, flags, requested, configuration));
3907 pcfg1Data->RequestedParameters = cpu_to_le32(requested);
3908 pcfg1Data->Reserved = 0;
3909 pcfg1Data->Configuration = cpu_to_le32(configuration);
3910 cfg.pageAddr = (vtarget->bus_id<<8) | vtarget->target_id;
3911 mpt_config(hd->ioc, &cfg);
3915 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pcfg1Data, cfg1_dma_addr);
3918 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3920 * mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
3921 * @hd: Pointer to a SCSI HOST structure
3922 * @vtarget: per device private data
3925 * Uses the ISR, but with special processing.
3926 * MUST be single-threaded.
3930 mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
3934 /* Following parameters will not change
3937 iocmd.cmd = SYNCHRONIZE_CACHE;
3939 iocmd.physDiskNum = -1;
3941 iocmd.data_dma = -1;
3943 iocmd.rsvd = iocmd.rsvd2 = 0;
3944 iocmd.bus = vdevice->bus_id;
3945 iocmd.id = vdevice->target_id;
3946 iocmd.lun = (u8)vdevice->lun;
3948 if ((vdevice->vtarget->type & TYPE_DISK) &&
3949 (vdevice->configured_lun))
3950 mptscsih_do_cmd(hd, &iocmd);
3953 /* Search IOC page 3 to determine if this is hidden physical disk
3955 /* Search IOC page 3 to determine if this is hidden physical disk
3958 mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id)
3962 if (!ioc->raid_data.isRaid || !ioc->raid_data.pIocPg3)
3965 for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
3966 if (id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID)
3973 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
3974 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3976 * mptscsih_domainValidation - Top level handler for domain validation.
3977 * @hd: Pointer to MPT_SCSI_HOST structure.
3979 * Uses the ISR, but with special processing.
3980 * Called from schedule, should not be in interrupt mode.
3981 * While thread alive, do dv for all devices needing dv
3986 mptscsih_domainValidation(void *arg)
3990 unsigned long flags;
3991 int id, maxid, dvStatus, did;
3994 spin_lock_irqsave(&dvtaskQ_lock, flags);
3996 if (dvtaskQ_release) {
3998 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4001 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4003 /* For this ioc, loop through all devices and do dv to each device.
4004 * When complete with this ioc, search through the ioc list, and
4005 * for each scsi ioc found, do dv for all devices. Exit when no
4011 list_for_each_entry(ioc, &ioc_list, list) {
4012 spin_lock_irqsave(&dvtaskQ_lock, flags);
4013 if (dvtaskQ_release) {
4015 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4018 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4022 /* DV only to SPI adapters */
4023 if (ioc->bus_type != SPI)
4026 /* Make sure everything looks ok */
4027 if (ioc->sh == NULL)
4030 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
4034 if ((ioc->spi_data.forceDv & MPT_SCSICFG_RELOAD_IOC_PG3) != 0) {
4035 mpt_read_ioc_pg_3(ioc);
4036 if (ioc->raid_data.pIocPg3) {
4037 Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
4038 int numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
4041 if (ioc->spi_data.dvStatus[pPDisk->PhysDiskID] & MPT_SCSICFG_DV_NOT_DONE)
4042 ioc->spi_data.dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV;
4048 ioc->spi_data.forceDv &= ~MPT_SCSICFG_RELOAD_IOC_PG3;
4051 maxid = min_t(int, ioc->sh->max_id, MPT_MAX_SCSI_DEVICES);
4053 for (id = 0; id < maxid; id++) {
4054 spin_lock_irqsave(&dvtaskQ_lock, flags);
4055 if (dvtaskQ_release) {
4057 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4060 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4061 dvStatus = hd->ioc->spi_data.dvStatus[id];
4063 if (dvStatus & MPT_SCSICFG_NEED_DV) {
4065 hd->ioc->spi_data.dvStatus[id] |= MPT_SCSICFG_DV_PENDING;
4066 hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_NEED_DV;
4070 /* If hidden phys disk, block IO's to all
4072 * else, process normally
4074 isPhysDisk = mptscsih_is_phys_disk(ioc, id);
4076 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4077 if (hd->ioc->raid_data.isRaid & (1 << ii)) {
4078 hd->ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_DV_PENDING;
4083 if(mpt_alt_ioc_wait(hd->ioc)!=0) {
4084 ddvprintk((MYIOC_s_WARN_FMT "alt_ioc busy!\n",
4089 if (mptscsih_doDv(hd, 0, id) == 1) {
4090 /* Untagged device was busy, try again
4092 hd->ioc->spi_data.dvStatus[id] |= MPT_SCSICFG_NEED_DV;
4093 hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_PENDING;
4095 /* DV is complete. Clear flags.
4097 hd->ioc->spi_data.dvStatus[id] &= ~(MPT_SCSICFG_DV_NOT_DONE | MPT_SCSICFG_DV_PENDING);
4100 spin_lock(&hd->ioc->initializing_hba_lock);
4101 hd->ioc->initializing_hba_lock_flag=0;
4102 spin_unlock(&hd->ioc->initializing_hba_lock);
4105 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4106 if (hd->ioc->raid_data.isRaid & (1 << ii)) {
4107 hd->ioc->spi_data.dvStatus[ii] &= ~MPT_SCSICFG_DV_PENDING;
4112 if (hd->ioc->spi_data.noQas)
4113 mptscsih_qas_check(hd, id);
4119 spin_lock_irqsave(&dvtaskQ_lock, flags);
4121 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4126 /* Write SDP1 if no QAS has been enabled
4129 mptscsih_qas_check(MPT_SCSI_HOST *hd, int id)
4131 VirtTarget *vtarget;
4134 if (hd->Targets == NULL)
4137 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4141 if ((hd->ioc->spi_data.dvStatus[ii] & MPT_SCSICFG_DV_NOT_DONE) != 0)
4144 vtarget = hd->Targets[ii];
4146 if ((vtarget != NULL) && (!vtarget->raidVolume)) {
4147 if ((vtarget->negoFlags & hd->ioc->spi_data.noQas) == 0) {
4148 vtarget->negoFlags |= hd->ioc->spi_data.noQas;
4149 dnegoprintk(("writeSDP1: id=%d flags=0\n", id));
4150 mptscsih_writeSDP1(hd, 0, ii, 0);
4153 if (mptscsih_is_phys_disk(hd->ioc, ii) == 1) {
4154 dnegoprintk(("writeSDP1: id=%d SCSICFG_USE_NVRAM\n", id));
4155 mptscsih_writeSDP1(hd, 0, ii, MPT_SCSICFG_USE_NVRAM);
4164 #define MPT_GET_NVRAM_VALS 0x01
4165 #define MPT_UPDATE_MAX 0x02
4166 #define MPT_SET_MAX 0x04
4167 #define MPT_SET_MIN 0x08
4168 #define MPT_FALLBACK 0x10
4169 #define MPT_SAVE 0x20
4171 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4173 * mptscsih_doDv - Perform domain validation to a target.
4174 * @hd: Pointer to MPT_SCSI_HOST structure.
4175 * @portnum: IOC port number.
4176 * @target: Physical ID of this target
4178 * Uses the ISR, but with special processing.
4179 * MUST be single-threaded.
4180 * Test will exit if target is at async & narrow.
4185 mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
4187 MPT_ADAPTER *ioc = hd->ioc;
4188 VirtTarget *vtarget;
4189 SCSIDevicePage1_t *pcfg1Data;
4190 SCSIDevicePage0_t *pcfg0Data;
4194 dma_addr_t dvbuf_dma = -1;
4195 dma_addr_t buf1_dma = -1;
4196 dma_addr_t buf2_dma = -1;
4197 dma_addr_t cfg1_dma_addr = -1;
4198 dma_addr_t cfg0_dma_addr = -1;
4199 ConfigPageHeader_t header1;
4200 ConfigPageHeader_t header0;
4207 int dataBufSize = 0;
4208 int echoBufSize = 0;
4213 int nfactor = MPT_ULTRA320;
4215 char doFallback = 0;
4220 if (ioc->spi_data.sdp1length == 0)
4223 if (ioc->spi_data.sdp0length == 0)
4226 /* If multiple buses are used, require that the initiator
4227 * id be the same on all buses.
4229 if (id == ioc->pfacts[0].PortSCSIID)
4233 bus = (u8) bus_number;
4234 ddvtprintk((MYIOC_s_NOTE_FMT
4235 "DV started: bus=%d, id=%d dv @ %p\n",
4236 ioc->name, bus, id, &dv));
4238 /* Prep DV structure
4240 memset (&dv, 0, sizeof(DVPARAMETERS));
4243 /* Populate tmax with the current maximum
4244 * transfer parameters for this target.
4245 * Exit if narrow and async.
4247 dv.cmd = MPT_GET_NVRAM_VALS;
4248 mptscsih_dv_parms(hd, &dv, NULL);
4250 /* Prep SCSI IO structure
4256 iocmd.physDiskNum = -1;
4257 iocmd.rsvd = iocmd.rsvd2 = 0;
4259 vtarget = hd->Targets[id];
4261 /* Use tagged commands if possible.
4264 if (vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)
4265 iocmd.flags |= MPT_ICFLAG_TAGGED_CMD;
4267 if (hd->ioc->facts.FWVersion.Word < 0x01000600)
4270 if ((hd->ioc->facts.FWVersion.Word >= 0x01010000) &&
4271 (hd->ioc->facts.FWVersion.Word < 0x01010B00))
4276 /* Prep cfg structure
4278 cfg.pageAddr = (bus<<8) | id;
4279 cfg.cfghdr.hdr = NULL;
4283 header0.PageVersion = ioc->spi_data.sdp0version;
4284 header0.PageLength = ioc->spi_data.sdp0length;
4285 header0.PageNumber = 0;
4286 header0.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4290 header1.PageVersion = ioc->spi_data.sdp1version;
4291 header1.PageLength = ioc->spi_data.sdp1length;
4292 header1.PageNumber = 1;
4293 header1.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4295 if (header0.PageLength & 1)
4296 dv_alloc = (header0.PageLength * 4) + 4;
4298 dv_alloc += (2048 + (header1.PageLength * 4));
4300 pDvBuf = pci_alloc_consistent(ioc->pcidev, dv_alloc, &dvbuf_dma);
4305 pbuf1 = (u8 *)pDvBuf;
4306 buf1_dma = dvbuf_dma;
4309 pbuf2 = (u8 *) (pDvBuf + sz);
4310 buf2_dma = dvbuf_dma + sz;
4313 pcfg0Data = (SCSIDevicePage0_t *) (pDvBuf + sz);
4314 cfg0_dma_addr = dvbuf_dma + sz;
4315 sz += header0.PageLength * 4;
4319 if (header0.PageLength & 1)
4322 pcfg1Data = (SCSIDevicePage1_t *) (pDvBuf + sz);
4323 cfg1_dma_addr = dvbuf_dma + sz;
4325 /* Skip this ID? Set cfg.cfghdr.hdr to force config page write
4328 SpiCfgData *pspi_data = &hd->ioc->spi_data;
4329 if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
4330 /* Set the factor from nvram */
4331 nfactor = (pspi_data->nvram[id] & MPT_NVRAM_SYNC_MASK) >> 8;
4332 if (nfactor < pspi_data->minSyncFactor )
4333 nfactor = pspi_data->minSyncFactor;
4335 if (!(pspi_data->nvram[id] & MPT_NVRAM_ID_SCAN_ENABLE) ||
4336 (pspi_data->PortFlags == MPI_SCSIPORTPAGE2_PORT_FLAGS_OFF_DV) ) {
4338 ddvprintk((MYIOC_s_NOTE_FMT "DV Skipped: bus, id, lun (%d, %d, %d)\n",
4339 ioc->name, bus, id, lun));
4341 dv.cmd = MPT_SET_MAX;
4342 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
4343 cfg.cfghdr.hdr = &header1;
4345 /* Save the final negotiated settings to
4346 * SCSI device page 1.
4348 cfg.physAddr = cfg1_dma_addr;
4349 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4351 mpt_config(hd->ioc, &cfg);
4357 /* Finish iocmd inititialization - hidden or visible disk? */
4358 if (ioc->raid_data.pIocPg3) {
4359 /* Search IOC page 3 for matching id
4361 Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
4362 int numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
4365 if (pPDisk->PhysDiskID == id) {
4367 iocmd.flags |= MPT_ICFLAG_PHYS_DISK;
4368 iocmd.physDiskNum = pPDisk->PhysDiskNum;
4372 if (mptscsih_do_raid(hd, MPI_RAID_ACTION_QUIESCE_PHYS_IO, &iocmd) < 0) {
4373 ddvprintk((MYIOC_s_ERR_FMT "RAID Queisce FAILED!\n", ioc->name));
4383 /* RAID Volume ID's may double for a physical device. If RAID but
4384 * not a physical ID as well, skip DV.
4386 if ((hd->ioc->raid_data.isRaid & (1 << id)) && !(iocmd.flags & MPT_ICFLAG_PHYS_DISK))
4391 * Async & Narrow - Inquiry
4392 * Async & Narrow - Inquiry
4393 * Maximum transfer rate - Inquiry
4395 * If compare, test complete.
4396 * If miscompare and first pass, repeat
4397 * If miscompare and not first pass, fall back and repeat
4401 sz = SCSI_MAX_INQUIRY_BYTES;
4402 rc = MPT_SCANDV_GOOD;
4404 ddvprintk((MYIOC_s_NOTE_FMT "DV: Start Basic test on id=%d\n", ioc->name, id));
4406 dv.cmd = MPT_SET_MIN;
4407 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
4409 cfg.cfghdr.hdr = &header1;
4410 cfg.physAddr = cfg1_dma_addr;
4411 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4413 if (mpt_config(hd->ioc, &cfg) != 0)
4416 /* Wide - narrow - wide workaround case
4418 if ((rc == MPT_SCANDV_ISSUE_SENSE) && dv.max.width) {
4419 /* Send an untagged command to reset disk Qs corrupted
4420 * when a parity error occurs on a Request Sense.
4422 if ((hd->ioc->facts.FWVersion.Word >= 0x01000600) ||
4423 ((hd->ioc->facts.FWVersion.Word >= 0x01010000) &&
4424 (hd->ioc->facts.FWVersion.Word < 0x01010B00)) ) {
4426 iocmd.cmd = REQUEST_SENSE;
4427 iocmd.data_dma = buf1_dma;
4430 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4433 if (hd->pLocal == NULL)
4435 rc = hd->pLocal->completion;
4436 if ((rc == MPT_SCANDV_GOOD) || (rc == MPT_SCANDV_SENSE)) {
4446 iocmd.cmd = INQUIRY;
4447 iocmd.data_dma = buf1_dma;
4450 memset(pbuf1, 0x00, sz);
4451 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4454 if (hd->pLocal == NULL)
4456 rc = hd->pLocal->completion;
4457 if (rc == MPT_SCANDV_GOOD) {
4458 if (hd->pLocal->scsiStatus == SAM_STAT_BUSY) {
4459 if ((iocmd.flags & MPT_ICFLAG_TAGGED_CMD) == 0)
4466 } else if (rc == MPT_SCANDV_SENSE) {
4469 /* If first command doesn't complete
4470 * with a good status or with a check condition,
4477 /* Reset the size for disks
4479 inq0 = (*pbuf1) & 0x1F;
4480 if ((inq0 == 0) && vtarget && !vtarget->raidVolume) {
4485 /* Another GEM workaround. Check peripheral device type,
4486 * if PROCESSOR, quit DV.
4488 if (inq0 == TYPE_PROCESSOR) {
4489 mptscsih_initTarget(hd,
4500 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4504 if ((vtarget->maxWidth == 1) && (vtarget->maxOffset) && (nfactor < 0x0A)
4505 && (vtarget->minSyncFactor > 0x09)) {
4506 if ((pbuf1[56] & 0x04) == 0)
4508 else if ((pbuf1[56] & 0x01) == 1) {
4509 vtarget->minSyncFactor =
4510 nfactor > MPT_ULTRA320 ? nfactor : MPT_ULTRA320;
4512 vtarget->minSyncFactor =
4513 nfactor > MPT_ULTRA160 ? nfactor : MPT_ULTRA160;
4516 dv.max.factor = vtarget->minSyncFactor;
4518 if ((pbuf1[56] & 0x02) == 0) {
4519 vtarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
4520 hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS;
4521 ddvprintk((MYIOC_s_NOTE_FMT
4522 "DV: Start Basic noQas on id=%d due to pbuf1[56]=%x\n",
4523 ioc->name, id, pbuf1[56]));
4529 dv.cmd = MPT_FALLBACK;
4531 dv.cmd = MPT_SET_MAX;
4533 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
4534 if (mpt_config(hd->ioc, &cfg) != 0)
4537 if ((!dv.now.width) && (!dv.now.offset))
4540 iocmd.cmd = INQUIRY;
4541 iocmd.data_dma = buf2_dma;
4544 memset(pbuf2, 0x00, sz);
4545 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4547 else if (hd->pLocal == NULL)
4550 /* Save the return code.
4551 * If this is the first pass,
4552 * read SCSI Device Page 0
4553 * and update the target max parameters.
4555 rc = hd->pLocal->completion;
4557 if (rc == MPT_SCANDV_GOOD) {
4562 cfg.cfghdr.hdr = &header0;
4563 cfg.physAddr = cfg0_dma_addr;
4564 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4567 if (mpt_config(hd->ioc, &cfg) != 0)
4570 sdp0_info = le32_to_cpu(pcfg0Data->Information) & 0x0E;
4571 sdp0_nego = (le32_to_cpu(pcfg0Data->NegotiatedParameters) & 0xFF00 ) >> 8;
4573 /* Quantum and Fujitsu workarounds.
4574 * Quantum: PPR U320 -> PPR reply with Ultra2 and wide
4575 * Fujitsu: PPR U320 -> Msg Reject and Ultra2 and wide
4576 * Resetart with a request for U160.
4578 if ((dv.now.factor == MPT_ULTRA320) && (sdp0_nego == MPT_ULTRA2)) {
4581 dv.cmd = MPT_UPDATE_MAX;
4582 mptscsih_dv_parms(hd, &dv, (void *)pcfg0Data);
4583 /* Update the SCSI device page 1 area
4585 pcfg1Data->RequestedParameters = pcfg0Data->NegotiatedParameters;
4590 /* Quantum workaround. Restart this test will the fallback
4593 if (doFallback == 0) {
4594 if (memcmp(pbuf1, pbuf2, sz) != 0) {
4598 ddvprintk((MYIOC_s_NOTE_FMT
4599 "DV:Inquiry compared id=%d, calling initTarget\n", ioc->name, id));
4600 hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_NOT_DONE;
4601 mptscsih_initTarget(hd,
4606 break; /* test complete */
4611 } else if (rc == MPT_SCANDV_ISSUE_SENSE)
4612 doFallback = 1; /* set fallback flag */
4613 else if ((rc == MPT_SCANDV_DID_RESET) ||
4614 (rc == MPT_SCANDV_SENSE) ||
4615 (rc == MPT_SCANDV_FALLBACK))
4616 doFallback = 1; /* set fallback flag */
4623 ddvprintk((MYIOC_s_NOTE_FMT "DV: Basic test on id=%d completed OK.\n", ioc->name, id));
4625 if (ioc->spi_data.mpt_dv == 0)
4628 inq0 = (*pbuf1) & 0x1F;
4630 /* Continue only for disks
4635 if ( ioc->spi_data.PortFlags == MPI_SCSIPORTPAGE2_PORT_FLAGS_BASIC_DV_ONLY )
4638 /* Start the Enhanced Test.
4639 * 0) issue TUR to clear out check conditions
4640 * 1) read capacity of echo (regular) buffer
4642 * 3) do write-read-compare data pattern test
4644 * 5) update nego parms to target struct
4646 cfg.cfghdr.hdr = &header1;
4647 cfg.physAddr = cfg1_dma_addr;
4648 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4651 iocmd.cmd = TEST_UNIT_READY;
4652 iocmd.data_dma = -1;
4657 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4660 if (hd->pLocal == NULL)
4663 rc = hd->pLocal->completion;
4664 if (rc == MPT_SCANDV_GOOD)
4666 else if (rc == MPT_SCANDV_SENSE) {
4667 u8 skey = hd->pLocal->sense[2] & 0x0F;
4668 u8 asc = hd->pLocal->sense[12];
4669 u8 ascq = hd->pLocal->sense[13];
4670 ddvprintk((MYIOC_s_INFO_FMT
4671 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
4672 ioc->name, skey, asc, ascq));
4674 if (skey == UNIT_ATTENTION)
4675 notDone++; /* repeat */
4676 else if ((skey == NOT_READY) &&
4677 (asc == 0x04)&&(ascq == 0x01)) {
4678 /* wait then repeat */
4681 } else if ((skey == NOT_READY) && (asc == 0x3A)) {
4682 /* no medium, try read test anyway */
4685 /* All other errors are fatal.
4687 ddvprintk((MYIOC_s_INFO_FMT "DV: fatal error.",
4695 iocmd.cmd = READ_BUFFER;
4696 iocmd.data_dma = buf1_dma;
4699 iocmd.flags |= MPT_ICFLAG_BUF_CAP;
4703 for (patt = 0; patt < 2; patt++) {
4705 iocmd.flags |= MPT_ICFLAG_ECHO;
4707 iocmd.flags &= ~MPT_ICFLAG_ECHO;
4713 /* If not ready after 8 trials,
4714 * give up on this device.
4719 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4721 else if (hd->pLocal == NULL)
4724 rc = hd->pLocal->completion;
4725 ddvprintk(("ReadBuffer Comp Code %d", rc));
4726 ddvprintk((" buff: %0x %0x %0x %0x\n",
4727 pbuf1[0], pbuf1[1], pbuf1[2], pbuf1[3]));
4729 if (rc == MPT_SCANDV_GOOD) {
4731 if (iocmd.flags & MPT_ICFLAG_ECHO) {
4732 bufsize = ((pbuf1[2] & 0x1F) <<8) | pbuf1[3];
4733 if (pbuf1[0] & 0x01)
4734 iocmd.flags |= MPT_ICFLAG_EBOS;
4736 bufsize = pbuf1[1]<<16 | pbuf1[2]<<8 | pbuf1[3];
4738 } else if (rc == MPT_SCANDV_SENSE) {
4739 u8 skey = hd->pLocal->sense[2] & 0x0F;
4740 u8 asc = hd->pLocal->sense[12];
4741 u8 ascq = hd->pLocal->sense[13];
4742 ddvprintk((MYIOC_s_INFO_FMT
4743 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
4744 ioc->name, skey, asc, ascq));
4745 if (skey == ILLEGAL_REQUEST) {
4747 } else if (skey == UNIT_ATTENTION) {
4748 notDone++; /* repeat */
4749 } else if ((skey == NOT_READY) &&
4750 (asc == 0x04)&&(ascq == 0x01)) {
4751 /* wait then repeat */
4755 /* All other errors are fatal.
4757 ddvprintk((MYIOC_s_INFO_FMT "DV: fatal error.",
4762 /* All other errors are fatal
4769 if (iocmd.flags & MPT_ICFLAG_ECHO)
4770 echoBufSize = bufsize;
4772 dataBufSize = bufsize;
4775 iocmd.flags &= ~MPT_ICFLAG_BUF_CAP;
4777 /* Use echo buffers if possible,
4778 * Exit if both buffers are 0.
4780 if (echoBufSize > 0) {
4781 iocmd.flags |= MPT_ICFLAG_ECHO;
4782 if (dataBufSize > 0)
4783 bufsize = min(echoBufSize, dataBufSize);
4785 bufsize = echoBufSize;
4786 } else if (dataBufSize == 0)
4789 ddvprintk((MYIOC_s_INFO_FMT "%s Buffer Capacity %d\n", ioc->name,
4790 (iocmd.flags & MPT_ICFLAG_ECHO) ? "Echo" : " ", bufsize));
4792 /* Data buffers for write-read-compare test max 1K.
4794 sz = min(bufsize, 1024);
4797 * On first pass, always issue a reserve.
4798 * On additional loops, only if a reset has occurred.
4799 * iocmd.flags indicates if echo or regular buffer
4801 for (patt = 0; patt < 4; patt++) {
4802 ddvprintk(("Pattern %d\n", patt));
4803 if ((iocmd.flags & MPT_ICFLAG_RESERVED) && (iocmd.flags & MPT_ICFLAG_DID_RESET)) {
4804 iocmd.cmd = TEST_UNIT_READY;
4805 iocmd.data_dma = -1;
4808 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4811 iocmd.cmd = RELEASE;
4812 iocmd.data_dma = -1;
4815 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4817 else if (hd->pLocal == NULL)
4820 rc = hd->pLocal->completion;
4821 ddvprintk(("Release rc %d\n", rc));
4822 if (rc == MPT_SCANDV_GOOD)
4823 iocmd.flags &= ~MPT_ICFLAG_RESERVED;
4827 iocmd.flags &= ~MPT_ICFLAG_RESERVED;
4829 iocmd.flags &= ~MPT_ICFLAG_DID_RESET;
4831 if (iocmd.flags & MPT_ICFLAG_EBOS)
4835 while (repeat && (!(iocmd.flags & MPT_ICFLAG_RESERVED))) {
4836 iocmd.cmd = RESERVE;
4837 iocmd.data_dma = -1;
4840 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4842 else if (hd->pLocal == NULL)
4845 rc = hd->pLocal->completion;
4846 if (rc == MPT_SCANDV_GOOD) {
4847 iocmd.flags |= MPT_ICFLAG_RESERVED;
4848 } else if (rc == MPT_SCANDV_SENSE) {
4849 /* Wait if coming ready
4851 u8 skey = hd->pLocal->sense[2] & 0x0F;
4852 u8 asc = hd->pLocal->sense[12];
4853 u8 ascq = hd->pLocal->sense[13];
4854 ddvprintk((MYIOC_s_INFO_FMT
4855 "DV: Reserve Failed: ", ioc->name));
4856 ddvprintk(("SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
4859 if ((skey == NOT_READY) && (asc == 0x04)&&
4861 /* wait then repeat */
4865 ddvprintk((MYIOC_s_INFO_FMT
4866 "DV: Reserved Failed.", ioc->name));
4870 ddvprintk((MYIOC_s_INFO_FMT "DV: Reserved Failed.",
4878 mptscsih_fillbuf(pbuf1, sz, patt, 1);
4879 iocmd.cmd = WRITE_BUFFER;
4880 iocmd.data_dma = buf1_dma;
4883 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4885 else if (hd->pLocal == NULL)
4888 rc = hd->pLocal->completion;
4889 if (rc == MPT_SCANDV_GOOD)
4890 ; /* Issue read buffer */
4891 else if (rc == MPT_SCANDV_DID_RESET) {
4892 /* If using echo buffers, reset to data buffers.
4893 * Else do Fallback and restart
4894 * this test (re-issue reserve
4895 * because of bus reset).
4897 if ((iocmd.flags & MPT_ICFLAG_ECHO) && (dataBufSize >= bufsize)) {
4898 iocmd.flags &= ~MPT_ICFLAG_ECHO;
4900 dv.cmd = MPT_FALLBACK;
4901 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
4903 if (mpt_config(hd->ioc, &cfg) != 0)
4906 if ((!dv.now.width) && (!dv.now.offset))
4910 iocmd.flags |= MPT_ICFLAG_DID_RESET;
4913 } else if (rc == MPT_SCANDV_SENSE) {
4914 /* Restart data test if UA, else quit.
4916 u8 skey = hd->pLocal->sense[2] & 0x0F;
4917 ddvprintk((MYIOC_s_INFO_FMT
4918 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n", ioc->name, skey,
4919 hd->pLocal->sense[12], hd->pLocal->sense[13]));
4920 if (skey == UNIT_ATTENTION) {
4923 } else if (skey == ILLEGAL_REQUEST) {
4924 if (iocmd.flags & MPT_ICFLAG_ECHO) {
4925 if (dataBufSize >= bufsize) {
4926 iocmd.flags &= ~MPT_ICFLAG_ECHO;
4941 iocmd.cmd = READ_BUFFER;
4942 iocmd.data_dma = buf2_dma;
4945 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4947 else if (hd->pLocal == NULL)
4950 rc = hd->pLocal->completion;
4951 if (rc == MPT_SCANDV_GOOD) {
4952 /* If buffers compare,
4953 * go to next pattern,
4954 * else, do a fallback and restart
4955 * data transfer test.
4957 if (memcmp (pbuf1, pbuf2, sz) == 0) {
4958 ; /* goto next pattern */
4960 /* Miscompare with Echo buffer, go to data buffer,
4961 * if that buffer exists.
4962 * Miscompare with Data buffer, check first 4 bytes,
4963 * some devices return capacity. Exit in this case.
4965 if (iocmd.flags & MPT_ICFLAG_ECHO) {
4966 if (dataBufSize >= bufsize)
4967 iocmd.flags &= ~MPT_ICFLAG_ECHO;
4971 if (dataBufSize == (pbuf2[1]<<16 | pbuf2[2]<<8 | pbuf2[3])) {
4972 /* Argh. Device returning wrong data.
4973 * Quit DV for this device.
4978 /* Had an actual miscompare. Slow down.*/
4979 dv.cmd = MPT_FALLBACK;
4980 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
4982 if (mpt_config(hd->ioc, &cfg) != 0)
4985 if ((!dv.now.width) && (!dv.now.offset))
4992 } else if (rc == MPT_SCANDV_DID_RESET) {
4993 /* Do Fallback and restart
4994 * this test (re-issue reserve
4995 * because of bus reset).
4997 dv.cmd = MPT_FALLBACK;
4998 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5000 if (mpt_config(hd->ioc, &cfg) != 0)
5003 if ((!dv.now.width) && (!dv.now.offset))
5006 iocmd.flags |= MPT_ICFLAG_DID_RESET;
5009 } else if (rc == MPT_SCANDV_SENSE) {
5010 /* Restart data test if UA, else quit.
5012 u8 skey = hd->pLocal->sense[2] & 0x0F;
5013 ddvprintk((MYIOC_s_INFO_FMT
5014 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n", ioc->name, skey,
5015 hd->pLocal->sense[12], hd->pLocal->sense[13]));
5016 if (skey == UNIT_ATTENTION) {
5028 } /* --- end of patt loop ---- */
5031 if (iocmd.flags & MPT_ICFLAG_RESERVED) {
5032 iocmd.cmd = RELEASE;
5033 iocmd.data_dma = -1;
5036 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5037 printk(MYIOC_s_INFO_FMT "DV: Release failed. id %d",
5039 else if (hd->pLocal) {
5040 if (hd->pLocal->completion == MPT_SCANDV_GOOD)
5041 iocmd.flags &= ~MPT_ICFLAG_RESERVED;
5043 printk(MYIOC_s_INFO_FMT "DV: Release failed. id %d",
5049 /* Set if cfg1_dma_addr contents is valid
5051 if ((cfg.cfghdr.hdr != NULL) && (retcode == 0)){
5052 /* If disk, not U320, disable QAS
5054 if ((inq0 == 0) && (dv.now.factor > MPT_ULTRA320)) {
5055 hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS;
5056 ddvprintk((MYIOC_s_NOTE_FMT
5057 "noQas set due to id=%d has factor=%x\n", ioc->name, id, dv.now.factor));
5061 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5063 /* Double writes to SDP1 can cause problems,
5064 * skip save of the final negotiated settings to
5065 * SCSI device page 1.
5067 cfg.cfghdr.hdr = &header1;
5068 cfg.physAddr = cfg1_dma_addr;
5069 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5071 mpt_config(hd->ioc, &cfg);
5075 /* If this is a RAID Passthrough, enable internal IOs
5077 if (iocmd.flags & MPT_ICFLAG_PHYS_DISK) {
5078 if (mptscsih_do_raid(hd, MPI_RAID_ACTION_ENABLE_PHYS_IO, &iocmd) < 0)
5079 ddvprintk((MYIOC_s_ERR_FMT "RAID Enable FAILED!\n", ioc->name));
5082 /* Done with the DV scan of the current target
5085 pci_free_consistent(ioc->pcidev, dv_alloc, pDvBuf, dvbuf_dma);
5087 ddvtprintk((MYIOC_s_INFO_FMT "DV Done id=%d\n",
5093 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5094 /* mptscsih_dv_parms - perform a variety of operations on the
5095 * parameters used for negotiation.
5096 * @hd: Pointer to a SCSI host.
5097 * @dv: Pointer to a structure that contains the maximum and current
5098 * negotiated parameters.
5101 mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
5103 VirtTarget *vtarget;
5104 SCSIDevicePage0_t *pPage0;
5105 SCSIDevicePage1_t *pPage1;
5106 int val = 0, data, configuration;
5115 case MPT_GET_NVRAM_VALS:
5116 ddvprintk((MYIOC_s_NOTE_FMT "Getting NVRAM: ",
5118 /* Get the NVRAM values and save in tmax
5119 * If not an LVD bus, the adapter minSyncFactor has been
5120 * already throttled back.
5122 negoFlags = hd->ioc->spi_data.noQas;
5123 if ((hd->Targets)&&((vtarget = hd->Targets[(int)id]) != NULL) && !vtarget->raidVolume) {
5124 width = vtarget->maxWidth;
5125 offset = vtarget->maxOffset;
5126 factor = vtarget->minSyncFactor;
5127 negoFlags |= vtarget->negoFlags;
5129 if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
5130 data = hd->ioc->spi_data.nvram[id];
5131 width = data & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
5132 if ((offset = hd->ioc->spi_data.maxSyncOffset) == 0)
5135 factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT;
5136 if ((factor == 0) || (factor == MPT_ASYNC)){
5147 /* Set the negotiation flags */
5149 negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
5152 negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
5155 /* limit by adapter capabilities */
5156 width = min(width, hd->ioc->spi_data.maxBusWidth);
5157 offset = min(offset, hd->ioc->spi_data.maxSyncOffset);
5158 factor = max(factor, hd->ioc->spi_data.minSyncFactor);
5160 /* Check Consistency */
5161 if (offset && (factor < MPT_ULTRA2) && !width)
5162 factor = MPT_ULTRA2;
5164 dv->max.width = width;
5165 dv->max.offset = offset;
5166 dv->max.factor = factor;
5167 dv->max.flags = negoFlags;
5168 ddvprintk((" id=%d width=%d factor=%x offset=%x flags=%x\n",
5169 id, width, factor, offset, negoFlags));
5172 case MPT_UPDATE_MAX:
5173 ddvprintk((MYIOC_s_NOTE_FMT
5174 "Updating with SDP0 Data: ", hd->ioc->name));
5175 /* Update tmax values with those from Device Page 0.*/
5176 pPage0 = (SCSIDevicePage0_t *) pPage;
5178 val = le32_to_cpu(pPage0->NegotiatedParameters);
5179 dv->max.width = val & MPI_SCSIDEVPAGE0_NP_WIDE ? 1 : 0;
5180 dv->max.offset = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK) >> 16;
5181 dv->max.factor = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK) >> 8;
5184 dv->now.width = dv->max.width;
5185 dv->now.offset = dv->max.offset;
5186 dv->now.factor = dv->max.factor;
5187 ddvprintk(("id=%d width=%d factor=%x offset=%x flags=%x\n",
5188 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags));
5192 ddvprintk((MYIOC_s_NOTE_FMT "Setting Max: ",
5194 /* Set current to the max values. Update the config page.*/
5195 dv->now.width = dv->max.width;
5196 dv->now.offset = dv->max.offset;
5197 dv->now.factor = dv->max.factor;
5198 dv->now.flags = dv->max.flags;
5200 pPage1 = (SCSIDevicePage1_t *)pPage;
5202 mptscsih_setDevicePage1Flags (dv->now.width, dv->now.factor,
5203 dv->now.offset, &val, &configuration, dv->now.flags);
5204 dnegoprintk(("Setting Max: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
5205 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags, val, configuration));
5206 pPage1->RequestedParameters = cpu_to_le32(val);
5207 pPage1->Reserved = 0;
5208 pPage1->Configuration = cpu_to_le32(configuration);
5211 ddvprintk(("id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x configuration=%x\n",
5212 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags, val, configuration));
5216 ddvprintk((MYIOC_s_NOTE_FMT "Setting Min: ",
5218 /* Set page to asynchronous and narrow
5219 * Do not update now, breaks fallback routine. */
5223 negoFlags = dv->max.flags;
5225 pPage1 = (SCSIDevicePage1_t *)pPage;
5227 mptscsih_setDevicePage1Flags (width, factor,
5228 offset, &val, &configuration, negoFlags);
5229 dnegoprintk(("Setting Min: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
5230 id, width, factor, offset, negoFlags, val, configuration));
5231 pPage1->RequestedParameters = cpu_to_le32(val);
5232 pPage1->Reserved = 0;
5233 pPage1->Configuration = cpu_to_le32(configuration);
5235 ddvprintk(("id=%d width=%d factor=%x offset=%x request=%x config=%x negoFlags=%x\n",
5236 id, width, factor, offset, val, configuration, negoFlags));
5240 ddvprintk((MYIOC_s_NOTE_FMT
5241 "Fallback: Start: offset %d, factor %x, width %d \n",
5242 hd->ioc->name, dv->now.offset,
5243 dv->now.factor, dv->now.width));
5244 width = dv->now.width;
5245 offset = dv->now.offset;
5246 factor = dv->now.factor;
5247 if ((offset) && (dv->max.width)) {
5248 if (factor < MPT_ULTRA160)
5249 factor = MPT_ULTRA160;
5250 else if (factor < MPT_ULTRA2) {
5251 factor = MPT_ULTRA2;
5253 } else if ((factor == MPT_ULTRA2) && width) {
5254 factor = MPT_ULTRA2;
5256 } else if (factor < MPT_ULTRA) {
5259 } else if ((factor == MPT_ULTRA) && width) {
5261 } else if (factor < MPT_FAST) {
5264 } else if ((factor == MPT_FAST) && width) {
5267 } else if (factor < MPT_SCSI) {
5270 } else if ((factor == MPT_SCSI) && width) {
5278 } else if (offset) {
5280 if (factor < MPT_ULTRA)
5282 else if (factor < MPT_FAST)
5284 else if (factor < MPT_SCSI)
5295 dv->max.flags |= MPT_TARGET_NO_NEGO_QAS;
5296 dv->max.flags &= ~MPT_TAPE_NEGO_IDP;
5298 dv->now.width = width;
5299 dv->now.offset = offset;
5300 dv->now.factor = factor;
5301 dv->now.flags = dv->max.flags;
5303 pPage1 = (SCSIDevicePage1_t *)pPage;
5305 mptscsih_setDevicePage1Flags (width, factor, offset, &val,
5306 &configuration, dv->now.flags);
5307 dnegoprintk(("Finish: id=%d width=%d offset=%d factor=%x negoFlags=%x request=%x config=%x\n",
5308 id, width, offset, factor, dv->now.flags, val, configuration));
5310 pPage1->RequestedParameters = cpu_to_le32(val);
5311 pPage1->Reserved = 0;
5312 pPage1->Configuration = cpu_to_le32(configuration);
5315 ddvprintk(("Finish: id=%d offset=%d factor=%x width=%d request=%x config=%x\n",
5316 id, dv->now.offset, dv->now.factor, dv->now.width, val, configuration));
5320 ddvprintk((MYIOC_s_NOTE_FMT
5321 "Saving to Target structure: ", hd->ioc->name));
5322 ddvprintk(("id=%d width=%x factor=%x offset=%d flags=%x\n",
5323 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags));
5325 /* Save these values to target structures
5326 * or overwrite nvram (phys disks only).
5329 if ((hd->Targets)&&((vtarget = hd->Targets[(int)id]) != NULL) && !vtarget->raidVolume ) {
5330 vtarget->maxWidth = dv->now.width;
5331 vtarget->maxOffset = dv->now.offset;
5332 vtarget->minSyncFactor = dv->now.factor;
5333 vtarget->negoFlags = dv->now.flags;
5335 /* Preserv all flags, use
5336 * read-modify-write algorithm
5338 if (hd->ioc->spi_data.nvram) {
5339 data = hd->ioc->spi_data.nvram[id];
5342 data &= ~MPT_NVRAM_WIDE_DISABLE;
5344 data |= MPT_NVRAM_WIDE_DISABLE;
5346 if (!dv->now.offset)
5349 data &= ~MPT_NVRAM_SYNC_MASK;
5350 data |= (dv->now.factor << MPT_NVRAM_SYNC_SHIFT) & MPT_NVRAM_SYNC_MASK;
5352 hd->ioc->spi_data.nvram[id] = data;
5359 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5360 /* mptscsih_fillbuf - fill a buffer with a special data pattern
5361 * cleanup. For bus scan only.
5363 * @buffer: Pointer to data buffer to be filled.
5364 * @size: Number of bytes to fill
5365 * @index: Pattern index
5366 * @width: bus width, 0 (8 bits) or 1 (16 bits)
5369 mptscsih_fillbuf(char *buffer, int size, int index, int width)
5380 /* Pattern: 0000 FFFF 0000 FFFF
5382 for (ii=0; ii < size; ii++, ptr++) {
5389 /* Pattern: 00 FF 00 FF
5391 for (ii=0; ii < size; ii++, ptr++) {
5402 /* Pattern: 5555 AAAA 5555 AAAA 5555
5404 for (ii=0; ii < size; ii++, ptr++) {
5411 /* Pattern: 55 AA 55 AA 55
5413 for (ii=0; ii < size; ii++, ptr++) {
5423 /* Pattern: 00 01 02 03 04 05
5426 for (ii=0; ii < size; ii++, ptr++)
5432 /* Wide Pattern: FFFE 0001 FFFD 0002
5433 * ... 4000 DFFF 8000 EFFF
5436 for (ii=0; ii < size/2; ii++) {
5437 /* Create the base pattern
5440 /* every 64 (0x40) bytes flip the pattern
5441 * since we fill 2 bytes / iteration,
5442 * test for ii = 0x20
5448 *ptr = (char)( (val & 0xFF00) >> 8);
5450 *ptr = (char)(val & 0xFF);
5455 *ptr = (char)( (val & 0xFF00) >> 8);
5457 *ptr = (char)(val & 0xFF);
5463 /* Narrow Pattern: FE 01 FD 02 FB 04
5464 * .. 7F 80 01 FE 02 FD ... 80 7F
5467 for (ii=0; ii < size; ii++, ptr++) {
5468 /* Base pattern - first 32 bytes
5475 *ptr = (char) (~(1 << byte));
5478 /* Flip the pattern every 32 bytes
5488 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5489 /* If DV disabled (negoNvram set to USE_NVARM) or if not LUN 0, return.
5490 * Else set the NEED_DV flag after Read Capacity Issued (disks)
5491 * or Mode Sense (cdroms).
5493 * Tapes, initTarget will set this flag on completion of Inquiry command.
5494 * Called only if DV_NOT_DONE flag is set
5497 mptscsih_set_dvflags(MPT_SCSI_HOST *hd, struct scsi_cmnd *sc)
5499 MPT_ADAPTER *ioc = hd->ioc;
5503 ddvtprintk((MYIOC_s_NOTE_FMT
5504 " set_dvflags: id=%d lun=%d negoNvram=%x cmd=%x\n",
5505 hd->ioc->name, sc->device->id, sc->device->lun , hd->negoNvram, sc->cmnd[0]));
5507 if ((sc->device->lun != 0) || (hd->negoNvram != 0))
5512 if ((cmd == READ_CAPACITY) || (cmd == MODE_SENSE)) {
5513 pSpi = &ioc->spi_data;
5514 if ((ioc->raid_data.isRaid & (1 << sc->device->id)) && ioc->raid_data.pIocPg3) {
5515 /* Set NEED_DV for all hidden disks
5517 Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
5518 int numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
5521 pSpi->dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV;
5522 ddvtprintk(("NEED_DV set for phys disk id %d\n", pPDisk->PhysDiskID));
5527 pSpi->dvStatus[sc->device->id] |= MPT_SCSICFG_NEED_DV;
5528 ddvtprintk(("NEED_DV set for visible disk id %d\n", sc->device->id));
5532 /* mptscsih_raid_set_dv_flags()
5534 * New or replaced disk. Set DV flag and schedule DV.
5537 mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id)
5539 MPT_ADAPTER *ioc = hd->ioc;
5540 SpiCfgData *pSpi = &ioc->spi_data;
5541 Ioc3PhysDisk_t *pPDisk;
5544 if (hd->negoNvram != 0)
5547 ddvtprintk(("DV requested for phys disk id %d\n", id));
5548 if (ioc->raid_data.pIocPg3) {
5549 pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
5550 numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
5552 if (id == pPDisk->PhysDiskNum) {
5553 pSpi->dvStatus[pPDisk->PhysDiskID] =
5554 (MPT_SCSICFG_NEED_DV | MPT_SCSICFG_DV_NOT_DONE);
5555 pSpi->forceDv = MPT_SCSICFG_NEED_DV;
5556 ddvtprintk(("NEED_DV set for phys disk id %d\n",
5557 pPDisk->PhysDiskID));
5564 if (numPDisk == 0) {
5565 /* The physical disk that needs DV was not found
5566 * in the stored IOC Page 3. The driver must reload
5567 * this page. DV routine will set the NEED_DV flag for
5568 * all phys disks that have DV_NOT_DONE set.
5570 pSpi->forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
5571 ddvtprintk(("phys disk %d not found. Setting reload IOC Pg3 Flag\n",id));
5575 #endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */
5577 EXPORT_SYMBOL(mptscsih_remove);
5578 EXPORT_SYMBOL(mptscsih_shutdown);
5580 EXPORT_SYMBOL(mptscsih_suspend);
5581 EXPORT_SYMBOL(mptscsih_resume);
5583 EXPORT_SYMBOL(mptscsih_proc_info);
5584 EXPORT_SYMBOL(mptscsih_info);
5585 EXPORT_SYMBOL(mptscsih_qcmd);
5586 EXPORT_SYMBOL(mptscsih_target_alloc);
5587 EXPORT_SYMBOL(mptscsih_slave_alloc);
5588 EXPORT_SYMBOL(mptscsih_target_destroy);
5589 EXPORT_SYMBOL(mptscsih_slave_destroy);
5590 EXPORT_SYMBOL(mptscsih_slave_configure);
5591 EXPORT_SYMBOL(mptscsih_abort);
5592 EXPORT_SYMBOL(mptscsih_dev_reset);
5593 EXPORT_SYMBOL(mptscsih_bus_reset);
5594 EXPORT_SYMBOL(mptscsih_host_reset);
5595 EXPORT_SYMBOL(mptscsih_bios_param);
5596 EXPORT_SYMBOL(mptscsih_io_done);
5597 EXPORT_SYMBOL(mptscsih_taskmgmt_complete);
5598 EXPORT_SYMBOL(mptscsih_scandv_complete);
5599 EXPORT_SYMBOL(mptscsih_event_process);
5600 EXPORT_SYMBOL(mptscsih_ioc_reset);
5601 EXPORT_SYMBOL(mptscsih_change_queue_depth);
5602 EXPORT_SYMBOL(mptscsih_timer_expired);
5604 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/