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_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout);
149 int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
150 int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
152 static void mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, u8 lun, char *data, int dlen);
153 static void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *vtarget, char byte56);
154 static void mptscsih_setDevicePage1Flags (u8 width, u8 factor, u8 offset, int *requestedPtr, int *configurationPtr, u8 flags);
155 static void mptscsih_no_negotiate(MPT_SCSI_HOST *hd, struct scsi_cmnd *sc);
156 static int mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target, int flags);
157 static int mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus);
158 int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
159 static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
160 static void mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice);
161 static void mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtTarget *vtarget);
162 static int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id);
164 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
165 static int mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io);
166 static void mptscsih_domainValidation(void *hd);
167 static void mptscsih_qas_check(MPT_SCSI_HOST *hd, int id);
168 static int mptscsih_doDv(MPT_SCSI_HOST *hd, int channel, int target);
169 static void mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage);
170 static void mptscsih_fillbuf(char *buffer, int size, int index, int width);
171 static void mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id);
172 static void mptscsih_set_dvflags(MPT_SCSI_HOST *hd, struct scsi_cmnd *sc);
175 void mptscsih_remove(struct pci_dev *);
176 void mptscsih_shutdown(struct pci_dev *);
178 int mptscsih_suspend(struct pci_dev *pdev, pm_message_t state);
179 int mptscsih_resume(struct pci_dev *pdev);
182 #define SNS_LEN(scp) sizeof((scp)->sense_buffer)
184 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
186 * Domain Validation task structure
188 static DEFINE_SPINLOCK(dvtaskQ_lock);
189 static int dvtaskQ_active = 0;
190 static int dvtaskQ_release = 0;
191 static struct work_struct dvTaskQ_task;
194 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
196 * mptscsih_add_sge - Place a simple SGE at address pAddr.
197 * @pAddr: virtual address for SGE
198 * @flagslength: SGE flags and data transfer length
199 * @dma_addr: Physical address
201 * This routine places a MPT request frame back on the MPT adapter's
205 mptscsih_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
207 if (sizeof(dma_addr_t) == sizeof(u64)) {
208 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
209 u32 tmp = dma_addr & 0xFFFFFFFF;
211 pSge->FlagsLength = cpu_to_le32(flagslength);
212 pSge->Address.Low = cpu_to_le32(tmp);
213 tmp = (u32) ((u64)dma_addr >> 32);
214 pSge->Address.High = cpu_to_le32(tmp);
217 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
218 pSge->FlagsLength = cpu_to_le32(flagslength);
219 pSge->Address = cpu_to_le32(dma_addr);
221 } /* mptscsih_add_sge() */
223 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
225 * mptscsih_add_chain - Place a chain SGE at address pAddr.
226 * @pAddr: virtual address for SGE
227 * @next: nextChainOffset value (u32's)
228 * @length: length of next SGL segment
229 * @dma_addr: Physical address
231 * This routine places a MPT request frame back on the MPT adapter's
235 mptscsih_add_chain(char *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
237 if (sizeof(dma_addr_t) == sizeof(u64)) {
238 SGEChain64_t *pChain = (SGEChain64_t *) pAddr;
239 u32 tmp = dma_addr & 0xFFFFFFFF;
241 pChain->Length = cpu_to_le16(length);
242 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size();
244 pChain->NextChainOffset = next;
246 pChain->Address.Low = cpu_to_le32(tmp);
247 tmp = (u32) ((u64)dma_addr >> 32);
248 pChain->Address.High = cpu_to_le32(tmp);
250 SGEChain32_t *pChain = (SGEChain32_t *) pAddr;
251 pChain->Length = cpu_to_le16(length);
252 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size();
253 pChain->NextChainOffset = next;
254 pChain->Address = cpu_to_le32(dma_addr);
256 } /* mptscsih_add_chain() */
258 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
260 * mptscsih_getFreeChainBuffer - Function to get a free chain
261 * from the MPT_SCSI_HOST FreeChainQ.
262 * @ioc: Pointer to MPT_ADAPTER structure
263 * @req_idx: Index of the SCSI IO request frame. (output)
265 * return SUCCESS or FAILED
268 mptscsih_getFreeChainBuffer(MPT_ADAPTER *ioc, int *retIndex)
270 MPT_FRAME_HDR *chainBuf;
275 dsgprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer called\n",
277 spin_lock_irqsave(&ioc->FreeQlock, flags);
278 if (!list_empty(&ioc->FreeChainQ)) {
281 chainBuf = list_entry(ioc->FreeChainQ.next, MPT_FRAME_HDR,
282 u.frame.linkage.list);
283 list_del(&chainBuf->u.frame.linkage.list);
284 offset = (u8 *)chainBuf - (u8 *)ioc->ChainBuffer;
285 chain_idx = offset / ioc->req_sz;
287 dsgprintk((MYIOC_s_ERR_FMT "getFreeChainBuffer chainBuf=%p ChainBuffer=%p offset=%d chain_idx=%d\n",
288 ioc->name, chainBuf, ioc->ChainBuffer, offset, chain_idx));
291 chain_idx = MPT_HOST_NO_CHAIN;
292 dfailprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer failed\n",
295 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
297 *retIndex = chain_idx;
299 } /* mptscsih_getFreeChainBuffer() */
301 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
303 * mptscsih_AddSGE - Add a SGE (plus chain buffers) to the
304 * SCSIIORequest_t Message Frame.
305 * @ioc: Pointer to MPT_ADAPTER structure
306 * @SCpnt: Pointer to scsi_cmnd structure
307 * @pReq: Pointer to SCSIIORequest_t structure
312 mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
313 SCSIIORequest_t *pReq, int req_idx)
317 struct scatterlist *sg;
319 int sges_left, sg_done;
320 int chain_idx = MPT_HOST_NO_CHAIN;
322 int numSgeSlots, numSgeThisFrame;
323 u32 sgflags, sgdir, thisxfer = 0;
324 int chain_dma_off = 0;
330 sgdir = le32_to_cpu(pReq->Control) & MPI_SCSIIO_CONTROL_DATADIRECTION_MASK;
331 if (sgdir == MPI_SCSIIO_CONTROL_WRITE) {
332 sgdir = MPT_TRANSFER_HOST_TO_IOC;
334 sgdir = MPT_TRANSFER_IOC_TO_HOST;
337 psge = (char *) &pReq->SGL;
338 frm_sz = ioc->req_sz;
340 /* Map the data portion, if any.
341 * sges_left = 0 if no data transfer.
343 if ( (sges_left = SCpnt->use_sg) ) {
344 sges_left = pci_map_sg(ioc->pcidev,
345 (struct scatterlist *) SCpnt->request_buffer,
347 SCpnt->sc_data_direction);
350 } else if (SCpnt->request_bufflen) {
351 SCpnt->SCp.dma_handle = pci_map_single(ioc->pcidev,
352 SCpnt->request_buffer,
353 SCpnt->request_bufflen,
354 SCpnt->sc_data_direction);
355 dsgprintk((MYIOC_s_INFO_FMT "SG: non-SG for %p, len=%d\n",
356 ioc->name, SCpnt, SCpnt->request_bufflen));
357 mptscsih_add_sge((char *) &pReq->SGL,
358 0xD1000000|MPT_SGE_FLAGS_ADDRESSING|sgdir|SCpnt->request_bufflen,
359 SCpnt->SCp.dma_handle);
364 /* Handle the SG case.
366 sg = (struct scatterlist *) SCpnt->request_buffer;
368 sgeOffset = sizeof(SCSIIORequest_t) - sizeof(SGE_IO_UNION);
371 /* Prior to entering this loop - the following must be set
372 * current MF: sgeOffset (bytes)
373 * chainSge (Null if original MF is not a chain buffer)
374 * sg_done (num SGE done for this MF)
378 numSgeSlots = ((frm_sz - sgeOffset) / (sizeof(u32) + sizeof(dma_addr_t)) );
379 numSgeThisFrame = (sges_left < numSgeSlots) ? sges_left : numSgeSlots;
381 sgflags = MPT_SGE_FLAGS_SIMPLE_ELEMENT | MPT_SGE_FLAGS_ADDRESSING | sgdir;
383 /* Get first (num - 1) SG elements
384 * Skip any SG entries with a length of 0
385 * NOTE: at finish, sg and psge pointed to NEXT data/location positions
387 for (ii=0; ii < (numSgeThisFrame-1); ii++) {
388 thisxfer = sg_dma_len(sg);
390 sg ++; /* Get next SG element from the OS */
395 v2 = sg_dma_address(sg);
396 mptscsih_add_sge(psge, sgflags | thisxfer, v2);
398 sg++; /* Get next SG element from the OS */
399 psge += (sizeof(u32) + sizeof(dma_addr_t));
400 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
404 if (numSgeThisFrame == sges_left) {
405 /* Add last element, end of buffer and end of list flags.
407 sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT |
408 MPT_SGE_FLAGS_END_OF_BUFFER |
409 MPT_SGE_FLAGS_END_OF_LIST;
411 /* Add last SGE and set termination flags.
412 * Note: Last SGE may have a length of 0 - which should be ok.
414 thisxfer = sg_dma_len(sg);
416 v2 = sg_dma_address(sg);
417 mptscsih_add_sge(psge, sgflags | thisxfer, v2);
420 psge += (sizeof(u32) + sizeof(dma_addr_t));
422 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
426 /* The current buffer is a chain buffer,
427 * but there is not another one.
428 * Update the chain element
429 * Offset and Length fields.
431 mptscsih_add_chain((char *)chainSge, 0, sgeOffset, ioc->ChainBufferDMA + chain_dma_off);
433 /* The current buffer is the original MF
434 * and there is no Chain buffer.
436 pReq->ChainOffset = 0;
437 RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor) + 1) & 0x03;
438 dsgprintk((MYIOC_s_INFO_FMT
439 "Single Buffer RequestNB=%x, sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
440 ioc->RequestNB[req_idx] = RequestNB;
443 /* At least one chain buffer is needed.
444 * Complete the first MF
445 * - last SGE element, set the LastElement bit
446 * - set ChainOffset (words) for orig MF
447 * (OR finish previous MF chain buffer)
448 * - update MFStructPtr ChainIndex
449 * - Populate chain element
454 dsgprintk((MYIOC_s_INFO_FMT "SG: Chain Required! sg done %d\n",
455 ioc->name, sg_done));
457 /* Set LAST_ELEMENT flag for last non-chain element
458 * in the buffer. Since psge points at the NEXT
459 * SGE element, go back one SGE element, update the flags
460 * and reset the pointer. (Note: sgflags & thisxfer are already
464 u32 *ptmp = (u32 *) (psge - (sizeof(u32) + sizeof(dma_addr_t)));
465 sgflags = le32_to_cpu(*ptmp);
466 sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT;
467 *ptmp = cpu_to_le32(sgflags);
471 /* The current buffer is a chain buffer.
472 * chainSge points to the previous Chain Element.
473 * Update its chain element Offset and Length (must
474 * include chain element size) fields.
475 * Old chain element is now complete.
477 u8 nextChain = (u8) (sgeOffset >> 2);
478 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
479 mptscsih_add_chain((char *)chainSge, nextChain, sgeOffset, ioc->ChainBufferDMA + chain_dma_off);
481 /* The original MF buffer requires a chain buffer -
483 * Last element in this MF is a chain element.
485 pReq->ChainOffset = (u8) (sgeOffset >> 2);
486 RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor) + 1) & 0x03;
487 dsgprintk((MYIOC_s_ERR_FMT "Chain Buffer Needed, RequestNB=%x sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
488 ioc->RequestNB[req_idx] = RequestNB;
491 sges_left -= sg_done;
494 /* NOTE: psge points to the beginning of the chain element
495 * in current buffer. Get a chain buffer.
497 if ((mptscsih_getFreeChainBuffer(ioc, &newIndex)) == FAILED) {
498 dfailprintk((MYIOC_s_INFO_FMT
499 "getFreeChainBuffer FAILED SCSI cmd=%02x (%p)\n",
500 ioc->name, pReq->CDB[0], SCpnt));
504 /* Update the tracking arrays.
505 * If chainSge == NULL, update ReqToChain, else ChainToChain
508 ioc->ChainToChain[chain_idx] = newIndex;
510 ioc->ReqToChain[req_idx] = newIndex;
512 chain_idx = newIndex;
513 chain_dma_off = ioc->req_sz * chain_idx;
515 /* Populate the chainSGE for the current buffer.
516 * - Set chain buffer pointer to psge and fill
517 * out the Address and Flags fields.
519 chainSge = (char *) psge;
520 dsgprintk((KERN_INFO " Current buff @ %p (index 0x%x)",
523 /* Start the SGE for the next buffer
525 psge = (char *) (ioc->ChainBuffer + chain_dma_off);
529 dsgprintk((KERN_INFO " Chain buff @ %p (index 0x%x)\n",
532 /* Start the SGE for the next buffer
539 } /* mptscsih_AddSGE() */
541 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
543 * mptscsih_io_done - Main SCSI IO callback routine registered to
544 * Fusion MPT (base) driver
545 * @ioc: Pointer to MPT_ADAPTER structure
546 * @mf: Pointer to original MPT request frame
547 * @r: Pointer to MPT reply frame (NULL if TurboReply)
549 * This routine is called from mpt.c::mpt_interrupt() at the completion
550 * of any SCSI IO request.
551 * This routine is registered with the Fusion MPT (base) driver at driver
552 * load/init time via the mpt_register() API call.
554 * Returns 1 indicating alloc'd request frame ptr should be freed.
557 mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
559 struct scsi_cmnd *sc;
561 SCSIIORequest_t *pScsiReq;
562 SCSIIOReply_t *pScsiReply;
565 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
567 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
568 sc = hd->ScsiLookup[req_idx];
570 MPIHeader_t *hdr = (MPIHeader_t *)mf;
572 /* Remark: writeSDP1 will use the ScsiDoneCtx
573 * If a SCSI I/O cmd, device disabled by OS and
574 * completion done. Cannot touch sc struct. Just free mem.
576 if (hdr->Function == MPI_FUNCTION_SCSI_IO_REQUEST)
577 printk(MYIOC_s_ERR_FMT "NULL ScsiCmd ptr!\n",
580 mptscsih_freeChainBuffers(ioc, req_idx);
584 sc->result = DID_OK << 16; /* Set default reply as OK */
585 pScsiReq = (SCSIIORequest_t *) mf;
586 pScsiReply = (SCSIIOReply_t *) mr;
588 if((ioc->facts.MsgVersion >= MPI_VERSION_01_05) && pScsiReply){
589 dmfprintk((MYIOC_s_INFO_FMT
590 "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d,task-tag=%d)\n",
591 ioc->name, mf, mr, sc, req_idx, pScsiReply->TaskTag));
593 dmfprintk((MYIOC_s_INFO_FMT
594 "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n",
595 ioc->name, mf, mr, sc, req_idx));
598 if (pScsiReply == NULL) {
599 /* special context reply handling */
604 u8 scsi_state, scsi_status;
606 status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK;
607 scsi_state = pScsiReply->SCSIState;
608 scsi_status = pScsiReply->SCSIStatus;
609 xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
610 sc->resid = sc->request_bufflen - xfer_cnt;
613 * if we get a data underrun indication, yet no data was
614 * transferred and the SCSI status indicates that the
615 * command was never started, change the data underrun
618 if (status == MPI_IOCSTATUS_SCSI_DATA_UNDERRUN && xfer_cnt == 0 &&
619 (scsi_status == MPI_SCSI_STATUS_BUSY ||
620 scsi_status == MPI_SCSI_STATUS_RESERVATION_CONFLICT ||
621 scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)) {
622 status = MPI_IOCSTATUS_SUCCESS;
625 dreplyprintk((KERN_NOTICE "Reply ha=%d id=%d lun=%d:\n"
626 "IOCStatus=%04xh SCSIState=%02xh SCSIStatus=%02xh\n"
627 "resid=%d bufflen=%d xfer_cnt=%d\n",
628 ioc->id, sc->device->id, sc->device->lun,
629 status, scsi_state, scsi_status, sc->resid,
630 sc->request_bufflen, xfer_cnt));
632 if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)
633 mptscsih_copy_sense_data(sc, hd, mf, pScsiReply);
636 * Look for + dump FCP ResponseInfo[]!
638 if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID &&
639 pScsiReply->ResponseInfo) {
640 printk(KERN_NOTICE "ha=%d id=%d lun=%d: "
641 "FCP_ResponseInfo=%08xh\n",
642 ioc->id, sc->device->id, sc->device->lun,
643 le32_to_cpu(pScsiReply->ResponseInfo));
647 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
649 * Maybe: DRIVER_BUSY | SUGGEST_RETRY | DID_SOFT_ERROR (retry)
650 * But not: DID_BUS_BUSY lest one risk
651 * killing interrupt handler:-(
653 sc->result = SAM_STAT_BUSY;
656 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
657 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
658 sc->result = DID_BAD_TARGET << 16;
661 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
662 /* Spoof to SCSI Selection Timeout! */
663 sc->result = DID_NO_CONNECT << 16;
665 if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF)
666 hd->sel_timeout[pScsiReq->TargetID]++;
669 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
670 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
671 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
672 /* Linux handles an unsolicited DID_RESET better
673 * than an unsolicited DID_ABORT.
675 sc->result = DID_RESET << 16;
677 /* GEM Workaround. */
678 if (ioc->bus_type == SPI)
679 mptscsih_no_negotiate(hd, sc);
682 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
683 sc->resid = sc->request_bufflen - xfer_cnt;
684 if((xfer_cnt==0)||(sc->underflow > xfer_cnt))
685 sc->result=DID_SOFT_ERROR << 16;
686 else /* Sufficient data transfer occurred */
687 sc->result = (DID_OK << 16) | scsi_status;
688 dreplyprintk((KERN_NOTICE
689 "RESIDUAL_MISMATCH: result=%x on id=%d\n", sc->result, sc->device->id));
692 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
694 * Do upfront check for valid SenseData and give it
697 sc->result = (DID_OK << 16) | scsi_status;
698 if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
699 /* Have already saved the status and sense data
703 if (xfer_cnt < sc->underflow) {
704 if (scsi_status == SAM_STAT_BUSY)
705 sc->result = SAM_STAT_BUSY;
707 sc->result = DID_SOFT_ERROR << 16;
709 if (scsi_state & (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)) {
712 sc->result = DID_SOFT_ERROR << 16;
714 else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
715 /* Not real sure here either... */
716 sc->result = DID_RESET << 16;
720 dreplyprintk((KERN_NOTICE " sc->underflow={report ERR if < %02xh bytes xfer'd}\n",
722 dreplyprintk((KERN_NOTICE " ActBytesXferd=%02xh\n", xfer_cnt));
725 if (scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)
726 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
730 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
732 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
733 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
734 if (scsi_status == MPI_SCSI_STATUS_BUSY)
735 sc->result = (DID_BUS_BUSY << 16) | scsi_status;
737 sc->result = (DID_OK << 16) | scsi_status;
738 if (scsi_state == 0) {
740 } else if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
742 * If running against circa 200003dd 909 MPT f/w,
743 * may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL
744 * (QUEUE_FULL) returned from device! --> get 0x0000?128
745 * and with SenseBytes set to 0.
747 if (pScsiReply->SCSIStatus == MPI_SCSI_STATUS_TASK_SET_FULL)
748 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
751 else if (scsi_state &
752 (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)
757 sc->result = DID_SOFT_ERROR << 16;
759 else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
760 /* Not real sure here either... */
761 sc->result = DID_RESET << 16;
763 else if (scsi_state & MPI_SCSI_STATE_QUEUE_TAG_REJECTED) {
764 /* Device Inq. data indicates that it supports
765 * QTags, but rejects QTag messages.
766 * This command completed OK.
768 * Not real sure here either so do nothing... */
771 if (sc->result == MPI_SCSI_STATUS_TASK_SET_FULL)
772 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
775 * Reservation Conflict, Busy,
776 * Command Terminated, CHECK
780 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
781 sc->result = DID_SOFT_ERROR << 16;
784 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
785 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
786 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
787 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
788 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
789 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
790 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
791 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
792 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
797 sc->result = DID_SOFT_ERROR << 16;
800 } /* switch(status) */
802 dreplyprintk((KERN_NOTICE " sc->result is %08xh\n", sc->result));
803 } /* end of address reply case */
805 /* Unmap the DMA buffers, if any. */
807 pci_unmap_sg(ioc->pcidev, (struct scatterlist *) sc->request_buffer,
808 sc->use_sg, sc->sc_data_direction);
809 } else if (sc->request_bufflen) {
810 pci_unmap_single(ioc->pcidev, sc->SCp.dma_handle,
811 sc->request_bufflen, sc->sc_data_direction);
814 hd->ScsiLookup[req_idx] = NULL;
816 sc->scsi_done(sc); /* Issue the command callback */
818 /* Free Chain buffers */
819 mptscsih_freeChainBuffers(ioc, req_idx);
824 * mptscsih_flush_running_cmds - For each command found, search
825 * Scsi_Host instance taskQ and reply to OS.
826 * Called only if recovering from a FW reload.
827 * @hd: Pointer to a SCSI HOST structure
831 * Must be called while new I/Os are being queued.
834 mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
836 MPT_ADAPTER *ioc = hd->ioc;
837 struct scsi_cmnd *SCpnt;
840 int max = ioc->req_depth;
842 dprintk((KERN_INFO MYNAM ": flush_ScsiLookup called\n"));
843 for (ii= 0; ii < max; ii++) {
844 if ((SCpnt = hd->ScsiLookup[ii]) != NULL) {
849 /* Null ScsiLookup index
851 hd->ScsiLookup[ii] = NULL;
853 mf = MPT_INDEX_2_MFPTR(ioc, ii);
854 dmfprintk(( "flush: ScsiDone (mf=%p,sc=%p)\n",
857 /* Set status, free OS resources (SG DMA buffers)
859 * Free driver resources (chain, msg buffers)
862 pci_unmap_sg(ioc->pcidev,
863 (struct scatterlist *) SCpnt->request_buffer,
865 SCpnt->sc_data_direction);
866 } else if (SCpnt->request_bufflen) {
867 pci_unmap_single(ioc->pcidev,
868 SCpnt->SCp.dma_handle,
869 SCpnt->request_bufflen,
870 SCpnt->sc_data_direction);
872 SCpnt->result = DID_RESET << 16;
873 SCpnt->host_scribble = NULL;
875 /* Free Chain buffers */
876 mptscsih_freeChainBuffers(ioc, ii);
878 /* Free Message frames */
879 mpt_free_msg_frame(ioc, mf);
881 SCpnt->scsi_done(SCpnt); /* Issue the command callback */
889 * mptscsih_search_running_cmds - Delete any commands associated
890 * with the specified target and lun. Function called only
891 * when a lun is disable by mid-layer.
892 * Do NOT access the referenced scsi_cmnd structure or
893 * members. Will cause either a paging or NULL ptr error.
894 * (BUT, BUT, BUT, the code does reference it! - mdr)
895 * @hd: Pointer to a SCSI HOST structure
896 * @vdevice: per device private data
900 * Called from slave_destroy.
903 mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
905 SCSIIORequest_t *mf = NULL;
907 int max = hd->ioc->req_depth;
908 struct scsi_cmnd *sc;
910 dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n",
911 vdevice->target_id, vdevice->lun, max));
913 for (ii=0; ii < max; ii++) {
914 if ((sc = hd->ScsiLookup[ii]) != NULL) {
916 mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii);
918 dsprintk(( "search_running: found (sc=%p, mf = %p) target %d, lun %d \n",
919 hd->ScsiLookup[ii], mf, mf->TargetID, mf->LUN[1]));
921 if ((mf->TargetID != ((u8)vdevice->target_id)) || (mf->LUN[1] != ((u8) vdevice->lun)))
926 hd->ScsiLookup[ii] = NULL;
927 mptscsih_freeChainBuffers(hd->ioc, ii);
928 mpt_free_msg_frame(hd->ioc, (MPT_FRAME_HDR *)mf);
930 pci_unmap_sg(hd->ioc->pcidev,
931 (struct scatterlist *) sc->request_buffer,
933 sc->sc_data_direction);
934 } else if (sc->request_bufflen) {
935 pci_unmap_single(hd->ioc->pcidev,
938 sc->sc_data_direction);
940 sc->host_scribble = NULL;
941 sc->result = DID_NO_CONNECT << 16;
948 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
950 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
952 * mptscsih_report_queue_full - Report QUEUE_FULL status returned
953 * from a SCSI target device.
954 * @sc: Pointer to scsi_cmnd structure
955 * @pScsiReply: Pointer to SCSIIOReply_t
956 * @pScsiReq: Pointer to original SCSI request
958 * This routine periodically reports QUEUE_FULL status returned from a
959 * SCSI target device. It reports this to the console via kernel
960 * printk() API call, not more than once every 10 seconds.
963 mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq)
968 if (sc->device == NULL)
970 if (sc->device->host == NULL)
972 if ((hd = (MPT_SCSI_HOST *)sc->device->host->hostdata) == NULL)
975 if (time - hd->last_queue_full > 10 * HZ) {
976 dprintk((MYIOC_s_WARN_FMT "Device (%d:%d:%d) reported QUEUE_FULL!\n",
977 hd->ioc->name, 0, sc->device->id, sc->device->lun));
978 hd->last_queue_full = time;
982 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
984 * mptscsih_remove - Removed scsi devices
985 * @pdev: Pointer to pci_dev structure
990 mptscsih_remove(struct pci_dev *pdev)
992 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
993 struct Scsi_Host *host = ioc->sh;
995 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1006 scsi_remove_host(host);
1008 if((hd = (MPT_SCSI_HOST *)host->hostdata) == NULL)
1011 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1012 /* Check DV thread active */
1014 spin_lock_irqsave(&dvtaskQ_lock, flags);
1015 if (dvtaskQ_active) {
1016 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
1017 while(dvtaskQ_active && --count)
1018 schedule_timeout_interruptible(1);
1020 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
1023 printk(KERN_ERR MYNAM ": ERROR - DV thread still active!\n");
1024 #if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY)
1026 printk(KERN_ERR MYNAM ": DV thread orig %d, count %d\n", 10 * HZ, count);
1030 mptscsih_shutdown(pdev);
1034 if (hd->ScsiLookup != NULL) {
1035 sz1 = hd->ioc->req_depth * sizeof(void *);
1036 kfree(hd->ScsiLookup);
1037 hd->ScsiLookup = NULL;
1041 * Free pointer array.
1046 dprintk((MYIOC_s_INFO_FMT
1047 "Free'd ScsiLookup (%d) memory\n",
1048 hd->ioc->name, sz1));
1050 kfree(hd->info_kbuf);
1052 /* NULL the Scsi_Host pointer
1056 scsi_host_put(host);
1062 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1064 * mptscsih_shutdown - reboot notifier
1068 mptscsih_shutdown(struct pci_dev *pdev)
1070 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1071 struct Scsi_Host *host = ioc->sh;
1077 hd = (MPT_SCSI_HOST *)host->hostdata;
1082 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1084 * mptscsih_suspend - Fusion MPT scsi driver suspend routine.
1089 mptscsih_suspend(struct pci_dev *pdev, pm_message_t state)
1091 mptscsih_shutdown(pdev);
1092 return mpt_suspend(pdev,state);
1095 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1097 * mptscsih_resume - Fusion MPT scsi driver resume routine.
1102 mptscsih_resume(struct pci_dev *pdev)
1104 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1105 struct Scsi_Host *host = ioc->sh;
1113 hd = (MPT_SCSI_HOST *)host->hostdata;
1117 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1119 unsigned long lflags;
1120 spin_lock_irqsave(&dvtaskQ_lock, lflags);
1121 if (!dvtaskQ_active) {
1123 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1124 INIT_WORK(&dvTaskQ_task,
1125 mptscsih_domainValidation, (void *) hd);
1126 schedule_work(&dvTaskQ_task);
1128 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1137 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1139 * mptscsih_info - Return information about MPT adapter
1140 * @SChost: Pointer to Scsi_Host structure
1142 * (linux scsi_host_template.info routine)
1144 * Returns pointer to buffer where information was written.
1147 mptscsih_info(struct Scsi_Host *SChost)
1152 h = (MPT_SCSI_HOST *)SChost->hostdata;
1155 if (h->info_kbuf == NULL)
1156 if ((h->info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)
1157 return h->info_kbuf;
1158 h->info_kbuf[0] = '\0';
1160 mpt_print_ioc_summary(h->ioc, h->info_kbuf, &size, 0, 0);
1161 h->info_kbuf[size-1] = '\0';
1164 return h->info_kbuf;
1175 mptscsih_copy_mem_info(struct info_str *info, char *data, int len)
1177 if (info->pos + len > info->length)
1178 len = info->length - info->pos;
1180 if (info->pos + len < info->offset) {
1185 if (info->pos < info->offset) {
1186 data += (info->offset - info->pos);
1187 len -= (info->offset - info->pos);
1191 memcpy(info->buffer + info->pos, data, len);
1197 mptscsih_copy_info(struct info_str *info, char *fmt, ...)
1203 va_start(args, fmt);
1204 len = vsprintf(buf, fmt, args);
1207 mptscsih_copy_mem_info(info, buf, len);
1212 mptscsih_host_info(MPT_ADAPTER *ioc, char *pbuf, off_t offset, int len)
1214 struct info_str info;
1218 info.offset = offset;
1221 mptscsih_copy_info(&info, "%s: %s, ", ioc->name, ioc->prod_name);
1222 mptscsih_copy_info(&info, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING, ioc->facts.FWVersion.Word);
1223 mptscsih_copy_info(&info, "Ports=%d, ", ioc->facts.NumberOfPorts);
1224 mptscsih_copy_info(&info, "MaxQ=%d\n", ioc->req_depth);
1226 return ((info.pos > info.offset) ? info.pos - info.offset : 0);
1229 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1231 * mptscsih_proc_info - Return information about MPT adapter
1233 * (linux scsi_host_template.info routine)
1235 * buffer: if write, user data; if read, buffer for user
1236 * length: if write, return length;
1237 * offset: if write, 0; if read, the current offset into the buffer from
1238 * the previous read.
1239 * hostno: scsi host number
1240 * func: if write = 1; if read = 0
1243 mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
1244 int length, int func)
1246 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
1247 MPT_ADAPTER *ioc = hd->ioc;
1252 * write is not supported
1258 size = mptscsih_host_info(ioc, buffer, offset, length);
1264 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1265 #define ADD_INDEX_LOG(req_ent) do { } while(0)
1267 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1269 * mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine.
1270 * @SCpnt: Pointer to scsi_cmnd structure
1271 * @done: Pointer SCSI mid-layer IO completion function
1273 * (linux scsi_host_template.queuecommand routine)
1274 * This is the primary SCSI IO start routine. Create a MPI SCSIIORequest
1275 * from a linux scsi_cmnd request and send it to the IOC.
1277 * Returns 0. (rtn value discarded by linux scsi mid-layer)
1280 mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1284 SCSIIORequest_t *pScsiReq;
1285 VirtDevice *vdev = SCpnt->device->hostdata;
1294 hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata;
1295 lun = SCpnt->device->lun;
1296 SCpnt->scsi_done = done;
1298 dmfprintk((MYIOC_s_INFO_FMT "qcmd: SCpnt=%p, done()=%p\n",
1299 (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt, done));
1301 if (hd->resetPending) {
1302 dtmprintk((MYIOC_s_WARN_FMT "qcmd: SCpnt=%p timeout + 60HZ\n",
1303 (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt));
1304 return SCSI_MLQUEUE_HOST_BUSY;
1308 * Put together a MPT SCSI request...
1310 if ((mf = mpt_get_msg_frame(hd->ioc->DoneCtx, hd->ioc)) == NULL) {
1311 dprintk((MYIOC_s_WARN_FMT "QueueCmd, no msg frames!!\n",
1313 return SCSI_MLQUEUE_HOST_BUSY;
1316 pScsiReq = (SCSIIORequest_t *) mf;
1318 my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
1320 ADD_INDEX_LOG(my_idx);
1322 /* TUR's being issued with scsictl=0x02000000 (DATA_IN)!
1323 * Seems we may receive a buffer (datalen>0) even when there
1324 * will be no data transfer! GRRRRR...
1326 if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
1327 datalen = SCpnt->request_bufflen;
1328 scsidir = MPI_SCSIIO_CONTROL_READ; /* DATA IN (host<--ioc<--dev) */
1329 } else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
1330 datalen = SCpnt->request_bufflen;
1331 scsidir = MPI_SCSIIO_CONTROL_WRITE; /* DATA OUT (host-->ioc-->dev) */
1334 scsidir = MPI_SCSIIO_CONTROL_NODATATRANSFER;
1337 /* Default to untagged. Once a target structure has been allocated,
1338 * use the Inquiry data to determine if device supports tagged.
1341 && (vdev->vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)
1342 && (SCpnt->device->tagged_supported)) {
1343 scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
1345 scsictl = scsidir | MPI_SCSIIO_CONTROL_UNTAGGED;
1348 /* Use the above information to set up the message frame
1350 pScsiReq->TargetID = (u8) vdev->target_id;
1351 pScsiReq->Bus = vdev->bus_id;
1352 pScsiReq->ChainOffset = 0;
1353 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
1354 pScsiReq->CDBLength = SCpnt->cmd_len;
1355 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
1356 pScsiReq->Reserved = 0;
1357 pScsiReq->MsgFlags = mpt_msg_flags();
1358 pScsiReq->LUN[0] = 0;
1359 pScsiReq->LUN[1] = lun;
1360 pScsiReq->LUN[2] = 0;
1361 pScsiReq->LUN[3] = 0;
1362 pScsiReq->LUN[4] = 0;
1363 pScsiReq->LUN[5] = 0;
1364 pScsiReq->LUN[6] = 0;
1365 pScsiReq->LUN[7] = 0;
1366 pScsiReq->Control = cpu_to_le32(scsictl);
1369 * Write SCSI CDB into the message
1371 cmd_len = SCpnt->cmd_len;
1372 for (ii=0; ii < cmd_len; ii++)
1373 pScsiReq->CDB[ii] = SCpnt->cmnd[ii];
1375 for (ii=cmd_len; ii < 16; ii++)
1376 pScsiReq->CDB[ii] = 0;
1379 pScsiReq->DataLength = cpu_to_le32(datalen);
1381 /* SenseBuffer low address */
1382 pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
1383 + (my_idx * MPT_SENSE_BUFFER_ALLOC));
1385 /* Now add the SG list
1386 * Always have a SGE even if null length.
1389 /* Add a NULL SGE */
1390 mptscsih_add_sge((char *)&pScsiReq->SGL, MPT_SGE_FLAGS_SSIMPLE_READ | 0,
1393 /* Add a 32 or 64 bit SGE */
1394 if (mptscsih_AddSGE(hd->ioc, SCpnt, pScsiReq, my_idx) != SUCCESS)
1398 hd->ScsiLookup[my_idx] = SCpnt;
1399 SCpnt->host_scribble = NULL;
1401 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1402 if (hd->ioc->bus_type == SPI) {
1403 int dvStatus = hd->ioc->spi_data.dvStatus[vdev->target_id];
1406 if (dvStatus || hd->ioc->spi_data.forceDv) {
1408 if ((dvStatus & MPT_SCSICFG_NEED_DV) ||
1409 (hd->ioc->spi_data.forceDv & MPT_SCSICFG_NEED_DV)) {
1410 unsigned long lflags;
1411 /* Schedule DV if necessary */
1412 spin_lock_irqsave(&dvtaskQ_lock, lflags);
1413 if (!dvtaskQ_active) {
1415 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1416 INIT_WORK(&dvTaskQ_task, mptscsih_domainValidation, (void *) hd);
1418 schedule_work(&dvTaskQ_task);
1420 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1422 hd->ioc->spi_data.forceDv &= ~MPT_SCSICFG_NEED_DV;
1425 /* Trying to do DV to this target, extend timeout.
1426 * Wait to issue until flag is clear
1428 if (dvStatus & MPT_SCSICFG_DV_PENDING) {
1429 mod_timer(&SCpnt->eh_timeout, jiffies + 40 * HZ);
1433 /* Set the DV flags.
1435 if (dvStatus & MPT_SCSICFG_DV_NOT_DONE)
1436 mptscsih_set_dvflags(hd, SCpnt);
1444 mpt_put_msg_frame(hd->ioc->DoneCtx, hd->ioc, mf);
1445 dmfprintk((MYIOC_s_INFO_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n",
1446 hd->ioc->name, SCpnt, mf, my_idx));
1447 DBG_DUMP_REQUEST_FRAME(mf)
1451 hd->ScsiLookup[my_idx] = NULL;
1452 mptscsih_freeChainBuffers(hd->ioc, my_idx);
1453 mpt_free_msg_frame(hd->ioc, mf);
1454 return SCSI_MLQUEUE_HOST_BUSY;
1457 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1459 * mptscsih_freeChainBuffers - Function to free chain buffers associated
1460 * with a SCSI IO request
1461 * @hd: Pointer to the MPT_SCSI_HOST instance
1462 * @req_idx: Index of the SCSI IO request frame.
1464 * Called if SG chain buffer allocation fails and mptscsih callbacks.
1468 mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
1470 MPT_FRAME_HDR *chain;
1471 unsigned long flags;
1475 /* Get the first chain index and reset
1478 chain_idx = ioc->ReqToChain[req_idx];
1479 ioc->ReqToChain[req_idx] = MPT_HOST_NO_CHAIN;
1481 while (chain_idx != MPT_HOST_NO_CHAIN) {
1483 /* Save the next chain buffer index */
1484 next = ioc->ChainToChain[chain_idx];
1486 /* Free this chain buffer and reset
1489 ioc->ChainToChain[chain_idx] = MPT_HOST_NO_CHAIN;
1491 chain = (MPT_FRAME_HDR *) (ioc->ChainBuffer
1492 + (chain_idx * ioc->req_sz));
1494 spin_lock_irqsave(&ioc->FreeQlock, flags);
1495 list_add_tail(&chain->u.frame.linkage.list, &ioc->FreeChainQ);
1496 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1498 dmfprintk((MYIOC_s_INFO_FMT "FreeChainBuffers (index %d)\n",
1499 ioc->name, chain_idx));
1507 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1512 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1514 * mptscsih_TMHandler - Generic handler for SCSI Task Management.
1515 * Fall through to mpt_HardResetHandler if: not operational, too many
1516 * failed TM requests or handshake failure.
1518 * @ioc: Pointer to MPT_ADAPTER structure
1519 * @type: Task Management type
1520 * @target: Logical Target ID for reset (if appropriate)
1521 * @lun: Logical Unit for reset (if appropriate)
1522 * @ctx2abort: Context for the task to be aborted (if appropriate)
1524 * Remark: Currently invoked from a non-interrupt thread (_bh).
1526 * Remark: With old EH code, at most 1 SCSI TaskMgmt function per IOC
1529 * Returns 0 for SUCCESS or -1 if FAILED.
1532 mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout)
1538 unsigned long flags;
1540 /* If FW is being reloaded currently, return success to
1541 * the calling function.
1548 printk(KERN_ERR MYNAM " TMHandler" " NULL ioc!\n");
1551 dtmprintk((MYIOC_s_INFO_FMT "TMHandler Entered!\n", ioc->name));
1553 // SJR - CHECKME - Can we avoid this here?
1554 // (mpt_HardResetHandler has this check...)
1555 spin_lock_irqsave(&ioc->diagLock, flags);
1556 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)) {
1557 spin_unlock_irqrestore(&ioc->diagLock, flags);
1560 spin_unlock_irqrestore(&ioc->diagLock, flags);
1562 /* Wait a fixed amount of time for the TM pending flag to be cleared.
1563 * If we time out and not bus reset, then we return a FAILED status to the caller.
1564 * The call to mptscsih_tm_pending_wait() will set the pending flag if we are
1565 * successful. Otherwise, reload the FW.
1567 if (mptscsih_tm_pending_wait(hd) == FAILED) {
1568 if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
1569 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler abort: "
1570 "Timed out waiting for last TM (%d) to complete! \n",
1571 hd->ioc->name, hd->tmPending));
1573 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) {
1574 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler target reset: "
1575 "Timed out waiting for last TM (%d) to complete! \n",
1576 hd->ioc->name, hd->tmPending));
1578 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
1579 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler bus reset: "
1580 "Timed out waiting for last TM (%d) to complete! \n",
1581 hd->ioc->name, hd->tmPending));
1582 if (hd->tmPending & (1 << MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS))
1588 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
1589 hd->tmPending |= (1 << type);
1590 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1595 ioc_raw_state = mpt_GetIocState(hd->ioc, 0);
1597 #ifdef MPT_DEBUG_RESET
1598 if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) {
1599 printk(MYIOC_s_WARN_FMT
1600 "TM Handler: IOC Not operational(0x%x)!\n",
1601 hd->ioc->name, ioc_raw_state);
1605 if (doTask && ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL)
1606 && !(ioc_raw_state & MPI_DOORBELL_ACTIVE)) {
1608 /* Isse the Task Mgmt request.
1610 if (hd->hard_resets < -1)
1612 rc = mptscsih_IssueTaskMgmt(hd, type, channel, target, lun, ctx2abort, timeout);
1614 printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n", hd->ioc->name);
1616 dtmprintk((MYIOC_s_INFO_FMT "Issue of TaskMgmt Successful!\n", hd->ioc->name));
1620 /* Only fall through to the HRH if this is a bus reset
1622 if ((type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) && (rc ||
1623 ioc->reload_fw || (ioc->alt_ioc && ioc->alt_ioc->reload_fw))) {
1624 dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
1626 rc = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
1629 dtmprintk((MYIOC_s_INFO_FMT "TMHandler rc = %d!\n", hd->ioc->name, rc));
1635 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1637 * mptscsih_IssueTaskMgmt - Generic send Task Management function.
1638 * @hd: Pointer to MPT_SCSI_HOST structure
1639 * @type: Task Management type
1640 * @target: Logical Target ID for reset (if appropriate)
1641 * @lun: Logical Unit for reset (if appropriate)
1642 * @ctx2abort: Context for the task to be aborted (if appropriate)
1644 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
1645 * or a non-interrupt thread. In the former, must not call schedule().
1647 * Not all fields are meaningfull for all task types.
1649 * Returns 0 for SUCCESS, -999 for "no msg frames",
1650 * else other non-zero value returned.
1653 mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout)
1656 SCSITaskMgmt_t *pScsiTm;
1660 /* Return Fail to calling function if no message frames available.
1662 if ((mf = mpt_get_msg_frame(hd->ioc->TaskCtx, hd->ioc)) == NULL) {
1663 dfailprintk((MYIOC_s_ERR_FMT "IssueTaskMgmt, no msg frames!!\n",
1667 dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt request @ %p\n",
1668 hd->ioc->name, mf));
1670 /* Format the Request
1672 pScsiTm = (SCSITaskMgmt_t *) mf;
1673 pScsiTm->TargetID = target;
1674 pScsiTm->Bus = channel;
1675 pScsiTm->ChainOffset = 0;
1676 pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
1678 pScsiTm->Reserved = 0;
1679 pScsiTm->TaskType = type;
1680 pScsiTm->Reserved1 = 0;
1681 pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)
1682 ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0;
1684 for (ii= 0; ii < 8; ii++) {
1685 pScsiTm->LUN[ii] = 0;
1687 pScsiTm->LUN[1] = lun;
1689 for (ii=0; ii < 7; ii++)
1690 pScsiTm->Reserved2[ii] = 0;
1692 pScsiTm->TaskMsgContext = ctx2abort;
1694 dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt: ctx2abort (0x%08x) type=%d\n",
1695 hd->ioc->name, ctx2abort, type));
1697 DBG_DUMP_TM_REQUEST_FRAME((u32 *)pScsiTm);
1699 if ((retval = mpt_send_handshake_request(hd->ioc->TaskCtx, hd->ioc,
1700 sizeof(SCSITaskMgmt_t), (u32*)pScsiTm,
1702 dfailprintk((MYIOC_s_ERR_FMT "_send_handshake FAILED!"
1703 " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
1705 mpt_free_msg_frame(hd->ioc, mf);
1709 if(mptscsih_tm_wait_for_completion(hd, timeout) == FAILED) {
1710 dfailprintk((MYIOC_s_ERR_FMT "_wait_for_completion FAILED!"
1711 " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
1713 mpt_free_msg_frame(hd->ioc, mf);
1714 dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
1716 retval = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
1723 mptscsih_get_tm_timeout(MPT_ADAPTER *ioc)
1725 switch (ioc->bus_type) {
1736 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1738 * mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant
1739 * @SCpnt: Pointer to scsi_cmnd structure, IO to be aborted
1741 * (linux scsi_host_template.eh_abort_handler routine)
1743 * Returns SUCCESS or FAILED.
1746 mptscsih_abort(struct scsi_cmnd * SCpnt)
1756 /* If we can't locate our host adapter structure, return FAILED status.
1758 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL) {
1759 SCpnt->result = DID_RESET << 16;
1760 SCpnt->scsi_done(SCpnt);
1761 dfailprintk((KERN_INFO MYNAM ": mptscsih_abort: "
1762 "Can't locate host! (sc=%p)\n",
1768 if (hd->resetPending) {
1772 if (hd->timeouts < -1)
1775 /* Find this command
1777 if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) {
1778 /* Cmd not found in ScsiLookup.
1781 SCpnt->result = DID_RESET << 16;
1782 dtmprintk((KERN_INFO MYNAM ": %s: mptscsih_abort: "
1783 "Command not in the active list! (sc=%p)\n",
1784 hd->ioc->name, SCpnt));
1788 printk(KERN_WARNING MYNAM ": %s: attempting task abort! (sc=%p)\n",
1789 hd->ioc->name, SCpnt);
1790 scsi_print_command(SCpnt);
1792 /* Most important! Set TaskMsgContext to SCpnt's MsgContext!
1793 * (the IO to be ABORT'd)
1795 * NOTE: Since we do not byteswap MsgContext, we do not
1796 * swap it here either. It is an opaque cookie to
1797 * the controller, so it does not matter. -DaveM
1799 mf = MPT_INDEX_2_MFPTR(hd->ioc, scpnt_idx);
1800 ctx2abort = mf->u.frame.hwhdr.msgctxu.MsgContext;
1802 hd->abortSCpnt = SCpnt;
1804 vdev = SCpnt->device->hostdata;
1805 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
1806 vdev->bus_id, vdev->target_id, vdev->lun,
1807 ctx2abort, mptscsih_get_tm_timeout(ioc));
1809 printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n",
1811 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1816 if(retval != FAILED ) {
1818 hd->tmState = TM_STATE_NONE;
1823 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1825 * mptscsih_dev_reset - Perform a SCSI TARGET_RESET! new_eh variant
1826 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1828 * (linux scsi_host_template.eh_dev_reset_handler routine)
1830 * Returns SUCCESS or FAILED.
1833 mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
1839 /* If we can't locate our host adapter structure, return FAILED status.
1841 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1842 dtmprintk((KERN_INFO MYNAM ": mptscsih_dev_reset: "
1843 "Can't locate host! (sc=%p)\n",
1848 if (hd->resetPending)
1851 printk(KERN_WARNING MYNAM ": %s: attempting target reset! (sc=%p)\n",
1852 hd->ioc->name, SCpnt);
1853 scsi_print_command(SCpnt);
1855 vdev = SCpnt->device->hostdata;
1856 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
1857 vdev->bus_id, vdev->target_id,
1858 0, 0, mptscsih_get_tm_timeout(hd->ioc));
1860 printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n",
1862 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1867 if(retval != FAILED ) {
1869 hd->tmState = TM_STATE_NONE;
1874 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1876 * mptscsih_bus_reset - Perform a SCSI BUS_RESET! new_eh variant
1877 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1879 * (linux scsi_host_template.eh_bus_reset_handler routine)
1881 * Returns SUCCESS or FAILED.
1884 mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
1890 /* If we can't locate our host adapter structure, return FAILED status.
1892 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1893 dtmprintk((KERN_INFO MYNAM ": mptscsih_bus_reset: "
1894 "Can't locate host! (sc=%p)\n",
1899 printk(KERN_WARNING MYNAM ": %s: attempting bus reset! (sc=%p)\n",
1900 hd->ioc->name, SCpnt);
1901 scsi_print_command(SCpnt);
1903 if (hd->timeouts < -1)
1906 vdev = SCpnt->device->hostdata;
1907 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
1908 vdev->bus_id, 0, 0, 0, mptscsih_get_tm_timeout(hd->ioc));
1910 printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n",
1912 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1917 if(retval != FAILED ) {
1919 hd->tmState = TM_STATE_NONE;
1924 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1926 * mptscsih_host_reset - Perform a SCSI host adapter RESET!
1928 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1930 * (linux scsi_host_template.eh_host_reset_handler routine)
1932 * Returns SUCCESS or FAILED.
1935 mptscsih_host_reset(struct scsi_cmnd *SCpnt)
1938 int status = SUCCESS;
1940 /* If we can't locate the host to reset, then we failed. */
1941 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1942 dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
1943 "Can't locate host! (sc=%p)\n",
1948 printk(KERN_WARNING MYNAM ": %s: Attempting host reset! (sc=%p)\n",
1949 hd->ioc->name, SCpnt);
1951 /* If our attempts to reset the host failed, then return a failed
1952 * status. The host will be taken off line by the SCSI mid-layer.
1954 if (mpt_HardResetHandler(hd->ioc, CAN_SLEEP) < 0){
1957 /* Make sure TM pending is cleared and TM state is set to
1961 hd->tmState = TM_STATE_NONE;
1964 dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
1966 (status == SUCCESS) ? "SUCCESS" : "FAILED" ) );
1971 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1973 * mptscsih_tm_pending_wait - wait for pending task management request to
1975 * @hd: Pointer to MPT host structure.
1977 * Returns {SUCCESS,FAILED}.
1980 mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd)
1982 unsigned long flags;
1983 int loop_count = 4 * 10; /* Wait 10 seconds */
1984 int status = FAILED;
1987 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
1988 if (hd->tmState == TM_STATE_NONE) {
1989 hd->tmState = TM_STATE_IN_PROGRESS;
1991 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1995 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1997 } while (--loop_count);
2002 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2004 * mptscsih_tm_wait_for_completion - wait for completion of TM task
2005 * @hd: Pointer to MPT host structure.
2007 * Returns {SUCCESS,FAILED}.
2010 mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout )
2012 unsigned long flags;
2013 int loop_count = 4 * timeout;
2014 int status = FAILED;
2017 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
2018 if(hd->tmPending == 0) {
2020 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2023 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2024 msleep_interruptible(250);
2025 } while (--loop_count);
2030 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2032 * mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
2033 * @ioc: Pointer to MPT_ADAPTER structure
2034 * @mf: Pointer to SCSI task mgmt request frame
2035 * @mr: Pointer to SCSI task mgmt reply frame
2037 * This routine is called from mptbase.c::mpt_interrupt() at the completion
2038 * of any SCSI task management request.
2039 * This routine is registered with the MPT (base) driver at driver
2040 * load/init time via the mpt_register() API call.
2042 * Returns 1 indicating alloc'd request frame ptr should be freed.
2045 mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
2047 SCSITaskMgmtReply_t *pScsiTmReply;
2048 SCSITaskMgmt_t *pScsiTmReq;
2050 unsigned long flags;
2054 dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt completed (mf=%p,mr=%p)\n",
2055 ioc->name, mf, mr));
2057 /* Depending on the thread, a timer is activated for
2058 * the TM request. Delete this timer on completion of TM.
2059 * Decrement count of outstanding TM requests.
2061 hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
2063 dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt Complete: NULL Scsi Host Ptr\n",
2069 dtmprintk((MYIOC_s_WARN_FMT "ERROR! TaskMgmt Reply: NULL Request %p\n",
2073 pScsiTmReply = (SCSITaskMgmtReply_t*)mr;
2074 pScsiTmReq = (SCSITaskMgmt_t*)mf;
2076 /* Figure out if this was ABORT_TASK, TARGET_RESET, or BUS_RESET! */
2077 tmType = pScsiTmReq->TaskType;
2079 dtmprintk((MYIOC_s_WARN_FMT " TaskType = %d, TerminationCount=%d\n",
2080 ioc->name, tmType, le32_to_cpu(pScsiTmReply->TerminationCount)));
2081 DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply);
2083 iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2084 dtmprintk((MYIOC_s_WARN_FMT " SCSI TaskMgmt (%d) IOCStatus=%04x IOCLogInfo=%08x\n",
2085 ioc->name, tmType, iocstatus, le32_to_cpu(pScsiTmReply->IOCLogInfo)));
2086 /* Error? (anything non-zero?) */
2089 /* clear flags and continue.
2091 if (tmType == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK)
2092 hd->abortSCpnt = NULL;
2094 /* If an internal command is present
2095 * or the TM failed - reload the FW.
2096 * FC FW may respond FAILED to an ABORT
2098 if (tmType == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
2100 (iocstatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED)) {
2101 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0) {
2102 printk((KERN_WARNING
2103 " Firmware Reload FAILED!!\n"));
2108 dtmprintk((MYIOC_s_WARN_FMT " TaskMgmt SUCCESS\n", ioc->name));
2110 hd->abortSCpnt = NULL;
2115 spin_lock_irqsave(&ioc->FreeQlock, flags);
2117 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2118 hd->tmState = TM_STATE_NONE;
2123 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2125 * This is anyones guess quite frankly.
2128 mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
2129 sector_t capacity, int geom[])
2139 dummy = heads * sectors;
2140 cylinders = capacity;
2141 sector_div(cylinders,dummy);
2144 * Handle extended translation size for logical drives
2147 if ((ulong)capacity >= 0x200000) {
2150 dummy = heads * sectors;
2151 cylinders = capacity;
2152 sector_div(cylinders,dummy);
2158 geom[2] = cylinders;
2160 dprintk((KERN_NOTICE
2161 ": bios_param: Id=%i Lun=%i Channel=%i CHS=%i/%i/%i\n",
2162 sdev->id, sdev->lun,sdev->channel,(int)cylinders,heads,sectors));
2167 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2169 * OS entry point to allow host driver to alloc memory
2170 * for each scsi target. Called once per device the bus scan.
2171 * Return non-zero if allocation fails.
2174 mptscsih_target_alloc(struct scsi_target *starget)
2176 VirtTarget *vtarget;
2178 vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
2181 starget->hostdata = vtarget;
2185 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2187 * OS entry point to allow host driver to alloc memory
2188 * for each scsi device. Called once per device the bus scan.
2189 * Return non-zero if allocation fails.
2192 mptscsih_slave_alloc(struct scsi_device *sdev)
2194 struct Scsi_Host *host = sdev->host;
2195 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
2196 VirtTarget *vtarget;
2198 struct scsi_target *starget;
2200 vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
2202 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
2203 hd->ioc->name, sizeof(VirtDevice));
2207 vdev->ioc_id = hd->ioc->id;
2208 vdev->target_id = sdev->id;
2209 vdev->bus_id = sdev->channel;
2210 vdev->lun = sdev->lun;
2211 sdev->hostdata = vdev;
2213 starget = scsi_target(sdev);
2214 vtarget = starget->hostdata;
2215 vdev->vtarget = vtarget;
2217 if (vtarget->num_luns == 0) {
2218 hd->Targets[sdev->id] = vtarget;
2219 vtarget->ioc_id = hd->ioc->id;
2220 vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
2221 vtarget->target_id = sdev->id;
2222 vtarget->bus_id = sdev->channel;
2223 if (hd->ioc->bus_type == SPI) {
2224 if (hd->ioc->raid_data.isRaid & (1 << sdev->id)) {
2225 vtarget->raidVolume = 1;
2226 ddvtprintk((KERN_INFO
2227 "RAID Volume @ id %d\n", sdev->id));
2230 vtarget->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
2233 vtarget->num_luns++;
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_target_destroy(struct scsi_target *starget)
2244 if (starget->hostdata)
2245 kfree(starget->hostdata);
2246 starget->hostdata = NULL;
2250 * OS entry point to allow for host driver to free allocated memory
2251 * Called if no device present or device being unloaded
2254 mptscsih_slave_destroy(struct scsi_device *sdev)
2256 struct Scsi_Host *host = sdev->host;
2257 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
2258 VirtTarget *vtarget;
2259 VirtDevice *vdevice;
2260 struct scsi_target *starget;
2262 starget = scsi_target(sdev);
2263 vtarget = starget->hostdata;
2264 vdevice = sdev->hostdata;
2266 mptscsih_search_running_cmds(hd, vdevice);
2267 vtarget->luns[0] &= ~(1 << vdevice->lun);
2268 vtarget->num_luns--;
2269 if (vtarget->num_luns == 0) {
2270 mptscsih_negotiate_to_asyn_narrow(hd, vtarget);
2271 if (hd->ioc->bus_type == SPI) {
2272 if (mptscsih_is_phys_disk(hd->ioc, vtarget->target_id)) {
2273 hd->ioc->spi_data.forceDv |= MPT_SCSICFG_RELOAD_IOC_PG3;
2275 hd->ioc->spi_data.dvStatus[vtarget->target_id] =
2276 MPT_SCSICFG_NEGOTIATE;
2277 if (!hd->negoNvram) {
2278 hd->ioc->spi_data.dvStatus[vtarget->target_id] |=
2279 MPT_SCSICFG_DV_NOT_DONE;
2283 hd->Targets[sdev->id] = NULL;
2285 mptscsih_synchronize_cache(hd, vdevice);
2287 sdev->hostdata = NULL;
2290 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2292 * mptscsih_change_queue_depth - This function will set a devices queue depth
2293 * @sdev: per scsi_device pointer
2294 * @qdepth: requested queue depth
2296 * Adding support for new 'change_queue_depth' api.
2299 mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
2301 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sdev->host->hostdata;
2302 VirtTarget *vtarget;
2303 struct scsi_target *starget;
2307 starget = scsi_target(sdev);
2308 vtarget = starget->hostdata;
2310 if (hd->ioc->bus_type == SPI) {
2311 if (vtarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) {
2312 if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
2314 else if (((vtarget->inq_data[0] & 0x1f) == 0x00) &&
2315 (vtarget->minSyncFactor <= MPT_ULTRA160 ))
2316 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2318 max_depth = MPT_SCSI_CMD_PER_DEV_LOW;
2320 /* error case - No Inq. Data */
2324 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2326 if (qdepth > max_depth)
2331 tagged = MSG_SIMPLE_TAG;
2333 scsi_adjust_queue_depth(sdev, tagged, qdepth);
2334 return sdev->queue_depth;
2338 * OS entry point to adjust the queue_depths on a per-device basis.
2339 * Called once per device the bus scan. Use it to force the queue_depth
2340 * member to 1 if a device does not support Q tags.
2341 * Return non-zero if fails.
2344 mptscsih_slave_configure(struct scsi_device *sdev)
2346 struct Scsi_Host *sh = sdev->host;
2347 VirtTarget *vtarget;
2348 VirtDevice *vdevice;
2349 struct scsi_target *starget;
2350 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sh->hostdata;
2351 int indexed_lun, lun_index;
2353 starget = scsi_target(sdev);
2354 vtarget = starget->hostdata;
2355 vdevice = sdev->hostdata;
2357 dsprintk((MYIOC_s_INFO_FMT
2358 "device @ %p, id=%d, LUN=%d, channel=%d\n",
2359 hd->ioc->name, sdev, sdev->id, sdev->lun, sdev->channel));
2360 if (hd->ioc->bus_type == SPI)
2361 dsprintk((MYIOC_s_INFO_FMT
2362 "sdtr %d wdtr %d ppr %d inq length=%d\n",
2363 hd->ioc->name, sdev->sdtr, sdev->wdtr,
2364 sdev->ppr, sdev->inquiry_len));
2366 if (sdev->id > sh->max_id) {
2367 /* error case, should never happen */
2368 scsi_adjust_queue_depth(sdev, 0, 1);
2369 goto slave_configure_exit;
2372 vdevice->configured_lun=1;
2373 lun_index = (vdevice->lun >> 5); /* 32 luns per lun_index */
2374 indexed_lun = (vdevice->lun % 32);
2375 vtarget->luns[lun_index] |= (1 << indexed_lun);
2376 mptscsih_initTarget(hd, vtarget, sdev->lun, sdev->inquiry,
2377 sdev->inquiry_len );
2378 mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH);
2380 dsprintk((MYIOC_s_INFO_FMT
2381 "Queue depth=%d, tflags=%x\n",
2382 hd->ioc->name, sdev->queue_depth, vtarget->tflags));
2384 if (hd->ioc->bus_type == SPI)
2385 dsprintk((MYIOC_s_INFO_FMT
2386 "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
2387 hd->ioc->name, vtarget->negoFlags, vtarget->maxOffset,
2388 vtarget->minSyncFactor));
2390 slave_configure_exit:
2392 dsprintk((MYIOC_s_INFO_FMT
2393 "tagged %d, simple %d, ordered %d\n",
2394 hd->ioc->name,sdev->tagged_supported, sdev->simple_tags,
2395 sdev->ordered_tags));
2400 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2402 * Private routines...
2405 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2406 /* Utility function to copy sense data from the scsi_cmnd buffer
2407 * to the FC and SCSI target structures.
2411 mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
2414 SCSIIORequest_t *pReq;
2415 u32 sense_count = le32_to_cpu(pScsiReply->SenseCount);
2417 /* Get target structure
2419 pReq = (SCSIIORequest_t *) mf;
2420 vdev = sc->device->hostdata;
2426 /* Copy the sense received into the scsi command block. */
2427 req_index = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2428 sense_data = ((u8 *)hd->ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC));
2429 memcpy(sc->sense_buffer, sense_data, SNS_LEN(sc));
2431 /* Log SMART data (asc = 0x5D, non-IM case only) if required.
2433 if ((hd->ioc->events) && (hd->ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) {
2434 if ((sense_data[12] == 0x5D) && (vdev->vtarget->raidVolume == 0)) {
2436 MPT_ADAPTER *ioc = hd->ioc;
2438 idx = ioc->eventContext % ioc->eventLogSize;
2439 ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
2440 ioc->events[idx].eventContext = ioc->eventContext;
2442 ioc->events[idx].data[0] = (pReq->LUN[1] << 24) ||
2443 (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) ||
2444 (sc->device->channel << 8) || sc->device->id;
2446 ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12];
2448 ioc->eventContext++;
2452 dprintk((MYIOC_s_INFO_FMT "Hmmm... SenseData len=0! (?)\n",
2458 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc)
2463 hd = (MPT_SCSI_HOST *) sc->device->host->hostdata;
2465 for (i = 0; i < hd->ioc->req_depth; i++) {
2466 if (hd->ScsiLookup[i] == sc) {
2474 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2476 mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2479 unsigned long flags;
2482 dtmprintk((KERN_WARNING MYNAM
2483 ": IOC %s_reset routed to SCSI host driver!\n",
2484 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
2485 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
2487 /* If a FW reload request arrives after base installed but
2488 * before all scsi hosts have been attached, then an alt_ioc
2489 * may have a NULL sh pointer.
2491 if ((ioc->sh == NULL) || (ioc->sh->hostdata == NULL))
2494 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2496 if (reset_phase == MPT_IOC_SETUP_RESET) {
2497 dtmprintk((MYIOC_s_WARN_FMT "Setup-Diag Reset\n", ioc->name));
2500 * 1. Set Hard Reset Pending Flag
2501 * All new commands go to doneQ
2503 hd->resetPending = 1;
2505 } else if (reset_phase == MPT_IOC_PRE_RESET) {
2506 dtmprintk((MYIOC_s_WARN_FMT "Pre-Diag Reset\n", ioc->name));
2508 /* 2. Flush running commands
2509 * Clean ScsiLookup (and associated memory)
2513 /* 2b. Reply to OS all known outstanding I/O commands.
2515 mptscsih_flush_running_cmds(hd);
2517 /* 2c. If there was an internal command that
2518 * has not completed, configuration or io request,
2519 * free these resources.
2522 del_timer(&hd->timer);
2523 mpt_free_msg_frame(ioc, hd->cmdPtr);
2526 dtmprintk((MYIOC_s_WARN_FMT "Pre-Reset complete.\n", ioc->name));
2529 dtmprintk((MYIOC_s_WARN_FMT "Post-Diag Reset\n", ioc->name));
2531 /* Once a FW reload begins, all new OS commands are
2532 * redirected to the doneQ w/ a reset status.
2533 * Init all control structures.
2536 /* ScsiLookup initialization
2538 for (ii=0; ii < hd->ioc->req_depth; ii++)
2539 hd->ScsiLookup[ii] = NULL;
2541 /* 2. Chain Buffer initialization
2544 /* 4. Renegotiate to all devices, if SPI
2546 if (ioc->bus_type == SPI) {
2547 dnegoprintk(("writeSDP1: ALL_IDS USE_NVRAM\n"));
2548 mptscsih_writeSDP1(hd, 0, 0, MPT_SCSICFG_ALL_IDS | MPT_SCSICFG_USE_NVRAM);
2551 /* 5. Enable new commands to be posted
2553 spin_lock_irqsave(&ioc->FreeQlock, flags);
2555 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2556 hd->resetPending = 0;
2557 hd->tmState = TM_STATE_NONE;
2559 /* 6. If there was an internal command,
2560 * wake this process up.
2564 * Wake up the original calling thread
2566 hd->pLocal = &hd->localReply;
2567 hd->pLocal->completion = MPT_SCANDV_DID_RESET;
2568 hd->scandv_wait_done = 1;
2569 wake_up(&hd->scandv_waitq);
2573 /* 7. SPI: Set flag to force DV and re-read IOC Page 3
2575 if (ioc->bus_type == SPI) {
2576 ioc->spi_data.forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
2577 ddvtprintk(("Set reload IOC Pg3 Flag\n"));
2580 /* 7. FC: Rescan for blocked rports which might have returned.
2582 else if (ioc->bus_type == FC) {
2584 unsigned long flags;
2586 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
2587 work_count = ++ioc->fc_rescan_work_count;
2588 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
2589 if (work_count == 1)
2590 schedule_work(&ioc->fc_rescan_work);
2592 dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name));
2596 return 1; /* currently means nothing really */
2599 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2601 mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2604 u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
2606 unsigned long flags;
2608 devtprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
2611 if (ioc->sh == NULL ||
2612 ((hd = (MPT_SCSI_HOST *)ioc->sh->hostdata) == NULL))
2616 case MPI_EVENT_UNIT_ATTENTION: /* 03 */
2619 case MPI_EVENT_IOC_BUS_RESET: /* 04 */
2620 case MPI_EVENT_EXT_BUS_RESET: /* 05 */
2621 if (hd && (ioc->bus_type == SPI) && (hd->soft_resets < -1))
2624 case MPI_EVENT_LOGOUT: /* 09 */
2628 case MPI_EVENT_RESCAN: /* 06 */
2629 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
2630 work_count = ++ioc->fc_rescan_work_count;
2631 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
2632 if (work_count == 1)
2633 schedule_work(&ioc->fc_rescan_work);
2637 * CHECKME! Don't think we need to do
2638 * anything for these, but...
2640 case MPI_EVENT_LINK_STATUS_CHANGE: /* 07 */
2641 case MPI_EVENT_LOOP_STATE_CHANGE: /* 08 */
2643 * CHECKME! Falling thru...
2647 case MPI_EVENT_INTEGRATED_RAID: /* 0B */
2649 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
2650 pMpiEventDataRaid_t pRaidEventData =
2651 (pMpiEventDataRaid_t) pEvReply->Data;
2652 /* Domain Validation Needed */
2653 if (ioc->bus_type == SPI &&
2654 pRaidEventData->ReasonCode ==
2655 MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED)
2656 mptscsih_set_dvflags_raid(hd, pRaidEventData->PhysDiskNum);
2661 case MPI_EVENT_NONE: /* 00 */
2662 case MPI_EVENT_LOG_DATA: /* 01 */
2663 case MPI_EVENT_STATE_CHANGE: /* 02 */
2664 case MPI_EVENT_EVENT_CHANGE: /* 0A */
2666 dprintk((KERN_INFO " Ignoring event (=%02Xh)\n", event));
2670 return 1; /* currently means nothing really */
2673 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2675 * mptscsih_initTarget - Target, LUN alloc/free functionality.
2676 * @hd: Pointer to MPT_SCSI_HOST structure
2677 * @vtarget: per target private data
2679 * @data: Pointer to data
2680 * @dlen: Number of INQUIRY bytes
2682 * NOTE: It's only SAFE to call this routine if data points to
2683 * sane & valid STANDARD INQUIRY data!
2685 * Allocate and initialize memory for this target.
2686 * Save inquiry data.
2690 mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, u8 lun, char *data, int dlen)
2696 dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n",
2697 hd->ioc->name, vtarget->bus_id, vtarget->target_id, lun, hd));
2700 * If the peripheral qualifier filter is enabled then if the target reports a 0x1
2701 * (i.e. The targer is capable of supporting the specified peripheral device type
2702 * on this logical unit; however, the physical device is not currently connected
2703 * to this logical unit) it will be converted to a 0x3 (i.e. The target is not
2704 * capable of supporting a physical device on this logical unit). This is to work
2705 * around a bug in th emid-layer in some distributions in which the mid-layer will
2706 * continue to try to communicate to the LUN and evntually create a dummy LUN.
2708 if (hd->mpt_pq_filter && dlen && (data[0] & 0xE0))
2711 /* Is LUN supported? If so, upper 2 bits will be 0
2712 * in first byte of inquiry data.
2717 if (vtarget == NULL)
2721 vtarget->type = data[0];
2723 if (hd->ioc->bus_type != SPI)
2726 if ((data[0] == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) {
2727 /* Treat all Processors as SAF-TE if
2728 * command line option is set */
2729 vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
2730 mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id);
2731 }else if ((data[0] == TYPE_PROCESSOR) &&
2732 !(vtarget->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) {
2734 vtarget->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
2735 if ( data[44] == 'S' &&
2741 vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
2742 mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id);
2746 if (!(vtarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY)) {
2747 inq_len = dlen < 8 ? dlen : 8;
2748 memcpy (vtarget->inq_data, data, inq_len);
2749 /* If have not done DV, set the DV flag.
2751 pSpi = &hd->ioc->spi_data;
2752 if ((data[0] == TYPE_TAPE) || (data[0] == TYPE_PROCESSOR)) {
2753 if (pSpi->dvStatus[vtarget->target_id] & MPT_SCSICFG_DV_NOT_DONE)
2754 pSpi->dvStatus[vtarget->target_id] |= MPT_SCSICFG_NEED_DV;
2756 vtarget->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
2758 data_56 = 0x0F; /* Default to full capabilities if Inq data length is < 57 */
2760 if ( (!(vtarget->tflags & MPT_TARGET_FLAGS_VALID_56))) {
2761 /* Update the target capabilities
2764 vtarget->tflags |= MPT_TARGET_FLAGS_VALID_56;
2767 mptscsih_setTargetNegoParms(hd, vtarget, data_56);
2769 /* Initial Inquiry may not request enough data bytes to
2770 * obtain byte 57. DV will; if target doesn't return
2771 * at least 57 bytes, data[56] will be zero. */
2773 if ( (!(vtarget->tflags & MPT_TARGET_FLAGS_VALID_56))) {
2774 /* Update the target capabilities
2777 vtarget->tflags |= MPT_TARGET_FLAGS_VALID_56;
2778 mptscsih_setTargetNegoParms(hd, vtarget, data_56);
2784 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2786 * Update the target negotiation parameters based on the
2787 * the Inquiry data, adapter capabilities, and NVRAM settings.
2791 mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target, char byte56)
2793 SpiCfgData *pspi_data = &hd->ioc->spi_data;
2794 int id = (int) target->target_id;
2796 VirtTarget *vtarget;
2798 u8 width = MPT_NARROW;
2799 u8 factor = MPT_ASYNC;
2801 u8 version, nfactor;
2804 target->negoFlags = pspi_data->noQas;
2806 /* noQas == 0 => device supports QAS. Need byte 56 of Inq to determine
2807 * support. If available, default QAS to off and allow enabling.
2808 * If not available, default QAS to on, turn off for non-disks.
2811 /* Set flags based on Inquiry data
2813 version = target->inq_data[2] & 0x07;
2816 factor = MPT_ULTRA2;
2817 offset = pspi_data->maxSyncOffset;
2818 target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
2820 if (target->inq_data[7] & 0x20) {
2824 if (target->inq_data[7] & 0x10) {
2825 factor = pspi_data->minSyncFactor;
2826 if (target->tflags & MPT_TARGET_FLAGS_VALID_56) {
2827 /* bits 2 & 3 show Clocking support */
2828 if ((byte56 & 0x0C) == 0)
2829 factor = MPT_ULTRA2;
2831 if ((byte56 & 0x03) == 0)
2832 factor = MPT_ULTRA160;
2834 factor = MPT_ULTRA320;
2837 ddvtprintk((KERN_INFO "Enabling QAS due to byte56=%02x on id=%d!\n", byte56, id));
2840 if (target->inq_data[0] == TYPE_TAPE) {
2842 target->negoFlags |= MPT_TAPE_NEGO_IDP;
2847 ddvtprintk((KERN_INFO "Enabling QAS on id=%d due to ~TARGET_FLAGS_VALID_56!\n", id));
2851 offset = pspi_data->maxSyncOffset;
2853 /* If RAID, never disable QAS
2854 * else if non RAID, do not disable
2855 * QAS if bit 1 is set
2856 * bit 1 QAS support, non-raid only
2859 if (target->raidVolume == 1) {
2868 if ( (target->inq_data[7] & 0x02) == 0) {
2869 target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
2872 /* Update tflags based on NVRAM settings. (SCSI only)
2874 if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
2875 nvram = pspi_data->nvram[id];
2876 nfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
2879 width = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
2882 /* Ensure factor is set to the
2883 * maximum of: adapter, nvram, inquiry
2886 if (nfactor < pspi_data->minSyncFactor )
2887 nfactor = pspi_data->minSyncFactor;
2889 factor = max(factor, nfactor);
2890 if (factor == MPT_ASYNC)
2901 /* Make sure data is consistent
2903 if ((!width) && (factor < MPT_ULTRA2)) {
2904 factor = MPT_ULTRA2;
2907 /* Save the data to the target structure.
2909 target->minSyncFactor = factor;
2910 target->maxOffset = offset;
2911 target->maxWidth = width;
2913 target->tflags |= MPT_TARGET_FLAGS_VALID_NEGO;
2915 /* Disable unused features.
2918 target->negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
2921 target->negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
2923 if ( factor > MPT_ULTRA320 )
2926 /* GEM, processor WORKAROUND
2928 if ((target->inq_data[0] == TYPE_PROCESSOR) || (target->inq_data[0] > 0x08)) {
2929 target->negoFlags |= (MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC);
2930 pspi_data->dvStatus[id] |= MPT_SCSICFG_BLK_NEGO;
2932 if (noQas && (pspi_data->noQas == 0)) {
2933 pspi_data->noQas |= MPT_TARGET_NO_NEGO_QAS;
2934 target->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
2936 /* Disable QAS in a mixed configuration case
2939 ddvtprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id));
2940 for (ii = 0; ii < id; ii++) {
2941 if ( (vtarget = hd->Targets[ii]) ) {
2942 vtarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
2943 mptscsih_writeSDP1(hd, 0, ii, vtarget->negoFlags);
2949 /* Write SDP1 on this I/O to this target */
2950 if (pspi_data->dvStatus[id] & MPT_SCSICFG_NEGOTIATE) {
2951 ddvtprintk((KERN_INFO "MPT_SCSICFG_NEGOTIATE on id=%d!\n", id));
2952 mptscsih_writeSDP1(hd, 0, id, hd->negoNvram);
2953 pspi_data->dvStatus[id] &= ~MPT_SCSICFG_NEGOTIATE;
2954 } else if (pspi_data->dvStatus[id] & MPT_SCSICFG_BLK_NEGO) {
2955 ddvtprintk((KERN_INFO "MPT_SCSICFG_BLK_NEGO on id=%d!\n", id));
2956 mptscsih_writeSDP1(hd, 0, id, MPT_SCSICFG_BLK_NEGO);
2957 pspi_data->dvStatus[id] &= ~MPT_SCSICFG_BLK_NEGO;
2961 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2963 * If no Target, bus reset on 1st I/O. Set the flag to
2964 * prevent any future negotiations to this device.
2967 mptscsih_no_negotiate(MPT_SCSI_HOST *hd, struct scsi_cmnd *sc)
2971 if ((vdev = sc->device->hostdata) != NULL)
2972 hd->ioc->spi_data.dvStatus[vdev->target_id] |= MPT_SCSICFG_BLK_NEGO;
2976 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2978 * SCSI Config Page functionality ...
2980 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2981 /* mptscsih_setDevicePage1Flags - add Requested and Configuration fields flags
2982 * based on width, factor and offset parameters.
2984 * @factor: sync factor
2985 * @offset: sync offset
2986 * @requestedPtr: pointer to requested values (updated)
2987 * @configurationPtr: pointer to configuration values (updated)
2988 * @flags: flags to block WDTR or SDTR negotiation
2992 * Remark: Called by writeSDP1 and _dv_params
2995 mptscsih_setDevicePage1Flags (u8 width, u8 factor, u8 offset, int *requestedPtr, int *configurationPtr, u8 flags)
2997 u8 nowide = flags & MPT_TARGET_NO_NEGO_WIDE;
2998 u8 nosync = flags & MPT_TARGET_NO_NEGO_SYNC;
3000 *configurationPtr = 0;
3001 *requestedPtr = width ? MPI_SCSIDEVPAGE1_RP_WIDE : 0;
3002 *requestedPtr |= (offset << 16) | (factor << 8);
3004 if (width && offset && !nowide && !nosync) {
3005 if (factor < MPT_ULTRA160) {
3006 *requestedPtr |= (MPI_SCSIDEVPAGE1_RP_IU + MPI_SCSIDEVPAGE1_RP_DT);
3007 if ((flags & MPT_TARGET_NO_NEGO_QAS) == 0)
3008 *requestedPtr |= MPI_SCSIDEVPAGE1_RP_QAS;
3009 if (flags & MPT_TAPE_NEGO_IDP)
3010 *requestedPtr |= 0x08000000;
3011 } else if (factor < MPT_ULTRA2) {
3012 *requestedPtr |= MPI_SCSIDEVPAGE1_RP_DT;
3017 *configurationPtr |= MPI_SCSIDEVPAGE1_CONF_WDTR_DISALLOWED;
3020 *configurationPtr |= MPI_SCSIDEVPAGE1_CONF_SDTR_DISALLOWED;
3025 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3026 /* mptscsih_writeSDP1 - write SCSI Device Page 1
3027 * @hd: Pointer to a SCSI Host Strucutre
3028 * @portnum: IOC port number
3029 * @target_id: writeSDP1 for single ID
3030 * @flags: MPT_SCSICFG_ALL_IDS, MPT_SCSICFG_USE_NVRAM, MPT_SCSICFG_BLK_NEGO
3032 * Return: -EFAULT if read of config page header fails
3035 * Remark: If a target has been found, the settings from the
3036 * target structure are used, else the device is set
3039 * Remark: Called during init and after a FW reload.
3040 * Remark: We do not wait for a return, write pages sequentially.
3043 mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
3045 MPT_ADAPTER *ioc = hd->ioc;
3047 SCSIDevicePage1_t *pData;
3048 VirtTarget *vtarget=NULL;
3053 u32 requested, configuration, flagsLength;
3055 int id = 0, maxid = 0;
3061 u8 maxwidth, maxoffset, maxfactor;
3063 if (ioc->spi_data.sdp1length == 0)
3066 if (flags & MPT_SCSICFG_ALL_IDS) {
3068 maxid = ioc->sh->max_id - 1;
3069 } else if (ioc->sh) {
3071 maxid = min_t(int, id, ioc->sh->max_id - 1);
3074 for (; id <= maxid; id++) {
3076 if (id == ioc->pfacts[portnum].PortSCSIID)
3079 /* Use NVRAM to get adapter and target maximums
3080 * Data over-riden by target structure information, if present
3082 maxwidth = ioc->spi_data.maxBusWidth;
3083 maxoffset = ioc->spi_data.maxSyncOffset;
3084 maxfactor = ioc->spi_data.minSyncFactor;
3085 if (ioc->spi_data.nvram && (ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
3086 nvram = ioc->spi_data.nvram[id];
3089 maxwidth = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
3091 if (maxoffset > 0) {
3092 maxfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
3093 if (maxfactor == 0) {
3095 maxfactor = MPT_ASYNC;
3097 } else if (maxfactor < ioc->spi_data.minSyncFactor) {
3098 maxfactor = ioc->spi_data.minSyncFactor;
3101 maxfactor = MPT_ASYNC;
3104 /* Set the negotiation flags.
3106 negoFlags = ioc->spi_data.noQas;
3108 negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
3111 negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
3113 if (flags & MPT_SCSICFG_USE_NVRAM) {
3122 //negoFlags = MPT_TARGET_NO_NEGO_SYNC;
3125 /* If id is not a raid volume, get the updated
3126 * transmission settings from the target structure.
3128 if (hd->Targets && (vtarget = hd->Targets[id]) && !vtarget->raidVolume) {
3129 width = vtarget->maxWidth;
3130 factor = vtarget->minSyncFactor;
3131 offset = vtarget->maxOffset;
3132 negoFlags = vtarget->negoFlags;
3135 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
3136 /* Force to async and narrow if DV has not been executed
3139 if ((hd->ioc->spi_data.dvStatus[id] & MPT_SCSICFG_DV_NOT_DONE) != 0) {
3146 if (flags & MPT_SCSICFG_BLK_NEGO)
3147 negoFlags |= MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC;
3149 mptscsih_setDevicePage1Flags(width, factor, offset,
3150 &requested, &configuration, negoFlags);
3151 dnegoprintk(("writeSDP1: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
3152 target_id, width, factor, offset, negoFlags, requested, configuration));
3154 /* Get a MF for this command.
3156 if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
3157 dfailprintk((MYIOC_s_WARN_FMT "write SDP1: no msg frames!\n",
3162 ddvprintk((MYIOC_s_INFO_FMT "WriteSDP1 (mf=%p, id=%d, req=0x%x, cfg=0x%x)\n",
3163 hd->ioc->name, mf, id, requested, configuration));
3166 /* Set the request and the data pointers.
3167 * Request takes: 36 bytes (32 bit SGE)
3168 * SCSI Device Page 1 requires 16 bytes
3169 * 40 + 16 <= size of SCSI IO Request = 56 bytes
3170 * and MF size >= 64 bytes.
3171 * Place data at end of MF.
3173 pReq = (Config_t *)mf;
3175 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3176 frameOffset = ioc->req_sz - sizeof(SCSIDevicePage1_t);
3178 pData = (SCSIDevicePage1_t *)((u8 *) mf + frameOffset);
3179 dataDma = ioc->req_frames_dma + (req_idx * ioc->req_sz) + frameOffset;
3181 /* Complete the request frame (same for all requests).
3183 pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
3185 pReq->ChainOffset = 0;
3186 pReq->Function = MPI_FUNCTION_CONFIG;
3187 pReq->ExtPageLength = 0;
3188 pReq->ExtPageType = 0;
3190 for (ii=0; ii < 8; ii++) {
3191 pReq->Reserved2[ii] = 0;
3193 pReq->Header.PageVersion = ioc->spi_data.sdp1version;
3194 pReq->Header.PageLength = ioc->spi_data.sdp1length;
3195 pReq->Header.PageNumber = 1;
3196 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
3197 pReq->PageAddress = cpu_to_le32(id | (bus << 8 ));
3199 /* Add a SGE to the config request.
3201 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE | ioc->spi_data.sdp1length * 4;
3203 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma);
3205 /* Set up the common data portion
3207 pData->Header.PageVersion = pReq->Header.PageVersion;
3208 pData->Header.PageLength = pReq->Header.PageLength;
3209 pData->Header.PageNumber = pReq->Header.PageNumber;
3210 pData->Header.PageType = pReq->Header.PageType;
3211 pData->RequestedParameters = cpu_to_le32(requested);
3212 pData->Reserved = 0;
3213 pData->Configuration = cpu_to_le32(configuration);
3215 dprintk((MYIOC_s_INFO_FMT
3216 "write SDP1: id %d pgaddr 0x%x req 0x%x config 0x%x\n",
3217 ioc->name, id, (id | (bus<<8)),
3218 requested, configuration));
3220 mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
3226 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3227 /* mptscsih_writeIOCPage4 - write IOC Page 4
3228 * @hd: Pointer to a SCSI Host Structure
3229 * @target_id: write IOC Page4 for this ID & Bus
3231 * Return: -EAGAIN if unable to obtain a Message Frame
3234 * Remark: We do not wait for a return, write pages sequentially.
3237 mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus)
3239 MPT_ADAPTER *ioc = hd->ioc;
3241 IOCPage4_t *IOCPage4Ptr;
3249 /* Get a MF for this command.
3251 if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
3252 dfailprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n",
3257 /* Set the request and the data pointers.
3258 * Place data at end of MF.
3260 pReq = (Config_t *)mf;
3262 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3263 frameOffset = ioc->req_sz - sizeof(IOCPage4_t);
3265 /* Complete the request frame (same for all requests).
3267 pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
3269 pReq->ChainOffset = 0;
3270 pReq->Function = MPI_FUNCTION_CONFIG;
3271 pReq->ExtPageLength = 0;
3272 pReq->ExtPageType = 0;
3274 for (ii=0; ii < 8; ii++) {
3275 pReq->Reserved2[ii] = 0;
3278 IOCPage4Ptr = ioc->spi_data.pIocPg4;
3279 dataDma = ioc->spi_data.IocPg4_dma;
3280 ii = IOCPage4Ptr->ActiveSEP++;
3281 IOCPage4Ptr->SEP[ii].SEPTargetID = target_id;
3282 IOCPage4Ptr->SEP[ii].SEPBus = bus;
3283 pReq->Header = IOCPage4Ptr->Header;
3284 pReq->PageAddress = cpu_to_le32(target_id | (bus << 8 ));
3286 /* Add a SGE to the config request.
3288 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE |
3289 (IOCPage4Ptr->Header.PageLength + ii) * 4;
3291 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma);
3293 dinitprintk((MYIOC_s_INFO_FMT
3294 "writeIOCPage4: MaxSEP=%d ActiveSEP=%d id=%d bus=%d\n",
3295 ioc->name, IOCPage4Ptr->MaxSEP, IOCPage4Ptr->ActiveSEP, target_id, bus));
3297 mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
3302 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3304 * Bus Scan and Domain Validation functionality ...
3307 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3309 * mptscsih_scandv_complete - Scan and DV callback routine registered
3310 * to Fustion MPT (base) driver.
3312 * @ioc: Pointer to MPT_ADAPTER structure
3313 * @mf: Pointer to original MPT request frame
3314 * @mr: Pointer to MPT reply frame (NULL if TurboReply)
3316 * This routine is called from mpt.c::mpt_interrupt() at the completion
3317 * of any SCSI IO request.
3318 * This routine is registered with the Fusion MPT (base) driver at driver
3319 * load/init time via the mpt_register() API call.
3321 * Returns 1 indicating alloc'd request frame ptr should be freed.
3323 * Remark: Sets a completion code and (possibly) saves sense data
3324 * in the IOC member localReply structure.
3325 * Used ONLY for DV and other internal commands.
3328 mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
3331 SCSIIORequest_t *pReq;
3335 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
3338 (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) {
3339 printk(MYIOC_s_ERR_FMT
3340 "ScanDvComplete, %s req frame ptr! (=%p)\n",
3341 ioc->name, mf?"BAD":"NULL", (void *) mf);
3345 del_timer(&hd->timer);
3346 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3347 hd->ScsiLookup[req_idx] = NULL;
3348 pReq = (SCSIIORequest_t *) mf;
3350 if (mf != hd->cmdPtr) {
3351 printk(MYIOC_s_WARN_FMT "ScanDvComplete (mf=%p, cmdPtr=%p, idx=%d)\n",
3352 hd->ioc->name, (void *)mf, (void *) hd->cmdPtr, req_idx);
3356 ddvprintk((MYIOC_s_INFO_FMT "ScanDvComplete (mf=%p,mr=%p,idx=%d)\n",
3357 hd->ioc->name, mf, mr, req_idx));
3359 hd->pLocal = &hd->localReply;
3360 hd->pLocal->scsiStatus = 0;
3362 /* If target struct exists, clear sense valid flag.
3365 completionCode = MPT_SCANDV_GOOD;
3367 SCSIIOReply_t *pReply;
3371 pReply = (SCSIIOReply_t *) mr;
3373 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
3374 scsi_status = pReply->SCSIStatus;
3376 ddvtprintk((KERN_NOTICE " IOCStatus=%04xh, SCSIState=%02xh, SCSIStatus=%02xh, IOCLogInfo=%08xh\n",
3377 status, pReply->SCSIState, scsi_status,
3378 le32_to_cpu(pReply->IOCLogInfo)));
3382 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
3383 completionCode = MPT_SCANDV_SELECTION_TIMEOUT;
3386 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
3387 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
3388 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
3389 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
3390 completionCode = MPT_SCANDV_DID_RESET;
3393 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
3394 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
3395 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
3396 if (pReply->Function == MPI_FUNCTION_CONFIG) {
3397 ConfigReply_t *pr = (ConfigReply_t *)mr;
3398 completionCode = MPT_SCANDV_GOOD;
3399 hd->pLocal->header.PageVersion = pr->Header.PageVersion;
3400 hd->pLocal->header.PageLength = pr->Header.PageLength;
3401 hd->pLocal->header.PageNumber = pr->Header.PageNumber;
3402 hd->pLocal->header.PageType = pr->Header.PageType;
3404 } else if (pReply->Function == MPI_FUNCTION_RAID_ACTION) {
3405 /* If the RAID Volume request is successful,
3406 * return GOOD, else indicate that
3407 * some type of error occurred.
3409 MpiRaidActionReply_t *pr = (MpiRaidActionReply_t *)mr;
3410 if (le16_to_cpu(pr->ActionStatus) == MPI_RAID_ACTION_ASTATUS_SUCCESS)
3411 completionCode = MPT_SCANDV_GOOD;
3413 completionCode = MPT_SCANDV_SOME_ERROR;
3415 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID) {
3419 /* save sense data in global structure
3421 completionCode = MPT_SCANDV_SENSE;
3422 hd->pLocal->scsiStatus = scsi_status;
3423 sense_data = ((u8 *)hd->ioc->sense_buf_pool +
3424 (req_idx * MPT_SENSE_BUFFER_ALLOC));
3426 sz = min_t(int, pReq->SenseBufferLength,
3427 SCSI_STD_SENSE_BYTES);
3428 memcpy(hd->pLocal->sense, sense_data, sz);
3430 ddvprintk((KERN_NOTICE " Check Condition, sense ptr %p\n",
3432 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_FAILED) {
3433 if (pReq->CDB[0] == INQUIRY)
3434 completionCode = MPT_SCANDV_ISSUE_SENSE;
3436 completionCode = MPT_SCANDV_DID_RESET;
3438 else if (pReply->SCSIState & MPI_SCSI_STATE_NO_SCSI_STATUS)
3439 completionCode = MPT_SCANDV_DID_RESET;
3440 else if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
3441 completionCode = MPT_SCANDV_DID_RESET;
3443 completionCode = MPT_SCANDV_GOOD;
3444 hd->pLocal->scsiStatus = scsi_status;
3448 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
3449 if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
3450 completionCode = MPT_SCANDV_DID_RESET;
3452 completionCode = MPT_SCANDV_SOME_ERROR;
3456 completionCode = MPT_SCANDV_SOME_ERROR;
3459 } /* switch(status) */
3461 ddvtprintk((KERN_NOTICE " completionCode set to %08xh\n",
3463 } /* end of address reply case */
3465 hd->pLocal->completion = completionCode;
3467 /* MF and RF are freed in mpt_interrupt
3470 /* Free Chain buffers (will never chain) in scan or dv */
3471 //mptscsih_freeChainBuffers(ioc, req_idx);
3474 * Wake up the original calling thread
3476 hd->scandv_wait_done = 1;
3477 wake_up(&hd->scandv_waitq);
3482 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3483 /* mptscsih_timer_expired - Call back for timer process.
3484 * Used only for dv functionality.
3485 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
3489 mptscsih_timer_expired(unsigned long data)
3491 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) data;
3493 ddvprintk((MYIOC_s_WARN_FMT "Timer Expired! Cmd %p\n", hd->ioc->name, hd->cmdPtr));
3496 MPIHeader_t *cmd = (MPIHeader_t *)hd->cmdPtr;
3498 if (cmd->Function == MPI_FUNCTION_SCSI_IO_REQUEST) {
3499 /* Desire to issue a task management request here.
3500 * TM requests MUST be single threaded.
3501 * If old eh code and no TM current, issue request.
3502 * If new eh code, do nothing. Wait for OS cmd timeout
3505 ddvtprintk((MYIOC_s_NOTE_FMT "DV Cmd Timeout: NoOp\n", hd->ioc->name));
3507 /* Perform a FW reload */
3508 if (mpt_HardResetHandler(hd->ioc, NO_SLEEP) < 0) {
3509 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", hd->ioc->name);
3513 /* This should NEVER happen */
3514 printk(MYIOC_s_WARN_FMT "Null cmdPtr!!!!\n", hd->ioc->name);
3517 /* No more processing.
3518 * TM call will generate an interrupt for SCSI TM Management.
3519 * The FW will reply to all outstanding commands, callback will finish cleanup.
3520 * Hard reset clean-up will free all resources.
3522 ddvprintk((MYIOC_s_WARN_FMT "Timer Expired Complete!\n", hd->ioc->name));
3527 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
3528 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3529 /* mptscsih_do_raid - Format and Issue a RAID volume request message.
3530 * @hd: Pointer to scsi host structure
3531 * @action: What do be done.
3532 * @id: Logical target id.
3533 * @bus: Target locations bus.
3535 * Returns: < 0 on a fatal error
3538 * Remark: Wait to return until reply processed by the ISR.
3541 mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io)
3543 MpiRaidActionRequest_t *pReq;
3547 in_isr = in_interrupt();
3549 dprintk((MYIOC_s_WARN_FMT "Internal raid request not allowed in ISR context!\n",
3554 /* Get and Populate a free Frame
3556 if ((mf = mpt_get_msg_frame(hd->ioc->InternalCtx, hd->ioc)) == NULL) {
3557 ddvprintk((MYIOC_s_WARN_FMT "_do_raid: no msg frames!\n",
3561 pReq = (MpiRaidActionRequest_t *)mf;
3562 pReq->Action = action;
3563 pReq->Reserved1 = 0;
3564 pReq->ChainOffset = 0;
3565 pReq->Function = MPI_FUNCTION_RAID_ACTION;
3566 pReq->VolumeID = io->id;
3567 pReq->VolumeBus = io->bus;
3568 pReq->PhysDiskNum = io->physDiskNum;
3570 pReq->Reserved2 = 0;
3571 pReq->ActionDataWord = 0; /* Reserved for this action */
3572 //pReq->ActionDataSGE = 0;
3574 mpt_add_sge((char *)&pReq->ActionDataSGE,
3575 MPT_SGE_FLAGS_SSIMPLE_READ | 0, (dma_addr_t) -1);
3577 ddvprintk((MYIOC_s_INFO_FMT "RAID Volume action %x id %d\n",
3578 hd->ioc->name, action, io->id));
3581 hd->timer.expires = jiffies + HZ*10; /* 10 second timeout */
3582 hd->scandv_wait_done = 0;
3584 /* Save cmd pointer, for resource free if timeout or
3589 add_timer(&hd->timer);
3590 mpt_put_msg_frame(hd->ioc->InternalCtx, hd->ioc, mf);
3591 wait_event(hd->scandv_waitq, hd->scandv_wait_done);
3593 if ((hd->pLocal == NULL) || (hd->pLocal->completion != MPT_SCANDV_GOOD))
3598 #endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */
3600 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3602 * mptscsih_do_cmd - Do internal command.
3603 * @hd: MPT_SCSI_HOST pointer
3604 * @io: INTERNAL_CMD pointer.
3606 * Issue the specified internally generated command and do command
3607 * specific cleanup. For bus scan / DV only.
3608 * NOTES: If command is Inquiry and status is good,
3609 * initialize a target structure, save the data
3611 * Remark: Single threaded access only.
3614 * < 0 if an illegal command or no resources
3618 * > 0 if command complete but some type of completion error.
3621 mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
3624 SCSIIORequest_t *pScsiReq;
3625 SCSIIORequest_t ReqCopy;
3626 int my_idx, ii, dir;
3630 char CDB[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
3633 in_isr = in_interrupt();
3635 dprintk((MYIOC_s_WARN_FMT "Internal SCSI IO request not allowed in ISR context!\n",
3641 /* Set command specific information
3646 dir = MPI_SCSIIO_CONTROL_READ;
3652 case TEST_UNIT_READY:
3654 dir = MPI_SCSIIO_CONTROL_READ;
3660 dir = MPI_SCSIIO_CONTROL_READ;
3662 CDB[4] = 1; /*Spin up the disk */
3670 dir = MPI_SCSIIO_CONTROL_READ;
3676 dir = MPI_SCSIIO_CONTROL_READ;
3678 if (io->flags & MPT_ICFLAG_ECHO) {
3684 if (io->flags & MPT_ICFLAG_BUF_CAP) {
3687 CDB[6] = (io->size >> 16) & 0xFF;
3688 CDB[7] = (io->size >> 8) & 0xFF;
3689 CDB[8] = io->size & 0xFF;
3695 dir = MPI_SCSIIO_CONTROL_WRITE;
3697 if (io->flags & MPT_ICFLAG_ECHO) {
3702 CDB[6] = (io->size >> 16) & 0xFF;
3703 CDB[7] = (io->size >> 8) & 0xFF;
3704 CDB[8] = io->size & 0xFF;
3710 dir = MPI_SCSIIO_CONTROL_READ;
3717 dir = MPI_SCSIIO_CONTROL_READ;
3722 case SYNCHRONIZE_CACHE:
3724 dir = MPI_SCSIIO_CONTROL_READ;
3726 // CDB[1] = 0x02; /* set immediate bit */
3735 /* Get and Populate a free Frame
3737 if ((mf = mpt_get_msg_frame(hd->ioc->InternalCtx, hd->ioc)) == NULL) {
3738 ddvprintk((MYIOC_s_WARN_FMT "No msg frames!\n",
3743 pScsiReq = (SCSIIORequest_t *) mf;
3745 /* Get the request index */
3746 my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3747 ADD_INDEX_LOG(my_idx); /* for debug */
3749 if (io->flags & MPT_ICFLAG_PHYS_DISK) {
3750 pScsiReq->TargetID = io->physDiskNum;
3752 pScsiReq->ChainOffset = 0;
3753 pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
3755 pScsiReq->TargetID = io->id;
3756 pScsiReq->Bus = io->bus;
3757 pScsiReq->ChainOffset = 0;
3758 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
3761 pScsiReq->CDBLength = cmdLen;
3762 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
3764 pScsiReq->Reserved = 0;
3766 pScsiReq->MsgFlags = mpt_msg_flags();
3767 /* MsgContext set in mpt_get_msg_fram call */
3769 for (ii=0; ii < 8; ii++)
3770 pScsiReq->LUN[ii] = 0;
3771 pScsiReq->LUN[1] = io->lun;
3773 if (io->flags & MPT_ICFLAG_TAGGED_CMD)
3774 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ);
3776 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3778 if (cmd == REQUEST_SENSE) {
3779 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3780 ddvprintk((MYIOC_s_INFO_FMT "Untagged! 0x%2x\n",
3781 hd->ioc->name, cmd));
3784 for (ii=0; ii < 16; ii++)
3785 pScsiReq->CDB[ii] = CDB[ii];
3787 pScsiReq->DataLength = cpu_to_le32(io->size);
3788 pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
3789 + (my_idx * MPT_SENSE_BUFFER_ALLOC));
3791 ddvprintk((MYIOC_s_INFO_FMT "Sending Command 0x%x for (%d:%d:%d)\n",
3792 hd->ioc->name, cmd, io->bus, io->id, io->lun));
3794 if (dir == MPI_SCSIIO_CONTROL_READ) {
3795 mpt_add_sge((char *) &pScsiReq->SGL,
3796 MPT_SGE_FLAGS_SSIMPLE_READ | io->size,
3799 mpt_add_sge((char *) &pScsiReq->SGL,
3800 MPT_SGE_FLAGS_SSIMPLE_WRITE | io->size,
3804 /* The ISR will free the request frame, but we need
3805 * the information to initialize the target. Duplicate.
3807 memcpy(&ReqCopy, pScsiReq, sizeof(SCSIIORequest_t));
3809 /* Issue this command after:
3812 * Wait until the reply has been received
3813 * ScsiScanDvCtx callback function will
3815 * set scandv_wait_done and call wake_up
3818 hd->timer.expires = jiffies + HZ*cmdTimeout;
3819 hd->scandv_wait_done = 0;
3821 /* Save cmd pointer, for resource free if timeout or
3826 add_timer(&hd->timer);
3827 mpt_put_msg_frame(hd->ioc->InternalCtx, hd->ioc, mf);
3828 wait_event(hd->scandv_waitq, hd->scandv_wait_done);
3831 rc = hd->pLocal->completion;
3832 hd->pLocal->skip = 0;
3834 /* Always set fatal error codes in some cases.
3836 if (rc == MPT_SCANDV_SELECTION_TIMEOUT)
3838 else if (rc == MPT_SCANDV_SOME_ERROR)
3842 /* This should never happen. */
3843 ddvprintk((MYIOC_s_INFO_FMT "_do_cmd: Null pLocal!!!\n",
3850 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3852 * mptscsih_negotiate_to_asyn_narrow - Restore devices to default state
3853 * @hd: Pointer to a SCSI HOST structure
3854 * @vtarget: per device private data
3856 * Uses the ISR, but with special processing.
3857 * MUST be single-threaded.
3861 mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtTarget *vtarget)
3863 MPT_ADAPTER *ioc= hd->ioc;
3864 SCSIDevicePage1_t *pcfg1Data;
3866 dma_addr_t cfg1_dma_addr;
3867 ConfigPageHeader_t header;
3869 int requested, configuration, data,i;
3872 if (ioc->bus_type != SPI)
3875 if (!ioc->spi_data.sdp1length)
3878 pcfg1Data = (SCSIDevicePage1_t *)pci_alloc_consistent(ioc->pcidev,
3879 ioc->spi_data.sdp1length * 4, &cfg1_dma_addr);
3881 if (pcfg1Data == NULL)
3884 header.PageVersion = ioc->spi_data.sdp1version;
3885 header.PageLength = ioc->spi_data.sdp1length;
3886 header.PageNumber = 1;
3887 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
3888 cfg.cfghdr.hdr = &header;
3889 cfg.physAddr = cfg1_dma_addr;
3890 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
3894 if (vtarget->raidVolume && ioc->raid_data.pIocPg3) {
3895 for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
3896 id = ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID;
3897 flags = hd->ioc->spi_data.noQas;
3898 if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
3899 data = hd->ioc->spi_data.nvram[id];
3900 if (data & MPT_NVRAM_WIDE_DISABLE)
3901 flags |= MPT_TARGET_NO_NEGO_WIDE;
3902 factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT;
3903 if ((factor == 0) || (factor == MPT_ASYNC))
3904 flags |= MPT_TARGET_NO_NEGO_SYNC;
3906 mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested,
3907 &configuration, flags);
3908 dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC "
3909 "offset=0 negoFlags=%x request=%x config=%x\n",
3910 id, flags, requested, configuration));
3911 pcfg1Data->RequestedParameters = cpu_to_le32(requested);
3912 pcfg1Data->Reserved = 0;
3913 pcfg1Data->Configuration = cpu_to_le32(configuration);
3914 cfg.pageAddr = (vtarget->bus_id<<8) | id;
3915 mpt_config(hd->ioc, &cfg);
3918 flags = vtarget->negoFlags;
3919 mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested,
3920 &configuration, flags);
3921 dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC "
3922 "offset=0 negoFlags=%x request=%x config=%x\n",
3923 vtarget->target_id, flags, requested, configuration));
3924 pcfg1Data->RequestedParameters = cpu_to_le32(requested);
3925 pcfg1Data->Reserved = 0;
3926 pcfg1Data->Configuration = cpu_to_le32(configuration);
3927 cfg.pageAddr = (vtarget->bus_id<<8) | vtarget->target_id;
3928 mpt_config(hd->ioc, &cfg);
3932 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pcfg1Data, cfg1_dma_addr);
3935 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3937 * mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
3938 * @hd: Pointer to a SCSI HOST structure
3939 * @vtarget: per device private data
3942 * Uses the ISR, but with special processing.
3943 * MUST be single-threaded.
3947 mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
3951 /* Following parameters will not change
3954 iocmd.cmd = SYNCHRONIZE_CACHE;
3956 iocmd.physDiskNum = -1;
3958 iocmd.data_dma = -1;
3960 iocmd.rsvd = iocmd.rsvd2 = 0;
3961 iocmd.bus = vdevice->bus_id;
3962 iocmd.id = vdevice->target_id;
3963 iocmd.lun = (u8)vdevice->lun;
3965 if ((vdevice->vtarget->type & TYPE_DISK) &&
3966 (vdevice->configured_lun))
3967 mptscsih_do_cmd(hd, &iocmd);
3970 /* Search IOC page 3 to determine if this is hidden physical disk
3973 mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id)
3977 if (!ioc->raid_data.isRaid || !ioc->raid_data.pIocPg3)
3980 for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
3981 if (id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID)
3988 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
3989 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3991 * mptscsih_domainValidation - Top level handler for domain validation.
3992 * @hd: Pointer to MPT_SCSI_HOST structure.
3994 * Uses the ISR, but with special processing.
3995 * Called from schedule, should not be in interrupt mode.
3996 * While thread alive, do dv for all devices needing dv
4001 mptscsih_domainValidation(void *arg)
4005 unsigned long flags;
4006 int id, maxid, dvStatus, did;
4009 spin_lock_irqsave(&dvtaskQ_lock, flags);
4011 if (dvtaskQ_release) {
4013 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4016 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4018 /* For this ioc, loop through all devices and do dv to each device.
4019 * When complete with this ioc, search through the ioc list, and
4020 * for each scsi ioc found, do dv for all devices. Exit when no
4026 list_for_each_entry(ioc, &ioc_list, list) {
4027 spin_lock_irqsave(&dvtaskQ_lock, flags);
4028 if (dvtaskQ_release) {
4030 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4033 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4037 /* DV only to SPI adapters */
4038 if (ioc->bus_type != SPI)
4041 /* Make sure everything looks ok */
4042 if (ioc->sh == NULL)
4045 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
4049 if ((ioc->spi_data.forceDv & MPT_SCSICFG_RELOAD_IOC_PG3) != 0) {
4050 mpt_read_ioc_pg_3(ioc);
4051 if (ioc->raid_data.pIocPg3) {
4052 Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
4053 int numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
4056 if (ioc->spi_data.dvStatus[pPDisk->PhysDiskID] & MPT_SCSICFG_DV_NOT_DONE)
4057 ioc->spi_data.dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV;
4063 ioc->spi_data.forceDv &= ~MPT_SCSICFG_RELOAD_IOC_PG3;
4066 maxid = min_t(int, ioc->sh->max_id, MPT_MAX_SCSI_DEVICES);
4068 for (id = 0; id < maxid; id++) {
4069 spin_lock_irqsave(&dvtaskQ_lock, flags);
4070 if (dvtaskQ_release) {
4072 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4075 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4076 dvStatus = hd->ioc->spi_data.dvStatus[id];
4078 if (dvStatus & MPT_SCSICFG_NEED_DV) {
4080 hd->ioc->spi_data.dvStatus[id] |= MPT_SCSICFG_DV_PENDING;
4081 hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_NEED_DV;
4085 /* If hidden phys disk, block IO's to all
4087 * else, process normally
4089 isPhysDisk = mptscsih_is_phys_disk(ioc, id);
4091 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4092 if (hd->ioc->raid_data.isRaid & (1 << ii)) {
4093 hd->ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_DV_PENDING;
4098 if(mpt_alt_ioc_wait(hd->ioc)!=0) {
4099 ddvprintk((MYIOC_s_WARN_FMT "alt_ioc busy!\n",
4104 if (mptscsih_doDv(hd, 0, id) == 1) {
4105 /* Untagged device was busy, try again
4107 hd->ioc->spi_data.dvStatus[id] |= MPT_SCSICFG_NEED_DV;
4108 hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_PENDING;
4110 /* DV is complete. Clear flags.
4112 hd->ioc->spi_data.dvStatus[id] &= ~(MPT_SCSICFG_DV_NOT_DONE | MPT_SCSICFG_DV_PENDING);
4115 spin_lock(&hd->ioc->initializing_hba_lock);
4116 hd->ioc->initializing_hba_lock_flag=0;
4117 spin_unlock(&hd->ioc->initializing_hba_lock);
4120 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4121 if (hd->ioc->raid_data.isRaid & (1 << ii)) {
4122 hd->ioc->spi_data.dvStatus[ii] &= ~MPT_SCSICFG_DV_PENDING;
4127 if (hd->ioc->spi_data.noQas)
4128 mptscsih_qas_check(hd, id);
4134 spin_lock_irqsave(&dvtaskQ_lock, flags);
4136 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4141 /* Write SDP1 if no QAS has been enabled
4144 mptscsih_qas_check(MPT_SCSI_HOST *hd, int id)
4146 VirtTarget *vtarget;
4149 if (hd->Targets == NULL)
4152 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4156 if ((hd->ioc->spi_data.dvStatus[ii] & MPT_SCSICFG_DV_NOT_DONE) != 0)
4159 vtarget = hd->Targets[ii];
4161 if ((vtarget != NULL) && (!vtarget->raidVolume)) {
4162 if ((vtarget->negoFlags & hd->ioc->spi_data.noQas) == 0) {
4163 vtarget->negoFlags |= hd->ioc->spi_data.noQas;
4164 dnegoprintk(("writeSDP1: id=%d flags=0\n", id));
4165 mptscsih_writeSDP1(hd, 0, ii, 0);
4168 if (mptscsih_is_phys_disk(hd->ioc, ii) == 1) {
4169 dnegoprintk(("writeSDP1: id=%d SCSICFG_USE_NVRAM\n", id));
4170 mptscsih_writeSDP1(hd, 0, ii, MPT_SCSICFG_USE_NVRAM);
4179 #define MPT_GET_NVRAM_VALS 0x01
4180 #define MPT_UPDATE_MAX 0x02
4181 #define MPT_SET_MAX 0x04
4182 #define MPT_SET_MIN 0x08
4183 #define MPT_FALLBACK 0x10
4184 #define MPT_SAVE 0x20
4186 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4188 * mptscsih_doDv - Perform domain validation to a target.
4189 * @hd: Pointer to MPT_SCSI_HOST structure.
4190 * @portnum: IOC port number.
4191 * @target: Physical ID of this target
4193 * Uses the ISR, but with special processing.
4194 * MUST be single-threaded.
4195 * Test will exit if target is at async & narrow.
4200 mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
4202 MPT_ADAPTER *ioc = hd->ioc;
4203 VirtTarget *vtarget;
4204 SCSIDevicePage1_t *pcfg1Data;
4205 SCSIDevicePage0_t *pcfg0Data;
4209 dma_addr_t dvbuf_dma = -1;
4210 dma_addr_t buf1_dma = -1;
4211 dma_addr_t buf2_dma = -1;
4212 dma_addr_t cfg1_dma_addr = -1;
4213 dma_addr_t cfg0_dma_addr = -1;
4214 ConfigPageHeader_t header1;
4215 ConfigPageHeader_t header0;
4222 int dataBufSize = 0;
4223 int echoBufSize = 0;
4228 int nfactor = MPT_ULTRA320;
4230 char doFallback = 0;
4235 if (ioc->spi_data.sdp1length == 0)
4238 if (ioc->spi_data.sdp0length == 0)
4241 /* If multiple buses are used, require that the initiator
4242 * id be the same on all buses.
4244 if (id == ioc->pfacts[0].PortSCSIID)
4248 bus = (u8) bus_number;
4249 ddvtprintk((MYIOC_s_NOTE_FMT
4250 "DV started: bus=%d, id=%d dv @ %p\n",
4251 ioc->name, bus, id, &dv));
4253 /* Prep DV structure
4255 memset (&dv, 0, sizeof(DVPARAMETERS));
4258 /* Populate tmax with the current maximum
4259 * transfer parameters for this target.
4260 * Exit if narrow and async.
4262 dv.cmd = MPT_GET_NVRAM_VALS;
4263 mptscsih_dv_parms(hd, &dv, NULL);
4265 /* Prep SCSI IO structure
4271 iocmd.physDiskNum = -1;
4272 iocmd.rsvd = iocmd.rsvd2 = 0;
4274 vtarget = hd->Targets[id];
4276 /* Use tagged commands if possible.
4279 if (vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)
4280 iocmd.flags |= MPT_ICFLAG_TAGGED_CMD;
4282 if (hd->ioc->facts.FWVersion.Word < 0x01000600)
4285 if ((hd->ioc->facts.FWVersion.Word >= 0x01010000) &&
4286 (hd->ioc->facts.FWVersion.Word < 0x01010B00))
4291 /* Prep cfg structure
4293 cfg.pageAddr = (bus<<8) | id;
4294 cfg.cfghdr.hdr = NULL;
4298 header0.PageVersion = ioc->spi_data.sdp0version;
4299 header0.PageLength = ioc->spi_data.sdp0length;
4300 header0.PageNumber = 0;
4301 header0.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4305 header1.PageVersion = ioc->spi_data.sdp1version;
4306 header1.PageLength = ioc->spi_data.sdp1length;
4307 header1.PageNumber = 1;
4308 header1.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4310 if (header0.PageLength & 1)
4311 dv_alloc = (header0.PageLength * 4) + 4;
4313 dv_alloc += (2048 + (header1.PageLength * 4));
4315 pDvBuf = pci_alloc_consistent(ioc->pcidev, dv_alloc, &dvbuf_dma);
4320 pbuf1 = (u8 *)pDvBuf;
4321 buf1_dma = dvbuf_dma;
4324 pbuf2 = (u8 *) (pDvBuf + sz);
4325 buf2_dma = dvbuf_dma + sz;
4328 pcfg0Data = (SCSIDevicePage0_t *) (pDvBuf + sz);
4329 cfg0_dma_addr = dvbuf_dma + sz;
4330 sz += header0.PageLength * 4;
4334 if (header0.PageLength & 1)
4337 pcfg1Data = (SCSIDevicePage1_t *) (pDvBuf + sz);
4338 cfg1_dma_addr = dvbuf_dma + sz;
4340 /* Skip this ID? Set cfg.cfghdr.hdr to force config page write
4343 SpiCfgData *pspi_data = &hd->ioc->spi_data;
4344 if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
4345 /* Set the factor from nvram */
4346 nfactor = (pspi_data->nvram[id] & MPT_NVRAM_SYNC_MASK) >> 8;
4347 if (nfactor < pspi_data->minSyncFactor )
4348 nfactor = pspi_data->minSyncFactor;
4350 if (!(pspi_data->nvram[id] & MPT_NVRAM_ID_SCAN_ENABLE) ||
4351 (pspi_data->PortFlags == MPI_SCSIPORTPAGE2_PORT_FLAGS_OFF_DV) ) {
4353 ddvprintk((MYIOC_s_NOTE_FMT "DV Skipped: bus, id, lun (%d, %d, %d)\n",
4354 ioc->name, bus, id, lun));
4356 dv.cmd = MPT_SET_MAX;
4357 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
4358 cfg.cfghdr.hdr = &header1;
4360 /* Save the final negotiated settings to
4361 * SCSI device page 1.
4363 cfg.physAddr = cfg1_dma_addr;
4364 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4366 mpt_config(hd->ioc, &cfg);
4372 /* Finish iocmd inititialization - hidden or visible disk? */
4373 if (ioc->raid_data.pIocPg3) {
4374 /* Search IOC page 3 for matching id
4376 Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
4377 int numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
4380 if (pPDisk->PhysDiskID == id) {
4382 iocmd.flags |= MPT_ICFLAG_PHYS_DISK;
4383 iocmd.physDiskNum = pPDisk->PhysDiskNum;
4387 if (mptscsih_do_raid(hd, MPI_RAID_ACTION_QUIESCE_PHYS_IO, &iocmd) < 0) {
4388 ddvprintk((MYIOC_s_ERR_FMT "RAID Queisce FAILED!\n", ioc->name));
4398 /* RAID Volume ID's may double for a physical device. If RAID but
4399 * not a physical ID as well, skip DV.
4401 if ((hd->ioc->raid_data.isRaid & (1 << id)) && !(iocmd.flags & MPT_ICFLAG_PHYS_DISK))
4406 * Async & Narrow - Inquiry
4407 * Async & Narrow - Inquiry
4408 * Maximum transfer rate - Inquiry
4410 * If compare, test complete.
4411 * If miscompare and first pass, repeat
4412 * If miscompare and not first pass, fall back and repeat
4416 sz = SCSI_MAX_INQUIRY_BYTES;
4417 rc = MPT_SCANDV_GOOD;
4419 ddvprintk((MYIOC_s_NOTE_FMT "DV: Start Basic test on id=%d\n", ioc->name, id));
4421 dv.cmd = MPT_SET_MIN;
4422 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
4424 cfg.cfghdr.hdr = &header1;
4425 cfg.physAddr = cfg1_dma_addr;
4426 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4428 if (mpt_config(hd->ioc, &cfg) != 0)
4431 /* Wide - narrow - wide workaround case
4433 if ((rc == MPT_SCANDV_ISSUE_SENSE) && dv.max.width) {
4434 /* Send an untagged command to reset disk Qs corrupted
4435 * when a parity error occurs on a Request Sense.
4437 if ((hd->ioc->facts.FWVersion.Word >= 0x01000600) ||
4438 ((hd->ioc->facts.FWVersion.Word >= 0x01010000) &&
4439 (hd->ioc->facts.FWVersion.Word < 0x01010B00)) ) {
4441 iocmd.cmd = REQUEST_SENSE;
4442 iocmd.data_dma = buf1_dma;
4445 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4448 if (hd->pLocal == NULL)
4450 rc = hd->pLocal->completion;
4451 if ((rc == MPT_SCANDV_GOOD) || (rc == MPT_SCANDV_SENSE)) {
4461 iocmd.cmd = INQUIRY;
4462 iocmd.data_dma = buf1_dma;
4465 memset(pbuf1, 0x00, sz);
4466 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4469 if (hd->pLocal == NULL)
4471 rc = hd->pLocal->completion;
4472 if (rc == MPT_SCANDV_GOOD) {
4473 if (hd->pLocal->scsiStatus == SAM_STAT_BUSY) {
4474 if ((iocmd.flags & MPT_ICFLAG_TAGGED_CMD) == 0)
4481 } else if (rc == MPT_SCANDV_SENSE) {
4484 /* If first command doesn't complete
4485 * with a good status or with a check condition,
4492 /* Reset the size for disks
4494 inq0 = (*pbuf1) & 0x1F;
4495 if ((inq0 == 0) && vtarget && !vtarget->raidVolume) {
4500 /* Another GEM workaround. Check peripheral device type,
4501 * if PROCESSOR, quit DV.
4503 if (inq0 == TYPE_PROCESSOR) {
4504 mptscsih_initTarget(hd,
4515 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4519 if ((vtarget->maxWidth == 1) && (vtarget->maxOffset) && (nfactor < 0x0A)
4520 && (vtarget->minSyncFactor > 0x09)) {
4521 if ((pbuf1[56] & 0x04) == 0)
4523 else if ((pbuf1[56] & 0x01) == 1) {
4524 vtarget->minSyncFactor =
4525 nfactor > MPT_ULTRA320 ? nfactor : MPT_ULTRA320;
4527 vtarget->minSyncFactor =
4528 nfactor > MPT_ULTRA160 ? nfactor : MPT_ULTRA160;
4531 dv.max.factor = vtarget->minSyncFactor;
4533 if ((pbuf1[56] & 0x02) == 0) {
4534 vtarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
4535 hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS;
4536 ddvprintk((MYIOC_s_NOTE_FMT
4537 "DV: Start Basic noQas on id=%d due to pbuf1[56]=%x\n",
4538 ioc->name, id, pbuf1[56]));
4544 dv.cmd = MPT_FALLBACK;
4546 dv.cmd = MPT_SET_MAX;
4548 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
4549 if (mpt_config(hd->ioc, &cfg) != 0)
4552 if ((!dv.now.width) && (!dv.now.offset))
4555 iocmd.cmd = INQUIRY;
4556 iocmd.data_dma = buf2_dma;
4559 memset(pbuf2, 0x00, sz);
4560 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4562 else if (hd->pLocal == NULL)
4565 /* Save the return code.
4566 * If this is the first pass,
4567 * read SCSI Device Page 0
4568 * and update the target max parameters.
4570 rc = hd->pLocal->completion;
4572 if (rc == MPT_SCANDV_GOOD) {
4577 cfg.cfghdr.hdr = &header0;
4578 cfg.physAddr = cfg0_dma_addr;
4579 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4582 if (mpt_config(hd->ioc, &cfg) != 0)
4585 sdp0_info = le32_to_cpu(pcfg0Data->Information) & 0x0E;
4586 sdp0_nego = (le32_to_cpu(pcfg0Data->NegotiatedParameters) & 0xFF00 ) >> 8;
4588 /* Quantum and Fujitsu workarounds.
4589 * Quantum: PPR U320 -> PPR reply with Ultra2 and wide
4590 * Fujitsu: PPR U320 -> Msg Reject and Ultra2 and wide
4591 * Resetart with a request for U160.
4593 if ((dv.now.factor == MPT_ULTRA320) && (sdp0_nego == MPT_ULTRA2)) {
4596 dv.cmd = MPT_UPDATE_MAX;
4597 mptscsih_dv_parms(hd, &dv, (void *)pcfg0Data);
4598 /* Update the SCSI device page 1 area
4600 pcfg1Data->RequestedParameters = pcfg0Data->NegotiatedParameters;
4605 /* Quantum workaround. Restart this test will the fallback
4608 if (doFallback == 0) {
4609 if (memcmp(pbuf1, pbuf2, sz) != 0) {
4613 ddvprintk((MYIOC_s_NOTE_FMT
4614 "DV:Inquiry compared id=%d, calling initTarget\n", ioc->name, id));
4615 hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_NOT_DONE;
4616 mptscsih_initTarget(hd,
4621 break; /* test complete */
4626 } else if (rc == MPT_SCANDV_ISSUE_SENSE)
4627 doFallback = 1; /* set fallback flag */
4628 else if ((rc == MPT_SCANDV_DID_RESET) ||
4629 (rc == MPT_SCANDV_SENSE) ||
4630 (rc == MPT_SCANDV_FALLBACK))
4631 doFallback = 1; /* set fallback flag */
4638 ddvprintk((MYIOC_s_NOTE_FMT "DV: Basic test on id=%d completed OK.\n", ioc->name, id));
4640 if (ioc->spi_data.mpt_dv == 0)
4643 inq0 = (*pbuf1) & 0x1F;
4645 /* Continue only for disks
4650 if ( ioc->spi_data.PortFlags == MPI_SCSIPORTPAGE2_PORT_FLAGS_BASIC_DV_ONLY )
4653 /* Start the Enhanced Test.
4654 * 0) issue TUR to clear out check conditions
4655 * 1) read capacity of echo (regular) buffer
4657 * 3) do write-read-compare data pattern test
4659 * 5) update nego parms to target struct
4661 cfg.cfghdr.hdr = &header1;
4662 cfg.physAddr = cfg1_dma_addr;
4663 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4666 iocmd.cmd = TEST_UNIT_READY;
4667 iocmd.data_dma = -1;
4672 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4675 if (hd->pLocal == NULL)
4678 rc = hd->pLocal->completion;
4679 if (rc == MPT_SCANDV_GOOD)
4681 else if (rc == MPT_SCANDV_SENSE) {
4682 u8 skey = hd->pLocal->sense[2] & 0x0F;
4683 u8 asc = hd->pLocal->sense[12];
4684 u8 ascq = hd->pLocal->sense[13];
4685 ddvprintk((MYIOC_s_INFO_FMT
4686 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
4687 ioc->name, skey, asc, ascq));
4689 if (skey == UNIT_ATTENTION)
4690 notDone++; /* repeat */
4691 else if ((skey == NOT_READY) &&
4692 (asc == 0x04)&&(ascq == 0x01)) {
4693 /* wait then repeat */
4696 } else if ((skey == NOT_READY) && (asc == 0x3A)) {
4697 /* no medium, try read test anyway */
4700 /* All other errors are fatal.
4702 ddvprintk((MYIOC_s_INFO_FMT "DV: fatal error.",
4710 iocmd.cmd = READ_BUFFER;
4711 iocmd.data_dma = buf1_dma;
4714 iocmd.flags |= MPT_ICFLAG_BUF_CAP;
4718 for (patt = 0; patt < 2; patt++) {
4720 iocmd.flags |= MPT_ICFLAG_ECHO;
4722 iocmd.flags &= ~MPT_ICFLAG_ECHO;
4728 /* If not ready after 8 trials,
4729 * give up on this device.
4734 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4736 else if (hd->pLocal == NULL)
4739 rc = hd->pLocal->completion;
4740 ddvprintk(("ReadBuffer Comp Code %d", rc));
4741 ddvprintk((" buff: %0x %0x %0x %0x\n",
4742 pbuf1[0], pbuf1[1], pbuf1[2], pbuf1[3]));
4744 if (rc == MPT_SCANDV_GOOD) {
4746 if (iocmd.flags & MPT_ICFLAG_ECHO) {
4747 bufsize = ((pbuf1[2] & 0x1F) <<8) | pbuf1[3];
4748 if (pbuf1[0] & 0x01)
4749 iocmd.flags |= MPT_ICFLAG_EBOS;
4751 bufsize = pbuf1[1]<<16 | pbuf1[2]<<8 | pbuf1[3];
4753 } else if (rc == MPT_SCANDV_SENSE) {
4754 u8 skey = hd->pLocal->sense[2] & 0x0F;
4755 u8 asc = hd->pLocal->sense[12];
4756 u8 ascq = hd->pLocal->sense[13];
4757 ddvprintk((MYIOC_s_INFO_FMT
4758 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
4759 ioc->name, skey, asc, ascq));
4760 if (skey == ILLEGAL_REQUEST) {
4762 } else if (skey == UNIT_ATTENTION) {
4763 notDone++; /* repeat */
4764 } else if ((skey == NOT_READY) &&
4765 (asc == 0x04)&&(ascq == 0x01)) {
4766 /* wait then repeat */
4770 /* All other errors are fatal.
4772 ddvprintk((MYIOC_s_INFO_FMT "DV: fatal error.",
4777 /* All other errors are fatal
4784 if (iocmd.flags & MPT_ICFLAG_ECHO)
4785 echoBufSize = bufsize;
4787 dataBufSize = bufsize;
4790 iocmd.flags &= ~MPT_ICFLAG_BUF_CAP;
4792 /* Use echo buffers if possible,
4793 * Exit if both buffers are 0.
4795 if (echoBufSize > 0) {
4796 iocmd.flags |= MPT_ICFLAG_ECHO;
4797 if (dataBufSize > 0)
4798 bufsize = min(echoBufSize, dataBufSize);
4800 bufsize = echoBufSize;
4801 } else if (dataBufSize == 0)
4804 ddvprintk((MYIOC_s_INFO_FMT "%s Buffer Capacity %d\n", ioc->name,
4805 (iocmd.flags & MPT_ICFLAG_ECHO) ? "Echo" : " ", bufsize));
4807 /* Data buffers for write-read-compare test max 1K.
4809 sz = min(bufsize, 1024);
4812 * On first pass, always issue a reserve.
4813 * On additional loops, only if a reset has occurred.
4814 * iocmd.flags indicates if echo or regular buffer
4816 for (patt = 0; patt < 4; patt++) {
4817 ddvprintk(("Pattern %d\n", patt));
4818 if ((iocmd.flags & MPT_ICFLAG_RESERVED) && (iocmd.flags & MPT_ICFLAG_DID_RESET)) {
4819 iocmd.cmd = TEST_UNIT_READY;
4820 iocmd.data_dma = -1;
4823 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4826 iocmd.cmd = RELEASE;
4827 iocmd.data_dma = -1;
4830 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4832 else if (hd->pLocal == NULL)
4835 rc = hd->pLocal->completion;
4836 ddvprintk(("Release rc %d\n", rc));
4837 if (rc == MPT_SCANDV_GOOD)
4838 iocmd.flags &= ~MPT_ICFLAG_RESERVED;
4842 iocmd.flags &= ~MPT_ICFLAG_RESERVED;
4844 iocmd.flags &= ~MPT_ICFLAG_DID_RESET;
4846 if (iocmd.flags & MPT_ICFLAG_EBOS)
4850 while (repeat && (!(iocmd.flags & MPT_ICFLAG_RESERVED))) {
4851 iocmd.cmd = RESERVE;
4852 iocmd.data_dma = -1;
4855 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4857 else if (hd->pLocal == NULL)
4860 rc = hd->pLocal->completion;
4861 if (rc == MPT_SCANDV_GOOD) {
4862 iocmd.flags |= MPT_ICFLAG_RESERVED;
4863 } else if (rc == MPT_SCANDV_SENSE) {
4864 /* Wait if coming ready
4866 u8 skey = hd->pLocal->sense[2] & 0x0F;
4867 u8 asc = hd->pLocal->sense[12];
4868 u8 ascq = hd->pLocal->sense[13];
4869 ddvprintk((MYIOC_s_INFO_FMT
4870 "DV: Reserve Failed: ", ioc->name));
4871 ddvprintk(("SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
4874 if ((skey == NOT_READY) && (asc == 0x04)&&
4876 /* wait then repeat */
4880 ddvprintk((MYIOC_s_INFO_FMT
4881 "DV: Reserved Failed.", ioc->name));
4885 ddvprintk((MYIOC_s_INFO_FMT "DV: Reserved Failed.",
4893 mptscsih_fillbuf(pbuf1, sz, patt, 1);
4894 iocmd.cmd = WRITE_BUFFER;
4895 iocmd.data_dma = buf1_dma;
4898 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4900 else if (hd->pLocal == NULL)
4903 rc = hd->pLocal->completion;
4904 if (rc == MPT_SCANDV_GOOD)
4905 ; /* Issue read buffer */
4906 else if (rc == MPT_SCANDV_DID_RESET) {
4907 /* If using echo buffers, reset to data buffers.
4908 * Else do Fallback and restart
4909 * this test (re-issue reserve
4910 * because of bus reset).
4912 if ((iocmd.flags & MPT_ICFLAG_ECHO) && (dataBufSize >= bufsize)) {
4913 iocmd.flags &= ~MPT_ICFLAG_ECHO;
4915 dv.cmd = MPT_FALLBACK;
4916 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
4918 if (mpt_config(hd->ioc, &cfg) != 0)
4921 if ((!dv.now.width) && (!dv.now.offset))
4925 iocmd.flags |= MPT_ICFLAG_DID_RESET;
4928 } else if (rc == MPT_SCANDV_SENSE) {
4929 /* Restart data test if UA, else quit.
4931 u8 skey = hd->pLocal->sense[2] & 0x0F;
4932 ddvprintk((MYIOC_s_INFO_FMT
4933 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n", ioc->name, skey,
4934 hd->pLocal->sense[12], hd->pLocal->sense[13]));
4935 if (skey == UNIT_ATTENTION) {
4938 } else if (skey == ILLEGAL_REQUEST) {
4939 if (iocmd.flags & MPT_ICFLAG_ECHO) {
4940 if (dataBufSize >= bufsize) {
4941 iocmd.flags &= ~MPT_ICFLAG_ECHO;
4956 iocmd.cmd = READ_BUFFER;
4957 iocmd.data_dma = buf2_dma;
4960 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4962 else if (hd->pLocal == NULL)
4965 rc = hd->pLocal->completion;
4966 if (rc == MPT_SCANDV_GOOD) {
4967 /* If buffers compare,
4968 * go to next pattern,
4969 * else, do a fallback and restart
4970 * data transfer test.
4972 if (memcmp (pbuf1, pbuf2, sz) == 0) {
4973 ; /* goto next pattern */
4975 /* Miscompare with Echo buffer, go to data buffer,
4976 * if that buffer exists.
4977 * Miscompare with Data buffer, check first 4 bytes,
4978 * some devices return capacity. Exit in this case.
4980 if (iocmd.flags & MPT_ICFLAG_ECHO) {
4981 if (dataBufSize >= bufsize)
4982 iocmd.flags &= ~MPT_ICFLAG_ECHO;
4986 if (dataBufSize == (pbuf2[1]<<16 | pbuf2[2]<<8 | pbuf2[3])) {
4987 /* Argh. Device returning wrong data.
4988 * Quit DV for this device.
4993 /* Had an actual miscompare. Slow down.*/
4994 dv.cmd = MPT_FALLBACK;
4995 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
4997 if (mpt_config(hd->ioc, &cfg) != 0)
5000 if ((!dv.now.width) && (!dv.now.offset))
5007 } else if (rc == MPT_SCANDV_DID_RESET) {
5008 /* Do Fallback and restart
5009 * this test (re-issue reserve
5010 * because of bus reset).
5012 dv.cmd = MPT_FALLBACK;
5013 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5015 if (mpt_config(hd->ioc, &cfg) != 0)
5018 if ((!dv.now.width) && (!dv.now.offset))
5021 iocmd.flags |= MPT_ICFLAG_DID_RESET;
5024 } else if (rc == MPT_SCANDV_SENSE) {
5025 /* Restart data test if UA, else quit.
5027 u8 skey = hd->pLocal->sense[2] & 0x0F;
5028 ddvprintk((MYIOC_s_INFO_FMT
5029 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n", ioc->name, skey,
5030 hd->pLocal->sense[12], hd->pLocal->sense[13]));
5031 if (skey == UNIT_ATTENTION) {
5043 } /* --- end of patt loop ---- */
5046 if (iocmd.flags & MPT_ICFLAG_RESERVED) {
5047 iocmd.cmd = RELEASE;
5048 iocmd.data_dma = -1;
5051 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5052 printk(MYIOC_s_INFO_FMT "DV: Release failed. id %d",
5054 else if (hd->pLocal) {
5055 if (hd->pLocal->completion == MPT_SCANDV_GOOD)
5056 iocmd.flags &= ~MPT_ICFLAG_RESERVED;
5058 printk(MYIOC_s_INFO_FMT "DV: Release failed. id %d",
5064 /* Set if cfg1_dma_addr contents is valid
5066 if ((cfg.cfghdr.hdr != NULL) && (retcode == 0)){
5067 /* If disk, not U320, disable QAS
5069 if ((inq0 == 0) && (dv.now.factor > MPT_ULTRA320)) {
5070 hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS;
5071 ddvprintk((MYIOC_s_NOTE_FMT
5072 "noQas set due to id=%d has factor=%x\n", ioc->name, id, dv.now.factor));
5076 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5078 /* Double writes to SDP1 can cause problems,
5079 * skip save of the final negotiated settings to
5080 * SCSI device page 1.
5082 cfg.cfghdr.hdr = &header1;
5083 cfg.physAddr = cfg1_dma_addr;
5084 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5086 mpt_config(hd->ioc, &cfg);
5090 /* If this is a RAID Passthrough, enable internal IOs
5092 if (iocmd.flags & MPT_ICFLAG_PHYS_DISK) {
5093 if (mptscsih_do_raid(hd, MPI_RAID_ACTION_ENABLE_PHYS_IO, &iocmd) < 0)
5094 ddvprintk((MYIOC_s_ERR_FMT "RAID Enable FAILED!\n", ioc->name));
5097 /* Done with the DV scan of the current target
5100 pci_free_consistent(ioc->pcidev, dv_alloc, pDvBuf, dvbuf_dma);
5102 ddvtprintk((MYIOC_s_INFO_FMT "DV Done id=%d\n",
5108 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5109 /* mptscsih_dv_parms - perform a variety of operations on the
5110 * parameters used for negotiation.
5111 * @hd: Pointer to a SCSI host.
5112 * @dv: Pointer to a structure that contains the maximum and current
5113 * negotiated parameters.
5116 mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
5118 VirtTarget *vtarget;
5119 SCSIDevicePage0_t *pPage0;
5120 SCSIDevicePage1_t *pPage1;
5121 int val = 0, data, configuration;
5130 case MPT_GET_NVRAM_VALS:
5131 ddvprintk((MYIOC_s_NOTE_FMT "Getting NVRAM: ",
5133 /* Get the NVRAM values and save in tmax
5134 * If not an LVD bus, the adapter minSyncFactor has been
5135 * already throttled back.
5137 negoFlags = hd->ioc->spi_data.noQas;
5138 if ((hd->Targets)&&((vtarget = hd->Targets[(int)id]) != NULL) && !vtarget->raidVolume) {
5139 width = vtarget->maxWidth;
5140 offset = vtarget->maxOffset;
5141 factor = vtarget->minSyncFactor;
5142 negoFlags |= vtarget->negoFlags;
5144 if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
5145 data = hd->ioc->spi_data.nvram[id];
5146 width = data & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
5147 if ((offset = hd->ioc->spi_data.maxSyncOffset) == 0)
5150 factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT;
5151 if ((factor == 0) || (factor == MPT_ASYNC)){
5162 /* Set the negotiation flags */
5164 negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
5167 negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
5170 /* limit by adapter capabilities */
5171 width = min(width, hd->ioc->spi_data.maxBusWidth);
5172 offset = min(offset, hd->ioc->spi_data.maxSyncOffset);
5173 factor = max(factor, hd->ioc->spi_data.minSyncFactor);
5175 /* Check Consistency */
5176 if (offset && (factor < MPT_ULTRA2) && !width)
5177 factor = MPT_ULTRA2;
5179 dv->max.width = width;
5180 dv->max.offset = offset;
5181 dv->max.factor = factor;
5182 dv->max.flags = negoFlags;
5183 ddvprintk((" id=%d width=%d factor=%x offset=%x flags=%x\n",
5184 id, width, factor, offset, negoFlags));
5187 case MPT_UPDATE_MAX:
5188 ddvprintk((MYIOC_s_NOTE_FMT
5189 "Updating with SDP0 Data: ", hd->ioc->name));
5190 /* Update tmax values with those from Device Page 0.*/
5191 pPage0 = (SCSIDevicePage0_t *) pPage;
5193 val = le32_to_cpu(pPage0->NegotiatedParameters);
5194 dv->max.width = val & MPI_SCSIDEVPAGE0_NP_WIDE ? 1 : 0;
5195 dv->max.offset = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK) >> 16;
5196 dv->max.factor = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK) >> 8;
5199 dv->now.width = dv->max.width;
5200 dv->now.offset = dv->max.offset;
5201 dv->now.factor = dv->max.factor;
5202 ddvprintk(("id=%d width=%d factor=%x offset=%x flags=%x\n",
5203 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags));
5207 ddvprintk((MYIOC_s_NOTE_FMT "Setting Max: ",
5209 /* Set current to the max values. Update the config page.*/
5210 dv->now.width = dv->max.width;
5211 dv->now.offset = dv->max.offset;
5212 dv->now.factor = dv->max.factor;
5213 dv->now.flags = dv->max.flags;
5215 pPage1 = (SCSIDevicePage1_t *)pPage;
5217 mptscsih_setDevicePage1Flags (dv->now.width, dv->now.factor,
5218 dv->now.offset, &val, &configuration, dv->now.flags);
5219 dnegoprintk(("Setting Max: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
5220 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags, val, configuration));
5221 pPage1->RequestedParameters = cpu_to_le32(val);
5222 pPage1->Reserved = 0;
5223 pPage1->Configuration = cpu_to_le32(configuration);
5226 ddvprintk(("id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x configuration=%x\n",
5227 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags, val, configuration));
5231 ddvprintk((MYIOC_s_NOTE_FMT "Setting Min: ",
5233 /* Set page to asynchronous and narrow
5234 * Do not update now, breaks fallback routine. */
5238 negoFlags = dv->max.flags;
5240 pPage1 = (SCSIDevicePage1_t *)pPage;
5242 mptscsih_setDevicePage1Flags (width, factor,
5243 offset, &val, &configuration, negoFlags);
5244 dnegoprintk(("Setting Min: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
5245 id, width, factor, offset, negoFlags, val, configuration));
5246 pPage1->RequestedParameters = cpu_to_le32(val);
5247 pPage1->Reserved = 0;
5248 pPage1->Configuration = cpu_to_le32(configuration);
5250 ddvprintk(("id=%d width=%d factor=%x offset=%x request=%x config=%x negoFlags=%x\n",
5251 id, width, factor, offset, val, configuration, negoFlags));
5255 ddvprintk((MYIOC_s_NOTE_FMT
5256 "Fallback: Start: offset %d, factor %x, width %d \n",
5257 hd->ioc->name, dv->now.offset,
5258 dv->now.factor, dv->now.width));
5259 width = dv->now.width;
5260 offset = dv->now.offset;
5261 factor = dv->now.factor;
5262 if ((offset) && (dv->max.width)) {
5263 if (factor < MPT_ULTRA160)
5264 factor = MPT_ULTRA160;
5265 else if (factor < MPT_ULTRA2) {
5266 factor = MPT_ULTRA2;
5268 } else if ((factor == MPT_ULTRA2) && width) {
5269 factor = MPT_ULTRA2;
5271 } else if (factor < MPT_ULTRA) {
5274 } else if ((factor == MPT_ULTRA) && width) {
5276 } else if (factor < MPT_FAST) {
5279 } else if ((factor == MPT_FAST) && width) {
5282 } else if (factor < MPT_SCSI) {
5285 } else if ((factor == MPT_SCSI) && width) {
5293 } else if (offset) {
5295 if (factor < MPT_ULTRA)
5297 else if (factor < MPT_FAST)
5299 else if (factor < MPT_SCSI)
5310 dv->max.flags |= MPT_TARGET_NO_NEGO_QAS;
5311 dv->max.flags &= ~MPT_TAPE_NEGO_IDP;
5313 dv->now.width = width;
5314 dv->now.offset = offset;
5315 dv->now.factor = factor;
5316 dv->now.flags = dv->max.flags;
5318 pPage1 = (SCSIDevicePage1_t *)pPage;
5320 mptscsih_setDevicePage1Flags (width, factor, offset, &val,
5321 &configuration, dv->now.flags);
5322 dnegoprintk(("Finish: id=%d width=%d offset=%d factor=%x negoFlags=%x request=%x config=%x\n",
5323 id, width, offset, factor, dv->now.flags, val, configuration));
5325 pPage1->RequestedParameters = cpu_to_le32(val);
5326 pPage1->Reserved = 0;
5327 pPage1->Configuration = cpu_to_le32(configuration);
5330 ddvprintk(("Finish: id=%d offset=%d factor=%x width=%d request=%x config=%x\n",
5331 id, dv->now.offset, dv->now.factor, dv->now.width, val, configuration));
5335 ddvprintk((MYIOC_s_NOTE_FMT
5336 "Saving to Target structure: ", hd->ioc->name));
5337 ddvprintk(("id=%d width=%x factor=%x offset=%d flags=%x\n",
5338 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags));
5340 /* Save these values to target structures
5341 * or overwrite nvram (phys disks only).
5344 if ((hd->Targets)&&((vtarget = hd->Targets[(int)id]) != NULL) && !vtarget->raidVolume ) {
5345 vtarget->maxWidth = dv->now.width;
5346 vtarget->maxOffset = dv->now.offset;
5347 vtarget->minSyncFactor = dv->now.factor;
5348 vtarget->negoFlags = dv->now.flags;
5350 /* Preserv all flags, use
5351 * read-modify-write algorithm
5353 if (hd->ioc->spi_data.nvram) {
5354 data = hd->ioc->spi_data.nvram[id];
5357 data &= ~MPT_NVRAM_WIDE_DISABLE;
5359 data |= MPT_NVRAM_WIDE_DISABLE;
5361 if (!dv->now.offset)
5364 data &= ~MPT_NVRAM_SYNC_MASK;
5365 data |= (dv->now.factor << MPT_NVRAM_SYNC_SHIFT) & MPT_NVRAM_SYNC_MASK;
5367 hd->ioc->spi_data.nvram[id] = data;
5374 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5375 /* mptscsih_fillbuf - fill a buffer with a special data pattern
5376 * cleanup. For bus scan only.
5378 * @buffer: Pointer to data buffer to be filled.
5379 * @size: Number of bytes to fill
5380 * @index: Pattern index
5381 * @width: bus width, 0 (8 bits) or 1 (16 bits)
5384 mptscsih_fillbuf(char *buffer, int size, int index, int width)
5395 /* Pattern: 0000 FFFF 0000 FFFF
5397 for (ii=0; ii < size; ii++, ptr++) {
5404 /* Pattern: 00 FF 00 FF
5406 for (ii=0; ii < size; ii++, ptr++) {
5417 /* Pattern: 5555 AAAA 5555 AAAA 5555
5419 for (ii=0; ii < size; ii++, ptr++) {
5426 /* Pattern: 55 AA 55 AA 55
5428 for (ii=0; ii < size; ii++, ptr++) {
5438 /* Pattern: 00 01 02 03 04 05
5441 for (ii=0; ii < size; ii++, ptr++)
5447 /* Wide Pattern: FFFE 0001 FFFD 0002
5448 * ... 4000 DFFF 8000 EFFF
5451 for (ii=0; ii < size/2; ii++) {
5452 /* Create the base pattern
5455 /* every 64 (0x40) bytes flip the pattern
5456 * since we fill 2 bytes / iteration,
5457 * test for ii = 0x20
5463 *ptr = (char)( (val & 0xFF00) >> 8);
5465 *ptr = (char)(val & 0xFF);
5470 *ptr = (char)( (val & 0xFF00) >> 8);
5472 *ptr = (char)(val & 0xFF);
5478 /* Narrow Pattern: FE 01 FD 02 FB 04
5479 * .. 7F 80 01 FE 02 FD ... 80 7F
5482 for (ii=0; ii < size; ii++, ptr++) {
5483 /* Base pattern - first 32 bytes
5490 *ptr = (char) (~(1 << byte));
5493 /* Flip the pattern every 32 bytes
5503 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5504 /* If DV disabled (negoNvram set to USE_NVARM) or if not LUN 0, return.
5505 * Else set the NEED_DV flag after Read Capacity Issued (disks)
5506 * or Mode Sense (cdroms).
5508 * Tapes, initTarget will set this flag on completion of Inquiry command.
5509 * Called only if DV_NOT_DONE flag is set
5512 mptscsih_set_dvflags(MPT_SCSI_HOST *hd, struct scsi_cmnd *sc)
5514 MPT_ADAPTER *ioc = hd->ioc;
5518 ddvtprintk((MYIOC_s_NOTE_FMT
5519 " set_dvflags: id=%d lun=%d negoNvram=%x cmd=%x\n",
5520 hd->ioc->name, sc->device->id, sc->device->lun , hd->negoNvram, sc->cmnd[0]));
5522 if ((sc->device->lun != 0) || (hd->negoNvram != 0))
5527 if ((cmd == READ_CAPACITY) || (cmd == MODE_SENSE)) {
5528 pSpi = &ioc->spi_data;
5529 if ((ioc->raid_data.isRaid & (1 << sc->device->id)) && ioc->raid_data.pIocPg3) {
5530 /* Set NEED_DV for all hidden disks
5532 Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
5533 int numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
5536 pSpi->dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV;
5537 ddvtprintk(("NEED_DV set for phys disk id %d\n", pPDisk->PhysDiskID));
5542 pSpi->dvStatus[sc->device->id] |= MPT_SCSICFG_NEED_DV;
5543 ddvtprintk(("NEED_DV set for visible disk id %d\n", sc->device->id));
5547 /* mptscsih_raid_set_dv_flags()
5549 * New or replaced disk. Set DV flag and schedule DV.
5552 mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id)
5554 MPT_ADAPTER *ioc = hd->ioc;
5555 SpiCfgData *pSpi = &ioc->spi_data;
5556 Ioc3PhysDisk_t *pPDisk;
5559 if (hd->negoNvram != 0)
5562 ddvtprintk(("DV requested for phys disk id %d\n", id));
5563 if (ioc->raid_data.pIocPg3) {
5564 pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
5565 numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
5567 if (id == pPDisk->PhysDiskNum) {
5568 pSpi->dvStatus[pPDisk->PhysDiskID] =
5569 (MPT_SCSICFG_NEED_DV | MPT_SCSICFG_DV_NOT_DONE);
5570 pSpi->forceDv = MPT_SCSICFG_NEED_DV;
5571 ddvtprintk(("NEED_DV set for phys disk id %d\n",
5572 pPDisk->PhysDiskID));
5579 if (numPDisk == 0) {
5580 /* The physical disk that needs DV was not found
5581 * in the stored IOC Page 3. The driver must reload
5582 * this page. DV routine will set the NEED_DV flag for
5583 * all phys disks that have DV_NOT_DONE set.
5585 pSpi->forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
5586 ddvtprintk(("phys disk %d not found. Setting reload IOC Pg3 Flag\n",id));
5590 #endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */
5592 EXPORT_SYMBOL(mptscsih_remove);
5593 EXPORT_SYMBOL(mptscsih_shutdown);
5595 EXPORT_SYMBOL(mptscsih_suspend);
5596 EXPORT_SYMBOL(mptscsih_resume);
5598 EXPORT_SYMBOL(mptscsih_proc_info);
5599 EXPORT_SYMBOL(mptscsih_info);
5600 EXPORT_SYMBOL(mptscsih_qcmd);
5601 EXPORT_SYMBOL(mptscsih_target_alloc);
5602 EXPORT_SYMBOL(mptscsih_slave_alloc);
5603 EXPORT_SYMBOL(mptscsih_target_destroy);
5604 EXPORT_SYMBOL(mptscsih_slave_destroy);
5605 EXPORT_SYMBOL(mptscsih_slave_configure);
5606 EXPORT_SYMBOL(mptscsih_abort);
5607 EXPORT_SYMBOL(mptscsih_dev_reset);
5608 EXPORT_SYMBOL(mptscsih_bus_reset);
5609 EXPORT_SYMBOL(mptscsih_host_reset);
5610 EXPORT_SYMBOL(mptscsih_bios_param);
5611 EXPORT_SYMBOL(mptscsih_io_done);
5612 EXPORT_SYMBOL(mptscsih_taskmgmt_complete);
5613 EXPORT_SYMBOL(mptscsih_scandv_complete);
5614 EXPORT_SYMBOL(mptscsih_event_process);
5615 EXPORT_SYMBOL(mptscsih_ioc_reset);
5616 EXPORT_SYMBOL(mptscsih_change_queue_depth);
5617 EXPORT_SYMBOL(mptscsih_timer_expired);
5618 EXPORT_SYMBOL(mptscsih_TMHandler);
5620 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/