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 = kmalloc(sizeof(VirtTarget), GFP_KERNEL);
2168 memset(vtarget, 0, sizeof(VirtTarget));
2169 starget->hostdata = vtarget;
2173 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2175 * OS entry point to allow host driver to alloc memory
2176 * for each scsi device. Called once per device the bus scan.
2177 * Return non-zero if allocation fails.
2180 mptscsih_slave_alloc(struct scsi_device *sdev)
2182 struct Scsi_Host *host = sdev->host;
2183 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
2184 VirtTarget *vtarget;
2186 struct scsi_target *starget;
2188 vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL);
2190 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
2191 hd->ioc->name, sizeof(VirtDevice));
2195 memset(vdev, 0, sizeof(VirtDevice));
2196 vdev->ioc_id = hd->ioc->id;
2197 vdev->target_id = sdev->id;
2198 vdev->bus_id = sdev->channel;
2199 vdev->lun = sdev->lun;
2200 sdev->hostdata = vdev;
2202 starget = scsi_target(sdev);
2203 vtarget = starget->hostdata;
2204 vdev->vtarget = vtarget;
2206 if (vtarget->num_luns == 0) {
2207 hd->Targets[sdev->id] = vtarget;
2208 vtarget->ioc_id = hd->ioc->id;
2209 vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
2210 vtarget->target_id = sdev->id;
2211 vtarget->bus_id = sdev->channel;
2212 if (hd->ioc->bus_type == SPI) {
2213 if (hd->ioc->raid_data.isRaid & (1 << sdev->id)) {
2214 vtarget->raidVolume = 1;
2215 ddvtprintk((KERN_INFO
2216 "RAID Volume @ id %d\n", sdev->id));
2219 vtarget->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
2222 vtarget->num_luns++;
2227 * OS entry point to allow for host driver to free allocated memory
2228 * Called if no device present or device being unloaded
2231 mptscsih_target_destroy(struct scsi_target *starget)
2233 if (starget->hostdata)
2234 kfree(starget->hostdata);
2235 starget->hostdata = NULL;
2239 * OS entry point to allow for host driver to free allocated memory
2240 * Called if no device present or device being unloaded
2243 mptscsih_slave_destroy(struct scsi_device *sdev)
2245 struct Scsi_Host *host = sdev->host;
2246 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
2247 VirtTarget *vtarget;
2248 VirtDevice *vdevice;
2249 struct scsi_target *starget;
2251 starget = scsi_target(sdev);
2252 vtarget = starget->hostdata;
2253 vdevice = sdev->hostdata;
2255 mptscsih_search_running_cmds(hd, vdevice);
2256 vtarget->luns[0] &= ~(1 << vdevice->lun);
2257 vtarget->num_luns--;
2258 if (vtarget->num_luns == 0) {
2259 mptscsih_negotiate_to_asyn_narrow(hd, vtarget);
2260 if (hd->ioc->bus_type == SPI) {
2261 if (mptscsih_is_phys_disk(hd->ioc, vtarget->target_id)) {
2262 hd->ioc->spi_data.forceDv |= MPT_SCSICFG_RELOAD_IOC_PG3;
2264 hd->ioc->spi_data.dvStatus[vtarget->target_id] =
2265 MPT_SCSICFG_NEGOTIATE;
2266 if (!hd->negoNvram) {
2267 hd->ioc->spi_data.dvStatus[vtarget->target_id] |=
2268 MPT_SCSICFG_DV_NOT_DONE;
2272 hd->Targets[sdev->id] = NULL;
2274 mptscsih_synchronize_cache(hd, vdevice);
2276 sdev->hostdata = NULL;
2279 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2281 * mptscsih_change_queue_depth - This function will set a devices queue depth
2282 * @sdev: per scsi_device pointer
2283 * @qdepth: requested queue depth
2285 * Adding support for new 'change_queue_depth' api.
2288 mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
2290 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sdev->host->hostdata;
2291 VirtTarget *vtarget;
2292 struct scsi_target *starget;
2296 starget = scsi_target(sdev);
2297 vtarget = starget->hostdata;
2299 if (hd->ioc->bus_type == SPI) {
2300 if (vtarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) {
2301 if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
2303 else if (((vtarget->inq_data[0] & 0x1f) == 0x00) &&
2304 (vtarget->minSyncFactor <= MPT_ULTRA160 ))
2305 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2307 max_depth = MPT_SCSI_CMD_PER_DEV_LOW;
2309 /* error case - No Inq. Data */
2313 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2315 if (qdepth > max_depth)
2320 tagged = MSG_SIMPLE_TAG;
2322 scsi_adjust_queue_depth(sdev, tagged, qdepth);
2323 return sdev->queue_depth;
2327 * OS entry point to adjust the queue_depths on a per-device basis.
2328 * Called once per device the bus scan. Use it to force the queue_depth
2329 * member to 1 if a device does not support Q tags.
2330 * Return non-zero if fails.
2333 mptscsih_slave_configure(struct scsi_device *sdev)
2335 struct Scsi_Host *sh = sdev->host;
2336 VirtTarget *vtarget;
2337 VirtDevice *vdevice;
2338 struct scsi_target *starget;
2339 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sh->hostdata;
2340 int indexed_lun, lun_index;
2342 starget = scsi_target(sdev);
2343 vtarget = starget->hostdata;
2344 vdevice = sdev->hostdata;
2346 dsprintk((MYIOC_s_INFO_FMT
2347 "device @ %p, id=%d, LUN=%d, channel=%d\n",
2348 hd->ioc->name, sdev, sdev->id, sdev->lun, sdev->channel));
2349 if (hd->ioc->bus_type == SPI)
2350 dsprintk((MYIOC_s_INFO_FMT
2351 "sdtr %d wdtr %d ppr %d inq length=%d\n",
2352 hd->ioc->name, sdev->sdtr, sdev->wdtr,
2353 sdev->ppr, sdev->inquiry_len));
2355 if (sdev->id > sh->max_id) {
2356 /* error case, should never happen */
2357 scsi_adjust_queue_depth(sdev, 0, 1);
2358 goto slave_configure_exit;
2361 vdevice->configured_lun=1;
2362 lun_index = (vdevice->lun >> 5); /* 32 luns per lun_index */
2363 indexed_lun = (vdevice->lun % 32);
2364 vtarget->luns[lun_index] |= (1 << indexed_lun);
2365 mptscsih_initTarget(hd, vtarget, sdev->lun, sdev->inquiry,
2366 sdev->inquiry_len );
2367 mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH);
2369 dsprintk((MYIOC_s_INFO_FMT
2370 "Queue depth=%d, tflags=%x\n",
2371 hd->ioc->name, sdev->queue_depth, vtarget->tflags));
2373 if (hd->ioc->bus_type == SPI)
2374 dsprintk((MYIOC_s_INFO_FMT
2375 "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
2376 hd->ioc->name, vtarget->negoFlags, vtarget->maxOffset,
2377 vtarget->minSyncFactor));
2379 slave_configure_exit:
2381 dsprintk((MYIOC_s_INFO_FMT
2382 "tagged %d, simple %d, ordered %d\n",
2383 hd->ioc->name,sdev->tagged_supported, sdev->simple_tags,
2384 sdev->ordered_tags));
2389 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2391 * Private routines...
2394 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2395 /* Utility function to copy sense data from the scsi_cmnd buffer
2396 * to the FC and SCSI target structures.
2400 mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
2403 SCSIIORequest_t *pReq;
2404 u32 sense_count = le32_to_cpu(pScsiReply->SenseCount);
2406 /* Get target structure
2408 pReq = (SCSIIORequest_t *) mf;
2409 vdev = sc->device->hostdata;
2415 /* Copy the sense received into the scsi command block. */
2416 req_index = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2417 sense_data = ((u8 *)hd->ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC));
2418 memcpy(sc->sense_buffer, sense_data, SNS_LEN(sc));
2420 /* Log SMART data (asc = 0x5D, non-IM case only) if required.
2422 if ((hd->ioc->events) && (hd->ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) {
2423 if ((sense_data[12] == 0x5D) && (vdev->vtarget->raidVolume == 0)) {
2425 MPT_ADAPTER *ioc = hd->ioc;
2427 idx = ioc->eventContext % ioc->eventLogSize;
2428 ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
2429 ioc->events[idx].eventContext = ioc->eventContext;
2431 ioc->events[idx].data[0] = (pReq->LUN[1] << 24) ||
2432 (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) ||
2433 (sc->device->channel << 8) || sc->device->id;
2435 ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12];
2437 ioc->eventContext++;
2441 dprintk((MYIOC_s_INFO_FMT "Hmmm... SenseData len=0! (?)\n",
2447 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc)
2452 hd = (MPT_SCSI_HOST *) sc->device->host->hostdata;
2454 for (i = 0; i < hd->ioc->req_depth; i++) {
2455 if (hd->ScsiLookup[i] == sc) {
2463 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2465 mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2468 unsigned long flags;
2471 dtmprintk((KERN_WARNING MYNAM
2472 ": IOC %s_reset routed to SCSI host driver!\n",
2473 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
2474 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
2476 /* If a FW reload request arrives after base installed but
2477 * before all scsi hosts have been attached, then an alt_ioc
2478 * may have a NULL sh pointer.
2480 if ((ioc->sh == NULL) || (ioc->sh->hostdata == NULL))
2483 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2485 if (reset_phase == MPT_IOC_SETUP_RESET) {
2486 dtmprintk((MYIOC_s_WARN_FMT "Setup-Diag Reset\n", ioc->name));
2489 * 1. Set Hard Reset Pending Flag
2490 * All new commands go to doneQ
2492 hd->resetPending = 1;
2494 } else if (reset_phase == MPT_IOC_PRE_RESET) {
2495 dtmprintk((MYIOC_s_WARN_FMT "Pre-Diag Reset\n", ioc->name));
2497 /* 2. Flush running commands
2498 * Clean ScsiLookup (and associated memory)
2502 /* 2b. Reply to OS all known outstanding I/O commands.
2504 mptscsih_flush_running_cmds(hd);
2506 /* 2c. If there was an internal command that
2507 * has not completed, configuration or io request,
2508 * free these resources.
2511 del_timer(&hd->timer);
2512 mpt_free_msg_frame(ioc, hd->cmdPtr);
2515 dtmprintk((MYIOC_s_WARN_FMT "Pre-Reset complete.\n", ioc->name));
2518 dtmprintk((MYIOC_s_WARN_FMT "Post-Diag Reset\n", ioc->name));
2520 /* Once a FW reload begins, all new OS commands are
2521 * redirected to the doneQ w/ a reset status.
2522 * Init all control structures.
2525 /* ScsiLookup initialization
2527 for (ii=0; ii < hd->ioc->req_depth; ii++)
2528 hd->ScsiLookup[ii] = NULL;
2530 /* 2. Chain Buffer initialization
2533 /* 4. Renegotiate to all devices, if SPI
2535 if (ioc->bus_type == SPI) {
2536 dnegoprintk(("writeSDP1: ALL_IDS USE_NVRAM\n"));
2537 mptscsih_writeSDP1(hd, 0, 0, MPT_SCSICFG_ALL_IDS | MPT_SCSICFG_USE_NVRAM);
2540 /* 5. Enable new commands to be posted
2542 spin_lock_irqsave(&ioc->FreeQlock, flags);
2544 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2545 hd->resetPending = 0;
2546 hd->tmState = TM_STATE_NONE;
2548 /* 6. If there was an internal command,
2549 * wake this process up.
2553 * Wake up the original calling thread
2555 hd->pLocal = &hd->localReply;
2556 hd->pLocal->completion = MPT_SCANDV_DID_RESET;
2557 hd->scandv_wait_done = 1;
2558 wake_up(&hd->scandv_waitq);
2562 /* 7. Set flag to force DV and re-read IOC Page 3
2564 if (ioc->bus_type == SPI) {
2565 ioc->spi_data.forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
2566 ddvtprintk(("Set reload IOC Pg3 Flag\n"));
2569 dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name));
2573 return 1; /* currently means nothing really */
2576 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2577 /* work queue thread to clear the persitency table */
2579 mptscsih_sas_persist_clear_table(void * arg)
2581 MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg;
2583 mptbase_sas_persist_operation(ioc, MPI_SAS_OP_CLEAR_NOT_PRESENT);
2586 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2588 mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2591 u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
2593 devtprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
2596 if (ioc->sh == NULL ||
2597 ((hd = (MPT_SCSI_HOST *)ioc->sh->hostdata) == NULL))
2601 case MPI_EVENT_UNIT_ATTENTION: /* 03 */
2604 case MPI_EVENT_IOC_BUS_RESET: /* 04 */
2605 case MPI_EVENT_EXT_BUS_RESET: /* 05 */
2606 if (hd && (ioc->bus_type == SPI) && (hd->soft_resets < -1))
2609 case MPI_EVENT_LOGOUT: /* 09 */
2614 * CHECKME! Don't think we need to do
2615 * anything for these, but...
2617 case MPI_EVENT_RESCAN: /* 06 */
2618 case MPI_EVENT_LINK_STATUS_CHANGE: /* 07 */
2619 case MPI_EVENT_LOOP_STATE_CHANGE: /* 08 */
2621 * CHECKME! Falling thru...
2625 case MPI_EVENT_INTEGRATED_RAID: /* 0B */
2627 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
2628 pMpiEventDataRaid_t pRaidEventData =
2629 (pMpiEventDataRaid_t) pEvReply->Data;
2630 /* Domain Validation Needed */
2631 if (ioc->bus_type == SPI &&
2632 pRaidEventData->ReasonCode ==
2633 MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED)
2634 mptscsih_set_dvflags_raid(hd, pRaidEventData->PhysDiskNum);
2639 /* Persistent table is full. */
2640 case MPI_EVENT_PERSISTENT_TABLE_FULL:
2641 INIT_WORK(&mptscsih_persistTask,
2642 mptscsih_sas_persist_clear_table,(void *)ioc);
2643 schedule_work(&mptscsih_persistTask);
2646 case MPI_EVENT_NONE: /* 00 */
2647 case MPI_EVENT_LOG_DATA: /* 01 */
2648 case MPI_EVENT_STATE_CHANGE: /* 02 */
2649 case MPI_EVENT_EVENT_CHANGE: /* 0A */
2651 dprintk((KERN_INFO " Ignoring event (=%02Xh)\n", event));
2655 return 1; /* currently means nothing really */
2658 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2660 * mptscsih_initTarget - Target, LUN alloc/free functionality.
2661 * @hd: Pointer to MPT_SCSI_HOST structure
2662 * @vtarget: per target private data
2664 * @data: Pointer to data
2665 * @dlen: Number of INQUIRY bytes
2667 * NOTE: It's only SAFE to call this routine if data points to
2668 * sane & valid STANDARD INQUIRY data!
2670 * Allocate and initialize memory for this target.
2671 * Save inquiry data.
2675 mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, u8 lun, char *data, int dlen)
2681 dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n",
2682 hd->ioc->name, vtarget->bus_id, vtarget->target_id, lun, hd));
2685 * If the peripheral qualifier filter is enabled then if the target reports a 0x1
2686 * (i.e. The targer is capable of supporting the specified peripheral device type
2687 * on this logical unit; however, the physical device is not currently connected
2688 * to this logical unit) it will be converted to a 0x3 (i.e. The target is not
2689 * capable of supporting a physical device on this logical unit). This is to work
2690 * around a bug in th emid-layer in some distributions in which the mid-layer will
2691 * continue to try to communicate to the LUN and evntually create a dummy LUN.
2693 if (hd->mpt_pq_filter && dlen && (data[0] & 0xE0))
2696 /* Is LUN supported? If so, upper 2 bits will be 0
2697 * in first byte of inquiry data.
2702 if (vtarget == NULL)
2706 vtarget->type = data[0];
2708 if (hd->ioc->bus_type != SPI)
2711 if ((data[0] == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) {
2712 /* Treat all Processors as SAF-TE if
2713 * command line option is set */
2714 vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
2715 mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id);
2716 }else if ((data[0] == TYPE_PROCESSOR) &&
2717 !(vtarget->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) {
2719 vtarget->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
2720 if ( data[44] == 'S' &&
2726 vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
2727 mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id);
2731 if (!(vtarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY)) {
2732 inq_len = dlen < 8 ? dlen : 8;
2733 memcpy (vtarget->inq_data, data, inq_len);
2734 /* If have not done DV, set the DV flag.
2736 pSpi = &hd->ioc->spi_data;
2737 if ((data[0] == TYPE_TAPE) || (data[0] == TYPE_PROCESSOR)) {
2738 if (pSpi->dvStatus[vtarget->target_id] & MPT_SCSICFG_DV_NOT_DONE)
2739 pSpi->dvStatus[vtarget->target_id] |= MPT_SCSICFG_NEED_DV;
2741 vtarget->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
2743 data_56 = 0x0F; /* Default to full capabilities if Inq data length is < 57 */
2745 if ( (!(vtarget->tflags & MPT_TARGET_FLAGS_VALID_56))) {
2746 /* Update the target capabilities
2749 vtarget->tflags |= MPT_TARGET_FLAGS_VALID_56;
2752 mptscsih_setTargetNegoParms(hd, vtarget, data_56);
2754 /* Initial Inquiry may not request enough data bytes to
2755 * obtain byte 57. DV will; if target doesn't return
2756 * at least 57 bytes, data[56] will be zero. */
2758 if ( (!(vtarget->tflags & MPT_TARGET_FLAGS_VALID_56))) {
2759 /* Update the target capabilities
2762 vtarget->tflags |= MPT_TARGET_FLAGS_VALID_56;
2763 mptscsih_setTargetNegoParms(hd, vtarget, data_56);
2769 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2771 * Update the target negotiation parameters based on the
2772 * the Inquiry data, adapter capabilities, and NVRAM settings.
2776 mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target, char byte56)
2778 SpiCfgData *pspi_data = &hd->ioc->spi_data;
2779 int id = (int) target->target_id;
2781 VirtTarget *vtarget;
2783 u8 width = MPT_NARROW;
2784 u8 factor = MPT_ASYNC;
2786 u8 version, nfactor;
2789 target->negoFlags = pspi_data->noQas;
2791 /* noQas == 0 => device supports QAS. Need byte 56 of Inq to determine
2792 * support. If available, default QAS to off and allow enabling.
2793 * If not available, default QAS to on, turn off for non-disks.
2796 /* Set flags based on Inquiry data
2798 version = target->inq_data[2] & 0x07;
2801 factor = MPT_ULTRA2;
2802 offset = pspi_data->maxSyncOffset;
2803 target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
2805 if (target->inq_data[7] & 0x20) {
2809 if (target->inq_data[7] & 0x10) {
2810 factor = pspi_data->minSyncFactor;
2811 if (target->tflags & MPT_TARGET_FLAGS_VALID_56) {
2812 /* bits 2 & 3 show Clocking support */
2813 if ((byte56 & 0x0C) == 0)
2814 factor = MPT_ULTRA2;
2816 if ((byte56 & 0x03) == 0)
2817 factor = MPT_ULTRA160;
2819 factor = MPT_ULTRA320;
2822 ddvtprintk((KERN_INFO "Enabling QAS due to byte56=%02x on id=%d!\n", byte56, id));
2825 if (target->inq_data[0] == TYPE_TAPE) {
2827 target->negoFlags |= MPT_TAPE_NEGO_IDP;
2832 ddvtprintk((KERN_INFO "Enabling QAS on id=%d due to ~TARGET_FLAGS_VALID_56!\n", id));
2836 offset = pspi_data->maxSyncOffset;
2838 /* If RAID, never disable QAS
2839 * else if non RAID, do not disable
2840 * QAS if bit 1 is set
2841 * bit 1 QAS support, non-raid only
2844 if (target->raidVolume == 1) {
2853 if ( (target->inq_data[7] & 0x02) == 0) {
2854 target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
2857 /* Update tflags based on NVRAM settings. (SCSI only)
2859 if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
2860 nvram = pspi_data->nvram[id];
2861 nfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
2864 width = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
2867 /* Ensure factor is set to the
2868 * maximum of: adapter, nvram, inquiry
2871 if (nfactor < pspi_data->minSyncFactor )
2872 nfactor = pspi_data->minSyncFactor;
2874 factor = max(factor, nfactor);
2875 if (factor == MPT_ASYNC)
2886 /* Make sure data is consistent
2888 if ((!width) && (factor < MPT_ULTRA2)) {
2889 factor = MPT_ULTRA2;
2892 /* Save the data to the target structure.
2894 target->minSyncFactor = factor;
2895 target->maxOffset = offset;
2896 target->maxWidth = width;
2898 target->tflags |= MPT_TARGET_FLAGS_VALID_NEGO;
2900 /* Disable unused features.
2903 target->negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
2906 target->negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
2908 if ( factor > MPT_ULTRA320 )
2911 /* GEM, processor WORKAROUND
2913 if ((target->inq_data[0] == TYPE_PROCESSOR) || (target->inq_data[0] > 0x08)) {
2914 target->negoFlags |= (MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC);
2915 pspi_data->dvStatus[id] |= MPT_SCSICFG_BLK_NEGO;
2917 if (noQas && (pspi_data->noQas == 0)) {
2918 pspi_data->noQas |= MPT_TARGET_NO_NEGO_QAS;
2919 target->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
2921 /* Disable QAS in a mixed configuration case
2924 ddvtprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id));
2925 for (ii = 0; ii < id; ii++) {
2926 if ( (vtarget = hd->Targets[ii]) ) {
2927 vtarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
2928 mptscsih_writeSDP1(hd, 0, ii, vtarget->negoFlags);
2934 /* Write SDP1 on this I/O to this target */
2935 if (pspi_data->dvStatus[id] & MPT_SCSICFG_NEGOTIATE) {
2936 ddvtprintk((KERN_INFO "MPT_SCSICFG_NEGOTIATE on id=%d!\n", id));
2937 mptscsih_writeSDP1(hd, 0, id, hd->negoNvram);
2938 pspi_data->dvStatus[id] &= ~MPT_SCSICFG_NEGOTIATE;
2939 } else if (pspi_data->dvStatus[id] & MPT_SCSICFG_BLK_NEGO) {
2940 ddvtprintk((KERN_INFO "MPT_SCSICFG_BLK_NEGO on id=%d!\n", id));
2941 mptscsih_writeSDP1(hd, 0, id, MPT_SCSICFG_BLK_NEGO);
2942 pspi_data->dvStatus[id] &= ~MPT_SCSICFG_BLK_NEGO;
2946 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2948 * If no Target, bus reset on 1st I/O. Set the flag to
2949 * prevent any future negotiations to this device.
2952 mptscsih_no_negotiate(MPT_SCSI_HOST *hd, struct scsi_cmnd *sc)
2956 if ((vdev = sc->device->hostdata) != NULL)
2957 hd->ioc->spi_data.dvStatus[vdev->target_id] |= MPT_SCSICFG_BLK_NEGO;
2961 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2963 * SCSI Config Page functionality ...
2965 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2966 /* mptscsih_setDevicePage1Flags - add Requested and Configuration fields flags
2967 * based on width, factor and offset parameters.
2969 * @factor: sync factor
2970 * @offset: sync offset
2971 * @requestedPtr: pointer to requested values (updated)
2972 * @configurationPtr: pointer to configuration values (updated)
2973 * @flags: flags to block WDTR or SDTR negotiation
2977 * Remark: Called by writeSDP1 and _dv_params
2980 mptscsih_setDevicePage1Flags (u8 width, u8 factor, u8 offset, int *requestedPtr, int *configurationPtr, u8 flags)
2982 u8 nowide = flags & MPT_TARGET_NO_NEGO_WIDE;
2983 u8 nosync = flags & MPT_TARGET_NO_NEGO_SYNC;
2985 *configurationPtr = 0;
2986 *requestedPtr = width ? MPI_SCSIDEVPAGE1_RP_WIDE : 0;
2987 *requestedPtr |= (offset << 16) | (factor << 8);
2989 if (width && offset && !nowide && !nosync) {
2990 if (factor < MPT_ULTRA160) {
2991 *requestedPtr |= (MPI_SCSIDEVPAGE1_RP_IU + MPI_SCSIDEVPAGE1_RP_DT);
2992 if ((flags & MPT_TARGET_NO_NEGO_QAS) == 0)
2993 *requestedPtr |= MPI_SCSIDEVPAGE1_RP_QAS;
2994 if (flags & MPT_TAPE_NEGO_IDP)
2995 *requestedPtr |= 0x08000000;
2996 } else if (factor < MPT_ULTRA2) {
2997 *requestedPtr |= MPI_SCSIDEVPAGE1_RP_DT;
3002 *configurationPtr |= MPI_SCSIDEVPAGE1_CONF_WDTR_DISALLOWED;
3005 *configurationPtr |= MPI_SCSIDEVPAGE1_CONF_SDTR_DISALLOWED;
3010 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3011 /* mptscsih_writeSDP1 - write SCSI Device Page 1
3012 * @hd: Pointer to a SCSI Host Strucutre
3013 * @portnum: IOC port number
3014 * @target_id: writeSDP1 for single ID
3015 * @flags: MPT_SCSICFG_ALL_IDS, MPT_SCSICFG_USE_NVRAM, MPT_SCSICFG_BLK_NEGO
3017 * Return: -EFAULT if read of config page header fails
3020 * Remark: If a target has been found, the settings from the
3021 * target structure are used, else the device is set
3024 * Remark: Called during init and after a FW reload.
3025 * Remark: We do not wait for a return, write pages sequentially.
3028 mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
3030 MPT_ADAPTER *ioc = hd->ioc;
3032 SCSIDevicePage1_t *pData;
3033 VirtTarget *vtarget=NULL;
3038 u32 requested, configuration, flagsLength;
3040 int id = 0, maxid = 0;
3046 u8 maxwidth, maxoffset, maxfactor;
3048 if (ioc->spi_data.sdp1length == 0)
3051 if (flags & MPT_SCSICFG_ALL_IDS) {
3053 maxid = ioc->sh->max_id - 1;
3054 } else if (ioc->sh) {
3056 maxid = min_t(int, id, ioc->sh->max_id - 1);
3059 for (; id <= maxid; id++) {
3061 if (id == ioc->pfacts[portnum].PortSCSIID)
3064 /* Use NVRAM to get adapter and target maximums
3065 * Data over-riden by target structure information, if present
3067 maxwidth = ioc->spi_data.maxBusWidth;
3068 maxoffset = ioc->spi_data.maxSyncOffset;
3069 maxfactor = ioc->spi_data.minSyncFactor;
3070 if (ioc->spi_data.nvram && (ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
3071 nvram = ioc->spi_data.nvram[id];
3074 maxwidth = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
3076 if (maxoffset > 0) {
3077 maxfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
3078 if (maxfactor == 0) {
3080 maxfactor = MPT_ASYNC;
3082 } else if (maxfactor < ioc->spi_data.minSyncFactor) {
3083 maxfactor = ioc->spi_data.minSyncFactor;
3086 maxfactor = MPT_ASYNC;
3089 /* Set the negotiation flags.
3091 negoFlags = ioc->spi_data.noQas;
3093 negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
3096 negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
3098 if (flags & MPT_SCSICFG_USE_NVRAM) {
3107 //negoFlags = MPT_TARGET_NO_NEGO_SYNC;
3110 /* If id is not a raid volume, get the updated
3111 * transmission settings from the target structure.
3113 if (hd->Targets && (vtarget = hd->Targets[id]) && !vtarget->raidVolume) {
3114 width = vtarget->maxWidth;
3115 factor = vtarget->minSyncFactor;
3116 offset = vtarget->maxOffset;
3117 negoFlags = vtarget->negoFlags;
3120 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
3121 /* Force to async and narrow if DV has not been executed
3124 if ((hd->ioc->spi_data.dvStatus[id] & MPT_SCSICFG_DV_NOT_DONE) != 0) {
3131 if (flags & MPT_SCSICFG_BLK_NEGO)
3132 negoFlags |= MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC;
3134 mptscsih_setDevicePage1Flags(width, factor, offset,
3135 &requested, &configuration, negoFlags);
3136 dnegoprintk(("writeSDP1: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
3137 target_id, width, factor, offset, negoFlags, requested, configuration));
3139 /* Get a MF for this command.
3141 if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
3142 dfailprintk((MYIOC_s_WARN_FMT "write SDP1: no msg frames!\n",
3147 ddvprintk((MYIOC_s_INFO_FMT "WriteSDP1 (mf=%p, id=%d, req=0x%x, cfg=0x%x)\n",
3148 hd->ioc->name, mf, id, requested, configuration));
3151 /* Set the request and the data pointers.
3152 * Request takes: 36 bytes (32 bit SGE)
3153 * SCSI Device Page 1 requires 16 bytes
3154 * 40 + 16 <= size of SCSI IO Request = 56 bytes
3155 * and MF size >= 64 bytes.
3156 * Place data at end of MF.
3158 pReq = (Config_t *)mf;
3160 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3161 frameOffset = ioc->req_sz - sizeof(SCSIDevicePage1_t);
3163 pData = (SCSIDevicePage1_t *)((u8 *) mf + frameOffset);
3164 dataDma = ioc->req_frames_dma + (req_idx * ioc->req_sz) + frameOffset;
3166 /* Complete the request frame (same for all requests).
3168 pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
3170 pReq->ChainOffset = 0;
3171 pReq->Function = MPI_FUNCTION_CONFIG;
3172 pReq->ExtPageLength = 0;
3173 pReq->ExtPageType = 0;
3175 for (ii=0; ii < 8; ii++) {
3176 pReq->Reserved2[ii] = 0;
3178 pReq->Header.PageVersion = ioc->spi_data.sdp1version;
3179 pReq->Header.PageLength = ioc->spi_data.sdp1length;
3180 pReq->Header.PageNumber = 1;
3181 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
3182 pReq->PageAddress = cpu_to_le32(id | (bus << 8 ));
3184 /* Add a SGE to the config request.
3186 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE | ioc->spi_data.sdp1length * 4;
3188 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma);
3190 /* Set up the common data portion
3192 pData->Header.PageVersion = pReq->Header.PageVersion;
3193 pData->Header.PageLength = pReq->Header.PageLength;
3194 pData->Header.PageNumber = pReq->Header.PageNumber;
3195 pData->Header.PageType = pReq->Header.PageType;
3196 pData->RequestedParameters = cpu_to_le32(requested);
3197 pData->Reserved = 0;
3198 pData->Configuration = cpu_to_le32(configuration);
3200 dprintk((MYIOC_s_INFO_FMT
3201 "write SDP1: id %d pgaddr 0x%x req 0x%x config 0x%x\n",
3202 ioc->name, id, (id | (bus<<8)),
3203 requested, configuration));
3205 mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
3211 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3212 /* mptscsih_writeIOCPage4 - write IOC Page 4
3213 * @hd: Pointer to a SCSI Host Structure
3214 * @target_id: write IOC Page4 for this ID & Bus
3216 * Return: -EAGAIN if unable to obtain a Message Frame
3219 * Remark: We do not wait for a return, write pages sequentially.
3222 mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus)
3224 MPT_ADAPTER *ioc = hd->ioc;
3226 IOCPage4_t *IOCPage4Ptr;
3234 /* Get a MF for this command.
3236 if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
3237 dfailprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n",
3242 /* Set the request and the data pointers.
3243 * Place data at end of MF.
3245 pReq = (Config_t *)mf;
3247 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3248 frameOffset = ioc->req_sz - sizeof(IOCPage4_t);
3250 /* Complete the request frame (same for all requests).
3252 pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
3254 pReq->ChainOffset = 0;
3255 pReq->Function = MPI_FUNCTION_CONFIG;
3256 pReq->ExtPageLength = 0;
3257 pReq->ExtPageType = 0;
3259 for (ii=0; ii < 8; ii++) {
3260 pReq->Reserved2[ii] = 0;
3263 IOCPage4Ptr = ioc->spi_data.pIocPg4;
3264 dataDma = ioc->spi_data.IocPg4_dma;
3265 ii = IOCPage4Ptr->ActiveSEP++;
3266 IOCPage4Ptr->SEP[ii].SEPTargetID = target_id;
3267 IOCPage4Ptr->SEP[ii].SEPBus = bus;
3268 pReq->Header = IOCPage4Ptr->Header;
3269 pReq->PageAddress = cpu_to_le32(target_id | (bus << 8 ));
3271 /* Add a SGE to the config request.
3273 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE |
3274 (IOCPage4Ptr->Header.PageLength + ii) * 4;
3276 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma);
3278 dinitprintk((MYIOC_s_INFO_FMT
3279 "writeIOCPage4: MaxSEP=%d ActiveSEP=%d id=%d bus=%d\n",
3280 ioc->name, IOCPage4Ptr->MaxSEP, IOCPage4Ptr->ActiveSEP, target_id, bus));
3282 mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
3287 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3289 * Bus Scan and Domain Validation functionality ...
3292 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3294 * mptscsih_scandv_complete - Scan and DV callback routine registered
3295 * to Fustion MPT (base) driver.
3297 * @ioc: Pointer to MPT_ADAPTER structure
3298 * @mf: Pointer to original MPT request frame
3299 * @mr: Pointer to MPT reply frame (NULL if TurboReply)
3301 * This routine is called from mpt.c::mpt_interrupt() at the completion
3302 * of any SCSI IO request.
3303 * This routine is registered with the Fusion MPT (base) driver at driver
3304 * load/init time via the mpt_register() API call.
3306 * Returns 1 indicating alloc'd request frame ptr should be freed.
3308 * Remark: Sets a completion code and (possibly) saves sense data
3309 * in the IOC member localReply structure.
3310 * Used ONLY for DV and other internal commands.
3313 mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
3316 SCSIIORequest_t *pReq;
3320 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
3323 (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) {
3324 printk(MYIOC_s_ERR_FMT
3325 "ScanDvComplete, %s req frame ptr! (=%p)\n",
3326 ioc->name, mf?"BAD":"NULL", (void *) mf);
3330 del_timer(&hd->timer);
3331 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3332 hd->ScsiLookup[req_idx] = NULL;
3333 pReq = (SCSIIORequest_t *) mf;
3335 if (mf != hd->cmdPtr) {
3336 printk(MYIOC_s_WARN_FMT "ScanDvComplete (mf=%p, cmdPtr=%p, idx=%d)\n",
3337 hd->ioc->name, (void *)mf, (void *) hd->cmdPtr, req_idx);
3341 ddvprintk((MYIOC_s_INFO_FMT "ScanDvComplete (mf=%p,mr=%p,idx=%d)\n",
3342 hd->ioc->name, mf, mr, req_idx));
3344 hd->pLocal = &hd->localReply;
3345 hd->pLocal->scsiStatus = 0;
3347 /* If target struct exists, clear sense valid flag.
3350 completionCode = MPT_SCANDV_GOOD;
3352 SCSIIOReply_t *pReply;
3356 pReply = (SCSIIOReply_t *) mr;
3358 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
3359 scsi_status = pReply->SCSIStatus;
3361 ddvtprintk((KERN_NOTICE " IOCStatus=%04xh, SCSIState=%02xh, SCSIStatus=%02xh, IOCLogInfo=%08xh\n",
3362 status, pReply->SCSIState, scsi_status,
3363 le32_to_cpu(pReply->IOCLogInfo)));
3367 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
3368 completionCode = MPT_SCANDV_SELECTION_TIMEOUT;
3371 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
3372 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
3373 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
3374 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
3375 completionCode = MPT_SCANDV_DID_RESET;
3378 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
3379 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
3380 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
3381 if (pReply->Function == MPI_FUNCTION_CONFIG) {
3382 ConfigReply_t *pr = (ConfigReply_t *)mr;
3383 completionCode = MPT_SCANDV_GOOD;
3384 hd->pLocal->header.PageVersion = pr->Header.PageVersion;
3385 hd->pLocal->header.PageLength = pr->Header.PageLength;
3386 hd->pLocal->header.PageNumber = pr->Header.PageNumber;
3387 hd->pLocal->header.PageType = pr->Header.PageType;
3389 } else if (pReply->Function == MPI_FUNCTION_RAID_ACTION) {
3390 /* If the RAID Volume request is successful,
3391 * return GOOD, else indicate that
3392 * some type of error occurred.
3394 MpiRaidActionReply_t *pr = (MpiRaidActionReply_t *)mr;
3395 if (le16_to_cpu(pr->ActionStatus) == MPI_RAID_ACTION_ASTATUS_SUCCESS)
3396 completionCode = MPT_SCANDV_GOOD;
3398 completionCode = MPT_SCANDV_SOME_ERROR;
3400 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID) {
3404 /* save sense data in global structure
3406 completionCode = MPT_SCANDV_SENSE;
3407 hd->pLocal->scsiStatus = scsi_status;
3408 sense_data = ((u8 *)hd->ioc->sense_buf_pool +
3409 (req_idx * MPT_SENSE_BUFFER_ALLOC));
3411 sz = min_t(int, pReq->SenseBufferLength,
3412 SCSI_STD_SENSE_BYTES);
3413 memcpy(hd->pLocal->sense, sense_data, sz);
3415 ddvprintk((KERN_NOTICE " Check Condition, sense ptr %p\n",
3417 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_FAILED) {
3418 if (pReq->CDB[0] == INQUIRY)
3419 completionCode = MPT_SCANDV_ISSUE_SENSE;
3421 completionCode = MPT_SCANDV_DID_RESET;
3423 else if (pReply->SCSIState & MPI_SCSI_STATE_NO_SCSI_STATUS)
3424 completionCode = MPT_SCANDV_DID_RESET;
3425 else if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
3426 completionCode = MPT_SCANDV_DID_RESET;
3428 completionCode = MPT_SCANDV_GOOD;
3429 hd->pLocal->scsiStatus = scsi_status;
3433 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
3434 if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
3435 completionCode = MPT_SCANDV_DID_RESET;
3437 completionCode = MPT_SCANDV_SOME_ERROR;
3441 completionCode = MPT_SCANDV_SOME_ERROR;
3444 } /* switch(status) */
3446 ddvtprintk((KERN_NOTICE " completionCode set to %08xh\n",
3448 } /* end of address reply case */
3450 hd->pLocal->completion = completionCode;
3452 /* MF and RF are freed in mpt_interrupt
3455 /* Free Chain buffers (will never chain) in scan or dv */
3456 //mptscsih_freeChainBuffers(ioc, req_idx);
3459 * Wake up the original calling thread
3461 hd->scandv_wait_done = 1;
3462 wake_up(&hd->scandv_waitq);
3467 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3468 /* mptscsih_timer_expired - Call back for timer process.
3469 * Used only for dv functionality.
3470 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
3474 mptscsih_timer_expired(unsigned long data)
3476 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) data;
3478 ddvprintk((MYIOC_s_WARN_FMT "Timer Expired! Cmd %p\n", hd->ioc->name, hd->cmdPtr));
3481 MPIHeader_t *cmd = (MPIHeader_t *)hd->cmdPtr;
3483 if (cmd->Function == MPI_FUNCTION_SCSI_IO_REQUEST) {
3484 /* Desire to issue a task management request here.
3485 * TM requests MUST be single threaded.
3486 * If old eh code and no TM current, issue request.
3487 * If new eh code, do nothing. Wait for OS cmd timeout
3490 ddvtprintk((MYIOC_s_NOTE_FMT "DV Cmd Timeout: NoOp\n", hd->ioc->name));
3492 /* Perform a FW reload */
3493 if (mpt_HardResetHandler(hd->ioc, NO_SLEEP) < 0) {
3494 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", hd->ioc->name);
3498 /* This should NEVER happen */
3499 printk(MYIOC_s_WARN_FMT "Null cmdPtr!!!!\n", hd->ioc->name);
3502 /* No more processing.
3503 * TM call will generate an interrupt for SCSI TM Management.
3504 * The FW will reply to all outstanding commands, callback will finish cleanup.
3505 * Hard reset clean-up will free all resources.
3507 ddvprintk((MYIOC_s_WARN_FMT "Timer Expired Complete!\n", hd->ioc->name));
3512 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
3513 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3514 /* mptscsih_do_raid - Format and Issue a RAID volume request message.
3515 * @hd: Pointer to scsi host structure
3516 * @action: What do be done.
3517 * @id: Logical target id.
3518 * @bus: Target locations bus.
3520 * Returns: < 0 on a fatal error
3523 * Remark: Wait to return until reply processed by the ISR.
3526 mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io)
3528 MpiRaidActionRequest_t *pReq;
3532 in_isr = in_interrupt();
3534 dprintk((MYIOC_s_WARN_FMT "Internal raid request not allowed in ISR context!\n",
3539 /* Get and Populate a free Frame
3541 if ((mf = mpt_get_msg_frame(hd->ioc->InternalCtx, hd->ioc)) == NULL) {
3542 ddvprintk((MYIOC_s_WARN_FMT "_do_raid: no msg frames!\n",
3546 pReq = (MpiRaidActionRequest_t *)mf;
3547 pReq->Action = action;
3548 pReq->Reserved1 = 0;
3549 pReq->ChainOffset = 0;
3550 pReq->Function = MPI_FUNCTION_RAID_ACTION;
3551 pReq->VolumeID = io->id;
3552 pReq->VolumeBus = io->bus;
3553 pReq->PhysDiskNum = io->physDiskNum;
3555 pReq->Reserved2 = 0;
3556 pReq->ActionDataWord = 0; /* Reserved for this action */
3557 //pReq->ActionDataSGE = 0;
3559 mpt_add_sge((char *)&pReq->ActionDataSGE,
3560 MPT_SGE_FLAGS_SSIMPLE_READ | 0, (dma_addr_t) -1);
3562 ddvprintk((MYIOC_s_INFO_FMT "RAID Volume action %x id %d\n",
3563 hd->ioc->name, action, io->id));
3566 hd->timer.expires = jiffies + HZ*10; /* 10 second timeout */
3567 hd->scandv_wait_done = 0;
3569 /* Save cmd pointer, for resource free if timeout or
3574 add_timer(&hd->timer);
3575 mpt_put_msg_frame(hd->ioc->InternalCtx, hd->ioc, mf);
3576 wait_event(hd->scandv_waitq, hd->scandv_wait_done);
3578 if ((hd->pLocal == NULL) || (hd->pLocal->completion != MPT_SCANDV_GOOD))
3583 #endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */
3585 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3587 * mptscsih_do_cmd - Do internal command.
3588 * @hd: MPT_SCSI_HOST pointer
3589 * @io: INTERNAL_CMD pointer.
3591 * Issue the specified internally generated command and do command
3592 * specific cleanup. For bus scan / DV only.
3593 * NOTES: If command is Inquiry and status is good,
3594 * initialize a target structure, save the data
3596 * Remark: Single threaded access only.
3599 * < 0 if an illegal command or no resources
3603 * > 0 if command complete but some type of completion error.
3606 mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
3609 SCSIIORequest_t *pScsiReq;
3610 SCSIIORequest_t ReqCopy;
3611 int my_idx, ii, dir;
3615 char CDB[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
3618 in_isr = in_interrupt();
3620 dprintk((MYIOC_s_WARN_FMT "Internal SCSI IO request not allowed in ISR context!\n",
3626 /* Set command specific information
3631 dir = MPI_SCSIIO_CONTROL_READ;
3637 case TEST_UNIT_READY:
3639 dir = MPI_SCSIIO_CONTROL_READ;
3645 dir = MPI_SCSIIO_CONTROL_READ;
3647 CDB[4] = 1; /*Spin up the disk */
3655 dir = MPI_SCSIIO_CONTROL_READ;
3661 dir = MPI_SCSIIO_CONTROL_READ;
3663 if (io->flags & MPT_ICFLAG_ECHO) {
3669 if (io->flags & MPT_ICFLAG_BUF_CAP) {
3672 CDB[6] = (io->size >> 16) & 0xFF;
3673 CDB[7] = (io->size >> 8) & 0xFF;
3674 CDB[8] = io->size & 0xFF;
3680 dir = MPI_SCSIIO_CONTROL_WRITE;
3682 if (io->flags & MPT_ICFLAG_ECHO) {
3687 CDB[6] = (io->size >> 16) & 0xFF;
3688 CDB[7] = (io->size >> 8) & 0xFF;
3689 CDB[8] = io->size & 0xFF;
3695 dir = MPI_SCSIIO_CONTROL_READ;
3702 dir = MPI_SCSIIO_CONTROL_READ;
3707 case SYNCHRONIZE_CACHE:
3709 dir = MPI_SCSIIO_CONTROL_READ;
3711 // CDB[1] = 0x02; /* set immediate bit */
3720 /* Get and Populate a free Frame
3722 if ((mf = mpt_get_msg_frame(hd->ioc->InternalCtx, hd->ioc)) == NULL) {
3723 ddvprintk((MYIOC_s_WARN_FMT "No msg frames!\n",
3728 pScsiReq = (SCSIIORequest_t *) mf;
3730 /* Get the request index */
3731 my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3732 ADD_INDEX_LOG(my_idx); /* for debug */
3734 if (io->flags & MPT_ICFLAG_PHYS_DISK) {
3735 pScsiReq->TargetID = io->physDiskNum;
3737 pScsiReq->ChainOffset = 0;
3738 pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
3740 pScsiReq->TargetID = io->id;
3741 pScsiReq->Bus = io->bus;
3742 pScsiReq->ChainOffset = 0;
3743 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
3746 pScsiReq->CDBLength = cmdLen;
3747 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
3749 pScsiReq->Reserved = 0;
3751 pScsiReq->MsgFlags = mpt_msg_flags();
3752 /* MsgContext set in mpt_get_msg_fram call */
3754 for (ii=0; ii < 8; ii++)
3755 pScsiReq->LUN[ii] = 0;
3756 pScsiReq->LUN[1] = io->lun;
3758 if (io->flags & MPT_ICFLAG_TAGGED_CMD)
3759 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ);
3761 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3763 if (cmd == REQUEST_SENSE) {
3764 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3765 ddvprintk((MYIOC_s_INFO_FMT "Untagged! 0x%2x\n",
3766 hd->ioc->name, cmd));
3769 for (ii=0; ii < 16; ii++)
3770 pScsiReq->CDB[ii] = CDB[ii];
3772 pScsiReq->DataLength = cpu_to_le32(io->size);
3773 pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
3774 + (my_idx * MPT_SENSE_BUFFER_ALLOC));
3776 ddvprintk((MYIOC_s_INFO_FMT "Sending Command 0x%x for (%d:%d:%d)\n",
3777 hd->ioc->name, cmd, io->bus, io->id, io->lun));
3779 if (dir == MPI_SCSIIO_CONTROL_READ) {
3780 mpt_add_sge((char *) &pScsiReq->SGL,
3781 MPT_SGE_FLAGS_SSIMPLE_READ | io->size,
3784 mpt_add_sge((char *) &pScsiReq->SGL,
3785 MPT_SGE_FLAGS_SSIMPLE_WRITE | io->size,
3789 /* The ISR will free the request frame, but we need
3790 * the information to initialize the target. Duplicate.
3792 memcpy(&ReqCopy, pScsiReq, sizeof(SCSIIORequest_t));
3794 /* Issue this command after:
3797 * Wait until the reply has been received
3798 * ScsiScanDvCtx callback function will
3800 * set scandv_wait_done and call wake_up
3803 hd->timer.expires = jiffies + HZ*cmdTimeout;
3804 hd->scandv_wait_done = 0;
3806 /* Save cmd pointer, for resource free if timeout or
3811 add_timer(&hd->timer);
3812 mpt_put_msg_frame(hd->ioc->InternalCtx, hd->ioc, mf);
3813 wait_event(hd->scandv_waitq, hd->scandv_wait_done);
3816 rc = hd->pLocal->completion;
3817 hd->pLocal->skip = 0;
3819 /* Always set fatal error codes in some cases.
3821 if (rc == MPT_SCANDV_SELECTION_TIMEOUT)
3823 else if (rc == MPT_SCANDV_SOME_ERROR)
3827 /* This should never happen. */
3828 ddvprintk((MYIOC_s_INFO_FMT "_do_cmd: Null pLocal!!!\n",
3835 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3837 * mptscsih_negotiate_to_asyn_narrow - Restore devices to default state
3838 * @hd: Pointer to a SCSI HOST structure
3839 * @vtarget: per device private data
3841 * Uses the ISR, but with special processing.
3842 * MUST be single-threaded.
3846 mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtTarget *vtarget)
3848 MPT_ADAPTER *ioc= hd->ioc;
3849 SCSIDevicePage1_t *pcfg1Data;
3851 dma_addr_t cfg1_dma_addr;
3852 ConfigPageHeader_t header;
3854 int requested, configuration, data,i;
3857 if (ioc->bus_type != SPI)
3860 if (!ioc->spi_data.sdp1length)
3863 pcfg1Data = (SCSIDevicePage1_t *)pci_alloc_consistent(ioc->pcidev,
3864 ioc->spi_data.sdp1length * 4, &cfg1_dma_addr);
3866 if (pcfg1Data == NULL)
3869 header.PageVersion = ioc->spi_data.sdp1version;
3870 header.PageLength = ioc->spi_data.sdp1length;
3871 header.PageNumber = 1;
3872 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
3873 cfg.cfghdr.hdr = &header;
3874 cfg.physAddr = cfg1_dma_addr;
3875 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
3879 if (vtarget->raidVolume && ioc->raid_data.pIocPg3) {
3880 for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
3881 id = ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID;
3882 flags = hd->ioc->spi_data.noQas;
3883 if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
3884 data = hd->ioc->spi_data.nvram[id];
3885 if (data & MPT_NVRAM_WIDE_DISABLE)
3886 flags |= MPT_TARGET_NO_NEGO_WIDE;
3887 factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT;
3888 if ((factor == 0) || (factor == MPT_ASYNC))
3889 flags |= MPT_TARGET_NO_NEGO_SYNC;
3891 mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested,
3892 &configuration, flags);
3893 dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC "
3894 "offset=0 negoFlags=%x request=%x config=%x\n",
3895 id, flags, requested, configuration));
3896 pcfg1Data->RequestedParameters = cpu_to_le32(requested);
3897 pcfg1Data->Reserved = 0;
3898 pcfg1Data->Configuration = cpu_to_le32(configuration);
3899 cfg.pageAddr = (vtarget->bus_id<<8) | id;
3900 mpt_config(hd->ioc, &cfg);
3903 flags = vtarget->negoFlags;
3904 mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested,
3905 &configuration, flags);
3906 dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC "
3907 "offset=0 negoFlags=%x request=%x config=%x\n",
3908 vtarget->target_id, flags, requested, configuration));
3909 pcfg1Data->RequestedParameters = cpu_to_le32(requested);
3910 pcfg1Data->Reserved = 0;
3911 pcfg1Data->Configuration = cpu_to_le32(configuration);
3912 cfg.pageAddr = (vtarget->bus_id<<8) | vtarget->target_id;
3913 mpt_config(hd->ioc, &cfg);
3917 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pcfg1Data, cfg1_dma_addr);
3920 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3922 * mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
3923 * @hd: Pointer to a SCSI HOST structure
3924 * @vtarget: per device private data
3927 * Uses the ISR, but with special processing.
3928 * MUST be single-threaded.
3932 mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
3936 /* Following parameters will not change
3939 iocmd.cmd = SYNCHRONIZE_CACHE;
3941 iocmd.physDiskNum = -1;
3943 iocmd.data_dma = -1;
3945 iocmd.rsvd = iocmd.rsvd2 = 0;
3946 iocmd.bus = vdevice->bus_id;
3947 iocmd.id = vdevice->target_id;
3948 iocmd.lun = (u8)vdevice->lun;
3950 if ((vdevice->vtarget->type & TYPE_DISK) &&
3951 (vdevice->configured_lun))
3952 mptscsih_do_cmd(hd, &iocmd);
3955 /* Search IOC page 3 to determine if this is hidden physical disk
3957 /* Search IOC page 3 to determine if this is hidden physical disk
3960 mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id)
3964 if (!ioc->raid_data.isRaid || !ioc->raid_data.pIocPg3)
3967 for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
3968 if (id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID)
3975 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
3976 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3978 * mptscsih_domainValidation - Top level handler for domain validation.
3979 * @hd: Pointer to MPT_SCSI_HOST structure.
3981 * Uses the ISR, but with special processing.
3982 * Called from schedule, should not be in interrupt mode.
3983 * While thread alive, do dv for all devices needing dv
3988 mptscsih_domainValidation(void *arg)
3992 unsigned long flags;
3993 int id, maxid, dvStatus, did;
3996 spin_lock_irqsave(&dvtaskQ_lock, flags);
3998 if (dvtaskQ_release) {
4000 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4003 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4005 /* For this ioc, loop through all devices and do dv to each device.
4006 * When complete with this ioc, search through the ioc list, and
4007 * for each scsi ioc found, do dv for all devices. Exit when no
4013 list_for_each_entry(ioc, &ioc_list, list) {
4014 spin_lock_irqsave(&dvtaskQ_lock, flags);
4015 if (dvtaskQ_release) {
4017 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4020 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4024 /* DV only to SPI adapters */
4025 if (ioc->bus_type != SPI)
4028 /* Make sure everything looks ok */
4029 if (ioc->sh == NULL)
4032 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
4036 if ((ioc->spi_data.forceDv & MPT_SCSICFG_RELOAD_IOC_PG3) != 0) {
4037 mpt_read_ioc_pg_3(ioc);
4038 if (ioc->raid_data.pIocPg3) {
4039 Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
4040 int numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
4043 if (ioc->spi_data.dvStatus[pPDisk->PhysDiskID] & MPT_SCSICFG_DV_NOT_DONE)
4044 ioc->spi_data.dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV;
4050 ioc->spi_data.forceDv &= ~MPT_SCSICFG_RELOAD_IOC_PG3;
4053 maxid = min_t(int, ioc->sh->max_id, MPT_MAX_SCSI_DEVICES);
4055 for (id = 0; id < maxid; id++) {
4056 spin_lock_irqsave(&dvtaskQ_lock, flags);
4057 if (dvtaskQ_release) {
4059 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4062 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4063 dvStatus = hd->ioc->spi_data.dvStatus[id];
4065 if (dvStatus & MPT_SCSICFG_NEED_DV) {
4067 hd->ioc->spi_data.dvStatus[id] |= MPT_SCSICFG_DV_PENDING;
4068 hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_NEED_DV;
4072 /* If hidden phys disk, block IO's to all
4074 * else, process normally
4076 isPhysDisk = mptscsih_is_phys_disk(ioc, id);
4078 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4079 if (hd->ioc->raid_data.isRaid & (1 << ii)) {
4080 hd->ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_DV_PENDING;
4085 if(mpt_alt_ioc_wait(hd->ioc)!=0) {
4086 ddvprintk((MYIOC_s_WARN_FMT "alt_ioc busy!\n",
4091 if (mptscsih_doDv(hd, 0, id) == 1) {
4092 /* Untagged device was busy, try again
4094 hd->ioc->spi_data.dvStatus[id] |= MPT_SCSICFG_NEED_DV;
4095 hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_PENDING;
4097 /* DV is complete. Clear flags.
4099 hd->ioc->spi_data.dvStatus[id] &= ~(MPT_SCSICFG_DV_NOT_DONE | MPT_SCSICFG_DV_PENDING);
4102 spin_lock(&hd->ioc->initializing_hba_lock);
4103 hd->ioc->initializing_hba_lock_flag=0;
4104 spin_unlock(&hd->ioc->initializing_hba_lock);
4107 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4108 if (hd->ioc->raid_data.isRaid & (1 << ii)) {
4109 hd->ioc->spi_data.dvStatus[ii] &= ~MPT_SCSICFG_DV_PENDING;
4114 if (hd->ioc->spi_data.noQas)
4115 mptscsih_qas_check(hd, id);
4121 spin_lock_irqsave(&dvtaskQ_lock, flags);
4123 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4128 /* Write SDP1 if no QAS has been enabled
4131 mptscsih_qas_check(MPT_SCSI_HOST *hd, int id)
4133 VirtTarget *vtarget;
4136 if (hd->Targets == NULL)
4139 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4143 if ((hd->ioc->spi_data.dvStatus[ii] & MPT_SCSICFG_DV_NOT_DONE) != 0)
4146 vtarget = hd->Targets[ii];
4148 if ((vtarget != NULL) && (!vtarget->raidVolume)) {
4149 if ((vtarget->negoFlags & hd->ioc->spi_data.noQas) == 0) {
4150 vtarget->negoFlags |= hd->ioc->spi_data.noQas;
4151 dnegoprintk(("writeSDP1: id=%d flags=0\n", id));
4152 mptscsih_writeSDP1(hd, 0, ii, 0);
4155 if (mptscsih_is_phys_disk(hd->ioc, ii) == 1) {
4156 dnegoprintk(("writeSDP1: id=%d SCSICFG_USE_NVRAM\n", id));
4157 mptscsih_writeSDP1(hd, 0, ii, MPT_SCSICFG_USE_NVRAM);
4166 #define MPT_GET_NVRAM_VALS 0x01
4167 #define MPT_UPDATE_MAX 0x02
4168 #define MPT_SET_MAX 0x04
4169 #define MPT_SET_MIN 0x08
4170 #define MPT_FALLBACK 0x10
4171 #define MPT_SAVE 0x20
4173 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4175 * mptscsih_doDv - Perform domain validation to a target.
4176 * @hd: Pointer to MPT_SCSI_HOST structure.
4177 * @portnum: IOC port number.
4178 * @target: Physical ID of this target
4180 * Uses the ISR, but with special processing.
4181 * MUST be single-threaded.
4182 * Test will exit if target is at async & narrow.
4187 mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
4189 MPT_ADAPTER *ioc = hd->ioc;
4190 VirtTarget *vtarget;
4191 SCSIDevicePage1_t *pcfg1Data;
4192 SCSIDevicePage0_t *pcfg0Data;
4196 dma_addr_t dvbuf_dma = -1;
4197 dma_addr_t buf1_dma = -1;
4198 dma_addr_t buf2_dma = -1;
4199 dma_addr_t cfg1_dma_addr = -1;
4200 dma_addr_t cfg0_dma_addr = -1;
4201 ConfigPageHeader_t header1;
4202 ConfigPageHeader_t header0;
4209 int dataBufSize = 0;
4210 int echoBufSize = 0;
4215 int nfactor = MPT_ULTRA320;
4217 char doFallback = 0;
4222 if (ioc->spi_data.sdp1length == 0)
4225 if (ioc->spi_data.sdp0length == 0)
4228 /* If multiple buses are used, require that the initiator
4229 * id be the same on all buses.
4231 if (id == ioc->pfacts[0].PortSCSIID)
4235 bus = (u8) bus_number;
4236 ddvtprintk((MYIOC_s_NOTE_FMT
4237 "DV started: bus=%d, id=%d dv @ %p\n",
4238 ioc->name, bus, id, &dv));
4240 /* Prep DV structure
4242 memset (&dv, 0, sizeof(DVPARAMETERS));
4245 /* Populate tmax with the current maximum
4246 * transfer parameters for this target.
4247 * Exit if narrow and async.
4249 dv.cmd = MPT_GET_NVRAM_VALS;
4250 mptscsih_dv_parms(hd, &dv, NULL);
4252 /* Prep SCSI IO structure
4258 iocmd.physDiskNum = -1;
4259 iocmd.rsvd = iocmd.rsvd2 = 0;
4261 vtarget = hd->Targets[id];
4263 /* Use tagged commands if possible.
4266 if (vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)
4267 iocmd.flags |= MPT_ICFLAG_TAGGED_CMD;
4269 if (hd->ioc->facts.FWVersion.Word < 0x01000600)
4272 if ((hd->ioc->facts.FWVersion.Word >= 0x01010000) &&
4273 (hd->ioc->facts.FWVersion.Word < 0x01010B00))
4278 /* Prep cfg structure
4280 cfg.pageAddr = (bus<<8) | id;
4281 cfg.cfghdr.hdr = NULL;
4285 header0.PageVersion = ioc->spi_data.sdp0version;
4286 header0.PageLength = ioc->spi_data.sdp0length;
4287 header0.PageNumber = 0;
4288 header0.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4292 header1.PageVersion = ioc->spi_data.sdp1version;
4293 header1.PageLength = ioc->spi_data.sdp1length;
4294 header1.PageNumber = 1;
4295 header1.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4297 if (header0.PageLength & 1)
4298 dv_alloc = (header0.PageLength * 4) + 4;
4300 dv_alloc += (2048 + (header1.PageLength * 4));
4302 pDvBuf = pci_alloc_consistent(ioc->pcidev, dv_alloc, &dvbuf_dma);
4307 pbuf1 = (u8 *)pDvBuf;
4308 buf1_dma = dvbuf_dma;
4311 pbuf2 = (u8 *) (pDvBuf + sz);
4312 buf2_dma = dvbuf_dma + sz;
4315 pcfg0Data = (SCSIDevicePage0_t *) (pDvBuf + sz);
4316 cfg0_dma_addr = dvbuf_dma + sz;
4317 sz += header0.PageLength * 4;
4321 if (header0.PageLength & 1)
4324 pcfg1Data = (SCSIDevicePage1_t *) (pDvBuf + sz);
4325 cfg1_dma_addr = dvbuf_dma + sz;
4327 /* Skip this ID? Set cfg.cfghdr.hdr to force config page write
4330 SpiCfgData *pspi_data = &hd->ioc->spi_data;
4331 if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
4332 /* Set the factor from nvram */
4333 nfactor = (pspi_data->nvram[id] & MPT_NVRAM_SYNC_MASK) >> 8;
4334 if (nfactor < pspi_data->minSyncFactor )
4335 nfactor = pspi_data->minSyncFactor;
4337 if (!(pspi_data->nvram[id] & MPT_NVRAM_ID_SCAN_ENABLE) ||
4338 (pspi_data->PortFlags == MPI_SCSIPORTPAGE2_PORT_FLAGS_OFF_DV) ) {
4340 ddvprintk((MYIOC_s_NOTE_FMT "DV Skipped: bus, id, lun (%d, %d, %d)\n",
4341 ioc->name, bus, id, lun));
4343 dv.cmd = MPT_SET_MAX;
4344 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
4345 cfg.cfghdr.hdr = &header1;
4347 /* Save the final negotiated settings to
4348 * SCSI device page 1.
4350 cfg.physAddr = cfg1_dma_addr;
4351 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4353 mpt_config(hd->ioc, &cfg);
4359 /* Finish iocmd inititialization - hidden or visible disk? */
4360 if (ioc->raid_data.pIocPg3) {
4361 /* Search IOC page 3 for matching id
4363 Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
4364 int numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
4367 if (pPDisk->PhysDiskID == id) {
4369 iocmd.flags |= MPT_ICFLAG_PHYS_DISK;
4370 iocmd.physDiskNum = pPDisk->PhysDiskNum;
4374 if (mptscsih_do_raid(hd, MPI_RAID_ACTION_QUIESCE_PHYS_IO, &iocmd) < 0) {
4375 ddvprintk((MYIOC_s_ERR_FMT "RAID Queisce FAILED!\n", ioc->name));
4385 /* RAID Volume ID's may double for a physical device. If RAID but
4386 * not a physical ID as well, skip DV.
4388 if ((hd->ioc->raid_data.isRaid & (1 << id)) && !(iocmd.flags & MPT_ICFLAG_PHYS_DISK))
4393 * Async & Narrow - Inquiry
4394 * Async & Narrow - Inquiry
4395 * Maximum transfer rate - Inquiry
4397 * If compare, test complete.
4398 * If miscompare and first pass, repeat
4399 * If miscompare and not first pass, fall back and repeat
4403 sz = SCSI_MAX_INQUIRY_BYTES;
4404 rc = MPT_SCANDV_GOOD;
4406 ddvprintk((MYIOC_s_NOTE_FMT "DV: Start Basic test on id=%d\n", ioc->name, id));
4408 dv.cmd = MPT_SET_MIN;
4409 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
4411 cfg.cfghdr.hdr = &header1;
4412 cfg.physAddr = cfg1_dma_addr;
4413 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4415 if (mpt_config(hd->ioc, &cfg) != 0)
4418 /* Wide - narrow - wide workaround case
4420 if ((rc == MPT_SCANDV_ISSUE_SENSE) && dv.max.width) {
4421 /* Send an untagged command to reset disk Qs corrupted
4422 * when a parity error occurs on a Request Sense.
4424 if ((hd->ioc->facts.FWVersion.Word >= 0x01000600) ||
4425 ((hd->ioc->facts.FWVersion.Word >= 0x01010000) &&
4426 (hd->ioc->facts.FWVersion.Word < 0x01010B00)) ) {
4428 iocmd.cmd = REQUEST_SENSE;
4429 iocmd.data_dma = buf1_dma;
4432 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4435 if (hd->pLocal == NULL)
4437 rc = hd->pLocal->completion;
4438 if ((rc == MPT_SCANDV_GOOD) || (rc == MPT_SCANDV_SENSE)) {
4448 iocmd.cmd = INQUIRY;
4449 iocmd.data_dma = buf1_dma;
4452 memset(pbuf1, 0x00, sz);
4453 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4456 if (hd->pLocal == NULL)
4458 rc = hd->pLocal->completion;
4459 if (rc == MPT_SCANDV_GOOD) {
4460 if (hd->pLocal->scsiStatus == SAM_STAT_BUSY) {
4461 if ((iocmd.flags & MPT_ICFLAG_TAGGED_CMD) == 0)
4468 } else if (rc == MPT_SCANDV_SENSE) {
4471 /* If first command doesn't complete
4472 * with a good status or with a check condition,
4479 /* Reset the size for disks
4481 inq0 = (*pbuf1) & 0x1F;
4482 if ((inq0 == 0) && vtarget && !vtarget->raidVolume) {
4487 /* Another GEM workaround. Check peripheral device type,
4488 * if PROCESSOR, quit DV.
4490 if (inq0 == TYPE_PROCESSOR) {
4491 mptscsih_initTarget(hd,
4502 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4506 if ((vtarget->maxWidth == 1) && (vtarget->maxOffset) && (nfactor < 0x0A)
4507 && (vtarget->minSyncFactor > 0x09)) {
4508 if ((pbuf1[56] & 0x04) == 0)
4510 else if ((pbuf1[56] & 0x01) == 1) {
4511 vtarget->minSyncFactor =
4512 nfactor > MPT_ULTRA320 ? nfactor : MPT_ULTRA320;
4514 vtarget->minSyncFactor =
4515 nfactor > MPT_ULTRA160 ? nfactor : MPT_ULTRA160;
4518 dv.max.factor = vtarget->minSyncFactor;
4520 if ((pbuf1[56] & 0x02) == 0) {
4521 vtarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
4522 hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS;
4523 ddvprintk((MYIOC_s_NOTE_FMT
4524 "DV: Start Basic noQas on id=%d due to pbuf1[56]=%x\n",
4525 ioc->name, id, pbuf1[56]));
4531 dv.cmd = MPT_FALLBACK;
4533 dv.cmd = MPT_SET_MAX;
4535 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
4536 if (mpt_config(hd->ioc, &cfg) != 0)
4539 if ((!dv.now.width) && (!dv.now.offset))
4542 iocmd.cmd = INQUIRY;
4543 iocmd.data_dma = buf2_dma;
4546 memset(pbuf2, 0x00, sz);
4547 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4549 else if (hd->pLocal == NULL)
4552 /* Save the return code.
4553 * If this is the first pass,
4554 * read SCSI Device Page 0
4555 * and update the target max parameters.
4557 rc = hd->pLocal->completion;
4559 if (rc == MPT_SCANDV_GOOD) {
4564 cfg.cfghdr.hdr = &header0;
4565 cfg.physAddr = cfg0_dma_addr;
4566 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4569 if (mpt_config(hd->ioc, &cfg) != 0)
4572 sdp0_info = le32_to_cpu(pcfg0Data->Information) & 0x0E;
4573 sdp0_nego = (le32_to_cpu(pcfg0Data->NegotiatedParameters) & 0xFF00 ) >> 8;
4575 /* Quantum and Fujitsu workarounds.
4576 * Quantum: PPR U320 -> PPR reply with Ultra2 and wide
4577 * Fujitsu: PPR U320 -> Msg Reject and Ultra2 and wide
4578 * Resetart with a request for U160.
4580 if ((dv.now.factor == MPT_ULTRA320) && (sdp0_nego == MPT_ULTRA2)) {
4583 dv.cmd = MPT_UPDATE_MAX;
4584 mptscsih_dv_parms(hd, &dv, (void *)pcfg0Data);
4585 /* Update the SCSI device page 1 area
4587 pcfg1Data->RequestedParameters = pcfg0Data->NegotiatedParameters;
4592 /* Quantum workaround. Restart this test will the fallback
4595 if (doFallback == 0) {
4596 if (memcmp(pbuf1, pbuf2, sz) != 0) {
4600 ddvprintk((MYIOC_s_NOTE_FMT
4601 "DV:Inquiry compared id=%d, calling initTarget\n", ioc->name, id));
4602 hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_NOT_DONE;
4603 mptscsih_initTarget(hd,
4608 break; /* test complete */
4613 } else if (rc == MPT_SCANDV_ISSUE_SENSE)
4614 doFallback = 1; /* set fallback flag */
4615 else if ((rc == MPT_SCANDV_DID_RESET) ||
4616 (rc == MPT_SCANDV_SENSE) ||
4617 (rc == MPT_SCANDV_FALLBACK))
4618 doFallback = 1; /* set fallback flag */
4625 ddvprintk((MYIOC_s_NOTE_FMT "DV: Basic test on id=%d completed OK.\n", ioc->name, id));
4627 if (ioc->spi_data.mpt_dv == 0)
4630 inq0 = (*pbuf1) & 0x1F;
4632 /* Continue only for disks
4637 if ( ioc->spi_data.PortFlags == MPI_SCSIPORTPAGE2_PORT_FLAGS_BASIC_DV_ONLY )
4640 /* Start the Enhanced Test.
4641 * 0) issue TUR to clear out check conditions
4642 * 1) read capacity of echo (regular) buffer
4644 * 3) do write-read-compare data pattern test
4646 * 5) update nego parms to target struct
4648 cfg.cfghdr.hdr = &header1;
4649 cfg.physAddr = cfg1_dma_addr;
4650 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4653 iocmd.cmd = TEST_UNIT_READY;
4654 iocmd.data_dma = -1;
4659 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4662 if (hd->pLocal == NULL)
4665 rc = hd->pLocal->completion;
4666 if (rc == MPT_SCANDV_GOOD)
4668 else if (rc == MPT_SCANDV_SENSE) {
4669 u8 skey = hd->pLocal->sense[2] & 0x0F;
4670 u8 asc = hd->pLocal->sense[12];
4671 u8 ascq = hd->pLocal->sense[13];
4672 ddvprintk((MYIOC_s_INFO_FMT
4673 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
4674 ioc->name, skey, asc, ascq));
4676 if (skey == UNIT_ATTENTION)
4677 notDone++; /* repeat */
4678 else if ((skey == NOT_READY) &&
4679 (asc == 0x04)&&(ascq == 0x01)) {
4680 /* wait then repeat */
4683 } else if ((skey == NOT_READY) && (asc == 0x3A)) {
4684 /* no medium, try read test anyway */
4687 /* All other errors are fatal.
4689 ddvprintk((MYIOC_s_INFO_FMT "DV: fatal error.",
4697 iocmd.cmd = READ_BUFFER;
4698 iocmd.data_dma = buf1_dma;
4701 iocmd.flags |= MPT_ICFLAG_BUF_CAP;
4705 for (patt = 0; patt < 2; patt++) {
4707 iocmd.flags |= MPT_ICFLAG_ECHO;
4709 iocmd.flags &= ~MPT_ICFLAG_ECHO;
4715 /* If not ready after 8 trials,
4716 * give up on this device.
4721 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4723 else if (hd->pLocal == NULL)
4726 rc = hd->pLocal->completion;
4727 ddvprintk(("ReadBuffer Comp Code %d", rc));
4728 ddvprintk((" buff: %0x %0x %0x %0x\n",
4729 pbuf1[0], pbuf1[1], pbuf1[2], pbuf1[3]));
4731 if (rc == MPT_SCANDV_GOOD) {
4733 if (iocmd.flags & MPT_ICFLAG_ECHO) {
4734 bufsize = ((pbuf1[2] & 0x1F) <<8) | pbuf1[3];
4735 if (pbuf1[0] & 0x01)
4736 iocmd.flags |= MPT_ICFLAG_EBOS;
4738 bufsize = pbuf1[1]<<16 | pbuf1[2]<<8 | pbuf1[3];
4740 } else if (rc == MPT_SCANDV_SENSE) {
4741 u8 skey = hd->pLocal->sense[2] & 0x0F;
4742 u8 asc = hd->pLocal->sense[12];
4743 u8 ascq = hd->pLocal->sense[13];
4744 ddvprintk((MYIOC_s_INFO_FMT
4745 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
4746 ioc->name, skey, asc, ascq));
4747 if (skey == ILLEGAL_REQUEST) {
4749 } else if (skey == UNIT_ATTENTION) {
4750 notDone++; /* repeat */
4751 } else if ((skey == NOT_READY) &&
4752 (asc == 0x04)&&(ascq == 0x01)) {
4753 /* wait then repeat */
4757 /* All other errors are fatal.
4759 ddvprintk((MYIOC_s_INFO_FMT "DV: fatal error.",
4764 /* All other errors are fatal
4771 if (iocmd.flags & MPT_ICFLAG_ECHO)
4772 echoBufSize = bufsize;
4774 dataBufSize = bufsize;
4777 iocmd.flags &= ~MPT_ICFLAG_BUF_CAP;
4779 /* Use echo buffers if possible,
4780 * Exit if both buffers are 0.
4782 if (echoBufSize > 0) {
4783 iocmd.flags |= MPT_ICFLAG_ECHO;
4784 if (dataBufSize > 0)
4785 bufsize = min(echoBufSize, dataBufSize);
4787 bufsize = echoBufSize;
4788 } else if (dataBufSize == 0)
4791 ddvprintk((MYIOC_s_INFO_FMT "%s Buffer Capacity %d\n", ioc->name,
4792 (iocmd.flags & MPT_ICFLAG_ECHO) ? "Echo" : " ", bufsize));
4794 /* Data buffers for write-read-compare test max 1K.
4796 sz = min(bufsize, 1024);
4799 * On first pass, always issue a reserve.
4800 * On additional loops, only if a reset has occurred.
4801 * iocmd.flags indicates if echo or regular buffer
4803 for (patt = 0; patt < 4; patt++) {
4804 ddvprintk(("Pattern %d\n", patt));
4805 if ((iocmd.flags & MPT_ICFLAG_RESERVED) && (iocmd.flags & MPT_ICFLAG_DID_RESET)) {
4806 iocmd.cmd = TEST_UNIT_READY;
4807 iocmd.data_dma = -1;
4810 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4813 iocmd.cmd = RELEASE;
4814 iocmd.data_dma = -1;
4817 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4819 else if (hd->pLocal == NULL)
4822 rc = hd->pLocal->completion;
4823 ddvprintk(("Release rc %d\n", rc));
4824 if (rc == MPT_SCANDV_GOOD)
4825 iocmd.flags &= ~MPT_ICFLAG_RESERVED;
4829 iocmd.flags &= ~MPT_ICFLAG_RESERVED;
4831 iocmd.flags &= ~MPT_ICFLAG_DID_RESET;
4833 if (iocmd.flags & MPT_ICFLAG_EBOS)
4837 while (repeat && (!(iocmd.flags & MPT_ICFLAG_RESERVED))) {
4838 iocmd.cmd = RESERVE;
4839 iocmd.data_dma = -1;
4842 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4844 else if (hd->pLocal == NULL)
4847 rc = hd->pLocal->completion;
4848 if (rc == MPT_SCANDV_GOOD) {
4849 iocmd.flags |= MPT_ICFLAG_RESERVED;
4850 } else if (rc == MPT_SCANDV_SENSE) {
4851 /* Wait if coming ready
4853 u8 skey = hd->pLocal->sense[2] & 0x0F;
4854 u8 asc = hd->pLocal->sense[12];
4855 u8 ascq = hd->pLocal->sense[13];
4856 ddvprintk((MYIOC_s_INFO_FMT
4857 "DV: Reserve Failed: ", ioc->name));
4858 ddvprintk(("SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
4861 if ((skey == NOT_READY) && (asc == 0x04)&&
4863 /* wait then repeat */
4867 ddvprintk((MYIOC_s_INFO_FMT
4868 "DV: Reserved Failed.", ioc->name));
4872 ddvprintk((MYIOC_s_INFO_FMT "DV: Reserved Failed.",
4880 mptscsih_fillbuf(pbuf1, sz, patt, 1);
4881 iocmd.cmd = WRITE_BUFFER;
4882 iocmd.data_dma = buf1_dma;
4885 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4887 else if (hd->pLocal == NULL)
4890 rc = hd->pLocal->completion;
4891 if (rc == MPT_SCANDV_GOOD)
4892 ; /* Issue read buffer */
4893 else if (rc == MPT_SCANDV_DID_RESET) {
4894 /* If using echo buffers, reset to data buffers.
4895 * Else do Fallback and restart
4896 * this test (re-issue reserve
4897 * because of bus reset).
4899 if ((iocmd.flags & MPT_ICFLAG_ECHO) && (dataBufSize >= bufsize)) {
4900 iocmd.flags &= ~MPT_ICFLAG_ECHO;
4902 dv.cmd = MPT_FALLBACK;
4903 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
4905 if (mpt_config(hd->ioc, &cfg) != 0)
4908 if ((!dv.now.width) && (!dv.now.offset))
4912 iocmd.flags |= MPT_ICFLAG_DID_RESET;
4915 } else if (rc == MPT_SCANDV_SENSE) {
4916 /* Restart data test if UA, else quit.
4918 u8 skey = hd->pLocal->sense[2] & 0x0F;
4919 ddvprintk((MYIOC_s_INFO_FMT
4920 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n", ioc->name, skey,
4921 hd->pLocal->sense[12], hd->pLocal->sense[13]));
4922 if (skey == UNIT_ATTENTION) {
4925 } else if (skey == ILLEGAL_REQUEST) {
4926 if (iocmd.flags & MPT_ICFLAG_ECHO) {
4927 if (dataBufSize >= bufsize) {
4928 iocmd.flags &= ~MPT_ICFLAG_ECHO;
4943 iocmd.cmd = READ_BUFFER;
4944 iocmd.data_dma = buf2_dma;
4947 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4949 else if (hd->pLocal == NULL)
4952 rc = hd->pLocal->completion;
4953 if (rc == MPT_SCANDV_GOOD) {
4954 /* If buffers compare,
4955 * go to next pattern,
4956 * else, do a fallback and restart
4957 * data transfer test.
4959 if (memcmp (pbuf1, pbuf2, sz) == 0) {
4960 ; /* goto next pattern */
4962 /* Miscompare with Echo buffer, go to data buffer,
4963 * if that buffer exists.
4964 * Miscompare with Data buffer, check first 4 bytes,
4965 * some devices return capacity. Exit in this case.
4967 if (iocmd.flags & MPT_ICFLAG_ECHO) {
4968 if (dataBufSize >= bufsize)
4969 iocmd.flags &= ~MPT_ICFLAG_ECHO;
4973 if (dataBufSize == (pbuf2[1]<<16 | pbuf2[2]<<8 | pbuf2[3])) {
4974 /* Argh. Device returning wrong data.
4975 * Quit DV for this device.
4980 /* Had an actual miscompare. Slow down.*/
4981 dv.cmd = MPT_FALLBACK;
4982 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
4984 if (mpt_config(hd->ioc, &cfg) != 0)
4987 if ((!dv.now.width) && (!dv.now.offset))
4994 } else if (rc == MPT_SCANDV_DID_RESET) {
4995 /* Do Fallback and restart
4996 * this test (re-issue reserve
4997 * because of bus reset).
4999 dv.cmd = MPT_FALLBACK;
5000 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5002 if (mpt_config(hd->ioc, &cfg) != 0)
5005 if ((!dv.now.width) && (!dv.now.offset))
5008 iocmd.flags |= MPT_ICFLAG_DID_RESET;
5011 } else if (rc == MPT_SCANDV_SENSE) {
5012 /* Restart data test if UA, else quit.
5014 u8 skey = hd->pLocal->sense[2] & 0x0F;
5015 ddvprintk((MYIOC_s_INFO_FMT
5016 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n", ioc->name, skey,
5017 hd->pLocal->sense[12], hd->pLocal->sense[13]));
5018 if (skey == UNIT_ATTENTION) {
5030 } /* --- end of patt loop ---- */
5033 if (iocmd.flags & MPT_ICFLAG_RESERVED) {
5034 iocmd.cmd = RELEASE;
5035 iocmd.data_dma = -1;
5038 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5039 printk(MYIOC_s_INFO_FMT "DV: Release failed. id %d",
5041 else if (hd->pLocal) {
5042 if (hd->pLocal->completion == MPT_SCANDV_GOOD)
5043 iocmd.flags &= ~MPT_ICFLAG_RESERVED;
5045 printk(MYIOC_s_INFO_FMT "DV: Release failed. id %d",
5051 /* Set if cfg1_dma_addr contents is valid
5053 if ((cfg.cfghdr.hdr != NULL) && (retcode == 0)){
5054 /* If disk, not U320, disable QAS
5056 if ((inq0 == 0) && (dv.now.factor > MPT_ULTRA320)) {
5057 hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS;
5058 ddvprintk((MYIOC_s_NOTE_FMT
5059 "noQas set due to id=%d has factor=%x\n", ioc->name, id, dv.now.factor));
5063 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5065 /* Double writes to SDP1 can cause problems,
5066 * skip save of the final negotiated settings to
5067 * SCSI device page 1.
5069 cfg.cfghdr.hdr = &header1;
5070 cfg.physAddr = cfg1_dma_addr;
5071 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5073 mpt_config(hd->ioc, &cfg);
5077 /* If this is a RAID Passthrough, enable internal IOs
5079 if (iocmd.flags & MPT_ICFLAG_PHYS_DISK) {
5080 if (mptscsih_do_raid(hd, MPI_RAID_ACTION_ENABLE_PHYS_IO, &iocmd) < 0)
5081 ddvprintk((MYIOC_s_ERR_FMT "RAID Enable FAILED!\n", ioc->name));
5084 /* Done with the DV scan of the current target
5087 pci_free_consistent(ioc->pcidev, dv_alloc, pDvBuf, dvbuf_dma);
5089 ddvtprintk((MYIOC_s_INFO_FMT "DV Done id=%d\n",
5095 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5096 /* mptscsih_dv_parms - perform a variety of operations on the
5097 * parameters used for negotiation.
5098 * @hd: Pointer to a SCSI host.
5099 * @dv: Pointer to a structure that contains the maximum and current
5100 * negotiated parameters.
5103 mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
5105 VirtTarget *vtarget;
5106 SCSIDevicePage0_t *pPage0;
5107 SCSIDevicePage1_t *pPage1;
5108 int val = 0, data, configuration;
5117 case MPT_GET_NVRAM_VALS:
5118 ddvprintk((MYIOC_s_NOTE_FMT "Getting NVRAM: ",
5120 /* Get the NVRAM values and save in tmax
5121 * If not an LVD bus, the adapter minSyncFactor has been
5122 * already throttled back.
5124 negoFlags = hd->ioc->spi_data.noQas;
5125 if ((hd->Targets)&&((vtarget = hd->Targets[(int)id]) != NULL) && !vtarget->raidVolume) {
5126 width = vtarget->maxWidth;
5127 offset = vtarget->maxOffset;
5128 factor = vtarget->minSyncFactor;
5129 negoFlags |= vtarget->negoFlags;
5131 if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
5132 data = hd->ioc->spi_data.nvram[id];
5133 width = data & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
5134 if ((offset = hd->ioc->spi_data.maxSyncOffset) == 0)
5137 factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT;
5138 if ((factor == 0) || (factor == MPT_ASYNC)){
5149 /* Set the negotiation flags */
5151 negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
5154 negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
5157 /* limit by adapter capabilities */
5158 width = min(width, hd->ioc->spi_data.maxBusWidth);
5159 offset = min(offset, hd->ioc->spi_data.maxSyncOffset);
5160 factor = max(factor, hd->ioc->spi_data.minSyncFactor);
5162 /* Check Consistency */
5163 if (offset && (factor < MPT_ULTRA2) && !width)
5164 factor = MPT_ULTRA2;
5166 dv->max.width = width;
5167 dv->max.offset = offset;
5168 dv->max.factor = factor;
5169 dv->max.flags = negoFlags;
5170 ddvprintk((" id=%d width=%d factor=%x offset=%x flags=%x\n",
5171 id, width, factor, offset, negoFlags));
5174 case MPT_UPDATE_MAX:
5175 ddvprintk((MYIOC_s_NOTE_FMT
5176 "Updating with SDP0 Data: ", hd->ioc->name));
5177 /* Update tmax values with those from Device Page 0.*/
5178 pPage0 = (SCSIDevicePage0_t *) pPage;
5180 val = le32_to_cpu(pPage0->NegotiatedParameters);
5181 dv->max.width = val & MPI_SCSIDEVPAGE0_NP_WIDE ? 1 : 0;
5182 dv->max.offset = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK) >> 16;
5183 dv->max.factor = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK) >> 8;
5186 dv->now.width = dv->max.width;
5187 dv->now.offset = dv->max.offset;
5188 dv->now.factor = dv->max.factor;
5189 ddvprintk(("id=%d width=%d factor=%x offset=%x flags=%x\n",
5190 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags));
5194 ddvprintk((MYIOC_s_NOTE_FMT "Setting Max: ",
5196 /* Set current to the max values. Update the config page.*/
5197 dv->now.width = dv->max.width;
5198 dv->now.offset = dv->max.offset;
5199 dv->now.factor = dv->max.factor;
5200 dv->now.flags = dv->max.flags;
5202 pPage1 = (SCSIDevicePage1_t *)pPage;
5204 mptscsih_setDevicePage1Flags (dv->now.width, dv->now.factor,
5205 dv->now.offset, &val, &configuration, dv->now.flags);
5206 dnegoprintk(("Setting Max: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
5207 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags, val, configuration));
5208 pPage1->RequestedParameters = cpu_to_le32(val);
5209 pPage1->Reserved = 0;
5210 pPage1->Configuration = cpu_to_le32(configuration);
5213 ddvprintk(("id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x configuration=%x\n",
5214 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags, val, configuration));
5218 ddvprintk((MYIOC_s_NOTE_FMT "Setting Min: ",
5220 /* Set page to asynchronous and narrow
5221 * Do not update now, breaks fallback routine. */
5225 negoFlags = dv->max.flags;
5227 pPage1 = (SCSIDevicePage1_t *)pPage;
5229 mptscsih_setDevicePage1Flags (width, factor,
5230 offset, &val, &configuration, negoFlags);
5231 dnegoprintk(("Setting Min: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
5232 id, width, factor, offset, negoFlags, val, configuration));
5233 pPage1->RequestedParameters = cpu_to_le32(val);
5234 pPage1->Reserved = 0;
5235 pPage1->Configuration = cpu_to_le32(configuration);
5237 ddvprintk(("id=%d width=%d factor=%x offset=%x request=%x config=%x negoFlags=%x\n",
5238 id, width, factor, offset, val, configuration, negoFlags));
5242 ddvprintk((MYIOC_s_NOTE_FMT
5243 "Fallback: Start: offset %d, factor %x, width %d \n",
5244 hd->ioc->name, dv->now.offset,
5245 dv->now.factor, dv->now.width));
5246 width = dv->now.width;
5247 offset = dv->now.offset;
5248 factor = dv->now.factor;
5249 if ((offset) && (dv->max.width)) {
5250 if (factor < MPT_ULTRA160)
5251 factor = MPT_ULTRA160;
5252 else if (factor < MPT_ULTRA2) {
5253 factor = MPT_ULTRA2;
5255 } else if ((factor == MPT_ULTRA2) && width) {
5256 factor = MPT_ULTRA2;
5258 } else if (factor < MPT_ULTRA) {
5261 } else if ((factor == MPT_ULTRA) && width) {
5263 } else if (factor < MPT_FAST) {
5266 } else if ((factor == MPT_FAST) && width) {
5269 } else if (factor < MPT_SCSI) {
5272 } else if ((factor == MPT_SCSI) && width) {
5280 } else if (offset) {
5282 if (factor < MPT_ULTRA)
5284 else if (factor < MPT_FAST)
5286 else if (factor < MPT_SCSI)
5297 dv->max.flags |= MPT_TARGET_NO_NEGO_QAS;
5298 dv->max.flags &= ~MPT_TAPE_NEGO_IDP;
5300 dv->now.width = width;
5301 dv->now.offset = offset;
5302 dv->now.factor = factor;
5303 dv->now.flags = dv->max.flags;
5305 pPage1 = (SCSIDevicePage1_t *)pPage;
5307 mptscsih_setDevicePage1Flags (width, factor, offset, &val,
5308 &configuration, dv->now.flags);
5309 dnegoprintk(("Finish: id=%d width=%d offset=%d factor=%x negoFlags=%x request=%x config=%x\n",
5310 id, width, offset, factor, dv->now.flags, val, configuration));
5312 pPage1->RequestedParameters = cpu_to_le32(val);
5313 pPage1->Reserved = 0;
5314 pPage1->Configuration = cpu_to_le32(configuration);
5317 ddvprintk(("Finish: id=%d offset=%d factor=%x width=%d request=%x config=%x\n",
5318 id, dv->now.offset, dv->now.factor, dv->now.width, val, configuration));
5322 ddvprintk((MYIOC_s_NOTE_FMT
5323 "Saving to Target structure: ", hd->ioc->name));
5324 ddvprintk(("id=%d width=%x factor=%x offset=%d flags=%x\n",
5325 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags));
5327 /* Save these values to target structures
5328 * or overwrite nvram (phys disks only).
5331 if ((hd->Targets)&&((vtarget = hd->Targets[(int)id]) != NULL) && !vtarget->raidVolume ) {
5332 vtarget->maxWidth = dv->now.width;
5333 vtarget->maxOffset = dv->now.offset;
5334 vtarget->minSyncFactor = dv->now.factor;
5335 vtarget->negoFlags = dv->now.flags;
5337 /* Preserv all flags, use
5338 * read-modify-write algorithm
5340 if (hd->ioc->spi_data.nvram) {
5341 data = hd->ioc->spi_data.nvram[id];
5344 data &= ~MPT_NVRAM_WIDE_DISABLE;
5346 data |= MPT_NVRAM_WIDE_DISABLE;
5348 if (!dv->now.offset)
5351 data &= ~MPT_NVRAM_SYNC_MASK;
5352 data |= (dv->now.factor << MPT_NVRAM_SYNC_SHIFT) & MPT_NVRAM_SYNC_MASK;
5354 hd->ioc->spi_data.nvram[id] = data;
5361 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5362 /* mptscsih_fillbuf - fill a buffer with a special data pattern
5363 * cleanup. For bus scan only.
5365 * @buffer: Pointer to data buffer to be filled.
5366 * @size: Number of bytes to fill
5367 * @index: Pattern index
5368 * @width: bus width, 0 (8 bits) or 1 (16 bits)
5371 mptscsih_fillbuf(char *buffer, int size, int index, int width)
5382 /* Pattern: 0000 FFFF 0000 FFFF
5384 for (ii=0; ii < size; ii++, ptr++) {
5391 /* Pattern: 00 FF 00 FF
5393 for (ii=0; ii < size; ii++, ptr++) {
5404 /* Pattern: 5555 AAAA 5555 AAAA 5555
5406 for (ii=0; ii < size; ii++, ptr++) {
5413 /* Pattern: 55 AA 55 AA 55
5415 for (ii=0; ii < size; ii++, ptr++) {
5425 /* Pattern: 00 01 02 03 04 05
5428 for (ii=0; ii < size; ii++, ptr++)
5434 /* Wide Pattern: FFFE 0001 FFFD 0002
5435 * ... 4000 DFFF 8000 EFFF
5438 for (ii=0; ii < size/2; ii++) {
5439 /* Create the base pattern
5442 /* every 64 (0x40) bytes flip the pattern
5443 * since we fill 2 bytes / iteration,
5444 * test for ii = 0x20
5450 *ptr = (char)( (val & 0xFF00) >> 8);
5452 *ptr = (char)(val & 0xFF);
5457 *ptr = (char)( (val & 0xFF00) >> 8);
5459 *ptr = (char)(val & 0xFF);
5465 /* Narrow Pattern: FE 01 FD 02 FB 04
5466 * .. 7F 80 01 FE 02 FD ... 80 7F
5469 for (ii=0; ii < size; ii++, ptr++) {
5470 /* Base pattern - first 32 bytes
5477 *ptr = (char) (~(1 << byte));
5480 /* Flip the pattern every 32 bytes
5490 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5491 /* If DV disabled (negoNvram set to USE_NVARM) or if not LUN 0, return.
5492 * Else set the NEED_DV flag after Read Capacity Issued (disks)
5493 * or Mode Sense (cdroms).
5495 * Tapes, initTarget will set this flag on completion of Inquiry command.
5496 * Called only if DV_NOT_DONE flag is set
5499 mptscsih_set_dvflags(MPT_SCSI_HOST *hd, struct scsi_cmnd *sc)
5501 MPT_ADAPTER *ioc = hd->ioc;
5505 ddvtprintk((MYIOC_s_NOTE_FMT
5506 " set_dvflags: id=%d lun=%d negoNvram=%x cmd=%x\n",
5507 hd->ioc->name, sc->device->id, sc->device->lun , hd->negoNvram, sc->cmnd[0]));
5509 if ((sc->device->lun != 0) || (hd->negoNvram != 0))
5514 if ((cmd == READ_CAPACITY) || (cmd == MODE_SENSE)) {
5515 pSpi = &ioc->spi_data;
5516 if ((ioc->raid_data.isRaid & (1 << sc->device->id)) && ioc->raid_data.pIocPg3) {
5517 /* Set NEED_DV for all hidden disks
5519 Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
5520 int numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
5523 pSpi->dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV;
5524 ddvtprintk(("NEED_DV set for phys disk id %d\n", pPDisk->PhysDiskID));
5529 pSpi->dvStatus[sc->device->id] |= MPT_SCSICFG_NEED_DV;
5530 ddvtprintk(("NEED_DV set for visible disk id %d\n", sc->device->id));
5534 /* mptscsih_raid_set_dv_flags()
5536 * New or replaced disk. Set DV flag and schedule DV.
5539 mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id)
5541 MPT_ADAPTER *ioc = hd->ioc;
5542 SpiCfgData *pSpi = &ioc->spi_data;
5543 Ioc3PhysDisk_t *pPDisk;
5546 if (hd->negoNvram != 0)
5549 ddvtprintk(("DV requested for phys disk id %d\n", id));
5550 if (ioc->raid_data.pIocPg3) {
5551 pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
5552 numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
5554 if (id == pPDisk->PhysDiskNum) {
5555 pSpi->dvStatus[pPDisk->PhysDiskID] =
5556 (MPT_SCSICFG_NEED_DV | MPT_SCSICFG_DV_NOT_DONE);
5557 pSpi->forceDv = MPT_SCSICFG_NEED_DV;
5558 ddvtprintk(("NEED_DV set for phys disk id %d\n",
5559 pPDisk->PhysDiskID));
5566 if (numPDisk == 0) {
5567 /* The physical disk that needs DV was not found
5568 * in the stored IOC Page 3. The driver must reload
5569 * this page. DV routine will set the NEED_DV flag for
5570 * all phys disks that have DV_NOT_DONE set.
5572 pSpi->forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
5573 ddvtprintk(("phys disk %d not found. Setting reload IOC Pg3 Flag\n",id));
5577 #endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */
5579 EXPORT_SYMBOL(mptscsih_remove);
5580 EXPORT_SYMBOL(mptscsih_shutdown);
5582 EXPORT_SYMBOL(mptscsih_suspend);
5583 EXPORT_SYMBOL(mptscsih_resume);
5585 EXPORT_SYMBOL(mptscsih_proc_info);
5586 EXPORT_SYMBOL(mptscsih_info);
5587 EXPORT_SYMBOL(mptscsih_qcmd);
5588 EXPORT_SYMBOL(mptscsih_target_alloc);
5589 EXPORT_SYMBOL(mptscsih_slave_alloc);
5590 EXPORT_SYMBOL(mptscsih_target_destroy);
5591 EXPORT_SYMBOL(mptscsih_slave_destroy);
5592 EXPORT_SYMBOL(mptscsih_slave_configure);
5593 EXPORT_SYMBOL(mptscsih_abort);
5594 EXPORT_SYMBOL(mptscsih_dev_reset);
5595 EXPORT_SYMBOL(mptscsih_bus_reset);
5596 EXPORT_SYMBOL(mptscsih_host_reset);
5597 EXPORT_SYMBOL(mptscsih_bios_param);
5598 EXPORT_SYMBOL(mptscsih_io_done);
5599 EXPORT_SYMBOL(mptscsih_taskmgmt_complete);
5600 EXPORT_SYMBOL(mptscsih_scandv_complete);
5601 EXPORT_SYMBOL(mptscsih_event_process);
5602 EXPORT_SYMBOL(mptscsih_ioc_reset);
5603 EXPORT_SYMBOL(mptscsih_change_queue_depth);
5604 EXPORT_SYMBOL(mptscsih_timer_expired);
5606 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/