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 * (BUT, BUT, BUT, the code does reference it! - mdr)
897 * @hd: Pointer to a SCSI HOST structure
898 * @vdevice: per device private data
902 * Called from slave_destroy.
905 mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
907 SCSIIORequest_t *mf = NULL;
909 int max = hd->ioc->req_depth;
910 struct scsi_cmnd *sc;
912 dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n",
913 vdevice->target_id, vdevice->lun, max));
915 for (ii=0; ii < max; ii++) {
916 if ((sc = hd->ScsiLookup[ii]) != NULL) {
918 mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii);
920 dsprintk(( "search_running: found (sc=%p, mf = %p) target %d, lun %d \n",
921 hd->ScsiLookup[ii], mf, mf->TargetID, mf->LUN[1]));
923 if ((mf->TargetID != ((u8)vdevice->target_id)) || (mf->LUN[1] != ((u8) vdevice->lun)))
928 hd->ScsiLookup[ii] = NULL;
929 mptscsih_freeChainBuffers(hd->ioc, ii);
930 mpt_free_msg_frame(hd->ioc, (MPT_FRAME_HDR *)mf);
932 pci_unmap_sg(hd->ioc->pcidev,
933 (struct scatterlist *) sc->request_buffer,
935 sc->sc_data_direction);
936 } else if (sc->request_bufflen) {
937 pci_unmap_single(hd->ioc->pcidev,
940 sc->sc_data_direction);
942 sc->host_scribble = NULL;
943 sc->result = DID_NO_CONNECT << 16;
950 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
952 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
954 * mptscsih_report_queue_full - Report QUEUE_FULL status returned
955 * from a SCSI target device.
956 * @sc: Pointer to scsi_cmnd structure
957 * @pScsiReply: Pointer to SCSIIOReply_t
958 * @pScsiReq: Pointer to original SCSI request
960 * This routine periodically reports QUEUE_FULL status returned from a
961 * SCSI target device. It reports this to the console via kernel
962 * printk() API call, not more than once every 10 seconds.
965 mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq)
970 if (sc->device == NULL)
972 if (sc->device->host == NULL)
974 if ((hd = (MPT_SCSI_HOST *)sc->device->host->hostdata) == NULL)
977 if (time - hd->last_queue_full > 10 * HZ) {
978 dprintk((MYIOC_s_WARN_FMT "Device (%d:%d:%d) reported QUEUE_FULL!\n",
979 hd->ioc->name, 0, sc->device->id, sc->device->lun));
980 hd->last_queue_full = time;
984 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
986 * mptscsih_remove - Removed scsi devices
987 * @pdev: Pointer to pci_dev structure
992 mptscsih_remove(struct pci_dev *pdev)
994 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
995 struct Scsi_Host *host = ioc->sh;
997 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1008 scsi_remove_host(host);
1010 if((hd = (MPT_SCSI_HOST *)host->hostdata) == NULL)
1013 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1014 /* Check DV thread active */
1016 spin_lock_irqsave(&dvtaskQ_lock, flags);
1017 if (dvtaskQ_active) {
1018 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
1019 while(dvtaskQ_active && --count)
1020 schedule_timeout_interruptible(1);
1022 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
1025 printk(KERN_ERR MYNAM ": ERROR - DV thread still active!\n");
1026 #if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY)
1028 printk(KERN_ERR MYNAM ": DV thread orig %d, count %d\n", 10 * HZ, count);
1032 mptscsih_shutdown(pdev);
1036 if (hd->ScsiLookup != NULL) {
1037 sz1 = hd->ioc->req_depth * sizeof(void *);
1038 kfree(hd->ScsiLookup);
1039 hd->ScsiLookup = NULL;
1043 * Free pointer array.
1048 dprintk((MYIOC_s_INFO_FMT
1049 "Free'd ScsiLookup (%d) memory\n",
1050 hd->ioc->name, sz1));
1052 kfree(hd->info_kbuf);
1054 /* NULL the Scsi_Host pointer
1058 scsi_host_put(host);
1064 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1066 * mptscsih_shutdown - reboot notifier
1070 mptscsih_shutdown(struct pci_dev *pdev)
1072 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1073 struct Scsi_Host *host = ioc->sh;
1079 hd = (MPT_SCSI_HOST *)host->hostdata;
1084 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1086 * mptscsih_suspend - Fusion MPT scsi driver suspend routine.
1091 mptscsih_suspend(struct pci_dev *pdev, pm_message_t state)
1093 mptscsih_shutdown(pdev);
1094 return mpt_suspend(pdev,state);
1097 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1099 * mptscsih_resume - Fusion MPT scsi driver resume routine.
1104 mptscsih_resume(struct pci_dev *pdev)
1106 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1107 struct Scsi_Host *host = ioc->sh;
1115 hd = (MPT_SCSI_HOST *)host->hostdata;
1119 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1121 unsigned long lflags;
1122 spin_lock_irqsave(&dvtaskQ_lock, lflags);
1123 if (!dvtaskQ_active) {
1125 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1126 INIT_WORK(&dvTaskQ_task,
1127 mptscsih_domainValidation, (void *) hd);
1128 schedule_work(&dvTaskQ_task);
1130 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1139 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1141 * mptscsih_info - Return information about MPT adapter
1142 * @SChost: Pointer to Scsi_Host structure
1144 * (linux scsi_host_template.info routine)
1146 * Returns pointer to buffer where information was written.
1149 mptscsih_info(struct Scsi_Host *SChost)
1154 h = (MPT_SCSI_HOST *)SChost->hostdata;
1157 if (h->info_kbuf == NULL)
1158 if ((h->info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)
1159 return h->info_kbuf;
1160 h->info_kbuf[0] = '\0';
1162 mpt_print_ioc_summary(h->ioc, h->info_kbuf, &size, 0, 0);
1163 h->info_kbuf[size-1] = '\0';
1166 return h->info_kbuf;
1177 mptscsih_copy_mem_info(struct info_str *info, char *data, int len)
1179 if (info->pos + len > info->length)
1180 len = info->length - info->pos;
1182 if (info->pos + len < info->offset) {
1187 if (info->pos < info->offset) {
1188 data += (info->offset - info->pos);
1189 len -= (info->offset - info->pos);
1193 memcpy(info->buffer + info->pos, data, len);
1199 mptscsih_copy_info(struct info_str *info, char *fmt, ...)
1205 va_start(args, fmt);
1206 len = vsprintf(buf, fmt, args);
1209 mptscsih_copy_mem_info(info, buf, len);
1214 mptscsih_host_info(MPT_ADAPTER *ioc, char *pbuf, off_t offset, int len)
1216 struct info_str info;
1220 info.offset = offset;
1223 mptscsih_copy_info(&info, "%s: %s, ", ioc->name, ioc->prod_name);
1224 mptscsih_copy_info(&info, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING, ioc->facts.FWVersion.Word);
1225 mptscsih_copy_info(&info, "Ports=%d, ", ioc->facts.NumberOfPorts);
1226 mptscsih_copy_info(&info, "MaxQ=%d\n", ioc->req_depth);
1228 return ((info.pos > info.offset) ? info.pos - info.offset : 0);
1231 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1233 * mptscsih_proc_info - Return information about MPT adapter
1235 * (linux scsi_host_template.info routine)
1237 * buffer: if write, user data; if read, buffer for user
1238 * length: if write, return length;
1239 * offset: if write, 0; if read, the current offset into the buffer from
1240 * the previous read.
1241 * hostno: scsi host number
1242 * func: if write = 1; if read = 0
1245 mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
1246 int length, int func)
1248 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
1249 MPT_ADAPTER *ioc = hd->ioc;
1254 * write is not supported
1260 size = mptscsih_host_info(ioc, buffer, offset, length);
1266 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1267 #define ADD_INDEX_LOG(req_ent) do { } while(0)
1269 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1271 * mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine.
1272 * @SCpnt: Pointer to scsi_cmnd structure
1273 * @done: Pointer SCSI mid-layer IO completion function
1275 * (linux scsi_host_template.queuecommand routine)
1276 * This is the primary SCSI IO start routine. Create a MPI SCSIIORequest
1277 * from a linux scsi_cmnd request and send it to the IOC.
1279 * Returns 0. (rtn value discarded by linux scsi mid-layer)
1282 mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1286 SCSIIORequest_t *pScsiReq;
1287 VirtDevice *vdev = SCpnt->device->hostdata;
1296 hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata;
1297 lun = SCpnt->device->lun;
1298 SCpnt->scsi_done = done;
1300 dmfprintk((MYIOC_s_INFO_FMT "qcmd: SCpnt=%p, done()=%p\n",
1301 (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt, done));
1303 if (hd->resetPending) {
1304 dtmprintk((MYIOC_s_WARN_FMT "qcmd: SCpnt=%p timeout + 60HZ\n",
1305 (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt));
1306 return SCSI_MLQUEUE_HOST_BUSY;
1310 * Put together a MPT SCSI request...
1312 if ((mf = mpt_get_msg_frame(hd->ioc->DoneCtx, hd->ioc)) == NULL) {
1313 dprintk((MYIOC_s_WARN_FMT "QueueCmd, no msg frames!!\n",
1315 return SCSI_MLQUEUE_HOST_BUSY;
1318 pScsiReq = (SCSIIORequest_t *) mf;
1320 my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
1322 ADD_INDEX_LOG(my_idx);
1324 /* TUR's being issued with scsictl=0x02000000 (DATA_IN)!
1325 * Seems we may receive a buffer (datalen>0) even when there
1326 * will be no data transfer! GRRRRR...
1328 if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
1329 datalen = SCpnt->request_bufflen;
1330 scsidir = MPI_SCSIIO_CONTROL_READ; /* DATA IN (host<--ioc<--dev) */
1331 } else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
1332 datalen = SCpnt->request_bufflen;
1333 scsidir = MPI_SCSIIO_CONTROL_WRITE; /* DATA OUT (host-->ioc-->dev) */
1336 scsidir = MPI_SCSIIO_CONTROL_NODATATRANSFER;
1339 /* Default to untagged. Once a target structure has been allocated,
1340 * use the Inquiry data to determine if device supports tagged.
1343 && (vdev->vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)
1344 && (SCpnt->device->tagged_supported)) {
1345 scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
1347 scsictl = scsidir | MPI_SCSIIO_CONTROL_UNTAGGED;
1350 /* Use the above information to set up the message frame
1352 pScsiReq->TargetID = (u8) vdev->target_id;
1353 pScsiReq->Bus = vdev->bus_id;
1354 pScsiReq->ChainOffset = 0;
1355 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
1356 pScsiReq->CDBLength = SCpnt->cmd_len;
1357 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
1358 pScsiReq->Reserved = 0;
1359 pScsiReq->MsgFlags = mpt_msg_flags();
1360 pScsiReq->LUN[0] = 0;
1361 pScsiReq->LUN[1] = lun;
1362 pScsiReq->LUN[2] = 0;
1363 pScsiReq->LUN[3] = 0;
1364 pScsiReq->LUN[4] = 0;
1365 pScsiReq->LUN[5] = 0;
1366 pScsiReq->LUN[6] = 0;
1367 pScsiReq->LUN[7] = 0;
1368 pScsiReq->Control = cpu_to_le32(scsictl);
1371 * Write SCSI CDB into the message
1373 cmd_len = SCpnt->cmd_len;
1374 for (ii=0; ii < cmd_len; ii++)
1375 pScsiReq->CDB[ii] = SCpnt->cmnd[ii];
1377 for (ii=cmd_len; ii < 16; ii++)
1378 pScsiReq->CDB[ii] = 0;
1381 pScsiReq->DataLength = cpu_to_le32(datalen);
1383 /* SenseBuffer low address */
1384 pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
1385 + (my_idx * MPT_SENSE_BUFFER_ALLOC));
1387 /* Now add the SG list
1388 * Always have a SGE even if null length.
1391 /* Add a NULL SGE */
1392 mptscsih_add_sge((char *)&pScsiReq->SGL, MPT_SGE_FLAGS_SSIMPLE_READ | 0,
1395 /* Add a 32 or 64 bit SGE */
1396 if (mptscsih_AddSGE(hd->ioc, SCpnt, pScsiReq, my_idx) != SUCCESS)
1400 hd->ScsiLookup[my_idx] = SCpnt;
1401 SCpnt->host_scribble = NULL;
1403 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1404 if (hd->ioc->bus_type == SPI) {
1405 int dvStatus = hd->ioc->spi_data.dvStatus[vdev->target_id];
1408 if (dvStatus || hd->ioc->spi_data.forceDv) {
1410 if ((dvStatus & MPT_SCSICFG_NEED_DV) ||
1411 (hd->ioc->spi_data.forceDv & MPT_SCSICFG_NEED_DV)) {
1412 unsigned long lflags;
1413 /* Schedule DV if necessary */
1414 spin_lock_irqsave(&dvtaskQ_lock, lflags);
1415 if (!dvtaskQ_active) {
1417 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1418 INIT_WORK(&dvTaskQ_task, mptscsih_domainValidation, (void *) hd);
1420 schedule_work(&dvTaskQ_task);
1422 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1424 hd->ioc->spi_data.forceDv &= ~MPT_SCSICFG_NEED_DV;
1427 /* Trying to do DV to this target, extend timeout.
1428 * Wait to issue until flag is clear
1430 if (dvStatus & MPT_SCSICFG_DV_PENDING) {
1431 mod_timer(&SCpnt->eh_timeout, jiffies + 40 * HZ);
1435 /* Set the DV flags.
1437 if (dvStatus & MPT_SCSICFG_DV_NOT_DONE)
1438 mptscsih_set_dvflags(hd, SCpnt);
1446 mpt_put_msg_frame(hd->ioc->DoneCtx, hd->ioc, mf);
1447 dmfprintk((MYIOC_s_INFO_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n",
1448 hd->ioc->name, SCpnt, mf, my_idx));
1449 DBG_DUMP_REQUEST_FRAME(mf)
1453 hd->ScsiLookup[my_idx] = NULL;
1454 mptscsih_freeChainBuffers(hd->ioc, my_idx);
1455 mpt_free_msg_frame(hd->ioc, mf);
1456 return SCSI_MLQUEUE_HOST_BUSY;
1459 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1461 * mptscsih_freeChainBuffers - Function to free chain buffers associated
1462 * with a SCSI IO request
1463 * @hd: Pointer to the MPT_SCSI_HOST instance
1464 * @req_idx: Index of the SCSI IO request frame.
1466 * Called if SG chain buffer allocation fails and mptscsih callbacks.
1470 mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
1472 MPT_FRAME_HDR *chain;
1473 unsigned long flags;
1477 /* Get the first chain index and reset
1480 chain_idx = ioc->ReqToChain[req_idx];
1481 ioc->ReqToChain[req_idx] = MPT_HOST_NO_CHAIN;
1483 while (chain_idx != MPT_HOST_NO_CHAIN) {
1485 /* Save the next chain buffer index */
1486 next = ioc->ChainToChain[chain_idx];
1488 /* Free this chain buffer and reset
1491 ioc->ChainToChain[chain_idx] = MPT_HOST_NO_CHAIN;
1493 chain = (MPT_FRAME_HDR *) (ioc->ChainBuffer
1494 + (chain_idx * ioc->req_sz));
1496 spin_lock_irqsave(&ioc->FreeQlock, flags);
1497 list_add_tail(&chain->u.frame.linkage.list, &ioc->FreeChainQ);
1498 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1500 dmfprintk((MYIOC_s_INFO_FMT "FreeChainBuffers (index %d)\n",
1501 ioc->name, chain_idx));
1509 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1514 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1516 * mptscsih_TMHandler - Generic handler for SCSI Task Management.
1517 * Fall through to mpt_HardResetHandler if: not operational, too many
1518 * failed TM requests or handshake failure.
1520 * @ioc: Pointer to MPT_ADAPTER structure
1521 * @type: Task Management type
1522 * @target: Logical Target ID for reset (if appropriate)
1523 * @lun: Logical Unit for reset (if appropriate)
1524 * @ctx2abort: Context for the task to be aborted (if appropriate)
1526 * Remark: Currently invoked from a non-interrupt thread (_bh).
1528 * Remark: With old EH code, at most 1 SCSI TaskMgmt function per IOC
1531 * Returns 0 for SUCCESS or -1 if FAILED.
1534 mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout)
1540 unsigned long flags;
1542 /* If FW is being reloaded currently, return success to
1543 * the calling function.
1550 printk(KERN_ERR MYNAM " TMHandler" " NULL ioc!\n");
1553 dtmprintk((MYIOC_s_INFO_FMT "TMHandler Entered!\n", ioc->name));
1555 // SJR - CHECKME - Can we avoid this here?
1556 // (mpt_HardResetHandler has this check...)
1557 spin_lock_irqsave(&ioc->diagLock, flags);
1558 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)) {
1559 spin_unlock_irqrestore(&ioc->diagLock, flags);
1562 spin_unlock_irqrestore(&ioc->diagLock, flags);
1564 /* Wait a fixed amount of time for the TM pending flag to be cleared.
1565 * If we time out and not bus reset, then we return a FAILED status to the caller.
1566 * The call to mptscsih_tm_pending_wait() will set the pending flag if we are
1567 * successful. Otherwise, reload the FW.
1569 if (mptscsih_tm_pending_wait(hd) == FAILED) {
1570 if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
1571 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler abort: "
1572 "Timed out waiting for last TM (%d) to complete! \n",
1573 hd->ioc->name, hd->tmPending));
1575 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) {
1576 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler target reset: "
1577 "Timed out waiting for last TM (%d) to complete! \n",
1578 hd->ioc->name, hd->tmPending));
1580 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
1581 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler bus reset: "
1582 "Timed out waiting for last TM (%d) to complete! \n",
1583 hd->ioc->name, hd->tmPending));
1584 if (hd->tmPending & (1 << MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS))
1590 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
1591 hd->tmPending |= (1 << type);
1592 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1597 ioc_raw_state = mpt_GetIocState(hd->ioc, 0);
1599 #ifdef MPT_DEBUG_RESET
1600 if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) {
1601 printk(MYIOC_s_WARN_FMT
1602 "TM Handler: IOC Not operational(0x%x)!\n",
1603 hd->ioc->name, ioc_raw_state);
1607 if (doTask && ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL)
1608 && !(ioc_raw_state & MPI_DOORBELL_ACTIVE)) {
1610 /* Isse the Task Mgmt request.
1612 if (hd->hard_resets < -1)
1614 rc = mptscsih_IssueTaskMgmt(hd, type, channel, target, lun, ctx2abort, timeout);
1616 printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n", hd->ioc->name);
1618 dtmprintk((MYIOC_s_INFO_FMT "Issue of TaskMgmt Successful!\n", hd->ioc->name));
1622 /* Only fall through to the HRH if this is a bus reset
1624 if ((type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) && (rc ||
1625 ioc->reload_fw || (ioc->alt_ioc && ioc->alt_ioc->reload_fw))) {
1626 dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
1628 rc = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
1631 dtmprintk((MYIOC_s_INFO_FMT "TMHandler rc = %d!\n", hd->ioc->name, rc));
1637 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1639 * mptscsih_IssueTaskMgmt - Generic send Task Management function.
1640 * @hd: Pointer to MPT_SCSI_HOST structure
1641 * @type: Task Management type
1642 * @target: Logical Target ID for reset (if appropriate)
1643 * @lun: Logical Unit for reset (if appropriate)
1644 * @ctx2abort: Context for the task to be aborted (if appropriate)
1646 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
1647 * or a non-interrupt thread. In the former, must not call schedule().
1649 * Not all fields are meaningfull for all task types.
1651 * Returns 0 for SUCCESS, -999 for "no msg frames",
1652 * else other non-zero value returned.
1655 mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout)
1658 SCSITaskMgmt_t *pScsiTm;
1662 /* Return Fail to calling function if no message frames available.
1664 if ((mf = mpt_get_msg_frame(hd->ioc->TaskCtx, hd->ioc)) == NULL) {
1665 dfailprintk((MYIOC_s_ERR_FMT "IssueTaskMgmt, no msg frames!!\n",
1669 dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt request @ %p\n",
1670 hd->ioc->name, mf));
1672 /* Format the Request
1674 pScsiTm = (SCSITaskMgmt_t *) mf;
1675 pScsiTm->TargetID = target;
1676 pScsiTm->Bus = channel;
1677 pScsiTm->ChainOffset = 0;
1678 pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
1680 pScsiTm->Reserved = 0;
1681 pScsiTm->TaskType = type;
1682 pScsiTm->Reserved1 = 0;
1683 pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)
1684 ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0;
1686 for (ii= 0; ii < 8; ii++) {
1687 pScsiTm->LUN[ii] = 0;
1689 pScsiTm->LUN[1] = lun;
1691 for (ii=0; ii < 7; ii++)
1692 pScsiTm->Reserved2[ii] = 0;
1694 pScsiTm->TaskMsgContext = ctx2abort;
1696 dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt: ctx2abort (0x%08x) type=%d\n",
1697 hd->ioc->name, ctx2abort, type));
1699 DBG_DUMP_TM_REQUEST_FRAME((u32 *)pScsiTm);
1701 if ((retval = mpt_send_handshake_request(hd->ioc->TaskCtx, hd->ioc,
1702 sizeof(SCSITaskMgmt_t), (u32*)pScsiTm,
1704 dfailprintk((MYIOC_s_ERR_FMT "_send_handshake FAILED!"
1705 " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
1707 mpt_free_msg_frame(hd->ioc, mf);
1711 if(mptscsih_tm_wait_for_completion(hd, timeout) == FAILED) {
1712 dfailprintk((MYIOC_s_ERR_FMT "_wait_for_completion FAILED!"
1713 " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
1715 mpt_free_msg_frame(hd->ioc, mf);
1716 dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
1718 retval = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
1724 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1726 * mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant
1727 * @SCpnt: Pointer to scsi_cmnd structure, IO to be aborted
1729 * (linux scsi_host_template.eh_abort_handler routine)
1731 * Returns SUCCESS or FAILED.
1734 mptscsih_abort(struct scsi_cmnd * SCpnt)
1744 /* If we can't locate our host adapter structure, return FAILED status.
1746 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL) {
1747 SCpnt->result = DID_RESET << 16;
1748 SCpnt->scsi_done(SCpnt);
1749 dfailprintk((KERN_INFO MYNAM ": mptscsih_abort: "
1750 "Can't locate host! (sc=%p)\n",
1756 if (hd->resetPending) {
1760 if (hd->timeouts < -1)
1763 /* Find this command
1765 if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) {
1766 /* Cmd not found in ScsiLookup.
1769 SCpnt->result = DID_RESET << 16;
1770 dtmprintk((KERN_INFO MYNAM ": %s: mptscsih_abort: "
1771 "Command not in the active list! (sc=%p)\n",
1772 hd->ioc->name, SCpnt));
1776 printk(KERN_WARNING MYNAM ": %s: attempting task abort! (sc=%p)\n",
1777 hd->ioc->name, SCpnt);
1778 scsi_print_command(SCpnt);
1780 /* Most important! Set TaskMsgContext to SCpnt's MsgContext!
1781 * (the IO to be ABORT'd)
1783 * NOTE: Since we do not byteswap MsgContext, we do not
1784 * swap it here either. It is an opaque cookie to
1785 * the controller, so it does not matter. -DaveM
1787 mf = MPT_INDEX_2_MFPTR(hd->ioc, scpnt_idx);
1788 ctx2abort = mf->u.frame.hwhdr.msgctxu.MsgContext;
1790 hd->abortSCpnt = SCpnt;
1792 vdev = SCpnt->device->hostdata;
1793 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
1794 vdev->bus_id, vdev->target_id, vdev->lun,
1795 ctx2abort, 2 /* 2 second timeout */);
1797 printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n",
1799 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1804 if(retval != FAILED ) {
1806 hd->tmState = TM_STATE_NONE;
1811 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1813 * mptscsih_dev_reset - Perform a SCSI TARGET_RESET! new_eh variant
1814 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1816 * (linux scsi_host_template.eh_dev_reset_handler routine)
1818 * Returns SUCCESS or FAILED.
1821 mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
1827 /* If we can't locate our host adapter structure, return FAILED status.
1829 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1830 dtmprintk((KERN_INFO MYNAM ": mptscsih_dev_reset: "
1831 "Can't locate host! (sc=%p)\n",
1836 if (hd->resetPending)
1839 printk(KERN_WARNING MYNAM ": %s: attempting target reset! (sc=%p)\n",
1840 hd->ioc->name, SCpnt);
1841 scsi_print_command(SCpnt);
1843 vdev = SCpnt->device->hostdata;
1844 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
1845 vdev->bus_id, vdev->target_id,
1846 0, 0, 5 /* 5 second timeout */);
1848 printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n",
1850 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1855 if(retval != FAILED ) {
1857 hd->tmState = TM_STATE_NONE;
1862 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1864 * mptscsih_bus_reset - Perform a SCSI BUS_RESET! new_eh variant
1865 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1867 * (linux scsi_host_template.eh_bus_reset_handler routine)
1869 * Returns SUCCESS or FAILED.
1872 mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
1878 /* If we can't locate our host adapter structure, return FAILED status.
1880 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1881 dtmprintk((KERN_INFO MYNAM ": mptscsih_bus_reset: "
1882 "Can't locate host! (sc=%p)\n",
1887 printk(KERN_WARNING MYNAM ": %s: attempting bus reset! (sc=%p)\n",
1888 hd->ioc->name, SCpnt);
1889 scsi_print_command(SCpnt);
1891 if (hd->timeouts < -1)
1894 vdev = SCpnt->device->hostdata;
1895 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
1896 vdev->bus_id, 0, 0, 0, 5 /* 5 second timeout */);
1898 printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n",
1900 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1905 if(retval != FAILED ) {
1907 hd->tmState = TM_STATE_NONE;
1912 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1914 * mptscsih_host_reset - Perform a SCSI host adapter RESET!
1916 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1918 * (linux scsi_host_template.eh_host_reset_handler routine)
1920 * Returns SUCCESS or FAILED.
1923 mptscsih_host_reset(struct scsi_cmnd *SCpnt)
1926 int status = SUCCESS;
1928 /* If we can't locate the host to reset, then we failed. */
1929 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1930 dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
1931 "Can't locate host! (sc=%p)\n",
1936 printk(KERN_WARNING MYNAM ": %s: Attempting host reset! (sc=%p)\n",
1937 hd->ioc->name, SCpnt);
1939 /* If our attempts to reset the host failed, then return a failed
1940 * status. The host will be taken off line by the SCSI mid-layer.
1942 if (mpt_HardResetHandler(hd->ioc, CAN_SLEEP) < 0){
1945 /* Make sure TM pending is cleared and TM state is set to
1949 hd->tmState = TM_STATE_NONE;
1952 dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
1954 (status == SUCCESS) ? "SUCCESS" : "FAILED" ) );
1959 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1961 * mptscsih_tm_pending_wait - wait for pending task management request to
1963 * @hd: Pointer to MPT host structure.
1965 * Returns {SUCCESS,FAILED}.
1968 mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd)
1970 unsigned long flags;
1971 int loop_count = 4 * 10; /* Wait 10 seconds */
1972 int status = FAILED;
1975 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
1976 if (hd->tmState == TM_STATE_NONE) {
1977 hd->tmState = TM_STATE_IN_PROGRESS;
1979 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1983 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1985 } while (--loop_count);
1990 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1992 * mptscsih_tm_wait_for_completion - wait for completion of TM task
1993 * @hd: Pointer to MPT host structure.
1995 * Returns {SUCCESS,FAILED}.
1998 mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout )
2000 unsigned long flags;
2001 int loop_count = 4 * timeout;
2002 int status = FAILED;
2005 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
2006 if(hd->tmPending == 0) {
2008 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2011 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2012 msleep_interruptible(250);
2013 } while (--loop_count);
2018 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2020 * mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
2021 * @ioc: Pointer to MPT_ADAPTER structure
2022 * @mf: Pointer to SCSI task mgmt request frame
2023 * @mr: Pointer to SCSI task mgmt reply frame
2025 * This routine is called from mptbase.c::mpt_interrupt() at the completion
2026 * of any SCSI task management request.
2027 * This routine is registered with the MPT (base) driver at driver
2028 * load/init time via the mpt_register() API call.
2030 * Returns 1 indicating alloc'd request frame ptr should be freed.
2033 mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
2035 SCSITaskMgmtReply_t *pScsiTmReply;
2036 SCSITaskMgmt_t *pScsiTmReq;
2038 unsigned long flags;
2042 dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt completed (mf=%p,mr=%p)\n",
2043 ioc->name, mf, mr));
2045 /* Depending on the thread, a timer is activated for
2046 * the TM request. Delete this timer on completion of TM.
2047 * Decrement count of outstanding TM requests.
2049 hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
2051 dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt Complete: NULL Scsi Host Ptr\n",
2057 dtmprintk((MYIOC_s_WARN_FMT "ERROR! TaskMgmt Reply: NULL Request %p\n",
2061 pScsiTmReply = (SCSITaskMgmtReply_t*)mr;
2062 pScsiTmReq = (SCSITaskMgmt_t*)mf;
2064 /* Figure out if this was ABORT_TASK, TARGET_RESET, or BUS_RESET! */
2065 tmType = pScsiTmReq->TaskType;
2067 dtmprintk((MYIOC_s_WARN_FMT " TaskType = %d, TerminationCount=%d\n",
2068 ioc->name, tmType, le32_to_cpu(pScsiTmReply->TerminationCount)));
2069 DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply);
2071 iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2072 dtmprintk((MYIOC_s_WARN_FMT " SCSI TaskMgmt (%d) IOCStatus=%04x IOCLogInfo=%08x\n",
2073 ioc->name, tmType, iocstatus, le32_to_cpu(pScsiTmReply->IOCLogInfo)));
2074 /* Error? (anything non-zero?) */
2077 /* clear flags and continue.
2079 if (tmType == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK)
2080 hd->abortSCpnt = NULL;
2082 /* If an internal command is present
2083 * or the TM failed - reload the FW.
2084 * FC FW may respond FAILED to an ABORT
2086 if (tmType == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
2088 (iocstatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED)) {
2089 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0) {
2090 printk((KERN_WARNING
2091 " Firmware Reload FAILED!!\n"));
2096 dtmprintk((MYIOC_s_WARN_FMT " TaskMgmt SUCCESS\n", ioc->name));
2098 hd->abortSCpnt = NULL;
2103 spin_lock_irqsave(&ioc->FreeQlock, flags);
2105 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2106 hd->tmState = TM_STATE_NONE;
2111 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2113 * This is anyones guess quite frankly.
2116 mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
2117 sector_t capacity, int geom[])
2127 dummy = heads * sectors;
2128 cylinders = capacity;
2129 sector_div(cylinders,dummy);
2132 * Handle extended translation size for logical drives
2135 if ((ulong)capacity >= 0x200000) {
2138 dummy = heads * sectors;
2139 cylinders = capacity;
2140 sector_div(cylinders,dummy);
2146 geom[2] = cylinders;
2148 dprintk((KERN_NOTICE
2149 ": bios_param: Id=%i Lun=%i Channel=%i CHS=%i/%i/%i\n",
2150 sdev->id, sdev->lun,sdev->channel,(int)cylinders,heads,sectors));
2155 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2157 * OS entry point to allow host driver to alloc memory
2158 * for each scsi target. Called once per device the bus scan.
2159 * Return non-zero if allocation fails.
2162 mptscsih_target_alloc(struct scsi_target *starget)
2164 VirtTarget *vtarget;
2166 vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
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 = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
2190 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
2191 hd->ioc->name, sizeof(VirtDevice));
2195 vdev->ioc_id = hd->ioc->id;
2196 vdev->target_id = sdev->id;
2197 vdev->bus_id = sdev->channel;
2198 vdev->lun = sdev->lun;
2199 sdev->hostdata = vdev;
2201 starget = scsi_target(sdev);
2202 vtarget = starget->hostdata;
2203 vdev->vtarget = vtarget;
2205 if (vtarget->num_luns == 0) {
2206 hd->Targets[sdev->id] = vtarget;
2207 vtarget->ioc_id = hd->ioc->id;
2208 vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
2209 vtarget->target_id = sdev->id;
2210 vtarget->bus_id = sdev->channel;
2211 if (hd->ioc->bus_type == SPI) {
2212 if (hd->ioc->raid_data.isRaid & (1 << sdev->id)) {
2213 vtarget->raidVolume = 1;
2214 ddvtprintk((KERN_INFO
2215 "RAID Volume @ id %d\n", sdev->id));
2218 vtarget->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
2221 vtarget->num_luns++;
2226 * OS entry point to allow for host driver to free allocated memory
2227 * Called if no device present or device being unloaded
2230 mptscsih_target_destroy(struct scsi_target *starget)
2232 if (starget->hostdata)
2233 kfree(starget->hostdata);
2234 starget->hostdata = NULL;
2238 * OS entry point to allow for host driver to free allocated memory
2239 * Called if no device present or device being unloaded
2242 mptscsih_slave_destroy(struct scsi_device *sdev)
2244 struct Scsi_Host *host = sdev->host;
2245 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
2246 VirtTarget *vtarget;
2247 VirtDevice *vdevice;
2248 struct scsi_target *starget;
2250 starget = scsi_target(sdev);
2251 vtarget = starget->hostdata;
2252 vdevice = sdev->hostdata;
2254 mptscsih_search_running_cmds(hd, vdevice);
2255 vtarget->luns[0] &= ~(1 << vdevice->lun);
2256 vtarget->num_luns--;
2257 if (vtarget->num_luns == 0) {
2258 mptscsih_negotiate_to_asyn_narrow(hd, vtarget);
2259 if (hd->ioc->bus_type == SPI) {
2260 if (mptscsih_is_phys_disk(hd->ioc, vtarget->target_id)) {
2261 hd->ioc->spi_data.forceDv |= MPT_SCSICFG_RELOAD_IOC_PG3;
2263 hd->ioc->spi_data.dvStatus[vtarget->target_id] =
2264 MPT_SCSICFG_NEGOTIATE;
2265 if (!hd->negoNvram) {
2266 hd->ioc->spi_data.dvStatus[vtarget->target_id] |=
2267 MPT_SCSICFG_DV_NOT_DONE;
2271 hd->Targets[sdev->id] = NULL;
2273 mptscsih_synchronize_cache(hd, vdevice);
2275 sdev->hostdata = NULL;
2278 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2280 * mptscsih_change_queue_depth - This function will set a devices queue depth
2281 * @sdev: per scsi_device pointer
2282 * @qdepth: requested queue depth
2284 * Adding support for new 'change_queue_depth' api.
2287 mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
2289 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sdev->host->hostdata;
2290 VirtTarget *vtarget;
2291 struct scsi_target *starget;
2295 starget = scsi_target(sdev);
2296 vtarget = starget->hostdata;
2298 if (hd->ioc->bus_type == SPI) {
2299 if (vtarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) {
2300 if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
2302 else if (((vtarget->inq_data[0] & 0x1f) == 0x00) &&
2303 (vtarget->minSyncFactor <= MPT_ULTRA160 ))
2304 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2306 max_depth = MPT_SCSI_CMD_PER_DEV_LOW;
2308 /* error case - No Inq. Data */
2312 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2314 if (qdepth > max_depth)
2319 tagged = MSG_SIMPLE_TAG;
2321 scsi_adjust_queue_depth(sdev, tagged, qdepth);
2322 return sdev->queue_depth;
2326 * OS entry point to adjust the queue_depths on a per-device basis.
2327 * Called once per device the bus scan. Use it to force the queue_depth
2328 * member to 1 if a device does not support Q tags.
2329 * Return non-zero if fails.
2332 mptscsih_slave_configure(struct scsi_device *sdev)
2334 struct Scsi_Host *sh = sdev->host;
2335 VirtTarget *vtarget;
2336 VirtDevice *vdevice;
2337 struct scsi_target *starget;
2338 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sh->hostdata;
2339 int indexed_lun, lun_index;
2341 starget = scsi_target(sdev);
2342 vtarget = starget->hostdata;
2343 vdevice = sdev->hostdata;
2345 dsprintk((MYIOC_s_INFO_FMT
2346 "device @ %p, id=%d, LUN=%d, channel=%d\n",
2347 hd->ioc->name, sdev, sdev->id, sdev->lun, sdev->channel));
2348 if (hd->ioc->bus_type == SPI)
2349 dsprintk((MYIOC_s_INFO_FMT
2350 "sdtr %d wdtr %d ppr %d inq length=%d\n",
2351 hd->ioc->name, sdev->sdtr, sdev->wdtr,
2352 sdev->ppr, sdev->inquiry_len));
2354 if (sdev->id > sh->max_id) {
2355 /* error case, should never happen */
2356 scsi_adjust_queue_depth(sdev, 0, 1);
2357 goto slave_configure_exit;
2360 vdevice->configured_lun=1;
2361 lun_index = (vdevice->lun >> 5); /* 32 luns per lun_index */
2362 indexed_lun = (vdevice->lun % 32);
2363 vtarget->luns[lun_index] |= (1 << indexed_lun);
2364 mptscsih_initTarget(hd, vtarget, sdev->lun, sdev->inquiry,
2365 sdev->inquiry_len );
2366 mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH);
2368 dsprintk((MYIOC_s_INFO_FMT
2369 "Queue depth=%d, tflags=%x\n",
2370 hd->ioc->name, sdev->queue_depth, vtarget->tflags));
2372 if (hd->ioc->bus_type == SPI)
2373 dsprintk((MYIOC_s_INFO_FMT
2374 "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
2375 hd->ioc->name, vtarget->negoFlags, vtarget->maxOffset,
2376 vtarget->minSyncFactor));
2378 slave_configure_exit:
2380 dsprintk((MYIOC_s_INFO_FMT
2381 "tagged %d, simple %d, ordered %d\n",
2382 hd->ioc->name,sdev->tagged_supported, sdev->simple_tags,
2383 sdev->ordered_tags));
2388 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2390 * Private routines...
2393 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2394 /* Utility function to copy sense data from the scsi_cmnd buffer
2395 * to the FC and SCSI target structures.
2399 mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
2402 SCSIIORequest_t *pReq;
2403 u32 sense_count = le32_to_cpu(pScsiReply->SenseCount);
2405 /* Get target structure
2407 pReq = (SCSIIORequest_t *) mf;
2408 vdev = sc->device->hostdata;
2414 /* Copy the sense received into the scsi command block. */
2415 req_index = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2416 sense_data = ((u8 *)hd->ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC));
2417 memcpy(sc->sense_buffer, sense_data, SNS_LEN(sc));
2419 /* Log SMART data (asc = 0x5D, non-IM case only) if required.
2421 if ((hd->ioc->events) && (hd->ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) {
2422 if ((sense_data[12] == 0x5D) && (vdev->vtarget->raidVolume == 0)) {
2424 MPT_ADAPTER *ioc = hd->ioc;
2426 idx = ioc->eventContext % ioc->eventLogSize;
2427 ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
2428 ioc->events[idx].eventContext = ioc->eventContext;
2430 ioc->events[idx].data[0] = (pReq->LUN[1] << 24) ||
2431 (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) ||
2432 (sc->device->channel << 8) || sc->device->id;
2434 ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12];
2436 ioc->eventContext++;
2440 dprintk((MYIOC_s_INFO_FMT "Hmmm... SenseData len=0! (?)\n",
2446 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc)
2451 hd = (MPT_SCSI_HOST *) sc->device->host->hostdata;
2453 for (i = 0; i < hd->ioc->req_depth; i++) {
2454 if (hd->ScsiLookup[i] == sc) {
2462 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2464 mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2467 unsigned long flags;
2470 dtmprintk((KERN_WARNING MYNAM
2471 ": IOC %s_reset routed to SCSI host driver!\n",
2472 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
2473 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
2475 /* If a FW reload request arrives after base installed but
2476 * before all scsi hosts have been attached, then an alt_ioc
2477 * may have a NULL sh pointer.
2479 if ((ioc->sh == NULL) || (ioc->sh->hostdata == NULL))
2482 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2484 if (reset_phase == MPT_IOC_SETUP_RESET) {
2485 dtmprintk((MYIOC_s_WARN_FMT "Setup-Diag Reset\n", ioc->name));
2488 * 1. Set Hard Reset Pending Flag
2489 * All new commands go to doneQ
2491 hd->resetPending = 1;
2493 } else if (reset_phase == MPT_IOC_PRE_RESET) {
2494 dtmprintk((MYIOC_s_WARN_FMT "Pre-Diag Reset\n", ioc->name));
2496 /* 2. Flush running commands
2497 * Clean ScsiLookup (and associated memory)
2501 /* 2b. Reply to OS all known outstanding I/O commands.
2503 mptscsih_flush_running_cmds(hd);
2505 /* 2c. If there was an internal command that
2506 * has not completed, configuration or io request,
2507 * free these resources.
2510 del_timer(&hd->timer);
2511 mpt_free_msg_frame(ioc, hd->cmdPtr);
2514 dtmprintk((MYIOC_s_WARN_FMT "Pre-Reset complete.\n", ioc->name));
2517 dtmprintk((MYIOC_s_WARN_FMT "Post-Diag Reset\n", ioc->name));
2519 /* Once a FW reload begins, all new OS commands are
2520 * redirected to the doneQ w/ a reset status.
2521 * Init all control structures.
2524 /* ScsiLookup initialization
2526 for (ii=0; ii < hd->ioc->req_depth; ii++)
2527 hd->ScsiLookup[ii] = NULL;
2529 /* 2. Chain Buffer initialization
2532 /* 4. Renegotiate to all devices, if SPI
2534 if (ioc->bus_type == SPI) {
2535 dnegoprintk(("writeSDP1: ALL_IDS USE_NVRAM\n"));
2536 mptscsih_writeSDP1(hd, 0, 0, MPT_SCSICFG_ALL_IDS | MPT_SCSICFG_USE_NVRAM);
2539 /* 5. Enable new commands to be posted
2541 spin_lock_irqsave(&ioc->FreeQlock, flags);
2543 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2544 hd->resetPending = 0;
2545 hd->tmState = TM_STATE_NONE;
2547 /* 6. If there was an internal command,
2548 * wake this process up.
2552 * Wake up the original calling thread
2554 hd->pLocal = &hd->localReply;
2555 hd->pLocal->completion = MPT_SCANDV_DID_RESET;
2556 hd->scandv_wait_done = 1;
2557 wake_up(&hd->scandv_waitq);
2561 /* 7. SPI: Set flag to force DV and re-read IOC Page 3
2563 if (ioc->bus_type == SPI) {
2564 ioc->spi_data.forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
2565 ddvtprintk(("Set reload IOC Pg3 Flag\n"));
2568 /* 7. FC: Rescan for blocked rports which might have returned.
2570 else if (ioc->bus_type == FC) {
2572 unsigned long flags;
2574 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
2575 work_count = ++ioc->fc_rescan_work_count;
2576 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
2577 if (work_count == 1)
2578 schedule_work(&ioc->fc_rescan_work);
2580 dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name));
2584 return 1; /* currently means nothing really */
2587 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2588 /* work queue thread to clear the persitency table */
2590 mptscsih_sas_persist_clear_table(void * arg)
2592 MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg;
2594 mptbase_sas_persist_operation(ioc, MPI_SAS_OP_CLEAR_NOT_PRESENT);
2597 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2599 mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2602 u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
2604 unsigned long flags;
2606 devtprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
2609 if (ioc->sh == NULL ||
2610 ((hd = (MPT_SCSI_HOST *)ioc->sh->hostdata) == NULL))
2614 case MPI_EVENT_UNIT_ATTENTION: /* 03 */
2617 case MPI_EVENT_IOC_BUS_RESET: /* 04 */
2618 case MPI_EVENT_EXT_BUS_RESET: /* 05 */
2619 if (hd && (ioc->bus_type == SPI) && (hd->soft_resets < -1))
2622 case MPI_EVENT_LOGOUT: /* 09 */
2626 case MPI_EVENT_RESCAN: /* 06 */
2627 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
2628 work_count = ++ioc->fc_rescan_work_count;
2629 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
2630 if (work_count == 1)
2631 schedule_work(&ioc->fc_rescan_work);
2635 * CHECKME! Don't think we need to do
2636 * anything for these, but...
2638 case MPI_EVENT_LINK_STATUS_CHANGE: /* 07 */
2639 case MPI_EVENT_LOOP_STATE_CHANGE: /* 08 */
2641 * CHECKME! Falling thru...
2645 case MPI_EVENT_INTEGRATED_RAID: /* 0B */
2647 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
2648 pMpiEventDataRaid_t pRaidEventData =
2649 (pMpiEventDataRaid_t) pEvReply->Data;
2650 /* Domain Validation Needed */
2651 if (ioc->bus_type == SPI &&
2652 pRaidEventData->ReasonCode ==
2653 MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED)
2654 mptscsih_set_dvflags_raid(hd, pRaidEventData->PhysDiskNum);
2659 /* Persistent table is full. */
2660 case MPI_EVENT_PERSISTENT_TABLE_FULL:
2661 INIT_WORK(&mptscsih_persistTask,
2662 mptscsih_sas_persist_clear_table,(void *)ioc);
2663 schedule_work(&mptscsih_persistTask);
2666 case MPI_EVENT_NONE: /* 00 */
2667 case MPI_EVENT_LOG_DATA: /* 01 */
2668 case MPI_EVENT_STATE_CHANGE: /* 02 */
2669 case MPI_EVENT_EVENT_CHANGE: /* 0A */
2671 dprintk((KERN_INFO " Ignoring event (=%02Xh)\n", event));
2675 return 1; /* currently means nothing really */
2678 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2680 * mptscsih_initTarget - Target, LUN alloc/free functionality.
2681 * @hd: Pointer to MPT_SCSI_HOST structure
2682 * @vtarget: per target private data
2684 * @data: Pointer to data
2685 * @dlen: Number of INQUIRY bytes
2687 * NOTE: It's only SAFE to call this routine if data points to
2688 * sane & valid STANDARD INQUIRY data!
2690 * Allocate and initialize memory for this target.
2691 * Save inquiry data.
2695 mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, u8 lun, char *data, int dlen)
2701 dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n",
2702 hd->ioc->name, vtarget->bus_id, vtarget->target_id, lun, hd));
2705 * If the peripheral qualifier filter is enabled then if the target reports a 0x1
2706 * (i.e. The targer is capable of supporting the specified peripheral device type
2707 * on this logical unit; however, the physical device is not currently connected
2708 * to this logical unit) it will be converted to a 0x3 (i.e. The target is not
2709 * capable of supporting a physical device on this logical unit). This is to work
2710 * around a bug in th emid-layer in some distributions in which the mid-layer will
2711 * continue to try to communicate to the LUN and evntually create a dummy LUN.
2713 if (hd->mpt_pq_filter && dlen && (data[0] & 0xE0))
2716 /* Is LUN supported? If so, upper 2 bits will be 0
2717 * in first byte of inquiry data.
2722 if (vtarget == NULL)
2726 vtarget->type = data[0];
2728 if (hd->ioc->bus_type != SPI)
2731 if ((data[0] == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) {
2732 /* Treat all Processors as SAF-TE if
2733 * command line option is set */
2734 vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
2735 mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id);
2736 }else if ((data[0] == TYPE_PROCESSOR) &&
2737 !(vtarget->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) {
2739 vtarget->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
2740 if ( data[44] == 'S' &&
2746 vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
2747 mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id);
2751 if (!(vtarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY)) {
2752 inq_len = dlen < 8 ? dlen : 8;
2753 memcpy (vtarget->inq_data, data, inq_len);
2754 /* If have not done DV, set the DV flag.
2756 pSpi = &hd->ioc->spi_data;
2757 if ((data[0] == TYPE_TAPE) || (data[0] == TYPE_PROCESSOR)) {
2758 if (pSpi->dvStatus[vtarget->target_id] & MPT_SCSICFG_DV_NOT_DONE)
2759 pSpi->dvStatus[vtarget->target_id] |= MPT_SCSICFG_NEED_DV;
2761 vtarget->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
2763 data_56 = 0x0F; /* Default to full capabilities if Inq data length is < 57 */
2765 if ( (!(vtarget->tflags & MPT_TARGET_FLAGS_VALID_56))) {
2766 /* Update the target capabilities
2769 vtarget->tflags |= MPT_TARGET_FLAGS_VALID_56;
2772 mptscsih_setTargetNegoParms(hd, vtarget, data_56);
2774 /* Initial Inquiry may not request enough data bytes to
2775 * obtain byte 57. DV will; if target doesn't return
2776 * at least 57 bytes, data[56] will be zero. */
2778 if ( (!(vtarget->tflags & MPT_TARGET_FLAGS_VALID_56))) {
2779 /* Update the target capabilities
2782 vtarget->tflags |= MPT_TARGET_FLAGS_VALID_56;
2783 mptscsih_setTargetNegoParms(hd, vtarget, data_56);
2789 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2791 * Update the target negotiation parameters based on the
2792 * the Inquiry data, adapter capabilities, and NVRAM settings.
2796 mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target, char byte56)
2798 SpiCfgData *pspi_data = &hd->ioc->spi_data;
2799 int id = (int) target->target_id;
2801 VirtTarget *vtarget;
2803 u8 width = MPT_NARROW;
2804 u8 factor = MPT_ASYNC;
2806 u8 version, nfactor;
2809 target->negoFlags = pspi_data->noQas;
2811 /* noQas == 0 => device supports QAS. Need byte 56 of Inq to determine
2812 * support. If available, default QAS to off and allow enabling.
2813 * If not available, default QAS to on, turn off for non-disks.
2816 /* Set flags based on Inquiry data
2818 version = target->inq_data[2] & 0x07;
2821 factor = MPT_ULTRA2;
2822 offset = pspi_data->maxSyncOffset;
2823 target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
2825 if (target->inq_data[7] & 0x20) {
2829 if (target->inq_data[7] & 0x10) {
2830 factor = pspi_data->minSyncFactor;
2831 if (target->tflags & MPT_TARGET_FLAGS_VALID_56) {
2832 /* bits 2 & 3 show Clocking support */
2833 if ((byte56 & 0x0C) == 0)
2834 factor = MPT_ULTRA2;
2836 if ((byte56 & 0x03) == 0)
2837 factor = MPT_ULTRA160;
2839 factor = MPT_ULTRA320;
2842 ddvtprintk((KERN_INFO "Enabling QAS due to byte56=%02x on id=%d!\n", byte56, id));
2845 if (target->inq_data[0] == TYPE_TAPE) {
2847 target->negoFlags |= MPT_TAPE_NEGO_IDP;
2852 ddvtprintk((KERN_INFO "Enabling QAS on id=%d due to ~TARGET_FLAGS_VALID_56!\n", id));
2856 offset = pspi_data->maxSyncOffset;
2858 /* If RAID, never disable QAS
2859 * else if non RAID, do not disable
2860 * QAS if bit 1 is set
2861 * bit 1 QAS support, non-raid only
2864 if (target->raidVolume == 1) {
2873 if ( (target->inq_data[7] & 0x02) == 0) {
2874 target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
2877 /* Update tflags based on NVRAM settings. (SCSI only)
2879 if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
2880 nvram = pspi_data->nvram[id];
2881 nfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
2884 width = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
2887 /* Ensure factor is set to the
2888 * maximum of: adapter, nvram, inquiry
2891 if (nfactor < pspi_data->minSyncFactor )
2892 nfactor = pspi_data->minSyncFactor;
2894 factor = max(factor, nfactor);
2895 if (factor == MPT_ASYNC)
2906 /* Make sure data is consistent
2908 if ((!width) && (factor < MPT_ULTRA2)) {
2909 factor = MPT_ULTRA2;
2912 /* Save the data to the target structure.
2914 target->minSyncFactor = factor;
2915 target->maxOffset = offset;
2916 target->maxWidth = width;
2918 target->tflags |= MPT_TARGET_FLAGS_VALID_NEGO;
2920 /* Disable unused features.
2923 target->negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
2926 target->negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
2928 if ( factor > MPT_ULTRA320 )
2931 /* GEM, processor WORKAROUND
2933 if ((target->inq_data[0] == TYPE_PROCESSOR) || (target->inq_data[0] > 0x08)) {
2934 target->negoFlags |= (MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC);
2935 pspi_data->dvStatus[id] |= MPT_SCSICFG_BLK_NEGO;
2937 if (noQas && (pspi_data->noQas == 0)) {
2938 pspi_data->noQas |= MPT_TARGET_NO_NEGO_QAS;
2939 target->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
2941 /* Disable QAS in a mixed configuration case
2944 ddvtprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id));
2945 for (ii = 0; ii < id; ii++) {
2946 if ( (vtarget = hd->Targets[ii]) ) {
2947 vtarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
2948 mptscsih_writeSDP1(hd, 0, ii, vtarget->negoFlags);
2954 /* Write SDP1 on this I/O to this target */
2955 if (pspi_data->dvStatus[id] & MPT_SCSICFG_NEGOTIATE) {
2956 ddvtprintk((KERN_INFO "MPT_SCSICFG_NEGOTIATE on id=%d!\n", id));
2957 mptscsih_writeSDP1(hd, 0, id, hd->negoNvram);
2958 pspi_data->dvStatus[id] &= ~MPT_SCSICFG_NEGOTIATE;
2959 } else if (pspi_data->dvStatus[id] & MPT_SCSICFG_BLK_NEGO) {
2960 ddvtprintk((KERN_INFO "MPT_SCSICFG_BLK_NEGO on id=%d!\n", id));
2961 mptscsih_writeSDP1(hd, 0, id, MPT_SCSICFG_BLK_NEGO);
2962 pspi_data->dvStatus[id] &= ~MPT_SCSICFG_BLK_NEGO;
2966 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2968 * If no Target, bus reset on 1st I/O. Set the flag to
2969 * prevent any future negotiations to this device.
2972 mptscsih_no_negotiate(MPT_SCSI_HOST *hd, struct scsi_cmnd *sc)
2976 if ((vdev = sc->device->hostdata) != NULL)
2977 hd->ioc->spi_data.dvStatus[vdev->target_id] |= MPT_SCSICFG_BLK_NEGO;
2981 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2983 * SCSI Config Page functionality ...
2985 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2986 /* mptscsih_setDevicePage1Flags - add Requested and Configuration fields flags
2987 * based on width, factor and offset parameters.
2989 * @factor: sync factor
2990 * @offset: sync offset
2991 * @requestedPtr: pointer to requested values (updated)
2992 * @configurationPtr: pointer to configuration values (updated)
2993 * @flags: flags to block WDTR or SDTR negotiation
2997 * Remark: Called by writeSDP1 and _dv_params
3000 mptscsih_setDevicePage1Flags (u8 width, u8 factor, u8 offset, int *requestedPtr, int *configurationPtr, u8 flags)
3002 u8 nowide = flags & MPT_TARGET_NO_NEGO_WIDE;
3003 u8 nosync = flags & MPT_TARGET_NO_NEGO_SYNC;
3005 *configurationPtr = 0;
3006 *requestedPtr = width ? MPI_SCSIDEVPAGE1_RP_WIDE : 0;
3007 *requestedPtr |= (offset << 16) | (factor << 8);
3009 if (width && offset && !nowide && !nosync) {
3010 if (factor < MPT_ULTRA160) {
3011 *requestedPtr |= (MPI_SCSIDEVPAGE1_RP_IU + MPI_SCSIDEVPAGE1_RP_DT);
3012 if ((flags & MPT_TARGET_NO_NEGO_QAS) == 0)
3013 *requestedPtr |= MPI_SCSIDEVPAGE1_RP_QAS;
3014 if (flags & MPT_TAPE_NEGO_IDP)
3015 *requestedPtr |= 0x08000000;
3016 } else if (factor < MPT_ULTRA2) {
3017 *requestedPtr |= MPI_SCSIDEVPAGE1_RP_DT;
3022 *configurationPtr |= MPI_SCSIDEVPAGE1_CONF_WDTR_DISALLOWED;
3025 *configurationPtr |= MPI_SCSIDEVPAGE1_CONF_SDTR_DISALLOWED;
3030 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3031 /* mptscsih_writeSDP1 - write SCSI Device Page 1
3032 * @hd: Pointer to a SCSI Host Strucutre
3033 * @portnum: IOC port number
3034 * @target_id: writeSDP1 for single ID
3035 * @flags: MPT_SCSICFG_ALL_IDS, MPT_SCSICFG_USE_NVRAM, MPT_SCSICFG_BLK_NEGO
3037 * Return: -EFAULT if read of config page header fails
3040 * Remark: If a target has been found, the settings from the
3041 * target structure are used, else the device is set
3044 * Remark: Called during init and after a FW reload.
3045 * Remark: We do not wait for a return, write pages sequentially.
3048 mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
3050 MPT_ADAPTER *ioc = hd->ioc;
3052 SCSIDevicePage1_t *pData;
3053 VirtTarget *vtarget=NULL;
3058 u32 requested, configuration, flagsLength;
3060 int id = 0, maxid = 0;
3066 u8 maxwidth, maxoffset, maxfactor;
3068 if (ioc->spi_data.sdp1length == 0)
3071 if (flags & MPT_SCSICFG_ALL_IDS) {
3073 maxid = ioc->sh->max_id - 1;
3074 } else if (ioc->sh) {
3076 maxid = min_t(int, id, ioc->sh->max_id - 1);
3079 for (; id <= maxid; id++) {
3081 if (id == ioc->pfacts[portnum].PortSCSIID)
3084 /* Use NVRAM to get adapter and target maximums
3085 * Data over-riden by target structure information, if present
3087 maxwidth = ioc->spi_data.maxBusWidth;
3088 maxoffset = ioc->spi_data.maxSyncOffset;
3089 maxfactor = ioc->spi_data.minSyncFactor;
3090 if (ioc->spi_data.nvram && (ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
3091 nvram = ioc->spi_data.nvram[id];
3094 maxwidth = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
3096 if (maxoffset > 0) {
3097 maxfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
3098 if (maxfactor == 0) {
3100 maxfactor = MPT_ASYNC;
3102 } else if (maxfactor < ioc->spi_data.minSyncFactor) {
3103 maxfactor = ioc->spi_data.minSyncFactor;
3106 maxfactor = MPT_ASYNC;
3109 /* Set the negotiation flags.
3111 negoFlags = ioc->spi_data.noQas;
3113 negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
3116 negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
3118 if (flags & MPT_SCSICFG_USE_NVRAM) {
3127 //negoFlags = MPT_TARGET_NO_NEGO_SYNC;
3130 /* If id is not a raid volume, get the updated
3131 * transmission settings from the target structure.
3133 if (hd->Targets && (vtarget = hd->Targets[id]) && !vtarget->raidVolume) {
3134 width = vtarget->maxWidth;
3135 factor = vtarget->minSyncFactor;
3136 offset = vtarget->maxOffset;
3137 negoFlags = vtarget->negoFlags;
3140 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
3141 /* Force to async and narrow if DV has not been executed
3144 if ((hd->ioc->spi_data.dvStatus[id] & MPT_SCSICFG_DV_NOT_DONE) != 0) {
3151 if (flags & MPT_SCSICFG_BLK_NEGO)
3152 negoFlags |= MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC;
3154 mptscsih_setDevicePage1Flags(width, factor, offset,
3155 &requested, &configuration, negoFlags);
3156 dnegoprintk(("writeSDP1: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
3157 target_id, width, factor, offset, negoFlags, requested, configuration));
3159 /* Get a MF for this command.
3161 if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
3162 dfailprintk((MYIOC_s_WARN_FMT "write SDP1: no msg frames!\n",
3167 ddvprintk((MYIOC_s_INFO_FMT "WriteSDP1 (mf=%p, id=%d, req=0x%x, cfg=0x%x)\n",
3168 hd->ioc->name, mf, id, requested, configuration));
3171 /* Set the request and the data pointers.
3172 * Request takes: 36 bytes (32 bit SGE)
3173 * SCSI Device Page 1 requires 16 bytes
3174 * 40 + 16 <= size of SCSI IO Request = 56 bytes
3175 * and MF size >= 64 bytes.
3176 * Place data at end of MF.
3178 pReq = (Config_t *)mf;
3180 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3181 frameOffset = ioc->req_sz - sizeof(SCSIDevicePage1_t);
3183 pData = (SCSIDevicePage1_t *)((u8 *) mf + frameOffset);
3184 dataDma = ioc->req_frames_dma + (req_idx * ioc->req_sz) + frameOffset;
3186 /* Complete the request frame (same for all requests).
3188 pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
3190 pReq->ChainOffset = 0;
3191 pReq->Function = MPI_FUNCTION_CONFIG;
3192 pReq->ExtPageLength = 0;
3193 pReq->ExtPageType = 0;
3195 for (ii=0; ii < 8; ii++) {
3196 pReq->Reserved2[ii] = 0;
3198 pReq->Header.PageVersion = ioc->spi_data.sdp1version;
3199 pReq->Header.PageLength = ioc->spi_data.sdp1length;
3200 pReq->Header.PageNumber = 1;
3201 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
3202 pReq->PageAddress = cpu_to_le32(id | (bus << 8 ));
3204 /* Add a SGE to the config request.
3206 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE | ioc->spi_data.sdp1length * 4;
3208 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma);
3210 /* Set up the common data portion
3212 pData->Header.PageVersion = pReq->Header.PageVersion;
3213 pData->Header.PageLength = pReq->Header.PageLength;
3214 pData->Header.PageNumber = pReq->Header.PageNumber;
3215 pData->Header.PageType = pReq->Header.PageType;
3216 pData->RequestedParameters = cpu_to_le32(requested);
3217 pData->Reserved = 0;
3218 pData->Configuration = cpu_to_le32(configuration);
3220 dprintk((MYIOC_s_INFO_FMT
3221 "write SDP1: id %d pgaddr 0x%x req 0x%x config 0x%x\n",
3222 ioc->name, id, (id | (bus<<8)),
3223 requested, configuration));
3225 mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
3231 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3232 /* mptscsih_writeIOCPage4 - write IOC Page 4
3233 * @hd: Pointer to a SCSI Host Structure
3234 * @target_id: write IOC Page4 for this ID & Bus
3236 * Return: -EAGAIN if unable to obtain a Message Frame
3239 * Remark: We do not wait for a return, write pages sequentially.
3242 mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus)
3244 MPT_ADAPTER *ioc = hd->ioc;
3246 IOCPage4_t *IOCPage4Ptr;
3254 /* Get a MF for this command.
3256 if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
3257 dfailprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n",
3262 /* Set the request and the data pointers.
3263 * Place data at end of MF.
3265 pReq = (Config_t *)mf;
3267 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3268 frameOffset = ioc->req_sz - sizeof(IOCPage4_t);
3270 /* Complete the request frame (same for all requests).
3272 pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
3274 pReq->ChainOffset = 0;
3275 pReq->Function = MPI_FUNCTION_CONFIG;
3276 pReq->ExtPageLength = 0;
3277 pReq->ExtPageType = 0;
3279 for (ii=0; ii < 8; ii++) {
3280 pReq->Reserved2[ii] = 0;
3283 IOCPage4Ptr = ioc->spi_data.pIocPg4;
3284 dataDma = ioc->spi_data.IocPg4_dma;
3285 ii = IOCPage4Ptr->ActiveSEP++;
3286 IOCPage4Ptr->SEP[ii].SEPTargetID = target_id;
3287 IOCPage4Ptr->SEP[ii].SEPBus = bus;
3288 pReq->Header = IOCPage4Ptr->Header;
3289 pReq->PageAddress = cpu_to_le32(target_id | (bus << 8 ));
3291 /* Add a SGE to the config request.
3293 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE |
3294 (IOCPage4Ptr->Header.PageLength + ii) * 4;
3296 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma);
3298 dinitprintk((MYIOC_s_INFO_FMT
3299 "writeIOCPage4: MaxSEP=%d ActiveSEP=%d id=%d bus=%d\n",
3300 ioc->name, IOCPage4Ptr->MaxSEP, IOCPage4Ptr->ActiveSEP, target_id, bus));
3302 mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
3307 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3309 * Bus Scan and Domain Validation functionality ...
3312 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3314 * mptscsih_scandv_complete - Scan and DV callback routine registered
3315 * to Fustion MPT (base) driver.
3317 * @ioc: Pointer to MPT_ADAPTER structure
3318 * @mf: Pointer to original MPT request frame
3319 * @mr: Pointer to MPT reply frame (NULL if TurboReply)
3321 * This routine is called from mpt.c::mpt_interrupt() at the completion
3322 * of any SCSI IO request.
3323 * This routine is registered with the Fusion MPT (base) driver at driver
3324 * load/init time via the mpt_register() API call.
3326 * Returns 1 indicating alloc'd request frame ptr should be freed.
3328 * Remark: Sets a completion code and (possibly) saves sense data
3329 * in the IOC member localReply structure.
3330 * Used ONLY for DV and other internal commands.
3333 mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
3336 SCSIIORequest_t *pReq;
3340 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
3343 (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) {
3344 printk(MYIOC_s_ERR_FMT
3345 "ScanDvComplete, %s req frame ptr! (=%p)\n",
3346 ioc->name, mf?"BAD":"NULL", (void *) mf);
3350 del_timer(&hd->timer);
3351 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3352 hd->ScsiLookup[req_idx] = NULL;
3353 pReq = (SCSIIORequest_t *) mf;
3355 if (mf != hd->cmdPtr) {
3356 printk(MYIOC_s_WARN_FMT "ScanDvComplete (mf=%p, cmdPtr=%p, idx=%d)\n",
3357 hd->ioc->name, (void *)mf, (void *) hd->cmdPtr, req_idx);
3361 ddvprintk((MYIOC_s_INFO_FMT "ScanDvComplete (mf=%p,mr=%p,idx=%d)\n",
3362 hd->ioc->name, mf, mr, req_idx));
3364 hd->pLocal = &hd->localReply;
3365 hd->pLocal->scsiStatus = 0;
3367 /* If target struct exists, clear sense valid flag.
3370 completionCode = MPT_SCANDV_GOOD;
3372 SCSIIOReply_t *pReply;
3376 pReply = (SCSIIOReply_t *) mr;
3378 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
3379 scsi_status = pReply->SCSIStatus;
3381 ddvtprintk((KERN_NOTICE " IOCStatus=%04xh, SCSIState=%02xh, SCSIStatus=%02xh, IOCLogInfo=%08xh\n",
3382 status, pReply->SCSIState, scsi_status,
3383 le32_to_cpu(pReply->IOCLogInfo)));
3387 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
3388 completionCode = MPT_SCANDV_SELECTION_TIMEOUT;
3391 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
3392 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
3393 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
3394 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
3395 completionCode = MPT_SCANDV_DID_RESET;
3398 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
3399 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
3400 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
3401 if (pReply->Function == MPI_FUNCTION_CONFIG) {
3402 ConfigReply_t *pr = (ConfigReply_t *)mr;
3403 completionCode = MPT_SCANDV_GOOD;
3404 hd->pLocal->header.PageVersion = pr->Header.PageVersion;
3405 hd->pLocal->header.PageLength = pr->Header.PageLength;
3406 hd->pLocal->header.PageNumber = pr->Header.PageNumber;
3407 hd->pLocal->header.PageType = pr->Header.PageType;
3409 } else if (pReply->Function == MPI_FUNCTION_RAID_ACTION) {
3410 /* If the RAID Volume request is successful,
3411 * return GOOD, else indicate that
3412 * some type of error occurred.
3414 MpiRaidActionReply_t *pr = (MpiRaidActionReply_t *)mr;
3415 if (le16_to_cpu(pr->ActionStatus) == MPI_RAID_ACTION_ASTATUS_SUCCESS)
3416 completionCode = MPT_SCANDV_GOOD;
3418 completionCode = MPT_SCANDV_SOME_ERROR;
3420 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID) {
3424 /* save sense data in global structure
3426 completionCode = MPT_SCANDV_SENSE;
3427 hd->pLocal->scsiStatus = scsi_status;
3428 sense_data = ((u8 *)hd->ioc->sense_buf_pool +
3429 (req_idx * MPT_SENSE_BUFFER_ALLOC));
3431 sz = min_t(int, pReq->SenseBufferLength,
3432 SCSI_STD_SENSE_BYTES);
3433 memcpy(hd->pLocal->sense, sense_data, sz);
3435 ddvprintk((KERN_NOTICE " Check Condition, sense ptr %p\n",
3437 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_FAILED) {
3438 if (pReq->CDB[0] == INQUIRY)
3439 completionCode = MPT_SCANDV_ISSUE_SENSE;
3441 completionCode = MPT_SCANDV_DID_RESET;
3443 else if (pReply->SCSIState & MPI_SCSI_STATE_NO_SCSI_STATUS)
3444 completionCode = MPT_SCANDV_DID_RESET;
3445 else if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
3446 completionCode = MPT_SCANDV_DID_RESET;
3448 completionCode = MPT_SCANDV_GOOD;
3449 hd->pLocal->scsiStatus = scsi_status;
3453 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
3454 if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
3455 completionCode = MPT_SCANDV_DID_RESET;
3457 completionCode = MPT_SCANDV_SOME_ERROR;
3461 completionCode = MPT_SCANDV_SOME_ERROR;
3464 } /* switch(status) */
3466 ddvtprintk((KERN_NOTICE " completionCode set to %08xh\n",
3468 } /* end of address reply case */
3470 hd->pLocal->completion = completionCode;
3472 /* MF and RF are freed in mpt_interrupt
3475 /* Free Chain buffers (will never chain) in scan or dv */
3476 //mptscsih_freeChainBuffers(ioc, req_idx);
3479 * Wake up the original calling thread
3481 hd->scandv_wait_done = 1;
3482 wake_up(&hd->scandv_waitq);
3487 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3488 /* mptscsih_timer_expired - Call back for timer process.
3489 * Used only for dv functionality.
3490 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
3494 mptscsih_timer_expired(unsigned long data)
3496 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) data;
3498 ddvprintk((MYIOC_s_WARN_FMT "Timer Expired! Cmd %p\n", hd->ioc->name, hd->cmdPtr));
3501 MPIHeader_t *cmd = (MPIHeader_t *)hd->cmdPtr;
3503 if (cmd->Function == MPI_FUNCTION_SCSI_IO_REQUEST) {
3504 /* Desire to issue a task management request here.
3505 * TM requests MUST be single threaded.
3506 * If old eh code and no TM current, issue request.
3507 * If new eh code, do nothing. Wait for OS cmd timeout
3510 ddvtprintk((MYIOC_s_NOTE_FMT "DV Cmd Timeout: NoOp\n", hd->ioc->name));
3512 /* Perform a FW reload */
3513 if (mpt_HardResetHandler(hd->ioc, NO_SLEEP) < 0) {
3514 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", hd->ioc->name);
3518 /* This should NEVER happen */
3519 printk(MYIOC_s_WARN_FMT "Null cmdPtr!!!!\n", hd->ioc->name);
3522 /* No more processing.
3523 * TM call will generate an interrupt for SCSI TM Management.
3524 * The FW will reply to all outstanding commands, callback will finish cleanup.
3525 * Hard reset clean-up will free all resources.
3527 ddvprintk((MYIOC_s_WARN_FMT "Timer Expired Complete!\n", hd->ioc->name));
3532 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
3533 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3534 /* mptscsih_do_raid - Format and Issue a RAID volume request message.
3535 * @hd: Pointer to scsi host structure
3536 * @action: What do be done.
3537 * @id: Logical target id.
3538 * @bus: Target locations bus.
3540 * Returns: < 0 on a fatal error
3543 * Remark: Wait to return until reply processed by the ISR.
3546 mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io)
3548 MpiRaidActionRequest_t *pReq;
3552 in_isr = in_interrupt();
3554 dprintk((MYIOC_s_WARN_FMT "Internal raid request not allowed in ISR context!\n",
3559 /* Get and Populate a free Frame
3561 if ((mf = mpt_get_msg_frame(hd->ioc->InternalCtx, hd->ioc)) == NULL) {
3562 ddvprintk((MYIOC_s_WARN_FMT "_do_raid: no msg frames!\n",
3566 pReq = (MpiRaidActionRequest_t *)mf;
3567 pReq->Action = action;
3568 pReq->Reserved1 = 0;
3569 pReq->ChainOffset = 0;
3570 pReq->Function = MPI_FUNCTION_RAID_ACTION;
3571 pReq->VolumeID = io->id;
3572 pReq->VolumeBus = io->bus;
3573 pReq->PhysDiskNum = io->physDiskNum;
3575 pReq->Reserved2 = 0;
3576 pReq->ActionDataWord = 0; /* Reserved for this action */
3577 //pReq->ActionDataSGE = 0;
3579 mpt_add_sge((char *)&pReq->ActionDataSGE,
3580 MPT_SGE_FLAGS_SSIMPLE_READ | 0, (dma_addr_t) -1);
3582 ddvprintk((MYIOC_s_INFO_FMT "RAID Volume action %x id %d\n",
3583 hd->ioc->name, action, io->id));
3586 hd->timer.expires = jiffies + HZ*10; /* 10 second timeout */
3587 hd->scandv_wait_done = 0;
3589 /* Save cmd pointer, for resource free if timeout or
3594 add_timer(&hd->timer);
3595 mpt_put_msg_frame(hd->ioc->InternalCtx, hd->ioc, mf);
3596 wait_event(hd->scandv_waitq, hd->scandv_wait_done);
3598 if ((hd->pLocal == NULL) || (hd->pLocal->completion != MPT_SCANDV_GOOD))
3603 #endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */
3605 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3607 * mptscsih_do_cmd - Do internal command.
3608 * @hd: MPT_SCSI_HOST pointer
3609 * @io: INTERNAL_CMD pointer.
3611 * Issue the specified internally generated command and do command
3612 * specific cleanup. For bus scan / DV only.
3613 * NOTES: If command is Inquiry and status is good,
3614 * initialize a target structure, save the data
3616 * Remark: Single threaded access only.
3619 * < 0 if an illegal command or no resources
3623 * > 0 if command complete but some type of completion error.
3626 mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
3629 SCSIIORequest_t *pScsiReq;
3630 SCSIIORequest_t ReqCopy;
3631 int my_idx, ii, dir;
3635 char CDB[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
3638 in_isr = in_interrupt();
3640 dprintk((MYIOC_s_WARN_FMT "Internal SCSI IO request not allowed in ISR context!\n",
3646 /* Set command specific information
3651 dir = MPI_SCSIIO_CONTROL_READ;
3657 case TEST_UNIT_READY:
3659 dir = MPI_SCSIIO_CONTROL_READ;
3665 dir = MPI_SCSIIO_CONTROL_READ;
3667 CDB[4] = 1; /*Spin up the disk */
3675 dir = MPI_SCSIIO_CONTROL_READ;
3681 dir = MPI_SCSIIO_CONTROL_READ;
3683 if (io->flags & MPT_ICFLAG_ECHO) {
3689 if (io->flags & MPT_ICFLAG_BUF_CAP) {
3692 CDB[6] = (io->size >> 16) & 0xFF;
3693 CDB[7] = (io->size >> 8) & 0xFF;
3694 CDB[8] = io->size & 0xFF;
3700 dir = MPI_SCSIIO_CONTROL_WRITE;
3702 if (io->flags & MPT_ICFLAG_ECHO) {
3707 CDB[6] = (io->size >> 16) & 0xFF;
3708 CDB[7] = (io->size >> 8) & 0xFF;
3709 CDB[8] = io->size & 0xFF;
3715 dir = MPI_SCSIIO_CONTROL_READ;
3722 dir = MPI_SCSIIO_CONTROL_READ;
3727 case SYNCHRONIZE_CACHE:
3729 dir = MPI_SCSIIO_CONTROL_READ;
3731 // CDB[1] = 0x02; /* set immediate bit */
3740 /* Get and Populate a free Frame
3742 if ((mf = mpt_get_msg_frame(hd->ioc->InternalCtx, hd->ioc)) == NULL) {
3743 ddvprintk((MYIOC_s_WARN_FMT "No msg frames!\n",
3748 pScsiReq = (SCSIIORequest_t *) mf;
3750 /* Get the request index */
3751 my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3752 ADD_INDEX_LOG(my_idx); /* for debug */
3754 if (io->flags & MPT_ICFLAG_PHYS_DISK) {
3755 pScsiReq->TargetID = io->physDiskNum;
3757 pScsiReq->ChainOffset = 0;
3758 pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
3760 pScsiReq->TargetID = io->id;
3761 pScsiReq->Bus = io->bus;
3762 pScsiReq->ChainOffset = 0;
3763 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
3766 pScsiReq->CDBLength = cmdLen;
3767 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
3769 pScsiReq->Reserved = 0;
3771 pScsiReq->MsgFlags = mpt_msg_flags();
3772 /* MsgContext set in mpt_get_msg_fram call */
3774 for (ii=0; ii < 8; ii++)
3775 pScsiReq->LUN[ii] = 0;
3776 pScsiReq->LUN[1] = io->lun;
3778 if (io->flags & MPT_ICFLAG_TAGGED_CMD)
3779 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ);
3781 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3783 if (cmd == REQUEST_SENSE) {
3784 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3785 ddvprintk((MYIOC_s_INFO_FMT "Untagged! 0x%2x\n",
3786 hd->ioc->name, cmd));
3789 for (ii=0; ii < 16; ii++)
3790 pScsiReq->CDB[ii] = CDB[ii];
3792 pScsiReq->DataLength = cpu_to_le32(io->size);
3793 pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
3794 + (my_idx * MPT_SENSE_BUFFER_ALLOC));
3796 ddvprintk((MYIOC_s_INFO_FMT "Sending Command 0x%x for (%d:%d:%d)\n",
3797 hd->ioc->name, cmd, io->bus, io->id, io->lun));
3799 if (dir == MPI_SCSIIO_CONTROL_READ) {
3800 mpt_add_sge((char *) &pScsiReq->SGL,
3801 MPT_SGE_FLAGS_SSIMPLE_READ | io->size,
3804 mpt_add_sge((char *) &pScsiReq->SGL,
3805 MPT_SGE_FLAGS_SSIMPLE_WRITE | io->size,
3809 /* The ISR will free the request frame, but we need
3810 * the information to initialize the target. Duplicate.
3812 memcpy(&ReqCopy, pScsiReq, sizeof(SCSIIORequest_t));
3814 /* Issue this command after:
3817 * Wait until the reply has been received
3818 * ScsiScanDvCtx callback function will
3820 * set scandv_wait_done and call wake_up
3823 hd->timer.expires = jiffies + HZ*cmdTimeout;
3824 hd->scandv_wait_done = 0;
3826 /* Save cmd pointer, for resource free if timeout or
3831 add_timer(&hd->timer);
3832 mpt_put_msg_frame(hd->ioc->InternalCtx, hd->ioc, mf);
3833 wait_event(hd->scandv_waitq, hd->scandv_wait_done);
3836 rc = hd->pLocal->completion;
3837 hd->pLocal->skip = 0;
3839 /* Always set fatal error codes in some cases.
3841 if (rc == MPT_SCANDV_SELECTION_TIMEOUT)
3843 else if (rc == MPT_SCANDV_SOME_ERROR)
3847 /* This should never happen. */
3848 ddvprintk((MYIOC_s_INFO_FMT "_do_cmd: Null pLocal!!!\n",
3855 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3857 * mptscsih_negotiate_to_asyn_narrow - Restore devices to default state
3858 * @hd: Pointer to a SCSI HOST structure
3859 * @vtarget: per device private data
3861 * Uses the ISR, but with special processing.
3862 * MUST be single-threaded.
3866 mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtTarget *vtarget)
3868 MPT_ADAPTER *ioc= hd->ioc;
3869 SCSIDevicePage1_t *pcfg1Data;
3871 dma_addr_t cfg1_dma_addr;
3872 ConfigPageHeader_t header;
3874 int requested, configuration, data,i;
3877 if (ioc->bus_type != SPI)
3880 if (!ioc->spi_data.sdp1length)
3883 pcfg1Data = (SCSIDevicePage1_t *)pci_alloc_consistent(ioc->pcidev,
3884 ioc->spi_data.sdp1length * 4, &cfg1_dma_addr);
3886 if (pcfg1Data == NULL)
3889 header.PageVersion = ioc->spi_data.sdp1version;
3890 header.PageLength = ioc->spi_data.sdp1length;
3891 header.PageNumber = 1;
3892 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
3893 cfg.cfghdr.hdr = &header;
3894 cfg.physAddr = cfg1_dma_addr;
3895 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
3899 if (vtarget->raidVolume && ioc->raid_data.pIocPg3) {
3900 for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
3901 id = ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID;
3902 flags = hd->ioc->spi_data.noQas;
3903 if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
3904 data = hd->ioc->spi_data.nvram[id];
3905 if (data & MPT_NVRAM_WIDE_DISABLE)
3906 flags |= MPT_TARGET_NO_NEGO_WIDE;
3907 factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT;
3908 if ((factor == 0) || (factor == MPT_ASYNC))
3909 flags |= MPT_TARGET_NO_NEGO_SYNC;
3911 mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested,
3912 &configuration, flags);
3913 dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC "
3914 "offset=0 negoFlags=%x request=%x config=%x\n",
3915 id, flags, requested, configuration));
3916 pcfg1Data->RequestedParameters = cpu_to_le32(requested);
3917 pcfg1Data->Reserved = 0;
3918 pcfg1Data->Configuration = cpu_to_le32(configuration);
3919 cfg.pageAddr = (vtarget->bus_id<<8) | id;
3920 mpt_config(hd->ioc, &cfg);
3923 flags = vtarget->negoFlags;
3924 mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested,
3925 &configuration, flags);
3926 dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC "
3927 "offset=0 negoFlags=%x request=%x config=%x\n",
3928 vtarget->target_id, flags, requested, configuration));
3929 pcfg1Data->RequestedParameters = cpu_to_le32(requested);
3930 pcfg1Data->Reserved = 0;
3931 pcfg1Data->Configuration = cpu_to_le32(configuration);
3932 cfg.pageAddr = (vtarget->bus_id<<8) | vtarget->target_id;
3933 mpt_config(hd->ioc, &cfg);
3937 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pcfg1Data, cfg1_dma_addr);
3940 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3942 * mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
3943 * @hd: Pointer to a SCSI HOST structure
3944 * @vtarget: per device private data
3947 * Uses the ISR, but with special processing.
3948 * MUST be single-threaded.
3952 mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
3956 /* Following parameters will not change
3959 iocmd.cmd = SYNCHRONIZE_CACHE;
3961 iocmd.physDiskNum = -1;
3963 iocmd.data_dma = -1;
3965 iocmd.rsvd = iocmd.rsvd2 = 0;
3966 iocmd.bus = vdevice->bus_id;
3967 iocmd.id = vdevice->target_id;
3968 iocmd.lun = (u8)vdevice->lun;
3970 if ((vdevice->vtarget->type & TYPE_DISK) &&
3971 (vdevice->configured_lun))
3972 mptscsih_do_cmd(hd, &iocmd);
3975 /* Search IOC page 3 to determine if this is hidden physical disk
3978 mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id)
3982 if (!ioc->raid_data.isRaid || !ioc->raid_data.pIocPg3)
3985 for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
3986 if (id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID)
3993 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
3994 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3996 * mptscsih_domainValidation - Top level handler for domain validation.
3997 * @hd: Pointer to MPT_SCSI_HOST structure.
3999 * Uses the ISR, but with special processing.
4000 * Called from schedule, should not be in interrupt mode.
4001 * While thread alive, do dv for all devices needing dv
4006 mptscsih_domainValidation(void *arg)
4010 unsigned long flags;
4011 int id, maxid, dvStatus, did;
4014 spin_lock_irqsave(&dvtaskQ_lock, flags);
4016 if (dvtaskQ_release) {
4018 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4021 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4023 /* For this ioc, loop through all devices and do dv to each device.
4024 * When complete with this ioc, search through the ioc list, and
4025 * for each scsi ioc found, do dv for all devices. Exit when no
4031 list_for_each_entry(ioc, &ioc_list, list) {
4032 spin_lock_irqsave(&dvtaskQ_lock, flags);
4033 if (dvtaskQ_release) {
4035 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4038 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4042 /* DV only to SPI adapters */
4043 if (ioc->bus_type != SPI)
4046 /* Make sure everything looks ok */
4047 if (ioc->sh == NULL)
4050 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
4054 if ((ioc->spi_data.forceDv & MPT_SCSICFG_RELOAD_IOC_PG3) != 0) {
4055 mpt_read_ioc_pg_3(ioc);
4056 if (ioc->raid_data.pIocPg3) {
4057 Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
4058 int numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
4061 if (ioc->spi_data.dvStatus[pPDisk->PhysDiskID] & MPT_SCSICFG_DV_NOT_DONE)
4062 ioc->spi_data.dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV;
4068 ioc->spi_data.forceDv &= ~MPT_SCSICFG_RELOAD_IOC_PG3;
4071 maxid = min_t(int, ioc->sh->max_id, MPT_MAX_SCSI_DEVICES);
4073 for (id = 0; id < maxid; id++) {
4074 spin_lock_irqsave(&dvtaskQ_lock, flags);
4075 if (dvtaskQ_release) {
4077 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4080 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4081 dvStatus = hd->ioc->spi_data.dvStatus[id];
4083 if (dvStatus & MPT_SCSICFG_NEED_DV) {
4085 hd->ioc->spi_data.dvStatus[id] |= MPT_SCSICFG_DV_PENDING;
4086 hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_NEED_DV;
4090 /* If hidden phys disk, block IO's to all
4092 * else, process normally
4094 isPhysDisk = mptscsih_is_phys_disk(ioc, id);
4096 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4097 if (hd->ioc->raid_data.isRaid & (1 << ii)) {
4098 hd->ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_DV_PENDING;
4103 if(mpt_alt_ioc_wait(hd->ioc)!=0) {
4104 ddvprintk((MYIOC_s_WARN_FMT "alt_ioc busy!\n",
4109 if (mptscsih_doDv(hd, 0, id) == 1) {
4110 /* Untagged device was busy, try again
4112 hd->ioc->spi_data.dvStatus[id] |= MPT_SCSICFG_NEED_DV;
4113 hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_PENDING;
4115 /* DV is complete. Clear flags.
4117 hd->ioc->spi_data.dvStatus[id] &= ~(MPT_SCSICFG_DV_NOT_DONE | MPT_SCSICFG_DV_PENDING);
4120 spin_lock(&hd->ioc->initializing_hba_lock);
4121 hd->ioc->initializing_hba_lock_flag=0;
4122 spin_unlock(&hd->ioc->initializing_hba_lock);
4125 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4126 if (hd->ioc->raid_data.isRaid & (1 << ii)) {
4127 hd->ioc->spi_data.dvStatus[ii] &= ~MPT_SCSICFG_DV_PENDING;
4132 if (hd->ioc->spi_data.noQas)
4133 mptscsih_qas_check(hd, id);
4139 spin_lock_irqsave(&dvtaskQ_lock, flags);
4141 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4146 /* Write SDP1 if no QAS has been enabled
4149 mptscsih_qas_check(MPT_SCSI_HOST *hd, int id)
4151 VirtTarget *vtarget;
4154 if (hd->Targets == NULL)
4157 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4161 if ((hd->ioc->spi_data.dvStatus[ii] & MPT_SCSICFG_DV_NOT_DONE) != 0)
4164 vtarget = hd->Targets[ii];
4166 if ((vtarget != NULL) && (!vtarget->raidVolume)) {
4167 if ((vtarget->negoFlags & hd->ioc->spi_data.noQas) == 0) {
4168 vtarget->negoFlags |= hd->ioc->spi_data.noQas;
4169 dnegoprintk(("writeSDP1: id=%d flags=0\n", id));
4170 mptscsih_writeSDP1(hd, 0, ii, 0);
4173 if (mptscsih_is_phys_disk(hd->ioc, ii) == 1) {
4174 dnegoprintk(("writeSDP1: id=%d SCSICFG_USE_NVRAM\n", id));
4175 mptscsih_writeSDP1(hd, 0, ii, MPT_SCSICFG_USE_NVRAM);
4184 #define MPT_GET_NVRAM_VALS 0x01
4185 #define MPT_UPDATE_MAX 0x02
4186 #define MPT_SET_MAX 0x04
4187 #define MPT_SET_MIN 0x08
4188 #define MPT_FALLBACK 0x10
4189 #define MPT_SAVE 0x20
4191 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4193 * mptscsih_doDv - Perform domain validation to a target.
4194 * @hd: Pointer to MPT_SCSI_HOST structure.
4195 * @portnum: IOC port number.
4196 * @target: Physical ID of this target
4198 * Uses the ISR, but with special processing.
4199 * MUST be single-threaded.
4200 * Test will exit if target is at async & narrow.
4205 mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
4207 MPT_ADAPTER *ioc = hd->ioc;
4208 VirtTarget *vtarget;
4209 SCSIDevicePage1_t *pcfg1Data;
4210 SCSIDevicePage0_t *pcfg0Data;
4214 dma_addr_t dvbuf_dma = -1;
4215 dma_addr_t buf1_dma = -1;
4216 dma_addr_t buf2_dma = -1;
4217 dma_addr_t cfg1_dma_addr = -1;
4218 dma_addr_t cfg0_dma_addr = -1;
4219 ConfigPageHeader_t header1;
4220 ConfigPageHeader_t header0;
4227 int dataBufSize = 0;
4228 int echoBufSize = 0;
4233 int nfactor = MPT_ULTRA320;
4235 char doFallback = 0;
4240 if (ioc->spi_data.sdp1length == 0)
4243 if (ioc->spi_data.sdp0length == 0)
4246 /* If multiple buses are used, require that the initiator
4247 * id be the same on all buses.
4249 if (id == ioc->pfacts[0].PortSCSIID)
4253 bus = (u8) bus_number;
4254 ddvtprintk((MYIOC_s_NOTE_FMT
4255 "DV started: bus=%d, id=%d dv @ %p\n",
4256 ioc->name, bus, id, &dv));
4258 /* Prep DV structure
4260 memset (&dv, 0, sizeof(DVPARAMETERS));
4263 /* Populate tmax with the current maximum
4264 * transfer parameters for this target.
4265 * Exit if narrow and async.
4267 dv.cmd = MPT_GET_NVRAM_VALS;
4268 mptscsih_dv_parms(hd, &dv, NULL);
4270 /* Prep SCSI IO structure
4276 iocmd.physDiskNum = -1;
4277 iocmd.rsvd = iocmd.rsvd2 = 0;
4279 vtarget = hd->Targets[id];
4281 /* Use tagged commands if possible.
4284 if (vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)
4285 iocmd.flags |= MPT_ICFLAG_TAGGED_CMD;
4287 if (hd->ioc->facts.FWVersion.Word < 0x01000600)
4290 if ((hd->ioc->facts.FWVersion.Word >= 0x01010000) &&
4291 (hd->ioc->facts.FWVersion.Word < 0x01010B00))
4296 /* Prep cfg structure
4298 cfg.pageAddr = (bus<<8) | id;
4299 cfg.cfghdr.hdr = NULL;
4303 header0.PageVersion = ioc->spi_data.sdp0version;
4304 header0.PageLength = ioc->spi_data.sdp0length;
4305 header0.PageNumber = 0;
4306 header0.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4310 header1.PageVersion = ioc->spi_data.sdp1version;
4311 header1.PageLength = ioc->spi_data.sdp1length;
4312 header1.PageNumber = 1;
4313 header1.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4315 if (header0.PageLength & 1)
4316 dv_alloc = (header0.PageLength * 4) + 4;
4318 dv_alloc += (2048 + (header1.PageLength * 4));
4320 pDvBuf = pci_alloc_consistent(ioc->pcidev, dv_alloc, &dvbuf_dma);
4325 pbuf1 = (u8 *)pDvBuf;
4326 buf1_dma = dvbuf_dma;
4329 pbuf2 = (u8 *) (pDvBuf + sz);
4330 buf2_dma = dvbuf_dma + sz;
4333 pcfg0Data = (SCSIDevicePage0_t *) (pDvBuf + sz);
4334 cfg0_dma_addr = dvbuf_dma + sz;
4335 sz += header0.PageLength * 4;
4339 if (header0.PageLength & 1)
4342 pcfg1Data = (SCSIDevicePage1_t *) (pDvBuf + sz);
4343 cfg1_dma_addr = dvbuf_dma + sz;
4345 /* Skip this ID? Set cfg.cfghdr.hdr to force config page write
4348 SpiCfgData *pspi_data = &hd->ioc->spi_data;
4349 if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
4350 /* Set the factor from nvram */
4351 nfactor = (pspi_data->nvram[id] & MPT_NVRAM_SYNC_MASK) >> 8;
4352 if (nfactor < pspi_data->minSyncFactor )
4353 nfactor = pspi_data->minSyncFactor;
4355 if (!(pspi_data->nvram[id] & MPT_NVRAM_ID_SCAN_ENABLE) ||
4356 (pspi_data->PortFlags == MPI_SCSIPORTPAGE2_PORT_FLAGS_OFF_DV) ) {
4358 ddvprintk((MYIOC_s_NOTE_FMT "DV Skipped: bus, id, lun (%d, %d, %d)\n",
4359 ioc->name, bus, id, lun));
4361 dv.cmd = MPT_SET_MAX;
4362 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
4363 cfg.cfghdr.hdr = &header1;
4365 /* Save the final negotiated settings to
4366 * SCSI device page 1.
4368 cfg.physAddr = cfg1_dma_addr;
4369 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4371 mpt_config(hd->ioc, &cfg);
4377 /* Finish iocmd inititialization - hidden or visible disk? */
4378 if (ioc->raid_data.pIocPg3) {
4379 /* Search IOC page 3 for matching id
4381 Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
4382 int numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
4385 if (pPDisk->PhysDiskID == id) {
4387 iocmd.flags |= MPT_ICFLAG_PHYS_DISK;
4388 iocmd.physDiskNum = pPDisk->PhysDiskNum;
4392 if (mptscsih_do_raid(hd, MPI_RAID_ACTION_QUIESCE_PHYS_IO, &iocmd) < 0) {
4393 ddvprintk((MYIOC_s_ERR_FMT "RAID Queisce FAILED!\n", ioc->name));
4403 /* RAID Volume ID's may double for a physical device. If RAID but
4404 * not a physical ID as well, skip DV.
4406 if ((hd->ioc->raid_data.isRaid & (1 << id)) && !(iocmd.flags & MPT_ICFLAG_PHYS_DISK))
4411 * Async & Narrow - Inquiry
4412 * Async & Narrow - Inquiry
4413 * Maximum transfer rate - Inquiry
4415 * If compare, test complete.
4416 * If miscompare and first pass, repeat
4417 * If miscompare and not first pass, fall back and repeat
4421 sz = SCSI_MAX_INQUIRY_BYTES;
4422 rc = MPT_SCANDV_GOOD;
4424 ddvprintk((MYIOC_s_NOTE_FMT "DV: Start Basic test on id=%d\n", ioc->name, id));
4426 dv.cmd = MPT_SET_MIN;
4427 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
4429 cfg.cfghdr.hdr = &header1;
4430 cfg.physAddr = cfg1_dma_addr;
4431 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4433 if (mpt_config(hd->ioc, &cfg) != 0)
4436 /* Wide - narrow - wide workaround case
4438 if ((rc == MPT_SCANDV_ISSUE_SENSE) && dv.max.width) {
4439 /* Send an untagged command to reset disk Qs corrupted
4440 * when a parity error occurs on a Request Sense.
4442 if ((hd->ioc->facts.FWVersion.Word >= 0x01000600) ||
4443 ((hd->ioc->facts.FWVersion.Word >= 0x01010000) &&
4444 (hd->ioc->facts.FWVersion.Word < 0x01010B00)) ) {
4446 iocmd.cmd = REQUEST_SENSE;
4447 iocmd.data_dma = buf1_dma;
4450 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4453 if (hd->pLocal == NULL)
4455 rc = hd->pLocal->completion;
4456 if ((rc == MPT_SCANDV_GOOD) || (rc == MPT_SCANDV_SENSE)) {
4466 iocmd.cmd = INQUIRY;
4467 iocmd.data_dma = buf1_dma;
4470 memset(pbuf1, 0x00, sz);
4471 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4474 if (hd->pLocal == NULL)
4476 rc = hd->pLocal->completion;
4477 if (rc == MPT_SCANDV_GOOD) {
4478 if (hd->pLocal->scsiStatus == SAM_STAT_BUSY) {
4479 if ((iocmd.flags & MPT_ICFLAG_TAGGED_CMD) == 0)
4486 } else if (rc == MPT_SCANDV_SENSE) {
4489 /* If first command doesn't complete
4490 * with a good status or with a check condition,
4497 /* Reset the size for disks
4499 inq0 = (*pbuf1) & 0x1F;
4500 if ((inq0 == 0) && vtarget && !vtarget->raidVolume) {
4505 /* Another GEM workaround. Check peripheral device type,
4506 * if PROCESSOR, quit DV.
4508 if (inq0 == TYPE_PROCESSOR) {
4509 mptscsih_initTarget(hd,
4520 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4524 if ((vtarget->maxWidth == 1) && (vtarget->maxOffset) && (nfactor < 0x0A)
4525 && (vtarget->minSyncFactor > 0x09)) {
4526 if ((pbuf1[56] & 0x04) == 0)
4528 else if ((pbuf1[56] & 0x01) == 1) {
4529 vtarget->minSyncFactor =
4530 nfactor > MPT_ULTRA320 ? nfactor : MPT_ULTRA320;
4532 vtarget->minSyncFactor =
4533 nfactor > MPT_ULTRA160 ? nfactor : MPT_ULTRA160;
4536 dv.max.factor = vtarget->minSyncFactor;
4538 if ((pbuf1[56] & 0x02) == 0) {
4539 vtarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
4540 hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS;
4541 ddvprintk((MYIOC_s_NOTE_FMT
4542 "DV: Start Basic noQas on id=%d due to pbuf1[56]=%x\n",
4543 ioc->name, id, pbuf1[56]));
4549 dv.cmd = MPT_FALLBACK;
4551 dv.cmd = MPT_SET_MAX;
4553 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
4554 if (mpt_config(hd->ioc, &cfg) != 0)
4557 if ((!dv.now.width) && (!dv.now.offset))
4560 iocmd.cmd = INQUIRY;
4561 iocmd.data_dma = buf2_dma;
4564 memset(pbuf2, 0x00, sz);
4565 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4567 else if (hd->pLocal == NULL)
4570 /* Save the return code.
4571 * If this is the first pass,
4572 * read SCSI Device Page 0
4573 * and update the target max parameters.
4575 rc = hd->pLocal->completion;
4577 if (rc == MPT_SCANDV_GOOD) {
4582 cfg.cfghdr.hdr = &header0;
4583 cfg.physAddr = cfg0_dma_addr;
4584 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4587 if (mpt_config(hd->ioc, &cfg) != 0)
4590 sdp0_info = le32_to_cpu(pcfg0Data->Information) & 0x0E;
4591 sdp0_nego = (le32_to_cpu(pcfg0Data->NegotiatedParameters) & 0xFF00 ) >> 8;
4593 /* Quantum and Fujitsu workarounds.
4594 * Quantum: PPR U320 -> PPR reply with Ultra2 and wide
4595 * Fujitsu: PPR U320 -> Msg Reject and Ultra2 and wide
4596 * Resetart with a request for U160.
4598 if ((dv.now.factor == MPT_ULTRA320) && (sdp0_nego == MPT_ULTRA2)) {
4601 dv.cmd = MPT_UPDATE_MAX;
4602 mptscsih_dv_parms(hd, &dv, (void *)pcfg0Data);
4603 /* Update the SCSI device page 1 area
4605 pcfg1Data->RequestedParameters = pcfg0Data->NegotiatedParameters;
4610 /* Quantum workaround. Restart this test will the fallback
4613 if (doFallback == 0) {
4614 if (memcmp(pbuf1, pbuf2, sz) != 0) {
4618 ddvprintk((MYIOC_s_NOTE_FMT
4619 "DV:Inquiry compared id=%d, calling initTarget\n", ioc->name, id));
4620 hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_NOT_DONE;
4621 mptscsih_initTarget(hd,
4626 break; /* test complete */
4631 } else if (rc == MPT_SCANDV_ISSUE_SENSE)
4632 doFallback = 1; /* set fallback flag */
4633 else if ((rc == MPT_SCANDV_DID_RESET) ||
4634 (rc == MPT_SCANDV_SENSE) ||
4635 (rc == MPT_SCANDV_FALLBACK))
4636 doFallback = 1; /* set fallback flag */
4643 ddvprintk((MYIOC_s_NOTE_FMT "DV: Basic test on id=%d completed OK.\n", ioc->name, id));
4645 if (ioc->spi_data.mpt_dv == 0)
4648 inq0 = (*pbuf1) & 0x1F;
4650 /* Continue only for disks
4655 if ( ioc->spi_data.PortFlags == MPI_SCSIPORTPAGE2_PORT_FLAGS_BASIC_DV_ONLY )
4658 /* Start the Enhanced Test.
4659 * 0) issue TUR to clear out check conditions
4660 * 1) read capacity of echo (regular) buffer
4662 * 3) do write-read-compare data pattern test
4664 * 5) update nego parms to target struct
4666 cfg.cfghdr.hdr = &header1;
4667 cfg.physAddr = cfg1_dma_addr;
4668 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4671 iocmd.cmd = TEST_UNIT_READY;
4672 iocmd.data_dma = -1;
4677 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4680 if (hd->pLocal == NULL)
4683 rc = hd->pLocal->completion;
4684 if (rc == MPT_SCANDV_GOOD)
4686 else if (rc == MPT_SCANDV_SENSE) {
4687 u8 skey = hd->pLocal->sense[2] & 0x0F;
4688 u8 asc = hd->pLocal->sense[12];
4689 u8 ascq = hd->pLocal->sense[13];
4690 ddvprintk((MYIOC_s_INFO_FMT
4691 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
4692 ioc->name, skey, asc, ascq));
4694 if (skey == UNIT_ATTENTION)
4695 notDone++; /* repeat */
4696 else if ((skey == NOT_READY) &&
4697 (asc == 0x04)&&(ascq == 0x01)) {
4698 /* wait then repeat */
4701 } else if ((skey == NOT_READY) && (asc == 0x3A)) {
4702 /* no medium, try read test anyway */
4705 /* All other errors are fatal.
4707 ddvprintk((MYIOC_s_INFO_FMT "DV: fatal error.",
4715 iocmd.cmd = READ_BUFFER;
4716 iocmd.data_dma = buf1_dma;
4719 iocmd.flags |= MPT_ICFLAG_BUF_CAP;
4723 for (patt = 0; patt < 2; patt++) {
4725 iocmd.flags |= MPT_ICFLAG_ECHO;
4727 iocmd.flags &= ~MPT_ICFLAG_ECHO;
4733 /* If not ready after 8 trials,
4734 * give up on this device.
4739 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4741 else if (hd->pLocal == NULL)
4744 rc = hd->pLocal->completion;
4745 ddvprintk(("ReadBuffer Comp Code %d", rc));
4746 ddvprintk((" buff: %0x %0x %0x %0x\n",
4747 pbuf1[0], pbuf1[1], pbuf1[2], pbuf1[3]));
4749 if (rc == MPT_SCANDV_GOOD) {
4751 if (iocmd.flags & MPT_ICFLAG_ECHO) {
4752 bufsize = ((pbuf1[2] & 0x1F) <<8) | pbuf1[3];
4753 if (pbuf1[0] & 0x01)
4754 iocmd.flags |= MPT_ICFLAG_EBOS;
4756 bufsize = pbuf1[1]<<16 | pbuf1[2]<<8 | pbuf1[3];
4758 } else if (rc == MPT_SCANDV_SENSE) {
4759 u8 skey = hd->pLocal->sense[2] & 0x0F;
4760 u8 asc = hd->pLocal->sense[12];
4761 u8 ascq = hd->pLocal->sense[13];
4762 ddvprintk((MYIOC_s_INFO_FMT
4763 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
4764 ioc->name, skey, asc, ascq));
4765 if (skey == ILLEGAL_REQUEST) {
4767 } else if (skey == UNIT_ATTENTION) {
4768 notDone++; /* repeat */
4769 } else if ((skey == NOT_READY) &&
4770 (asc == 0x04)&&(ascq == 0x01)) {
4771 /* wait then repeat */
4775 /* All other errors are fatal.
4777 ddvprintk((MYIOC_s_INFO_FMT "DV: fatal error.",
4782 /* All other errors are fatal
4789 if (iocmd.flags & MPT_ICFLAG_ECHO)
4790 echoBufSize = bufsize;
4792 dataBufSize = bufsize;
4795 iocmd.flags &= ~MPT_ICFLAG_BUF_CAP;
4797 /* Use echo buffers if possible,
4798 * Exit if both buffers are 0.
4800 if (echoBufSize > 0) {
4801 iocmd.flags |= MPT_ICFLAG_ECHO;
4802 if (dataBufSize > 0)
4803 bufsize = min(echoBufSize, dataBufSize);
4805 bufsize = echoBufSize;
4806 } else if (dataBufSize == 0)
4809 ddvprintk((MYIOC_s_INFO_FMT "%s Buffer Capacity %d\n", ioc->name,
4810 (iocmd.flags & MPT_ICFLAG_ECHO) ? "Echo" : " ", bufsize));
4812 /* Data buffers for write-read-compare test max 1K.
4814 sz = min(bufsize, 1024);
4817 * On first pass, always issue a reserve.
4818 * On additional loops, only if a reset has occurred.
4819 * iocmd.flags indicates if echo or regular buffer
4821 for (patt = 0; patt < 4; patt++) {
4822 ddvprintk(("Pattern %d\n", patt));
4823 if ((iocmd.flags & MPT_ICFLAG_RESERVED) && (iocmd.flags & MPT_ICFLAG_DID_RESET)) {
4824 iocmd.cmd = TEST_UNIT_READY;
4825 iocmd.data_dma = -1;
4828 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4831 iocmd.cmd = RELEASE;
4832 iocmd.data_dma = -1;
4835 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4837 else if (hd->pLocal == NULL)
4840 rc = hd->pLocal->completion;
4841 ddvprintk(("Release rc %d\n", rc));
4842 if (rc == MPT_SCANDV_GOOD)
4843 iocmd.flags &= ~MPT_ICFLAG_RESERVED;
4847 iocmd.flags &= ~MPT_ICFLAG_RESERVED;
4849 iocmd.flags &= ~MPT_ICFLAG_DID_RESET;
4851 if (iocmd.flags & MPT_ICFLAG_EBOS)
4855 while (repeat && (!(iocmd.flags & MPT_ICFLAG_RESERVED))) {
4856 iocmd.cmd = RESERVE;
4857 iocmd.data_dma = -1;
4860 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4862 else if (hd->pLocal == NULL)
4865 rc = hd->pLocal->completion;
4866 if (rc == MPT_SCANDV_GOOD) {
4867 iocmd.flags |= MPT_ICFLAG_RESERVED;
4868 } else if (rc == MPT_SCANDV_SENSE) {
4869 /* Wait if coming ready
4871 u8 skey = hd->pLocal->sense[2] & 0x0F;
4872 u8 asc = hd->pLocal->sense[12];
4873 u8 ascq = hd->pLocal->sense[13];
4874 ddvprintk((MYIOC_s_INFO_FMT
4875 "DV: Reserve Failed: ", ioc->name));
4876 ddvprintk(("SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
4879 if ((skey == NOT_READY) && (asc == 0x04)&&
4881 /* wait then repeat */
4885 ddvprintk((MYIOC_s_INFO_FMT
4886 "DV: Reserved Failed.", ioc->name));
4890 ddvprintk((MYIOC_s_INFO_FMT "DV: Reserved Failed.",
4898 mptscsih_fillbuf(pbuf1, sz, patt, 1);
4899 iocmd.cmd = WRITE_BUFFER;
4900 iocmd.data_dma = buf1_dma;
4903 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4905 else if (hd->pLocal == NULL)
4908 rc = hd->pLocal->completion;
4909 if (rc == MPT_SCANDV_GOOD)
4910 ; /* Issue read buffer */
4911 else if (rc == MPT_SCANDV_DID_RESET) {
4912 /* If using echo buffers, reset to data buffers.
4913 * Else do Fallback and restart
4914 * this test (re-issue reserve
4915 * because of bus reset).
4917 if ((iocmd.flags & MPT_ICFLAG_ECHO) && (dataBufSize >= bufsize)) {
4918 iocmd.flags &= ~MPT_ICFLAG_ECHO;
4920 dv.cmd = MPT_FALLBACK;
4921 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
4923 if (mpt_config(hd->ioc, &cfg) != 0)
4926 if ((!dv.now.width) && (!dv.now.offset))
4930 iocmd.flags |= MPT_ICFLAG_DID_RESET;
4933 } else if (rc == MPT_SCANDV_SENSE) {
4934 /* Restart data test if UA, else quit.
4936 u8 skey = hd->pLocal->sense[2] & 0x0F;
4937 ddvprintk((MYIOC_s_INFO_FMT
4938 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n", ioc->name, skey,
4939 hd->pLocal->sense[12], hd->pLocal->sense[13]));
4940 if (skey == UNIT_ATTENTION) {
4943 } else if (skey == ILLEGAL_REQUEST) {
4944 if (iocmd.flags & MPT_ICFLAG_ECHO) {
4945 if (dataBufSize >= bufsize) {
4946 iocmd.flags &= ~MPT_ICFLAG_ECHO;
4961 iocmd.cmd = READ_BUFFER;
4962 iocmd.data_dma = buf2_dma;
4965 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4967 else if (hd->pLocal == NULL)
4970 rc = hd->pLocal->completion;
4971 if (rc == MPT_SCANDV_GOOD) {
4972 /* If buffers compare,
4973 * go to next pattern,
4974 * else, do a fallback and restart
4975 * data transfer test.
4977 if (memcmp (pbuf1, pbuf2, sz) == 0) {
4978 ; /* goto next pattern */
4980 /* Miscompare with Echo buffer, go to data buffer,
4981 * if that buffer exists.
4982 * Miscompare with Data buffer, check first 4 bytes,
4983 * some devices return capacity. Exit in this case.
4985 if (iocmd.flags & MPT_ICFLAG_ECHO) {
4986 if (dataBufSize >= bufsize)
4987 iocmd.flags &= ~MPT_ICFLAG_ECHO;
4991 if (dataBufSize == (pbuf2[1]<<16 | pbuf2[2]<<8 | pbuf2[3])) {
4992 /* Argh. Device returning wrong data.
4993 * Quit DV for this device.
4998 /* Had an actual miscompare. Slow down.*/
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))
5012 } else if (rc == MPT_SCANDV_DID_RESET) {
5013 /* Do Fallback and restart
5014 * this test (re-issue reserve
5015 * because of bus reset).
5017 dv.cmd = MPT_FALLBACK;
5018 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5020 if (mpt_config(hd->ioc, &cfg) != 0)
5023 if ((!dv.now.width) && (!dv.now.offset))
5026 iocmd.flags |= MPT_ICFLAG_DID_RESET;
5029 } else if (rc == MPT_SCANDV_SENSE) {
5030 /* Restart data test if UA, else quit.
5032 u8 skey = hd->pLocal->sense[2] & 0x0F;
5033 ddvprintk((MYIOC_s_INFO_FMT
5034 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n", ioc->name, skey,
5035 hd->pLocal->sense[12], hd->pLocal->sense[13]));
5036 if (skey == UNIT_ATTENTION) {
5048 } /* --- end of patt loop ---- */
5051 if (iocmd.flags & MPT_ICFLAG_RESERVED) {
5052 iocmd.cmd = RELEASE;
5053 iocmd.data_dma = -1;
5056 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5057 printk(MYIOC_s_INFO_FMT "DV: Release failed. id %d",
5059 else if (hd->pLocal) {
5060 if (hd->pLocal->completion == MPT_SCANDV_GOOD)
5061 iocmd.flags &= ~MPT_ICFLAG_RESERVED;
5063 printk(MYIOC_s_INFO_FMT "DV: Release failed. id %d",
5069 /* Set if cfg1_dma_addr contents is valid
5071 if ((cfg.cfghdr.hdr != NULL) && (retcode == 0)){
5072 /* If disk, not U320, disable QAS
5074 if ((inq0 == 0) && (dv.now.factor > MPT_ULTRA320)) {
5075 hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS;
5076 ddvprintk((MYIOC_s_NOTE_FMT
5077 "noQas set due to id=%d has factor=%x\n", ioc->name, id, dv.now.factor));
5081 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5083 /* Double writes to SDP1 can cause problems,
5084 * skip save of the final negotiated settings to
5085 * SCSI device page 1.
5087 cfg.cfghdr.hdr = &header1;
5088 cfg.physAddr = cfg1_dma_addr;
5089 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5091 mpt_config(hd->ioc, &cfg);
5095 /* If this is a RAID Passthrough, enable internal IOs
5097 if (iocmd.flags & MPT_ICFLAG_PHYS_DISK) {
5098 if (mptscsih_do_raid(hd, MPI_RAID_ACTION_ENABLE_PHYS_IO, &iocmd) < 0)
5099 ddvprintk((MYIOC_s_ERR_FMT "RAID Enable FAILED!\n", ioc->name));
5102 /* Done with the DV scan of the current target
5105 pci_free_consistent(ioc->pcidev, dv_alloc, pDvBuf, dvbuf_dma);
5107 ddvtprintk((MYIOC_s_INFO_FMT "DV Done id=%d\n",
5113 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5114 /* mptscsih_dv_parms - perform a variety of operations on the
5115 * parameters used for negotiation.
5116 * @hd: Pointer to a SCSI host.
5117 * @dv: Pointer to a structure that contains the maximum and current
5118 * negotiated parameters.
5121 mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
5123 VirtTarget *vtarget;
5124 SCSIDevicePage0_t *pPage0;
5125 SCSIDevicePage1_t *pPage1;
5126 int val = 0, data, configuration;
5135 case MPT_GET_NVRAM_VALS:
5136 ddvprintk((MYIOC_s_NOTE_FMT "Getting NVRAM: ",
5138 /* Get the NVRAM values and save in tmax
5139 * If not an LVD bus, the adapter minSyncFactor has been
5140 * already throttled back.
5142 negoFlags = hd->ioc->spi_data.noQas;
5143 if ((hd->Targets)&&((vtarget = hd->Targets[(int)id]) != NULL) && !vtarget->raidVolume) {
5144 width = vtarget->maxWidth;
5145 offset = vtarget->maxOffset;
5146 factor = vtarget->minSyncFactor;
5147 negoFlags |= vtarget->negoFlags;
5149 if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
5150 data = hd->ioc->spi_data.nvram[id];
5151 width = data & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
5152 if ((offset = hd->ioc->spi_data.maxSyncOffset) == 0)
5155 factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT;
5156 if ((factor == 0) || (factor == MPT_ASYNC)){
5167 /* Set the negotiation flags */
5169 negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
5172 negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
5175 /* limit by adapter capabilities */
5176 width = min(width, hd->ioc->spi_data.maxBusWidth);
5177 offset = min(offset, hd->ioc->spi_data.maxSyncOffset);
5178 factor = max(factor, hd->ioc->spi_data.minSyncFactor);
5180 /* Check Consistency */
5181 if (offset && (factor < MPT_ULTRA2) && !width)
5182 factor = MPT_ULTRA2;
5184 dv->max.width = width;
5185 dv->max.offset = offset;
5186 dv->max.factor = factor;
5187 dv->max.flags = negoFlags;
5188 ddvprintk((" id=%d width=%d factor=%x offset=%x flags=%x\n",
5189 id, width, factor, offset, negoFlags));
5192 case MPT_UPDATE_MAX:
5193 ddvprintk((MYIOC_s_NOTE_FMT
5194 "Updating with SDP0 Data: ", hd->ioc->name));
5195 /* Update tmax values with those from Device Page 0.*/
5196 pPage0 = (SCSIDevicePage0_t *) pPage;
5198 val = le32_to_cpu(pPage0->NegotiatedParameters);
5199 dv->max.width = val & MPI_SCSIDEVPAGE0_NP_WIDE ? 1 : 0;
5200 dv->max.offset = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK) >> 16;
5201 dv->max.factor = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK) >> 8;
5204 dv->now.width = dv->max.width;
5205 dv->now.offset = dv->max.offset;
5206 dv->now.factor = dv->max.factor;
5207 ddvprintk(("id=%d width=%d factor=%x offset=%x flags=%x\n",
5208 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags));
5212 ddvprintk((MYIOC_s_NOTE_FMT "Setting Max: ",
5214 /* Set current to the max values. Update the config page.*/
5215 dv->now.width = dv->max.width;
5216 dv->now.offset = dv->max.offset;
5217 dv->now.factor = dv->max.factor;
5218 dv->now.flags = dv->max.flags;
5220 pPage1 = (SCSIDevicePage1_t *)pPage;
5222 mptscsih_setDevicePage1Flags (dv->now.width, dv->now.factor,
5223 dv->now.offset, &val, &configuration, dv->now.flags);
5224 dnegoprintk(("Setting Max: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
5225 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags, val, configuration));
5226 pPage1->RequestedParameters = cpu_to_le32(val);
5227 pPage1->Reserved = 0;
5228 pPage1->Configuration = cpu_to_le32(configuration);
5231 ddvprintk(("id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x configuration=%x\n",
5232 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags, val, configuration));
5236 ddvprintk((MYIOC_s_NOTE_FMT "Setting Min: ",
5238 /* Set page to asynchronous and narrow
5239 * Do not update now, breaks fallback routine. */
5243 negoFlags = dv->max.flags;
5245 pPage1 = (SCSIDevicePage1_t *)pPage;
5247 mptscsih_setDevicePage1Flags (width, factor,
5248 offset, &val, &configuration, negoFlags);
5249 dnegoprintk(("Setting Min: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
5250 id, width, factor, offset, negoFlags, val, configuration));
5251 pPage1->RequestedParameters = cpu_to_le32(val);
5252 pPage1->Reserved = 0;
5253 pPage1->Configuration = cpu_to_le32(configuration);
5255 ddvprintk(("id=%d width=%d factor=%x offset=%x request=%x config=%x negoFlags=%x\n",
5256 id, width, factor, offset, val, configuration, negoFlags));
5260 ddvprintk((MYIOC_s_NOTE_FMT
5261 "Fallback: Start: offset %d, factor %x, width %d \n",
5262 hd->ioc->name, dv->now.offset,
5263 dv->now.factor, dv->now.width));
5264 width = dv->now.width;
5265 offset = dv->now.offset;
5266 factor = dv->now.factor;
5267 if ((offset) && (dv->max.width)) {
5268 if (factor < MPT_ULTRA160)
5269 factor = MPT_ULTRA160;
5270 else if (factor < MPT_ULTRA2) {
5271 factor = MPT_ULTRA2;
5273 } else if ((factor == MPT_ULTRA2) && width) {
5274 factor = MPT_ULTRA2;
5276 } else if (factor < MPT_ULTRA) {
5279 } else if ((factor == MPT_ULTRA) && width) {
5281 } else if (factor < MPT_FAST) {
5284 } else if ((factor == MPT_FAST) && width) {
5287 } else if (factor < MPT_SCSI) {
5290 } else if ((factor == MPT_SCSI) && width) {
5298 } else if (offset) {
5300 if (factor < MPT_ULTRA)
5302 else if (factor < MPT_FAST)
5304 else if (factor < MPT_SCSI)
5315 dv->max.flags |= MPT_TARGET_NO_NEGO_QAS;
5316 dv->max.flags &= ~MPT_TAPE_NEGO_IDP;
5318 dv->now.width = width;
5319 dv->now.offset = offset;
5320 dv->now.factor = factor;
5321 dv->now.flags = dv->max.flags;
5323 pPage1 = (SCSIDevicePage1_t *)pPage;
5325 mptscsih_setDevicePage1Flags (width, factor, offset, &val,
5326 &configuration, dv->now.flags);
5327 dnegoprintk(("Finish: id=%d width=%d offset=%d factor=%x negoFlags=%x request=%x config=%x\n",
5328 id, width, offset, factor, dv->now.flags, val, configuration));
5330 pPage1->RequestedParameters = cpu_to_le32(val);
5331 pPage1->Reserved = 0;
5332 pPage1->Configuration = cpu_to_le32(configuration);
5335 ddvprintk(("Finish: id=%d offset=%d factor=%x width=%d request=%x config=%x\n",
5336 id, dv->now.offset, dv->now.factor, dv->now.width, val, configuration));
5340 ddvprintk((MYIOC_s_NOTE_FMT
5341 "Saving to Target structure: ", hd->ioc->name));
5342 ddvprintk(("id=%d width=%x factor=%x offset=%d flags=%x\n",
5343 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags));
5345 /* Save these values to target structures
5346 * or overwrite nvram (phys disks only).
5349 if ((hd->Targets)&&((vtarget = hd->Targets[(int)id]) != NULL) && !vtarget->raidVolume ) {
5350 vtarget->maxWidth = dv->now.width;
5351 vtarget->maxOffset = dv->now.offset;
5352 vtarget->minSyncFactor = dv->now.factor;
5353 vtarget->negoFlags = dv->now.flags;
5355 /* Preserv all flags, use
5356 * read-modify-write algorithm
5358 if (hd->ioc->spi_data.nvram) {
5359 data = hd->ioc->spi_data.nvram[id];
5362 data &= ~MPT_NVRAM_WIDE_DISABLE;
5364 data |= MPT_NVRAM_WIDE_DISABLE;
5366 if (!dv->now.offset)
5369 data &= ~MPT_NVRAM_SYNC_MASK;
5370 data |= (dv->now.factor << MPT_NVRAM_SYNC_SHIFT) & MPT_NVRAM_SYNC_MASK;
5372 hd->ioc->spi_data.nvram[id] = data;
5379 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5380 /* mptscsih_fillbuf - fill a buffer with a special data pattern
5381 * cleanup. For bus scan only.
5383 * @buffer: Pointer to data buffer to be filled.
5384 * @size: Number of bytes to fill
5385 * @index: Pattern index
5386 * @width: bus width, 0 (8 bits) or 1 (16 bits)
5389 mptscsih_fillbuf(char *buffer, int size, int index, int width)
5400 /* Pattern: 0000 FFFF 0000 FFFF
5402 for (ii=0; ii < size; ii++, ptr++) {
5409 /* Pattern: 00 FF 00 FF
5411 for (ii=0; ii < size; ii++, ptr++) {
5422 /* Pattern: 5555 AAAA 5555 AAAA 5555
5424 for (ii=0; ii < size; ii++, ptr++) {
5431 /* Pattern: 55 AA 55 AA 55
5433 for (ii=0; ii < size; ii++, ptr++) {
5443 /* Pattern: 00 01 02 03 04 05
5446 for (ii=0; ii < size; ii++, ptr++)
5452 /* Wide Pattern: FFFE 0001 FFFD 0002
5453 * ... 4000 DFFF 8000 EFFF
5456 for (ii=0; ii < size/2; ii++) {
5457 /* Create the base pattern
5460 /* every 64 (0x40) bytes flip the pattern
5461 * since we fill 2 bytes / iteration,
5462 * test for ii = 0x20
5468 *ptr = (char)( (val & 0xFF00) >> 8);
5470 *ptr = (char)(val & 0xFF);
5475 *ptr = (char)( (val & 0xFF00) >> 8);
5477 *ptr = (char)(val & 0xFF);
5483 /* Narrow Pattern: FE 01 FD 02 FB 04
5484 * .. 7F 80 01 FE 02 FD ... 80 7F
5487 for (ii=0; ii < size; ii++, ptr++) {
5488 /* Base pattern - first 32 bytes
5495 *ptr = (char) (~(1 << byte));
5498 /* Flip the pattern every 32 bytes
5508 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5509 /* If DV disabled (negoNvram set to USE_NVARM) or if not LUN 0, return.
5510 * Else set the NEED_DV flag after Read Capacity Issued (disks)
5511 * or Mode Sense (cdroms).
5513 * Tapes, initTarget will set this flag on completion of Inquiry command.
5514 * Called only if DV_NOT_DONE flag is set
5517 mptscsih_set_dvflags(MPT_SCSI_HOST *hd, struct scsi_cmnd *sc)
5519 MPT_ADAPTER *ioc = hd->ioc;
5523 ddvtprintk((MYIOC_s_NOTE_FMT
5524 " set_dvflags: id=%d lun=%d negoNvram=%x cmd=%x\n",
5525 hd->ioc->name, sc->device->id, sc->device->lun , hd->negoNvram, sc->cmnd[0]));
5527 if ((sc->device->lun != 0) || (hd->negoNvram != 0))
5532 if ((cmd == READ_CAPACITY) || (cmd == MODE_SENSE)) {
5533 pSpi = &ioc->spi_data;
5534 if ((ioc->raid_data.isRaid & (1 << sc->device->id)) && ioc->raid_data.pIocPg3) {
5535 /* Set NEED_DV for all hidden disks
5537 Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
5538 int numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
5541 pSpi->dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV;
5542 ddvtprintk(("NEED_DV set for phys disk id %d\n", pPDisk->PhysDiskID));
5547 pSpi->dvStatus[sc->device->id] |= MPT_SCSICFG_NEED_DV;
5548 ddvtprintk(("NEED_DV set for visible disk id %d\n", sc->device->id));
5552 /* mptscsih_raid_set_dv_flags()
5554 * New or replaced disk. Set DV flag and schedule DV.
5557 mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id)
5559 MPT_ADAPTER *ioc = hd->ioc;
5560 SpiCfgData *pSpi = &ioc->spi_data;
5561 Ioc3PhysDisk_t *pPDisk;
5564 if (hd->negoNvram != 0)
5567 ddvtprintk(("DV requested for phys disk id %d\n", id));
5568 if (ioc->raid_data.pIocPg3) {
5569 pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
5570 numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
5572 if (id == pPDisk->PhysDiskNum) {
5573 pSpi->dvStatus[pPDisk->PhysDiskID] =
5574 (MPT_SCSICFG_NEED_DV | MPT_SCSICFG_DV_NOT_DONE);
5575 pSpi->forceDv = MPT_SCSICFG_NEED_DV;
5576 ddvtprintk(("NEED_DV set for phys disk id %d\n",
5577 pPDisk->PhysDiskID));
5584 if (numPDisk == 0) {
5585 /* The physical disk that needs DV was not found
5586 * in the stored IOC Page 3. The driver must reload
5587 * this page. DV routine will set the NEED_DV flag for
5588 * all phys disks that have DV_NOT_DONE set.
5590 pSpi->forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
5591 ddvtprintk(("phys disk %d not found. Setting reload IOC Pg3 Flag\n",id));
5595 #endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */
5597 EXPORT_SYMBOL(mptscsih_remove);
5598 EXPORT_SYMBOL(mptscsih_shutdown);
5600 EXPORT_SYMBOL(mptscsih_suspend);
5601 EXPORT_SYMBOL(mptscsih_resume);
5603 EXPORT_SYMBOL(mptscsih_proc_info);
5604 EXPORT_SYMBOL(mptscsih_info);
5605 EXPORT_SYMBOL(mptscsih_qcmd);
5606 EXPORT_SYMBOL(mptscsih_target_alloc);
5607 EXPORT_SYMBOL(mptscsih_slave_alloc);
5608 EXPORT_SYMBOL(mptscsih_target_destroy);
5609 EXPORT_SYMBOL(mptscsih_slave_destroy);
5610 EXPORT_SYMBOL(mptscsih_slave_configure);
5611 EXPORT_SYMBOL(mptscsih_abort);
5612 EXPORT_SYMBOL(mptscsih_dev_reset);
5613 EXPORT_SYMBOL(mptscsih_bus_reset);
5614 EXPORT_SYMBOL(mptscsih_host_reset);
5615 EXPORT_SYMBOL(mptscsih_bios_param);
5616 EXPORT_SYMBOL(mptscsih_io_done);
5617 EXPORT_SYMBOL(mptscsih_taskmgmt_complete);
5618 EXPORT_SYMBOL(mptscsih_scandv_complete);
5619 EXPORT_SYMBOL(mptscsih_event_process);
5620 EXPORT_SYMBOL(mptscsih_ioc_reset);
5621 EXPORT_SYMBOL(mptscsih_change_queue_depth);
5622 EXPORT_SYMBOL(mptscsih_timer_expired);
5624 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/