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, VirtDevice *vdevice);
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;
563 u16 req_idx, req_idx_MR;
565 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
567 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
568 req_idx_MR = (mr != NULL) ?
569 le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx) : req_idx;
570 if ((req_idx != req_idx_MR) ||
571 (mf->u.frame.linkage.arg1 == 0xdeadbeaf)) {
572 printk(MYIOC_s_ERR_FMT "Received a mf that was already freed\n",
574 printk (MYIOC_s_ERR_FMT
575 "req_idx=%x req_idx_MR=%x mf=%p mr=%p sc=%p\n",
576 ioc->name, req_idx, req_idx_MR, mf, mr,
577 hd->ScsiLookup[req_idx_MR]);
581 sc = hd->ScsiLookup[req_idx];
583 MPIHeader_t *hdr = (MPIHeader_t *)mf;
585 /* Remark: writeSDP1 will use the ScsiDoneCtx
586 * If a SCSI I/O cmd, device disabled by OS and
587 * completion done. Cannot touch sc struct. Just free mem.
589 if (hdr->Function == MPI_FUNCTION_SCSI_IO_REQUEST)
590 printk(MYIOC_s_ERR_FMT "NULL ScsiCmd ptr!\n",
593 mptscsih_freeChainBuffers(ioc, req_idx);
597 sc->result = DID_OK << 16; /* Set default reply as OK */
598 pScsiReq = (SCSIIORequest_t *) mf;
599 pScsiReply = (SCSIIOReply_t *) mr;
601 if((ioc->facts.MsgVersion >= MPI_VERSION_01_05) && pScsiReply){
602 dmfprintk((MYIOC_s_INFO_FMT
603 "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d,task-tag=%d)\n",
604 ioc->name, mf, mr, sc, req_idx, pScsiReply->TaskTag));
606 dmfprintk((MYIOC_s_INFO_FMT
607 "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n",
608 ioc->name, mf, mr, sc, req_idx));
611 if (pScsiReply == NULL) {
612 /* special context reply handling */
617 u8 scsi_state, scsi_status;
619 status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK;
620 scsi_state = pScsiReply->SCSIState;
621 scsi_status = pScsiReply->SCSIStatus;
622 xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
623 sc->resid = sc->request_bufflen - xfer_cnt;
626 * if we get a data underrun indication, yet no data was
627 * transferred and the SCSI status indicates that the
628 * command was never started, change the data underrun
631 if (status == MPI_IOCSTATUS_SCSI_DATA_UNDERRUN && xfer_cnt == 0 &&
632 (scsi_status == MPI_SCSI_STATUS_BUSY ||
633 scsi_status == MPI_SCSI_STATUS_RESERVATION_CONFLICT ||
634 scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)) {
635 status = MPI_IOCSTATUS_SUCCESS;
638 dreplyprintk((KERN_NOTICE "Reply ha=%d id=%d lun=%d:\n"
639 "IOCStatus=%04xh SCSIState=%02xh SCSIStatus=%02xh\n"
640 "resid=%d bufflen=%d xfer_cnt=%d\n",
641 ioc->id, sc->device->id, sc->device->lun,
642 status, scsi_state, scsi_status, sc->resid,
643 sc->request_bufflen, xfer_cnt));
645 if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)
646 mptscsih_copy_sense_data(sc, hd, mf, pScsiReply);
649 * Look for + dump FCP ResponseInfo[]!
651 if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID &&
652 pScsiReply->ResponseInfo) {
653 printk(KERN_NOTICE "ha=%d id=%d lun=%d: "
654 "FCP_ResponseInfo=%08xh\n",
655 ioc->id, sc->device->id, sc->device->lun,
656 le32_to_cpu(pScsiReply->ResponseInfo));
660 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
662 * Maybe: DRIVER_BUSY | SUGGEST_RETRY | DID_SOFT_ERROR (retry)
663 * But not: DID_BUS_BUSY lest one risk
664 * killing interrupt handler:-(
666 sc->result = SAM_STAT_BUSY;
669 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
670 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
671 sc->result = DID_BAD_TARGET << 16;
674 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
675 /* Spoof to SCSI Selection Timeout! */
676 sc->result = DID_NO_CONNECT << 16;
678 if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF)
679 hd->sel_timeout[pScsiReq->TargetID]++;
682 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
683 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
684 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
685 /* Linux handles an unsolicited DID_RESET better
686 * than an unsolicited DID_ABORT.
688 sc->result = DID_RESET << 16;
690 /* GEM Workaround. */
691 if (ioc->bus_type == SPI)
692 mptscsih_no_negotiate(hd, sc);
695 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
696 sc->resid = sc->request_bufflen - xfer_cnt;
697 if((xfer_cnt==0)||(sc->underflow > xfer_cnt))
698 sc->result=DID_SOFT_ERROR << 16;
699 else /* Sufficient data transfer occurred */
700 sc->result = (DID_OK << 16) | scsi_status;
701 dreplyprintk((KERN_NOTICE
702 "RESIDUAL_MISMATCH: result=%x on id=%d\n", sc->result, sc->device->id));
705 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
707 * Do upfront check for valid SenseData and give it
710 sc->result = (DID_OK << 16) | scsi_status;
711 if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
712 /* Have already saved the status and sense data
716 if (xfer_cnt < sc->underflow) {
717 if (scsi_status == SAM_STAT_BUSY)
718 sc->result = SAM_STAT_BUSY;
720 sc->result = DID_SOFT_ERROR << 16;
722 if (scsi_state & (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)) {
725 sc->result = DID_SOFT_ERROR << 16;
727 else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
728 /* Not real sure here either... */
729 sc->result = DID_RESET << 16;
733 dreplyprintk((KERN_NOTICE " sc->underflow={report ERR if < %02xh bytes xfer'd}\n",
735 dreplyprintk((KERN_NOTICE " ActBytesXferd=%02xh\n", xfer_cnt));
738 if (scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)
739 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
743 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
745 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
746 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
747 if (scsi_status == MPI_SCSI_STATUS_BUSY)
748 sc->result = (DID_BUS_BUSY << 16) | scsi_status;
750 sc->result = (DID_OK << 16) | scsi_status;
751 if (scsi_state == 0) {
753 } else if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
755 * If running against circa 200003dd 909 MPT f/w,
756 * may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL
757 * (QUEUE_FULL) returned from device! --> get 0x0000?128
758 * and with SenseBytes set to 0.
760 if (pScsiReply->SCSIStatus == MPI_SCSI_STATUS_TASK_SET_FULL)
761 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
764 else if (scsi_state &
765 (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)
770 sc->result = DID_SOFT_ERROR << 16;
772 else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
773 /* Not real sure here either... */
774 sc->result = DID_RESET << 16;
776 else if (scsi_state & MPI_SCSI_STATE_QUEUE_TAG_REJECTED) {
777 /* Device Inq. data indicates that it supports
778 * QTags, but rejects QTag messages.
779 * This command completed OK.
781 * Not real sure here either so do nothing... */
784 if (sc->result == MPI_SCSI_STATUS_TASK_SET_FULL)
785 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
788 * Reservation Conflict, Busy,
789 * Command Terminated, CHECK
793 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
794 sc->result = DID_SOFT_ERROR << 16;
797 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
798 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
799 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
800 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
801 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
802 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
803 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
804 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
805 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
810 sc->result = DID_SOFT_ERROR << 16;
813 } /* switch(status) */
815 dreplyprintk((KERN_NOTICE " sc->result is %08xh\n", sc->result));
816 } /* end of address reply case */
818 /* Unmap the DMA buffers, if any. */
820 pci_unmap_sg(ioc->pcidev, (struct scatterlist *) sc->request_buffer,
821 sc->use_sg, sc->sc_data_direction);
822 } else if (sc->request_bufflen) {
823 pci_unmap_single(ioc->pcidev, sc->SCp.dma_handle,
824 sc->request_bufflen, sc->sc_data_direction);
827 hd->ScsiLookup[req_idx] = NULL;
829 sc->scsi_done(sc); /* Issue the command callback */
831 /* Free Chain buffers */
832 mptscsih_freeChainBuffers(ioc, req_idx);
837 * mptscsih_flush_running_cmds - For each command found, search
838 * Scsi_Host instance taskQ and reply to OS.
839 * Called only if recovering from a FW reload.
840 * @hd: Pointer to a SCSI HOST structure
844 * Must be called while new I/Os are being queued.
847 mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
849 MPT_ADAPTER *ioc = hd->ioc;
850 struct scsi_cmnd *SCpnt;
853 int max = ioc->req_depth;
855 dprintk((KERN_INFO MYNAM ": flush_ScsiLookup called\n"));
856 for (ii= 0; ii < max; ii++) {
857 if ((SCpnt = hd->ScsiLookup[ii]) != NULL) {
862 /* Null ScsiLookup index
864 hd->ScsiLookup[ii] = NULL;
866 mf = MPT_INDEX_2_MFPTR(ioc, ii);
867 dmfprintk(( "flush: ScsiDone (mf=%p,sc=%p)\n",
870 /* Set status, free OS resources (SG DMA buffers)
872 * Free driver resources (chain, msg buffers)
875 pci_unmap_sg(ioc->pcidev,
876 (struct scatterlist *) SCpnt->request_buffer,
878 SCpnt->sc_data_direction);
879 } else if (SCpnt->request_bufflen) {
880 pci_unmap_single(ioc->pcidev,
881 SCpnt->SCp.dma_handle,
882 SCpnt->request_bufflen,
883 SCpnt->sc_data_direction);
885 SCpnt->result = DID_RESET << 16;
886 SCpnt->host_scribble = NULL;
888 /* Free Chain buffers */
889 mptscsih_freeChainBuffers(ioc, ii);
891 /* Free Message frames */
892 mpt_free_msg_frame(ioc, mf);
894 SCpnt->scsi_done(SCpnt); /* Issue the command callback */
902 * mptscsih_search_running_cmds - Delete any commands associated
903 * with the specified target and lun. Function called only
904 * when a lun is disable by mid-layer.
905 * Do NOT access the referenced scsi_cmnd structure or
906 * members. Will cause either a paging or NULL ptr error.
907 * (BUT, BUT, BUT, the code does reference it! - mdr)
908 * @hd: Pointer to a SCSI HOST structure
909 * @vdevice: per device private data
913 * Called from slave_destroy.
916 mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
918 SCSIIORequest_t *mf = NULL;
920 int max = hd->ioc->req_depth;
921 struct scsi_cmnd *sc;
923 dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n",
924 vdevice->target_id, vdevice->lun, max));
926 for (ii=0; ii < max; ii++) {
927 if ((sc = hd->ScsiLookup[ii]) != NULL) {
929 mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii);
931 dsprintk(( "search_running: found (sc=%p, mf = %p) target %d, lun %d \n",
932 hd->ScsiLookup[ii], mf, mf->TargetID, mf->LUN[1]));
934 if ((mf->TargetID != ((u8)vdevice->target_id)) || (mf->LUN[1] != ((u8) vdevice->lun)))
939 hd->ScsiLookup[ii] = NULL;
940 mptscsih_freeChainBuffers(hd->ioc, ii);
941 mpt_free_msg_frame(hd->ioc, (MPT_FRAME_HDR *)mf);
943 pci_unmap_sg(hd->ioc->pcidev,
944 (struct scatterlist *) sc->request_buffer,
946 sc->sc_data_direction);
947 } else if (sc->request_bufflen) {
948 pci_unmap_single(hd->ioc->pcidev,
951 sc->sc_data_direction);
953 sc->host_scribble = NULL;
954 sc->result = DID_NO_CONNECT << 16;
961 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
963 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
965 * mptscsih_report_queue_full - Report QUEUE_FULL status returned
966 * from a SCSI target device.
967 * @sc: Pointer to scsi_cmnd structure
968 * @pScsiReply: Pointer to SCSIIOReply_t
969 * @pScsiReq: Pointer to original SCSI request
971 * This routine periodically reports QUEUE_FULL status returned from a
972 * SCSI target device. It reports this to the console via kernel
973 * printk() API call, not more than once every 10 seconds.
976 mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq)
981 if (sc->device == NULL)
983 if (sc->device->host == NULL)
985 if ((hd = (MPT_SCSI_HOST *)sc->device->host->hostdata) == NULL)
988 if (time - hd->last_queue_full > 10 * HZ) {
989 dprintk((MYIOC_s_WARN_FMT "Device (%d:%d:%d) reported QUEUE_FULL!\n",
990 hd->ioc->name, 0, sc->device->id, sc->device->lun));
991 hd->last_queue_full = time;
995 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
997 * mptscsih_remove - Removed scsi devices
998 * @pdev: Pointer to pci_dev structure
1003 mptscsih_remove(struct pci_dev *pdev)
1005 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1006 struct Scsi_Host *host = ioc->sh;
1008 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1010 unsigned long flags;
1019 scsi_remove_host(host);
1021 if((hd = (MPT_SCSI_HOST *)host->hostdata) == NULL)
1024 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1025 /* Check DV thread active */
1027 spin_lock_irqsave(&dvtaskQ_lock, flags);
1028 if (dvtaskQ_active) {
1029 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
1030 while(dvtaskQ_active && --count)
1031 schedule_timeout_interruptible(1);
1033 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
1036 printk(KERN_ERR MYNAM ": ERROR - DV thread still active!\n");
1037 #if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY)
1039 printk(KERN_ERR MYNAM ": DV thread orig %d, count %d\n", 10 * HZ, count);
1043 mptscsih_shutdown(pdev);
1047 if (hd->ScsiLookup != NULL) {
1048 sz1 = hd->ioc->req_depth * sizeof(void *);
1049 kfree(hd->ScsiLookup);
1050 hd->ScsiLookup = NULL;
1054 * Free pointer array.
1059 dprintk((MYIOC_s_INFO_FMT
1060 "Free'd ScsiLookup (%d) memory\n",
1061 hd->ioc->name, sz1));
1063 kfree(hd->info_kbuf);
1065 /* NULL the Scsi_Host pointer
1069 scsi_host_put(host);
1075 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1077 * mptscsih_shutdown - reboot notifier
1081 mptscsih_shutdown(struct pci_dev *pdev)
1083 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1084 struct Scsi_Host *host = ioc->sh;
1090 hd = (MPT_SCSI_HOST *)host->hostdata;
1095 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1097 * mptscsih_suspend - Fusion MPT scsi driver suspend routine.
1102 mptscsih_suspend(struct pci_dev *pdev, pm_message_t state)
1104 mptscsih_shutdown(pdev);
1105 return mpt_suspend(pdev,state);
1108 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1110 * mptscsih_resume - Fusion MPT scsi driver resume routine.
1115 mptscsih_resume(struct pci_dev *pdev)
1117 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1118 struct Scsi_Host *host = ioc->sh;
1126 hd = (MPT_SCSI_HOST *)host->hostdata;
1130 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1132 unsigned long lflags;
1133 spin_lock_irqsave(&dvtaskQ_lock, lflags);
1134 if (!dvtaskQ_active) {
1136 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1137 INIT_WORK(&dvTaskQ_task,
1138 mptscsih_domainValidation, (void *) hd);
1139 schedule_work(&dvTaskQ_task);
1141 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1150 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1152 * mptscsih_info - Return information about MPT adapter
1153 * @SChost: Pointer to Scsi_Host structure
1155 * (linux scsi_host_template.info routine)
1157 * Returns pointer to buffer where information was written.
1160 mptscsih_info(struct Scsi_Host *SChost)
1165 h = (MPT_SCSI_HOST *)SChost->hostdata;
1168 if (h->info_kbuf == NULL)
1169 if ((h->info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)
1170 return h->info_kbuf;
1171 h->info_kbuf[0] = '\0';
1173 mpt_print_ioc_summary(h->ioc, h->info_kbuf, &size, 0, 0);
1174 h->info_kbuf[size-1] = '\0';
1177 return h->info_kbuf;
1188 mptscsih_copy_mem_info(struct info_str *info, char *data, int len)
1190 if (info->pos + len > info->length)
1191 len = info->length - info->pos;
1193 if (info->pos + len < info->offset) {
1198 if (info->pos < info->offset) {
1199 data += (info->offset - info->pos);
1200 len -= (info->offset - info->pos);
1204 memcpy(info->buffer + info->pos, data, len);
1210 mptscsih_copy_info(struct info_str *info, char *fmt, ...)
1216 va_start(args, fmt);
1217 len = vsprintf(buf, fmt, args);
1220 mptscsih_copy_mem_info(info, buf, len);
1225 mptscsih_host_info(MPT_ADAPTER *ioc, char *pbuf, off_t offset, int len)
1227 struct info_str info;
1231 info.offset = offset;
1234 mptscsih_copy_info(&info, "%s: %s, ", ioc->name, ioc->prod_name);
1235 mptscsih_copy_info(&info, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING, ioc->facts.FWVersion.Word);
1236 mptscsih_copy_info(&info, "Ports=%d, ", ioc->facts.NumberOfPorts);
1237 mptscsih_copy_info(&info, "MaxQ=%d\n", ioc->req_depth);
1239 return ((info.pos > info.offset) ? info.pos - info.offset : 0);
1242 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1244 * mptscsih_proc_info - Return information about MPT adapter
1246 * (linux scsi_host_template.info routine)
1248 * buffer: if write, user data; if read, buffer for user
1249 * length: if write, return length;
1250 * offset: if write, 0; if read, the current offset into the buffer from
1251 * the previous read.
1252 * hostno: scsi host number
1253 * func: if write = 1; if read = 0
1256 mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
1257 int length, int func)
1259 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
1260 MPT_ADAPTER *ioc = hd->ioc;
1265 * write is not supported
1271 size = mptscsih_host_info(ioc, buffer, offset, length);
1277 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1278 #define ADD_INDEX_LOG(req_ent) do { } while(0)
1280 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1282 * mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine.
1283 * @SCpnt: Pointer to scsi_cmnd structure
1284 * @done: Pointer SCSI mid-layer IO completion function
1286 * (linux scsi_host_template.queuecommand routine)
1287 * This is the primary SCSI IO start routine. Create a MPI SCSIIORequest
1288 * from a linux scsi_cmnd request and send it to the IOC.
1290 * Returns 0. (rtn value discarded by linux scsi mid-layer)
1293 mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1297 SCSIIORequest_t *pScsiReq;
1298 VirtDevice *vdev = SCpnt->device->hostdata;
1307 hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata;
1308 lun = SCpnt->device->lun;
1309 SCpnt->scsi_done = done;
1311 dmfprintk((MYIOC_s_INFO_FMT "qcmd: SCpnt=%p, done()=%p\n",
1312 (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt, done));
1314 if (hd->resetPending) {
1315 dtmprintk((MYIOC_s_WARN_FMT "qcmd: SCpnt=%p timeout + 60HZ\n",
1316 (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt));
1317 return SCSI_MLQUEUE_HOST_BUSY;
1321 * Put together a MPT SCSI request...
1323 if ((mf = mpt_get_msg_frame(hd->ioc->DoneCtx, hd->ioc)) == NULL) {
1324 dprintk((MYIOC_s_WARN_FMT "QueueCmd, no msg frames!!\n",
1326 return SCSI_MLQUEUE_HOST_BUSY;
1329 pScsiReq = (SCSIIORequest_t *) mf;
1331 my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
1333 ADD_INDEX_LOG(my_idx);
1335 /* TUR's being issued with scsictl=0x02000000 (DATA_IN)!
1336 * Seems we may receive a buffer (datalen>0) even when there
1337 * will be no data transfer! GRRRRR...
1339 if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
1340 datalen = SCpnt->request_bufflen;
1341 scsidir = MPI_SCSIIO_CONTROL_READ; /* DATA IN (host<--ioc<--dev) */
1342 } else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
1343 datalen = SCpnt->request_bufflen;
1344 scsidir = MPI_SCSIIO_CONTROL_WRITE; /* DATA OUT (host-->ioc-->dev) */
1347 scsidir = MPI_SCSIIO_CONTROL_NODATATRANSFER;
1350 /* Default to untagged. Once a target structure has been allocated,
1351 * use the Inquiry data to determine if device supports tagged.
1354 && (vdev->vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)
1355 && (SCpnt->device->tagged_supported)) {
1356 scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
1358 scsictl = scsidir | MPI_SCSIIO_CONTROL_UNTAGGED;
1361 /* Use the above information to set up the message frame
1363 pScsiReq->TargetID = (u8) vdev->target_id;
1364 pScsiReq->Bus = vdev->bus_id;
1365 pScsiReq->ChainOffset = 0;
1366 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
1367 pScsiReq->CDBLength = SCpnt->cmd_len;
1368 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
1369 pScsiReq->Reserved = 0;
1370 pScsiReq->MsgFlags = mpt_msg_flags();
1371 pScsiReq->LUN[0] = 0;
1372 pScsiReq->LUN[1] = lun;
1373 pScsiReq->LUN[2] = 0;
1374 pScsiReq->LUN[3] = 0;
1375 pScsiReq->LUN[4] = 0;
1376 pScsiReq->LUN[5] = 0;
1377 pScsiReq->LUN[6] = 0;
1378 pScsiReq->LUN[7] = 0;
1379 pScsiReq->Control = cpu_to_le32(scsictl);
1382 * Write SCSI CDB into the message
1384 cmd_len = SCpnt->cmd_len;
1385 for (ii=0; ii < cmd_len; ii++)
1386 pScsiReq->CDB[ii] = SCpnt->cmnd[ii];
1388 for (ii=cmd_len; ii < 16; ii++)
1389 pScsiReq->CDB[ii] = 0;
1392 pScsiReq->DataLength = cpu_to_le32(datalen);
1394 /* SenseBuffer low address */
1395 pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
1396 + (my_idx * MPT_SENSE_BUFFER_ALLOC));
1398 /* Now add the SG list
1399 * Always have a SGE even if null length.
1402 /* Add a NULL SGE */
1403 mptscsih_add_sge((char *)&pScsiReq->SGL, MPT_SGE_FLAGS_SSIMPLE_READ | 0,
1406 /* Add a 32 or 64 bit SGE */
1407 if (mptscsih_AddSGE(hd->ioc, SCpnt, pScsiReq, my_idx) != SUCCESS)
1411 hd->ScsiLookup[my_idx] = SCpnt;
1412 SCpnt->host_scribble = NULL;
1414 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1415 if (hd->ioc->bus_type == SPI) {
1416 int dvStatus = hd->ioc->spi_data.dvStatus[vdev->target_id];
1419 if (dvStatus || hd->ioc->spi_data.forceDv) {
1421 if ((dvStatus & MPT_SCSICFG_NEED_DV) ||
1422 (hd->ioc->spi_data.forceDv & MPT_SCSICFG_NEED_DV)) {
1423 unsigned long lflags;
1424 /* Schedule DV if necessary */
1425 spin_lock_irqsave(&dvtaskQ_lock, lflags);
1426 if (!dvtaskQ_active) {
1428 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1429 INIT_WORK(&dvTaskQ_task, mptscsih_domainValidation, (void *) hd);
1431 schedule_work(&dvTaskQ_task);
1433 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1435 hd->ioc->spi_data.forceDv &= ~MPT_SCSICFG_NEED_DV;
1438 /* Trying to do DV to this target, extend timeout.
1439 * Wait to issue until flag is clear
1441 if (dvStatus & MPT_SCSICFG_DV_PENDING) {
1442 mod_timer(&SCpnt->eh_timeout, jiffies + 40 * HZ);
1446 /* Set the DV flags.
1448 if (dvStatus & MPT_SCSICFG_DV_NOT_DONE)
1449 mptscsih_set_dvflags(hd, SCpnt);
1457 mpt_put_msg_frame(hd->ioc->DoneCtx, hd->ioc, mf);
1458 dmfprintk((MYIOC_s_INFO_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n",
1459 hd->ioc->name, SCpnt, mf, my_idx));
1460 DBG_DUMP_REQUEST_FRAME(mf)
1464 hd->ScsiLookup[my_idx] = NULL;
1465 mptscsih_freeChainBuffers(hd->ioc, my_idx);
1466 mpt_free_msg_frame(hd->ioc, mf);
1467 return SCSI_MLQUEUE_HOST_BUSY;
1470 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1472 * mptscsih_freeChainBuffers - Function to free chain buffers associated
1473 * with a SCSI IO request
1474 * @hd: Pointer to the MPT_SCSI_HOST instance
1475 * @req_idx: Index of the SCSI IO request frame.
1477 * Called if SG chain buffer allocation fails and mptscsih callbacks.
1481 mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
1483 MPT_FRAME_HDR *chain;
1484 unsigned long flags;
1488 /* Get the first chain index and reset
1491 chain_idx = ioc->ReqToChain[req_idx];
1492 ioc->ReqToChain[req_idx] = MPT_HOST_NO_CHAIN;
1494 while (chain_idx != MPT_HOST_NO_CHAIN) {
1496 /* Save the next chain buffer index */
1497 next = ioc->ChainToChain[chain_idx];
1499 /* Free this chain buffer and reset
1502 ioc->ChainToChain[chain_idx] = MPT_HOST_NO_CHAIN;
1504 chain = (MPT_FRAME_HDR *) (ioc->ChainBuffer
1505 + (chain_idx * ioc->req_sz));
1507 spin_lock_irqsave(&ioc->FreeQlock, flags);
1508 list_add_tail(&chain->u.frame.linkage.list, &ioc->FreeChainQ);
1509 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1511 dmfprintk((MYIOC_s_INFO_FMT "FreeChainBuffers (index %d)\n",
1512 ioc->name, chain_idx));
1520 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1525 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1527 * mptscsih_TMHandler - Generic handler for SCSI Task Management.
1528 * Fall through to mpt_HardResetHandler if: not operational, too many
1529 * failed TM requests or handshake failure.
1531 * @ioc: Pointer to MPT_ADAPTER structure
1532 * @type: Task Management type
1533 * @target: Logical Target ID for reset (if appropriate)
1534 * @lun: Logical Unit for reset (if appropriate)
1535 * @ctx2abort: Context for the task to be aborted (if appropriate)
1537 * Remark: Currently invoked from a non-interrupt thread (_bh).
1539 * Remark: With old EH code, at most 1 SCSI TaskMgmt function per IOC
1542 * Returns 0 for SUCCESS or -1 if FAILED.
1545 mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout)
1551 unsigned long flags;
1553 /* If FW is being reloaded currently, return success to
1554 * the calling function.
1561 printk(KERN_ERR MYNAM " TMHandler" " NULL ioc!\n");
1564 dtmprintk((MYIOC_s_INFO_FMT "TMHandler Entered!\n", ioc->name));
1566 // SJR - CHECKME - Can we avoid this here?
1567 // (mpt_HardResetHandler has this check...)
1568 spin_lock_irqsave(&ioc->diagLock, flags);
1569 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)) {
1570 spin_unlock_irqrestore(&ioc->diagLock, flags);
1573 spin_unlock_irqrestore(&ioc->diagLock, flags);
1575 /* Wait a fixed amount of time for the TM pending flag to be cleared.
1576 * If we time out and not bus reset, then we return a FAILED status to the caller.
1577 * The call to mptscsih_tm_pending_wait() will set the pending flag if we are
1578 * successful. Otherwise, reload the FW.
1580 if (mptscsih_tm_pending_wait(hd) == FAILED) {
1581 if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
1582 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler abort: "
1583 "Timed out waiting for last TM (%d) to complete! \n",
1584 hd->ioc->name, hd->tmPending));
1586 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) {
1587 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler target reset: "
1588 "Timed out waiting for last TM (%d) to complete! \n",
1589 hd->ioc->name, hd->tmPending));
1591 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
1592 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler bus reset: "
1593 "Timed out waiting for last TM (%d) to complete! \n",
1594 hd->ioc->name, hd->tmPending));
1595 if (hd->tmPending & (1 << MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS))
1601 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
1602 hd->tmPending |= (1 << type);
1603 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1608 ioc_raw_state = mpt_GetIocState(hd->ioc, 0);
1610 #ifdef MPT_DEBUG_RESET
1611 if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) {
1612 printk(MYIOC_s_WARN_FMT
1613 "TM Handler: IOC Not operational(0x%x)!\n",
1614 hd->ioc->name, ioc_raw_state);
1618 if (doTask && ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL)
1619 && !(ioc_raw_state & MPI_DOORBELL_ACTIVE)) {
1621 /* Isse the Task Mgmt request.
1623 if (hd->hard_resets < -1)
1625 rc = mptscsih_IssueTaskMgmt(hd, type, channel, target, lun, ctx2abort, timeout);
1627 printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n", hd->ioc->name);
1629 dtmprintk((MYIOC_s_INFO_FMT "Issue of TaskMgmt Successful!\n", hd->ioc->name));
1633 /* Only fall through to the HRH if this is a bus reset
1635 if ((type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) && (rc ||
1636 ioc->reload_fw || (ioc->alt_ioc && ioc->alt_ioc->reload_fw))) {
1637 dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
1639 rc = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
1642 dtmprintk((MYIOC_s_INFO_FMT "TMHandler rc = %d!\n", hd->ioc->name, rc));
1648 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1650 * mptscsih_IssueTaskMgmt - Generic send Task Management function.
1651 * @hd: Pointer to MPT_SCSI_HOST structure
1652 * @type: Task Management type
1653 * @target: Logical Target ID for reset (if appropriate)
1654 * @lun: Logical Unit for reset (if appropriate)
1655 * @ctx2abort: Context for the task to be aborted (if appropriate)
1657 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
1658 * or a non-interrupt thread. In the former, must not call schedule().
1660 * Not all fields are meaningfull for all task types.
1662 * Returns 0 for SUCCESS, -999 for "no msg frames",
1663 * else other non-zero value returned.
1666 mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout)
1669 SCSITaskMgmt_t *pScsiTm;
1673 /* Return Fail to calling function if no message frames available.
1675 if ((mf = mpt_get_msg_frame(hd->ioc->TaskCtx, hd->ioc)) == NULL) {
1676 dfailprintk((MYIOC_s_ERR_FMT "IssueTaskMgmt, no msg frames!!\n",
1680 dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt request @ %p\n",
1681 hd->ioc->name, mf));
1683 /* Format the Request
1685 pScsiTm = (SCSITaskMgmt_t *) mf;
1686 pScsiTm->TargetID = target;
1687 pScsiTm->Bus = channel;
1688 pScsiTm->ChainOffset = 0;
1689 pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
1691 pScsiTm->Reserved = 0;
1692 pScsiTm->TaskType = type;
1693 pScsiTm->Reserved1 = 0;
1694 pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)
1695 ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0;
1697 for (ii= 0; ii < 8; ii++) {
1698 pScsiTm->LUN[ii] = 0;
1700 pScsiTm->LUN[1] = lun;
1702 for (ii=0; ii < 7; ii++)
1703 pScsiTm->Reserved2[ii] = 0;
1705 pScsiTm->TaskMsgContext = ctx2abort;
1707 dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt: ctx2abort (0x%08x) type=%d\n",
1708 hd->ioc->name, ctx2abort, type));
1710 DBG_DUMP_TM_REQUEST_FRAME((u32 *)pScsiTm);
1712 if ((retval = mpt_send_handshake_request(hd->ioc->TaskCtx, hd->ioc,
1713 sizeof(SCSITaskMgmt_t), (u32*)pScsiTm,
1715 dfailprintk((MYIOC_s_ERR_FMT "_send_handshake FAILED!"
1716 " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
1718 mpt_free_msg_frame(hd->ioc, mf);
1722 if(mptscsih_tm_wait_for_completion(hd, timeout) == FAILED) {
1723 dfailprintk((MYIOC_s_ERR_FMT "_wait_for_completion FAILED!"
1724 " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
1726 mpt_free_msg_frame(hd->ioc, mf);
1727 dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
1729 retval = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
1736 mptscsih_get_tm_timeout(MPT_ADAPTER *ioc)
1738 switch (ioc->bus_type) {
1749 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1751 * mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant
1752 * @SCpnt: Pointer to scsi_cmnd structure, IO to be aborted
1754 * (linux scsi_host_template.eh_abort_handler routine)
1756 * Returns SUCCESS or FAILED.
1759 mptscsih_abort(struct scsi_cmnd * SCpnt)
1769 /* If we can't locate our host adapter structure, return FAILED status.
1771 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL) {
1772 SCpnt->result = DID_RESET << 16;
1773 SCpnt->scsi_done(SCpnt);
1774 dfailprintk((KERN_INFO MYNAM ": mptscsih_abort: "
1775 "Can't locate host! (sc=%p)\n",
1781 if (hd->resetPending) {
1785 if (hd->timeouts < -1)
1788 /* Find this command
1790 if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) {
1791 /* Cmd not found in ScsiLookup.
1794 SCpnt->result = DID_RESET << 16;
1795 dtmprintk((KERN_INFO MYNAM ": %s: mptscsih_abort: "
1796 "Command not in the active list! (sc=%p)\n",
1797 hd->ioc->name, SCpnt));
1801 printk(KERN_WARNING MYNAM ": %s: attempting task abort! (sc=%p)\n",
1802 hd->ioc->name, SCpnt);
1803 scsi_print_command(SCpnt);
1805 /* Most important! Set TaskMsgContext to SCpnt's MsgContext!
1806 * (the IO to be ABORT'd)
1808 * NOTE: Since we do not byteswap MsgContext, we do not
1809 * swap it here either. It is an opaque cookie to
1810 * the controller, so it does not matter. -DaveM
1812 mf = MPT_INDEX_2_MFPTR(hd->ioc, scpnt_idx);
1813 ctx2abort = mf->u.frame.hwhdr.msgctxu.MsgContext;
1815 hd->abortSCpnt = SCpnt;
1817 vdev = SCpnt->device->hostdata;
1818 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
1819 vdev->bus_id, vdev->target_id, vdev->lun,
1820 ctx2abort, mptscsih_get_tm_timeout(ioc));
1822 printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n",
1824 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1829 if(retval != FAILED ) {
1831 hd->tmState = TM_STATE_NONE;
1836 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1838 * mptscsih_dev_reset - Perform a SCSI TARGET_RESET! new_eh variant
1839 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1841 * (linux scsi_host_template.eh_dev_reset_handler routine)
1843 * Returns SUCCESS or FAILED.
1846 mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
1852 /* If we can't locate our host adapter structure, return FAILED status.
1854 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1855 dtmprintk((KERN_INFO MYNAM ": mptscsih_dev_reset: "
1856 "Can't locate host! (sc=%p)\n",
1861 if (hd->resetPending)
1864 printk(KERN_WARNING MYNAM ": %s: attempting target reset! (sc=%p)\n",
1865 hd->ioc->name, SCpnt);
1866 scsi_print_command(SCpnt);
1868 vdev = SCpnt->device->hostdata;
1869 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
1870 vdev->bus_id, vdev->target_id,
1871 0, 0, mptscsih_get_tm_timeout(hd->ioc));
1873 printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n",
1875 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1880 if(retval != FAILED ) {
1882 hd->tmState = TM_STATE_NONE;
1887 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1889 * mptscsih_bus_reset - Perform a SCSI BUS_RESET! new_eh variant
1890 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1892 * (linux scsi_host_template.eh_bus_reset_handler routine)
1894 * Returns SUCCESS or FAILED.
1897 mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
1903 /* If we can't locate our host adapter structure, return FAILED status.
1905 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1906 dtmprintk((KERN_INFO MYNAM ": mptscsih_bus_reset: "
1907 "Can't locate host! (sc=%p)\n",
1912 printk(KERN_WARNING MYNAM ": %s: attempting bus reset! (sc=%p)\n",
1913 hd->ioc->name, SCpnt);
1914 scsi_print_command(SCpnt);
1916 if (hd->timeouts < -1)
1919 vdev = SCpnt->device->hostdata;
1920 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
1921 vdev->bus_id, 0, 0, 0, mptscsih_get_tm_timeout(hd->ioc));
1923 printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n",
1925 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1930 if(retval != FAILED ) {
1932 hd->tmState = TM_STATE_NONE;
1937 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1939 * mptscsih_host_reset - Perform a SCSI host adapter RESET!
1941 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1943 * (linux scsi_host_template.eh_host_reset_handler routine)
1945 * Returns SUCCESS or FAILED.
1948 mptscsih_host_reset(struct scsi_cmnd *SCpnt)
1951 int status = SUCCESS;
1953 /* If we can't locate the host to reset, then we failed. */
1954 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1955 dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
1956 "Can't locate host! (sc=%p)\n",
1961 printk(KERN_WARNING MYNAM ": %s: Attempting host reset! (sc=%p)\n",
1962 hd->ioc->name, SCpnt);
1964 /* If our attempts to reset the host failed, then return a failed
1965 * status. The host will be taken off line by the SCSI mid-layer.
1967 if (mpt_HardResetHandler(hd->ioc, CAN_SLEEP) < 0){
1970 /* Make sure TM pending is cleared and TM state is set to
1974 hd->tmState = TM_STATE_NONE;
1977 dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
1979 (status == SUCCESS) ? "SUCCESS" : "FAILED" ) );
1984 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1986 * mptscsih_tm_pending_wait - wait for pending task management request to
1988 * @hd: Pointer to MPT host structure.
1990 * Returns {SUCCESS,FAILED}.
1993 mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd)
1995 unsigned long flags;
1996 int loop_count = 4 * 10; /* Wait 10 seconds */
1997 int status = FAILED;
2000 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
2001 if (hd->tmState == TM_STATE_NONE) {
2002 hd->tmState = TM_STATE_IN_PROGRESS;
2004 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2008 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2010 } while (--loop_count);
2015 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2017 * mptscsih_tm_wait_for_completion - wait for completion of TM task
2018 * @hd: Pointer to MPT host structure.
2020 * Returns {SUCCESS,FAILED}.
2023 mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout )
2025 unsigned long flags;
2026 int loop_count = 4 * timeout;
2027 int status = FAILED;
2030 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
2031 if(hd->tmPending == 0) {
2033 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2036 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2037 msleep_interruptible(250);
2038 } while (--loop_count);
2043 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2045 mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code)
2049 switch (response_code) {
2050 case MPI_SCSITASKMGMT_RSP_TM_COMPLETE:
2051 desc = "The task completed.";
2053 case MPI_SCSITASKMGMT_RSP_INVALID_FRAME:
2054 desc = "The IOC received an invalid frame status.";
2056 case MPI_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED:
2057 desc = "The task type is not supported.";
2059 case MPI_SCSITASKMGMT_RSP_TM_FAILED:
2060 desc = "The requested task failed.";
2062 case MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED:
2063 desc = "The task completed successfully.";
2065 case MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN:
2066 desc = "The LUN request is invalid.";
2068 case MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC:
2069 desc = "The task is in the IOC queue and has not been sent to target.";
2075 printk(MYIOC_s_INFO_FMT "Response Code(0x%08x): F/W: %s\n",
2076 ioc->name, response_code, desc);
2079 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2081 * mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
2082 * @ioc: Pointer to MPT_ADAPTER structure
2083 * @mf: Pointer to SCSI task mgmt request frame
2084 * @mr: Pointer to SCSI task mgmt reply frame
2086 * This routine is called from mptbase.c::mpt_interrupt() at the completion
2087 * of any SCSI task management request.
2088 * This routine is registered with the MPT (base) driver at driver
2089 * load/init time via the mpt_register() API call.
2091 * Returns 1 indicating alloc'd request frame ptr should be freed.
2094 mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
2096 SCSITaskMgmtReply_t *pScsiTmReply;
2097 SCSITaskMgmt_t *pScsiTmReq;
2099 unsigned long flags;
2103 dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt completed (mf=%p,mr=%p)\n",
2104 ioc->name, mf, mr));
2106 /* Depending on the thread, a timer is activated for
2107 * the TM request. Delete this timer on completion of TM.
2108 * Decrement count of outstanding TM requests.
2110 hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
2112 dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt Complete: NULL Scsi Host Ptr\n",
2118 dtmprintk((MYIOC_s_WARN_FMT "ERROR! TaskMgmt Reply: NULL Request %p\n",
2122 pScsiTmReply = (SCSITaskMgmtReply_t*)mr;
2123 pScsiTmReq = (SCSITaskMgmt_t*)mf;
2125 /* Figure out if this was ABORT_TASK, TARGET_RESET, or BUS_RESET! */
2126 tmType = pScsiTmReq->TaskType;
2128 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05 &&
2129 pScsiTmReply->ResponseCode)
2130 mptscsih_taskmgmt_response_code(ioc,
2131 pScsiTmReply->ResponseCode);
2133 dtmprintk((MYIOC_s_WARN_FMT " TaskType = %d, TerminationCount=%d\n",
2134 ioc->name, tmType, le32_to_cpu(pScsiTmReply->TerminationCount)));
2135 DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply);
2137 iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2138 dtmprintk((MYIOC_s_WARN_FMT " SCSI TaskMgmt (%d) IOCStatus=%04x IOCLogInfo=%08x\n",
2139 ioc->name, tmType, iocstatus, le32_to_cpu(pScsiTmReply->IOCLogInfo)));
2140 /* Error? (anything non-zero?) */
2143 /* clear flags and continue.
2145 if (tmType == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK)
2146 hd->abortSCpnt = NULL;
2148 /* If an internal command is present
2149 * or the TM failed - reload the FW.
2150 * FC FW may respond FAILED to an ABORT
2152 if (tmType == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
2154 (iocstatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED)) {
2155 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0) {
2156 printk((KERN_WARNING
2157 " Firmware Reload FAILED!!\n"));
2162 dtmprintk((MYIOC_s_WARN_FMT " TaskMgmt SUCCESS\n", ioc->name));
2164 hd->abortSCpnt = NULL;
2169 spin_lock_irqsave(&ioc->FreeQlock, flags);
2171 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2172 hd->tmState = TM_STATE_NONE;
2177 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2179 * This is anyones guess quite frankly.
2182 mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
2183 sector_t capacity, int geom[])
2193 dummy = heads * sectors;
2194 cylinders = capacity;
2195 sector_div(cylinders,dummy);
2198 * Handle extended translation size for logical drives
2201 if ((ulong)capacity >= 0x200000) {
2204 dummy = heads * sectors;
2205 cylinders = capacity;
2206 sector_div(cylinders,dummy);
2212 geom[2] = cylinders;
2214 dprintk((KERN_NOTICE
2215 ": bios_param: Id=%i Lun=%i Channel=%i CHS=%i/%i/%i\n",
2216 sdev->id, sdev->lun,sdev->channel,(int)cylinders,heads,sectors));
2221 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2223 * OS entry point to allow host driver to alloc memory
2224 * for each scsi target. Called once per device the bus scan.
2225 * Return non-zero if allocation fails.
2228 mptscsih_target_alloc(struct scsi_target *starget)
2230 VirtTarget *vtarget;
2232 vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
2235 starget->hostdata = vtarget;
2239 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2241 * OS entry point to allow host driver to alloc memory
2242 * for each scsi device. Called once per device the bus scan.
2243 * Return non-zero if allocation fails.
2246 mptscsih_slave_alloc(struct scsi_device *sdev)
2248 struct Scsi_Host *host = sdev->host;
2249 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
2250 VirtTarget *vtarget;
2252 struct scsi_target *starget;
2254 vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
2256 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
2257 hd->ioc->name, sizeof(VirtDevice));
2261 vdev->ioc_id = hd->ioc->id;
2262 vdev->target_id = sdev->id;
2263 vdev->bus_id = sdev->channel;
2264 vdev->lun = sdev->lun;
2265 sdev->hostdata = vdev;
2267 starget = scsi_target(sdev);
2268 vtarget = starget->hostdata;
2269 vdev->vtarget = vtarget;
2271 if (vtarget->num_luns == 0) {
2272 hd->Targets[sdev->id] = vtarget;
2273 vtarget->ioc_id = hd->ioc->id;
2274 vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
2275 vtarget->target_id = sdev->id;
2276 vtarget->bus_id = sdev->channel;
2277 if (hd->ioc->bus_type == SPI) {
2278 if (hd->ioc->raid_data.isRaid & (1 << sdev->id)) {
2279 vtarget->raidVolume = 1;
2280 ddvtprintk((KERN_INFO
2281 "RAID Volume @ id %d\n", sdev->id));
2284 vtarget->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
2287 vtarget->num_luns++;
2292 * OS entry point to allow for host driver to free allocated memory
2293 * Called if no device present or device being unloaded
2296 mptscsih_target_destroy(struct scsi_target *starget)
2298 if (starget->hostdata)
2299 kfree(starget->hostdata);
2300 starget->hostdata = NULL;
2304 * OS entry point to allow for host driver to free allocated memory
2305 * Called if no device present or device being unloaded
2308 mptscsih_slave_destroy(struct scsi_device *sdev)
2310 struct Scsi_Host *host = sdev->host;
2311 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
2312 VirtTarget *vtarget;
2313 VirtDevice *vdevice;
2314 struct scsi_target *starget;
2316 starget = scsi_target(sdev);
2317 vtarget = starget->hostdata;
2318 vdevice = sdev->hostdata;
2320 mptscsih_search_running_cmds(hd, vdevice);
2321 vtarget->luns[0] &= ~(1 << vdevice->lun);
2322 vtarget->num_luns--;
2323 if (vtarget->num_luns == 0) {
2324 mptscsih_negotiate_to_asyn_narrow(hd, vdevice);
2325 if (hd->ioc->bus_type == SPI) {
2326 if (mptscsih_is_phys_disk(hd->ioc, vtarget->target_id)) {
2327 hd->ioc->spi_data.forceDv |= MPT_SCSICFG_RELOAD_IOC_PG3;
2329 hd->ioc->spi_data.dvStatus[vtarget->target_id] =
2330 MPT_SCSICFG_NEGOTIATE;
2331 if (!hd->negoNvram) {
2332 hd->ioc->spi_data.dvStatus[vtarget->target_id] |=
2333 MPT_SCSICFG_DV_NOT_DONE;
2337 hd->Targets[sdev->id] = NULL;
2339 mptscsih_synchronize_cache(hd, vdevice);
2341 sdev->hostdata = NULL;
2344 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2346 * mptscsih_change_queue_depth - This function will set a devices queue depth
2347 * @sdev: per scsi_device pointer
2348 * @qdepth: requested queue depth
2350 * Adding support for new 'change_queue_depth' api.
2353 mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
2355 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sdev->host->hostdata;
2356 VirtTarget *vtarget;
2357 struct scsi_target *starget;
2361 starget = scsi_target(sdev);
2362 vtarget = starget->hostdata;
2364 if (hd->ioc->bus_type == SPI) {
2365 if (vtarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) {
2366 if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
2368 else if (((vtarget->inq_data[0] & 0x1f) == 0x00) &&
2369 (vtarget->minSyncFactor <= MPT_ULTRA160 ))
2370 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2372 max_depth = MPT_SCSI_CMD_PER_DEV_LOW;
2374 /* error case - No Inq. Data */
2378 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2380 if (qdepth > max_depth)
2385 tagged = MSG_SIMPLE_TAG;
2387 scsi_adjust_queue_depth(sdev, tagged, qdepth);
2388 return sdev->queue_depth;
2392 * OS entry point to adjust the queue_depths on a per-device basis.
2393 * Called once per device the bus scan. Use it to force the queue_depth
2394 * member to 1 if a device does not support Q tags.
2395 * Return non-zero if fails.
2398 mptscsih_slave_configure(struct scsi_device *sdev)
2400 struct Scsi_Host *sh = sdev->host;
2401 VirtTarget *vtarget;
2402 VirtDevice *vdevice;
2403 struct scsi_target *starget;
2404 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sh->hostdata;
2405 int indexed_lun, lun_index;
2407 starget = scsi_target(sdev);
2408 vtarget = starget->hostdata;
2409 vdevice = sdev->hostdata;
2411 dsprintk((MYIOC_s_INFO_FMT
2412 "device @ %p, id=%d, LUN=%d, channel=%d\n",
2413 hd->ioc->name, sdev, sdev->id, sdev->lun, sdev->channel));
2414 if (hd->ioc->bus_type == SPI)
2415 dsprintk((MYIOC_s_INFO_FMT
2416 "sdtr %d wdtr %d ppr %d inq length=%d\n",
2417 hd->ioc->name, sdev->sdtr, sdev->wdtr,
2418 sdev->ppr, sdev->inquiry_len));
2420 if (sdev->id > sh->max_id) {
2421 /* error case, should never happen */
2422 scsi_adjust_queue_depth(sdev, 0, 1);
2423 goto slave_configure_exit;
2426 vdevice->configured_lun=1;
2427 lun_index = (vdevice->lun >> 5); /* 32 luns per lun_index */
2428 indexed_lun = (vdevice->lun % 32);
2429 vtarget->luns[lun_index] |= (1 << indexed_lun);
2430 mptscsih_initTarget(hd, vtarget, sdev->lun, sdev->inquiry,
2431 sdev->inquiry_len );
2432 mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH);
2434 dsprintk((MYIOC_s_INFO_FMT
2435 "Queue depth=%d, tflags=%x\n",
2436 hd->ioc->name, sdev->queue_depth, vtarget->tflags));
2438 if (hd->ioc->bus_type == SPI)
2439 dsprintk((MYIOC_s_INFO_FMT
2440 "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
2441 hd->ioc->name, vtarget->negoFlags, vtarget->maxOffset,
2442 vtarget->minSyncFactor));
2444 slave_configure_exit:
2446 dsprintk((MYIOC_s_INFO_FMT
2447 "tagged %d, simple %d, ordered %d\n",
2448 hd->ioc->name,sdev->tagged_supported, sdev->simple_tags,
2449 sdev->ordered_tags));
2454 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2456 * Private routines...
2459 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2460 /* Utility function to copy sense data from the scsi_cmnd buffer
2461 * to the FC and SCSI target structures.
2465 mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
2468 SCSIIORequest_t *pReq;
2469 u32 sense_count = le32_to_cpu(pScsiReply->SenseCount);
2471 /* Get target structure
2473 pReq = (SCSIIORequest_t *) mf;
2474 vdev = sc->device->hostdata;
2480 /* Copy the sense received into the scsi command block. */
2481 req_index = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2482 sense_data = ((u8 *)hd->ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC));
2483 memcpy(sc->sense_buffer, sense_data, SNS_LEN(sc));
2485 /* Log SMART data (asc = 0x5D, non-IM case only) if required.
2487 if ((hd->ioc->events) && (hd->ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) {
2488 if ((sense_data[12] == 0x5D) && (vdev->vtarget->raidVolume == 0)) {
2490 MPT_ADAPTER *ioc = hd->ioc;
2492 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
2493 ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
2494 ioc->events[idx].eventContext = ioc->eventContext;
2496 ioc->events[idx].data[0] = (pReq->LUN[1] << 24) ||
2497 (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) ||
2498 (sc->device->channel << 8) || sc->device->id;
2500 ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12];
2502 ioc->eventContext++;
2506 dprintk((MYIOC_s_INFO_FMT "Hmmm... SenseData len=0! (?)\n",
2512 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc)
2517 hd = (MPT_SCSI_HOST *) sc->device->host->hostdata;
2519 for (i = 0; i < hd->ioc->req_depth; i++) {
2520 if (hd->ScsiLookup[i] == sc) {
2528 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2530 mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2533 unsigned long flags;
2536 dtmprintk((KERN_WARNING MYNAM
2537 ": IOC %s_reset routed to SCSI host driver!\n",
2538 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
2539 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
2541 /* If a FW reload request arrives after base installed but
2542 * before all scsi hosts have been attached, then an alt_ioc
2543 * may have a NULL sh pointer.
2545 if ((ioc->sh == NULL) || (ioc->sh->hostdata == NULL))
2548 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2550 if (reset_phase == MPT_IOC_SETUP_RESET) {
2551 dtmprintk((MYIOC_s_WARN_FMT "Setup-Diag Reset\n", ioc->name));
2554 * 1. Set Hard Reset Pending Flag
2555 * All new commands go to doneQ
2557 hd->resetPending = 1;
2559 } else if (reset_phase == MPT_IOC_PRE_RESET) {
2560 dtmprintk((MYIOC_s_WARN_FMT "Pre-Diag Reset\n", ioc->name));
2562 /* 2. Flush running commands
2563 * Clean ScsiLookup (and associated memory)
2567 /* 2b. Reply to OS all known outstanding I/O commands.
2569 mptscsih_flush_running_cmds(hd);
2571 /* 2c. If there was an internal command that
2572 * has not completed, configuration or io request,
2573 * free these resources.
2576 del_timer(&hd->timer);
2577 mpt_free_msg_frame(ioc, hd->cmdPtr);
2580 dtmprintk((MYIOC_s_WARN_FMT "Pre-Reset complete.\n", ioc->name));
2583 dtmprintk((MYIOC_s_WARN_FMT "Post-Diag Reset\n", ioc->name));
2585 /* Once a FW reload begins, all new OS commands are
2586 * redirected to the doneQ w/ a reset status.
2587 * Init all control structures.
2590 /* ScsiLookup initialization
2592 for (ii=0; ii < hd->ioc->req_depth; ii++)
2593 hd->ScsiLookup[ii] = NULL;
2595 /* 2. Chain Buffer initialization
2598 /* 4. Renegotiate to all devices, if SPI
2600 if (ioc->bus_type == SPI) {
2601 dnegoprintk(("writeSDP1: ALL_IDS USE_NVRAM\n"));
2602 mptscsih_writeSDP1(hd, 0, 0, MPT_SCSICFG_ALL_IDS | MPT_SCSICFG_USE_NVRAM);
2605 /* 5. Enable new commands to be posted
2607 spin_lock_irqsave(&ioc->FreeQlock, flags);
2609 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2610 hd->resetPending = 0;
2611 hd->tmState = TM_STATE_NONE;
2613 /* 6. If there was an internal command,
2614 * wake this process up.
2618 * Wake up the original calling thread
2620 hd->pLocal = &hd->localReply;
2621 hd->pLocal->completion = MPT_SCANDV_DID_RESET;
2622 hd->scandv_wait_done = 1;
2623 wake_up(&hd->scandv_waitq);
2627 /* 7. SPI: Set flag to force DV and re-read IOC Page 3
2629 if (ioc->bus_type == SPI) {
2630 ioc->spi_data.forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
2631 ddvtprintk(("Set reload IOC Pg3 Flag\n"));
2634 /* 7. FC: Rescan for blocked rports which might have returned.
2636 else if (ioc->bus_type == FC) {
2638 unsigned long flags;
2640 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
2641 work_count = ++ioc->fc_rescan_work_count;
2642 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
2643 if (work_count == 1)
2644 schedule_work(&ioc->fc_rescan_work);
2646 dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name));
2650 return 1; /* currently means nothing really */
2653 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2655 mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2658 u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
2660 unsigned long flags;
2662 devtprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
2665 if (ioc->sh == NULL ||
2666 ((hd = (MPT_SCSI_HOST *)ioc->sh->hostdata) == NULL))
2670 case MPI_EVENT_UNIT_ATTENTION: /* 03 */
2673 case MPI_EVENT_IOC_BUS_RESET: /* 04 */
2674 case MPI_EVENT_EXT_BUS_RESET: /* 05 */
2675 if (hd && (ioc->bus_type == SPI) && (hd->soft_resets < -1))
2678 case MPI_EVENT_LOGOUT: /* 09 */
2682 case MPI_EVENT_RESCAN: /* 06 */
2683 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
2684 work_count = ++ioc->fc_rescan_work_count;
2685 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
2686 if (work_count == 1)
2687 schedule_work(&ioc->fc_rescan_work);
2691 * CHECKME! Don't think we need to do
2692 * anything for these, but...
2694 case MPI_EVENT_LINK_STATUS_CHANGE: /* 07 */
2695 case MPI_EVENT_LOOP_STATE_CHANGE: /* 08 */
2697 * CHECKME! Falling thru...
2701 case MPI_EVENT_INTEGRATED_RAID: /* 0B */
2703 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
2704 pMpiEventDataRaid_t pRaidEventData =
2705 (pMpiEventDataRaid_t) pEvReply->Data;
2706 /* Domain Validation Needed */
2707 if (ioc->bus_type == SPI &&
2708 pRaidEventData->ReasonCode ==
2709 MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED)
2710 mptscsih_set_dvflags_raid(hd, pRaidEventData->PhysDiskNum);
2715 case MPI_EVENT_NONE: /* 00 */
2716 case MPI_EVENT_LOG_DATA: /* 01 */
2717 case MPI_EVENT_STATE_CHANGE: /* 02 */
2718 case MPI_EVENT_EVENT_CHANGE: /* 0A */
2720 dprintk((KERN_INFO " Ignoring event (=%02Xh)\n", event));
2724 return 1; /* currently means nothing really */
2727 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2729 * mptscsih_initTarget - Target, LUN alloc/free functionality.
2730 * @hd: Pointer to MPT_SCSI_HOST structure
2731 * @vtarget: per target private data
2733 * @data: Pointer to data
2734 * @dlen: Number of INQUIRY bytes
2736 * NOTE: It's only SAFE to call this routine if data points to
2737 * sane & valid STANDARD INQUIRY data!
2739 * Allocate and initialize memory for this target.
2740 * Save inquiry data.
2744 mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, u8 lun, char *data, int dlen)
2750 dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n",
2751 hd->ioc->name, vtarget->bus_id, vtarget->target_id, lun, hd));
2754 * If the peripheral qualifier filter is enabled then if the target reports a 0x1
2755 * (i.e. The targer is capable of supporting the specified peripheral device type
2756 * on this logical unit; however, the physical device is not currently connected
2757 * to this logical unit) it will be converted to a 0x3 (i.e. The target is not
2758 * capable of supporting a physical device on this logical unit). This is to work
2759 * around a bug in th emid-layer in some distributions in which the mid-layer will
2760 * continue to try to communicate to the LUN and evntually create a dummy LUN.
2762 if (hd->mpt_pq_filter && dlen && (data[0] & 0xE0))
2765 /* Is LUN supported? If so, upper 2 bits will be 0
2766 * in first byte of inquiry data.
2771 if (vtarget == NULL)
2775 vtarget->type = data[0];
2777 if (hd->ioc->bus_type != SPI)
2780 if ((data[0] == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) {
2781 /* Treat all Processors as SAF-TE if
2782 * command line option is set */
2783 vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
2784 mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id);
2785 }else if ((data[0] == TYPE_PROCESSOR) &&
2786 !(vtarget->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) {
2788 vtarget->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
2789 if ( data[44] == 'S' &&
2795 vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
2796 mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id);
2800 if (!(vtarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY)) {
2801 inq_len = dlen < 8 ? dlen : 8;
2802 memcpy (vtarget->inq_data, data, inq_len);
2803 /* If have not done DV, set the DV flag.
2805 pSpi = &hd->ioc->spi_data;
2806 if ((data[0] == TYPE_TAPE) || (data[0] == TYPE_PROCESSOR)) {
2807 if (pSpi->dvStatus[vtarget->target_id] & MPT_SCSICFG_DV_NOT_DONE)
2808 pSpi->dvStatus[vtarget->target_id] |= MPT_SCSICFG_NEED_DV;
2810 vtarget->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
2812 data_56 = 0x0F; /* Default to full capabilities if Inq data length is < 57 */
2814 if ( (!(vtarget->tflags & MPT_TARGET_FLAGS_VALID_56))) {
2815 /* Update the target capabilities
2818 vtarget->tflags |= MPT_TARGET_FLAGS_VALID_56;
2821 mptscsih_setTargetNegoParms(hd, vtarget, data_56);
2823 /* Initial Inquiry may not request enough data bytes to
2824 * obtain byte 57. DV will; if target doesn't return
2825 * at least 57 bytes, data[56] will be zero. */
2827 if ( (!(vtarget->tflags & MPT_TARGET_FLAGS_VALID_56))) {
2828 /* Update the target capabilities
2831 vtarget->tflags |= MPT_TARGET_FLAGS_VALID_56;
2832 mptscsih_setTargetNegoParms(hd, vtarget, data_56);
2838 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2840 * Update the target negotiation parameters based on the
2841 * the Inquiry data, adapter capabilities, and NVRAM settings.
2845 mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target, char byte56)
2847 SpiCfgData *pspi_data = &hd->ioc->spi_data;
2848 int id = (int) target->target_id;
2850 VirtTarget *vtarget;
2852 u8 width = MPT_NARROW;
2853 u8 factor = MPT_ASYNC;
2855 u8 version, nfactor;
2858 target->negoFlags = pspi_data->noQas;
2860 /* noQas == 0 => device supports QAS. Need byte 56 of Inq to determine
2861 * support. If available, default QAS to off and allow enabling.
2862 * If not available, default QAS to on, turn off for non-disks.
2865 /* Set flags based on Inquiry data
2867 version = target->inq_data[2] & 0x07;
2870 factor = MPT_ULTRA2;
2871 offset = pspi_data->maxSyncOffset;
2872 target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
2874 if (target->inq_data[7] & 0x20) {
2878 if (target->inq_data[7] & 0x10) {
2879 factor = pspi_data->minSyncFactor;
2880 if (target->tflags & MPT_TARGET_FLAGS_VALID_56) {
2881 /* bits 2 & 3 show Clocking support */
2882 if ((byte56 & 0x0C) == 0)
2883 factor = MPT_ULTRA2;
2885 if ((byte56 & 0x03) == 0)
2886 factor = MPT_ULTRA160;
2888 factor = MPT_ULTRA320;
2891 ddvtprintk((KERN_INFO "Enabling QAS due to byte56=%02x on id=%d!\n", byte56, id));
2894 if (target->inq_data[0] == TYPE_TAPE) {
2896 target->negoFlags |= MPT_TAPE_NEGO_IDP;
2901 ddvtprintk((KERN_INFO "Enabling QAS on id=%d due to ~TARGET_FLAGS_VALID_56!\n", id));
2905 offset = pspi_data->maxSyncOffset;
2907 /* If RAID, never disable QAS
2908 * else if non RAID, do not disable
2909 * QAS if bit 1 is set
2910 * bit 1 QAS support, non-raid only
2913 if (target->raidVolume == 1) {
2922 if ( (target->inq_data[7] & 0x02) == 0) {
2923 target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
2926 /* Update tflags based on NVRAM settings. (SCSI only)
2928 if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
2929 nvram = pspi_data->nvram[id];
2930 nfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
2933 width = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
2936 /* Ensure factor is set to the
2937 * maximum of: adapter, nvram, inquiry
2940 if (nfactor < pspi_data->minSyncFactor )
2941 nfactor = pspi_data->minSyncFactor;
2943 factor = max(factor, nfactor);
2944 if (factor == MPT_ASYNC)
2955 /* Make sure data is consistent
2957 if ((!width) && (factor < MPT_ULTRA2)) {
2958 factor = MPT_ULTRA2;
2961 /* Save the data to the target structure.
2963 target->minSyncFactor = factor;
2964 target->maxOffset = offset;
2965 target->maxWidth = width;
2967 target->tflags |= MPT_TARGET_FLAGS_VALID_NEGO;
2969 /* Disable unused features.
2972 target->negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
2975 target->negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
2977 if ( factor > MPT_ULTRA320 )
2980 /* GEM, processor WORKAROUND
2982 if ((target->inq_data[0] == TYPE_PROCESSOR) || (target->inq_data[0] > 0x08)) {
2983 target->negoFlags |= (MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC);
2984 pspi_data->dvStatus[id] |= MPT_SCSICFG_BLK_NEGO;
2986 if (noQas && (pspi_data->noQas == 0)) {
2987 pspi_data->noQas |= MPT_TARGET_NO_NEGO_QAS;
2988 target->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
2990 /* Disable QAS in a mixed configuration case
2993 ddvtprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id));
2994 for (ii = 0; ii < id; ii++) {
2995 if ( (vtarget = hd->Targets[ii]) ) {
2996 vtarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
2997 mptscsih_writeSDP1(hd, 0, ii, vtarget->negoFlags);
3003 /* Write SDP1 on this I/O to this target */
3004 if (pspi_data->dvStatus[id] & MPT_SCSICFG_NEGOTIATE) {
3005 ddvtprintk((KERN_INFO "MPT_SCSICFG_NEGOTIATE on id=%d!\n", id));
3006 mptscsih_writeSDP1(hd, 0, id, hd->negoNvram);
3007 pspi_data->dvStatus[id] &= ~MPT_SCSICFG_NEGOTIATE;
3008 } else if (pspi_data->dvStatus[id] & MPT_SCSICFG_BLK_NEGO) {
3009 ddvtprintk((KERN_INFO "MPT_SCSICFG_BLK_NEGO on id=%d!\n", id));
3010 mptscsih_writeSDP1(hd, 0, id, MPT_SCSICFG_BLK_NEGO);
3011 pspi_data->dvStatus[id] &= ~MPT_SCSICFG_BLK_NEGO;
3015 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3017 * If no Target, bus reset on 1st I/O. Set the flag to
3018 * prevent any future negotiations to this device.
3021 mptscsih_no_negotiate(MPT_SCSI_HOST *hd, struct scsi_cmnd *sc)
3025 if ((vdev = sc->device->hostdata) != NULL)
3026 hd->ioc->spi_data.dvStatus[vdev->target_id] |= MPT_SCSICFG_BLK_NEGO;
3030 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3032 * SCSI Config Page functionality ...
3034 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3035 /* mptscsih_setDevicePage1Flags - add Requested and Configuration fields flags
3036 * based on width, factor and offset parameters.
3038 * @factor: sync factor
3039 * @offset: sync offset
3040 * @requestedPtr: pointer to requested values (updated)
3041 * @configurationPtr: pointer to configuration values (updated)
3042 * @flags: flags to block WDTR or SDTR negotiation
3046 * Remark: Called by writeSDP1 and _dv_params
3049 mptscsih_setDevicePage1Flags (u8 width, u8 factor, u8 offset, int *requestedPtr, int *configurationPtr, u8 flags)
3051 u8 nowide = flags & MPT_TARGET_NO_NEGO_WIDE;
3052 u8 nosync = flags & MPT_TARGET_NO_NEGO_SYNC;
3054 *configurationPtr = 0;
3055 *requestedPtr = width ? MPI_SCSIDEVPAGE1_RP_WIDE : 0;
3056 *requestedPtr |= (offset << 16) | (factor << 8);
3058 if (width && offset && !nowide && !nosync) {
3059 if (factor < MPT_ULTRA160) {
3060 *requestedPtr |= (MPI_SCSIDEVPAGE1_RP_IU + MPI_SCSIDEVPAGE1_RP_DT);
3061 if ((flags & MPT_TARGET_NO_NEGO_QAS) == 0)
3062 *requestedPtr |= MPI_SCSIDEVPAGE1_RP_QAS;
3063 if (flags & MPT_TAPE_NEGO_IDP)
3064 *requestedPtr |= 0x08000000;
3065 } else if (factor < MPT_ULTRA2) {
3066 *requestedPtr |= MPI_SCSIDEVPAGE1_RP_DT;
3071 *configurationPtr |= MPI_SCSIDEVPAGE1_CONF_WDTR_DISALLOWED;
3074 *configurationPtr |= MPI_SCSIDEVPAGE1_CONF_SDTR_DISALLOWED;
3079 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3080 /* mptscsih_writeSDP1 - write SCSI Device Page 1
3081 * @hd: Pointer to a SCSI Host Strucutre
3082 * @portnum: IOC port number
3083 * @target_id: writeSDP1 for single ID
3084 * @flags: MPT_SCSICFG_ALL_IDS, MPT_SCSICFG_USE_NVRAM, MPT_SCSICFG_BLK_NEGO
3086 * Return: -EFAULT if read of config page header fails
3089 * Remark: If a target has been found, the settings from the
3090 * target structure are used, else the device is set
3093 * Remark: Called during init and after a FW reload.
3094 * Remark: We do not wait for a return, write pages sequentially.
3097 mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
3099 MPT_ADAPTER *ioc = hd->ioc;
3101 SCSIDevicePage1_t *pData;
3102 VirtTarget *vtarget=NULL;
3107 u32 requested, configuration, flagsLength;
3109 int id = 0, maxid = 0;
3115 u8 maxwidth, maxoffset, maxfactor;
3117 if (ioc->spi_data.sdp1length == 0)
3120 if (flags & MPT_SCSICFG_ALL_IDS) {
3122 maxid = ioc->sh->max_id - 1;
3123 } else if (ioc->sh) {
3125 maxid = min_t(int, id, ioc->sh->max_id - 1);
3128 for (; id <= maxid; id++) {
3130 if (id == ioc->pfacts[portnum].PortSCSIID)
3133 /* Use NVRAM to get adapter and target maximums
3134 * Data over-riden by target structure information, if present
3136 maxwidth = ioc->spi_data.maxBusWidth;
3137 maxoffset = ioc->spi_data.maxSyncOffset;
3138 maxfactor = ioc->spi_data.minSyncFactor;
3139 if (ioc->spi_data.nvram && (ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
3140 nvram = ioc->spi_data.nvram[id];
3143 maxwidth = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
3145 if (maxoffset > 0) {
3146 maxfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
3147 if (maxfactor == 0) {
3149 maxfactor = MPT_ASYNC;
3151 } else if (maxfactor < ioc->spi_data.minSyncFactor) {
3152 maxfactor = ioc->spi_data.minSyncFactor;
3155 maxfactor = MPT_ASYNC;
3158 /* Set the negotiation flags.
3160 negoFlags = ioc->spi_data.noQas;
3162 negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
3165 negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
3167 if (flags & MPT_SCSICFG_USE_NVRAM) {
3176 //negoFlags = MPT_TARGET_NO_NEGO_SYNC;
3179 /* If id is not a raid volume, get the updated
3180 * transmission settings from the target structure.
3182 if (hd->Targets && (vtarget = hd->Targets[id]) && !vtarget->raidVolume) {
3183 width = vtarget->maxWidth;
3184 factor = vtarget->minSyncFactor;
3185 offset = vtarget->maxOffset;
3186 negoFlags = vtarget->negoFlags;
3189 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
3190 /* Force to async and narrow if DV has not been executed
3193 if ((hd->ioc->spi_data.dvStatus[id] & MPT_SCSICFG_DV_NOT_DONE) != 0) {
3200 if (flags & MPT_SCSICFG_BLK_NEGO)
3201 negoFlags |= MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC;
3203 mptscsih_setDevicePage1Flags(width, factor, offset,
3204 &requested, &configuration, negoFlags);
3205 dnegoprintk(("writeSDP1: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
3206 target_id, width, factor, offset, negoFlags, requested, configuration));
3208 /* Get a MF for this command.
3210 if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
3211 dfailprintk((MYIOC_s_WARN_FMT "write SDP1: no msg frames!\n",
3216 ddvprintk((MYIOC_s_INFO_FMT "WriteSDP1 (mf=%p, id=%d, req=0x%x, cfg=0x%x)\n",
3217 hd->ioc->name, mf, id, requested, configuration));
3220 /* Set the request and the data pointers.
3221 * Request takes: 36 bytes (32 bit SGE)
3222 * SCSI Device Page 1 requires 16 bytes
3223 * 40 + 16 <= size of SCSI IO Request = 56 bytes
3224 * and MF size >= 64 bytes.
3225 * Place data at end of MF.
3227 pReq = (Config_t *)mf;
3229 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3230 frameOffset = ioc->req_sz - sizeof(SCSIDevicePage1_t);
3232 pData = (SCSIDevicePage1_t *)((u8 *) mf + frameOffset);
3233 dataDma = ioc->req_frames_dma + (req_idx * ioc->req_sz) + frameOffset;
3235 /* Complete the request frame (same for all requests).
3237 pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
3239 pReq->ChainOffset = 0;
3240 pReq->Function = MPI_FUNCTION_CONFIG;
3241 pReq->ExtPageLength = 0;
3242 pReq->ExtPageType = 0;
3244 for (ii=0; ii < 8; ii++) {
3245 pReq->Reserved2[ii] = 0;
3247 pReq->Header.PageVersion = ioc->spi_data.sdp1version;
3248 pReq->Header.PageLength = ioc->spi_data.sdp1length;
3249 pReq->Header.PageNumber = 1;
3250 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
3251 pReq->PageAddress = cpu_to_le32(id | (bus << 8 ));
3253 /* Add a SGE to the config request.
3255 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE | ioc->spi_data.sdp1length * 4;
3257 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma);
3259 /* Set up the common data portion
3261 pData->Header.PageVersion = pReq->Header.PageVersion;
3262 pData->Header.PageLength = pReq->Header.PageLength;
3263 pData->Header.PageNumber = pReq->Header.PageNumber;
3264 pData->Header.PageType = pReq->Header.PageType;
3265 pData->RequestedParameters = cpu_to_le32(requested);
3266 pData->Reserved = 0;
3267 pData->Configuration = cpu_to_le32(configuration);
3269 dprintk((MYIOC_s_INFO_FMT
3270 "write SDP1: id %d pgaddr 0x%x req 0x%x config 0x%x\n",
3271 ioc->name, id, (id | (bus<<8)),
3272 requested, configuration));
3274 mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
3280 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3281 /* mptscsih_writeIOCPage4 - write IOC Page 4
3282 * @hd: Pointer to a SCSI Host Structure
3283 * @target_id: write IOC Page4 for this ID & Bus
3285 * Return: -EAGAIN if unable to obtain a Message Frame
3288 * Remark: We do not wait for a return, write pages sequentially.
3291 mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus)
3293 MPT_ADAPTER *ioc = hd->ioc;
3295 IOCPage4_t *IOCPage4Ptr;
3303 /* Get a MF for this command.
3305 if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
3306 dfailprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n",
3311 /* Set the request and the data pointers.
3312 * Place data at end of MF.
3314 pReq = (Config_t *)mf;
3316 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3317 frameOffset = ioc->req_sz - sizeof(IOCPage4_t);
3319 /* Complete the request frame (same for all requests).
3321 pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
3323 pReq->ChainOffset = 0;
3324 pReq->Function = MPI_FUNCTION_CONFIG;
3325 pReq->ExtPageLength = 0;
3326 pReq->ExtPageType = 0;
3328 for (ii=0; ii < 8; ii++) {
3329 pReq->Reserved2[ii] = 0;
3332 IOCPage4Ptr = ioc->spi_data.pIocPg4;
3333 dataDma = ioc->spi_data.IocPg4_dma;
3334 ii = IOCPage4Ptr->ActiveSEP++;
3335 IOCPage4Ptr->SEP[ii].SEPTargetID = target_id;
3336 IOCPage4Ptr->SEP[ii].SEPBus = bus;
3337 pReq->Header = IOCPage4Ptr->Header;
3338 pReq->PageAddress = cpu_to_le32(target_id | (bus << 8 ));
3340 /* Add a SGE to the config request.
3342 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE |
3343 (IOCPage4Ptr->Header.PageLength + ii) * 4;
3345 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma);
3347 dinitprintk((MYIOC_s_INFO_FMT
3348 "writeIOCPage4: MaxSEP=%d ActiveSEP=%d id=%d bus=%d\n",
3349 ioc->name, IOCPage4Ptr->MaxSEP, IOCPage4Ptr->ActiveSEP, target_id, bus));
3351 mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
3356 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3358 * Bus Scan and Domain Validation functionality ...
3361 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3363 * mptscsih_scandv_complete - Scan and DV callback routine registered
3364 * to Fustion MPT (base) driver.
3366 * @ioc: Pointer to MPT_ADAPTER structure
3367 * @mf: Pointer to original MPT request frame
3368 * @mr: Pointer to MPT reply frame (NULL if TurboReply)
3370 * This routine is called from mpt.c::mpt_interrupt() at the completion
3371 * of any SCSI IO request.
3372 * This routine is registered with the Fusion MPT (base) driver at driver
3373 * load/init time via the mpt_register() API call.
3375 * Returns 1 indicating alloc'd request frame ptr should be freed.
3377 * Remark: Sets a completion code and (possibly) saves sense data
3378 * in the IOC member localReply structure.
3379 * Used ONLY for DV and other internal commands.
3382 mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
3385 SCSIIORequest_t *pReq;
3389 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
3392 (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) {
3393 printk(MYIOC_s_ERR_FMT
3394 "ScanDvComplete, %s req frame ptr! (=%p)\n",
3395 ioc->name, mf?"BAD":"NULL", (void *) mf);
3399 del_timer(&hd->timer);
3400 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3401 hd->ScsiLookup[req_idx] = NULL;
3402 pReq = (SCSIIORequest_t *) mf;
3404 if (mf != hd->cmdPtr) {
3405 printk(MYIOC_s_WARN_FMT "ScanDvComplete (mf=%p, cmdPtr=%p, idx=%d)\n",
3406 hd->ioc->name, (void *)mf, (void *) hd->cmdPtr, req_idx);
3410 ddvprintk((MYIOC_s_INFO_FMT "ScanDvComplete (mf=%p,mr=%p,idx=%d)\n",
3411 hd->ioc->name, mf, mr, req_idx));
3413 hd->pLocal = &hd->localReply;
3414 hd->pLocal->scsiStatus = 0;
3416 /* If target struct exists, clear sense valid flag.
3419 completionCode = MPT_SCANDV_GOOD;
3421 SCSIIOReply_t *pReply;
3425 pReply = (SCSIIOReply_t *) mr;
3427 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
3428 scsi_status = pReply->SCSIStatus;
3430 ddvtprintk((KERN_NOTICE " IOCStatus=%04xh, SCSIState=%02xh, SCSIStatus=%02xh, IOCLogInfo=%08xh\n",
3431 status, pReply->SCSIState, scsi_status,
3432 le32_to_cpu(pReply->IOCLogInfo)));
3436 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
3437 completionCode = MPT_SCANDV_SELECTION_TIMEOUT;
3440 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
3441 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
3442 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
3443 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
3444 completionCode = MPT_SCANDV_DID_RESET;
3447 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
3448 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
3449 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
3450 if (pReply->Function == MPI_FUNCTION_CONFIG) {
3451 ConfigReply_t *pr = (ConfigReply_t *)mr;
3452 completionCode = MPT_SCANDV_GOOD;
3453 hd->pLocal->header.PageVersion = pr->Header.PageVersion;
3454 hd->pLocal->header.PageLength = pr->Header.PageLength;
3455 hd->pLocal->header.PageNumber = pr->Header.PageNumber;
3456 hd->pLocal->header.PageType = pr->Header.PageType;
3458 } else if (pReply->Function == MPI_FUNCTION_RAID_ACTION) {
3459 /* If the RAID Volume request is successful,
3460 * return GOOD, else indicate that
3461 * some type of error occurred.
3463 MpiRaidActionReply_t *pr = (MpiRaidActionReply_t *)mr;
3464 if (le16_to_cpu(pr->ActionStatus) == MPI_RAID_ACTION_ASTATUS_SUCCESS)
3465 completionCode = MPT_SCANDV_GOOD;
3467 completionCode = MPT_SCANDV_SOME_ERROR;
3469 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID) {
3473 /* save sense data in global structure
3475 completionCode = MPT_SCANDV_SENSE;
3476 hd->pLocal->scsiStatus = scsi_status;
3477 sense_data = ((u8 *)hd->ioc->sense_buf_pool +
3478 (req_idx * MPT_SENSE_BUFFER_ALLOC));
3480 sz = min_t(int, pReq->SenseBufferLength,
3481 SCSI_STD_SENSE_BYTES);
3482 memcpy(hd->pLocal->sense, sense_data, sz);
3484 ddvprintk((KERN_NOTICE " Check Condition, sense ptr %p\n",
3486 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_FAILED) {
3487 if (pReq->CDB[0] == INQUIRY)
3488 completionCode = MPT_SCANDV_ISSUE_SENSE;
3490 completionCode = MPT_SCANDV_DID_RESET;
3492 else if (pReply->SCSIState & MPI_SCSI_STATE_NO_SCSI_STATUS)
3493 completionCode = MPT_SCANDV_DID_RESET;
3494 else if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
3495 completionCode = MPT_SCANDV_DID_RESET;
3497 completionCode = MPT_SCANDV_GOOD;
3498 hd->pLocal->scsiStatus = scsi_status;
3502 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
3503 if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
3504 completionCode = MPT_SCANDV_DID_RESET;
3506 completionCode = MPT_SCANDV_SOME_ERROR;
3510 completionCode = MPT_SCANDV_SOME_ERROR;
3513 } /* switch(status) */
3515 ddvtprintk((KERN_NOTICE " completionCode set to %08xh\n",
3517 } /* end of address reply case */
3519 hd->pLocal->completion = completionCode;
3521 /* MF and RF are freed in mpt_interrupt
3524 /* Free Chain buffers (will never chain) in scan or dv */
3525 //mptscsih_freeChainBuffers(ioc, req_idx);
3528 * Wake up the original calling thread
3530 hd->scandv_wait_done = 1;
3531 wake_up(&hd->scandv_waitq);
3536 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3537 /* mptscsih_timer_expired - Call back for timer process.
3538 * Used only for dv functionality.
3539 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
3543 mptscsih_timer_expired(unsigned long data)
3545 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) data;
3547 ddvprintk((MYIOC_s_WARN_FMT "Timer Expired! Cmd %p\n", hd->ioc->name, hd->cmdPtr));
3550 MPIHeader_t *cmd = (MPIHeader_t *)hd->cmdPtr;
3552 if (cmd->Function == MPI_FUNCTION_SCSI_IO_REQUEST) {
3553 /* Desire to issue a task management request here.
3554 * TM requests MUST be single threaded.
3555 * If old eh code and no TM current, issue request.
3556 * If new eh code, do nothing. Wait for OS cmd timeout
3559 ddvtprintk((MYIOC_s_NOTE_FMT "DV Cmd Timeout: NoOp\n", hd->ioc->name));
3561 /* Perform a FW reload */
3562 if (mpt_HardResetHandler(hd->ioc, NO_SLEEP) < 0) {
3563 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", hd->ioc->name);
3567 /* This should NEVER happen */
3568 printk(MYIOC_s_WARN_FMT "Null cmdPtr!!!!\n", hd->ioc->name);
3571 /* No more processing.
3572 * TM call will generate an interrupt for SCSI TM Management.
3573 * The FW will reply to all outstanding commands, callback will finish cleanup.
3574 * Hard reset clean-up will free all resources.
3576 ddvprintk((MYIOC_s_WARN_FMT "Timer Expired Complete!\n", hd->ioc->name));
3581 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
3582 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3583 /* mptscsih_do_raid - Format and Issue a RAID volume request message.
3584 * @hd: Pointer to scsi host structure
3585 * @action: What do be done.
3586 * @id: Logical target id.
3587 * @bus: Target locations bus.
3589 * Returns: < 0 on a fatal error
3592 * Remark: Wait to return until reply processed by the ISR.
3595 mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io)
3597 MpiRaidActionRequest_t *pReq;
3601 in_isr = in_interrupt();
3603 dprintk((MYIOC_s_WARN_FMT "Internal raid request not allowed in ISR context!\n",
3608 /* Get and Populate a free Frame
3610 if ((mf = mpt_get_msg_frame(hd->ioc->InternalCtx, hd->ioc)) == NULL) {
3611 ddvprintk((MYIOC_s_WARN_FMT "_do_raid: no msg frames!\n",
3615 pReq = (MpiRaidActionRequest_t *)mf;
3616 pReq->Action = action;
3617 pReq->Reserved1 = 0;
3618 pReq->ChainOffset = 0;
3619 pReq->Function = MPI_FUNCTION_RAID_ACTION;
3620 pReq->VolumeID = io->id;
3621 pReq->VolumeBus = io->bus;
3622 pReq->PhysDiskNum = io->physDiskNum;
3624 pReq->Reserved2 = 0;
3625 pReq->ActionDataWord = 0; /* Reserved for this action */
3626 //pReq->ActionDataSGE = 0;
3628 mpt_add_sge((char *)&pReq->ActionDataSGE,
3629 MPT_SGE_FLAGS_SSIMPLE_READ | 0, (dma_addr_t) -1);
3631 ddvprintk((MYIOC_s_INFO_FMT "RAID Volume action %x id %d\n",
3632 hd->ioc->name, action, io->id));
3635 hd->timer.expires = jiffies + HZ*10; /* 10 second timeout */
3636 hd->scandv_wait_done = 0;
3638 /* Save cmd pointer, for resource free if timeout or
3643 add_timer(&hd->timer);
3644 mpt_put_msg_frame(hd->ioc->InternalCtx, hd->ioc, mf);
3645 wait_event(hd->scandv_waitq, hd->scandv_wait_done);
3647 if ((hd->pLocal == NULL) || (hd->pLocal->completion != MPT_SCANDV_GOOD))
3652 #endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */
3654 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3656 * mptscsih_do_cmd - Do internal command.
3657 * @hd: MPT_SCSI_HOST pointer
3658 * @io: INTERNAL_CMD pointer.
3660 * Issue the specified internally generated command and do command
3661 * specific cleanup. For bus scan / DV only.
3662 * NOTES: If command is Inquiry and status is good,
3663 * initialize a target structure, save the data
3665 * Remark: Single threaded access only.
3668 * < 0 if an illegal command or no resources
3672 * > 0 if command complete but some type of completion error.
3675 mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
3678 SCSIIORequest_t *pScsiReq;
3679 SCSIIORequest_t ReqCopy;
3680 int my_idx, ii, dir;
3684 char CDB[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
3687 in_isr = in_interrupt();
3689 dprintk((MYIOC_s_WARN_FMT "Internal SCSI IO request not allowed in ISR context!\n",
3695 /* Set command specific information
3700 dir = MPI_SCSIIO_CONTROL_READ;
3706 case TEST_UNIT_READY:
3708 dir = MPI_SCSIIO_CONTROL_READ;
3714 dir = MPI_SCSIIO_CONTROL_READ;
3716 CDB[4] = 1; /*Spin up the disk */
3724 dir = MPI_SCSIIO_CONTROL_READ;
3730 dir = MPI_SCSIIO_CONTROL_READ;
3732 if (io->flags & MPT_ICFLAG_ECHO) {
3738 if (io->flags & MPT_ICFLAG_BUF_CAP) {
3741 CDB[6] = (io->size >> 16) & 0xFF;
3742 CDB[7] = (io->size >> 8) & 0xFF;
3743 CDB[8] = io->size & 0xFF;
3749 dir = MPI_SCSIIO_CONTROL_WRITE;
3751 if (io->flags & MPT_ICFLAG_ECHO) {
3756 CDB[6] = (io->size >> 16) & 0xFF;
3757 CDB[7] = (io->size >> 8) & 0xFF;
3758 CDB[8] = io->size & 0xFF;
3764 dir = MPI_SCSIIO_CONTROL_READ;
3771 dir = MPI_SCSIIO_CONTROL_READ;
3776 case SYNCHRONIZE_CACHE:
3778 dir = MPI_SCSIIO_CONTROL_READ;
3780 // CDB[1] = 0x02; /* set immediate bit */
3789 /* Get and Populate a free Frame
3791 if ((mf = mpt_get_msg_frame(hd->ioc->InternalCtx, hd->ioc)) == NULL) {
3792 ddvprintk((MYIOC_s_WARN_FMT "No msg frames!\n",
3797 pScsiReq = (SCSIIORequest_t *) mf;
3799 /* Get the request index */
3800 my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3801 ADD_INDEX_LOG(my_idx); /* for debug */
3803 if (io->flags & MPT_ICFLAG_PHYS_DISK) {
3804 pScsiReq->TargetID = io->physDiskNum;
3806 pScsiReq->ChainOffset = 0;
3807 pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
3809 pScsiReq->TargetID = io->id;
3810 pScsiReq->Bus = io->bus;
3811 pScsiReq->ChainOffset = 0;
3812 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
3815 pScsiReq->CDBLength = cmdLen;
3816 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
3818 pScsiReq->Reserved = 0;
3820 pScsiReq->MsgFlags = mpt_msg_flags();
3821 /* MsgContext set in mpt_get_msg_fram call */
3823 for (ii=0; ii < 8; ii++)
3824 pScsiReq->LUN[ii] = 0;
3825 pScsiReq->LUN[1] = io->lun;
3827 if (io->flags & MPT_ICFLAG_TAGGED_CMD)
3828 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ);
3830 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3832 if (cmd == REQUEST_SENSE) {
3833 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3834 ddvprintk((MYIOC_s_INFO_FMT "Untagged! 0x%2x\n",
3835 hd->ioc->name, cmd));
3838 for (ii=0; ii < 16; ii++)
3839 pScsiReq->CDB[ii] = CDB[ii];
3841 pScsiReq->DataLength = cpu_to_le32(io->size);
3842 pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
3843 + (my_idx * MPT_SENSE_BUFFER_ALLOC));
3845 ddvprintk((MYIOC_s_INFO_FMT "Sending Command 0x%x for (%d:%d:%d)\n",
3846 hd->ioc->name, cmd, io->bus, io->id, io->lun));
3848 if (dir == MPI_SCSIIO_CONTROL_READ) {
3849 mpt_add_sge((char *) &pScsiReq->SGL,
3850 MPT_SGE_FLAGS_SSIMPLE_READ | io->size,
3853 mpt_add_sge((char *) &pScsiReq->SGL,
3854 MPT_SGE_FLAGS_SSIMPLE_WRITE | io->size,
3858 /* The ISR will free the request frame, but we need
3859 * the information to initialize the target. Duplicate.
3861 memcpy(&ReqCopy, pScsiReq, sizeof(SCSIIORequest_t));
3863 /* Issue this command after:
3866 * Wait until the reply has been received
3867 * ScsiScanDvCtx callback function will
3869 * set scandv_wait_done and call wake_up
3872 hd->timer.expires = jiffies + HZ*cmdTimeout;
3873 hd->scandv_wait_done = 0;
3875 /* Save cmd pointer, for resource free if timeout or
3880 add_timer(&hd->timer);
3881 mpt_put_msg_frame(hd->ioc->InternalCtx, hd->ioc, mf);
3882 wait_event(hd->scandv_waitq, hd->scandv_wait_done);
3885 rc = hd->pLocal->completion;
3886 hd->pLocal->skip = 0;
3888 /* Always set fatal error codes in some cases.
3890 if (rc == MPT_SCANDV_SELECTION_TIMEOUT)
3892 else if (rc == MPT_SCANDV_SOME_ERROR)
3896 /* This should never happen. */
3897 ddvprintk((MYIOC_s_INFO_FMT "_do_cmd: Null pLocal!!!\n",
3904 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3906 * mptscsih_negotiate_to_asyn_narrow - Restore devices to default state
3907 * @hd: Pointer to a SCSI HOST structure
3908 * @vtarget: per device private data
3910 * Uses the ISR, but with special processing.
3911 * MUST be single-threaded.
3915 mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
3917 VirtTarget *vtarget = vdevice->vtarget;
3918 MPT_ADAPTER *ioc= hd->ioc;
3919 SCSIDevicePage1_t *pcfg1Data;
3921 dma_addr_t cfg1_dma_addr;
3922 ConfigPageHeader_t header;
3924 int requested, configuration, data,i;
3927 if ((ioc->bus_type != SPI) ||
3928 (!vdevice->configured_lun))
3931 if (!ioc->spi_data.sdp1length)
3934 pcfg1Data = (SCSIDevicePage1_t *)pci_alloc_consistent(ioc->pcidev,
3935 ioc->spi_data.sdp1length * 4, &cfg1_dma_addr);
3937 if (pcfg1Data == NULL)
3940 header.PageVersion = ioc->spi_data.sdp1version;
3941 header.PageLength = ioc->spi_data.sdp1length;
3942 header.PageNumber = 1;
3943 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
3944 cfg.cfghdr.hdr = &header;
3945 cfg.physAddr = cfg1_dma_addr;
3946 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
3950 if (vtarget->raidVolume && ioc->raid_data.pIocPg3) {
3951 for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
3952 id = ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID;
3953 flags = hd->ioc->spi_data.noQas;
3954 if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
3955 data = hd->ioc->spi_data.nvram[id];
3956 if (data & MPT_NVRAM_WIDE_DISABLE)
3957 flags |= MPT_TARGET_NO_NEGO_WIDE;
3958 factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT;
3959 if ((factor == 0) || (factor == MPT_ASYNC))
3960 flags |= MPT_TARGET_NO_NEGO_SYNC;
3962 mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested,
3963 &configuration, flags);
3964 dnegoprintk(("nego asyn narrow: id=%d width=0 factor=MPT_ASYNC "
3965 "offset=0 negoFlags=%x request=%x config=%x\n",
3966 id, flags, requested, configuration));
3967 pcfg1Data->RequestedParameters = cpu_to_le32(requested);
3968 pcfg1Data->Reserved = 0;
3969 pcfg1Data->Configuration = cpu_to_le32(configuration);
3970 cfg.pageAddr = (vtarget->bus_id<<8) | id;
3971 mpt_config(hd->ioc, &cfg);
3974 flags = vtarget->negoFlags;
3975 mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested,
3976 &configuration, flags);
3977 dnegoprintk(("nego asyn narrow: id=%d width=0 factor=MPT_ASYNC "
3978 "offset=0 negoFlags=%x request=%x config=%x\n",
3979 vtarget->target_id, flags, requested, configuration));
3980 pcfg1Data->RequestedParameters = cpu_to_le32(requested);
3981 pcfg1Data->Reserved = 0;
3982 pcfg1Data->Configuration = cpu_to_le32(configuration);
3983 cfg.pageAddr = (vtarget->bus_id<<8) | vtarget->target_id;
3984 mpt_config(hd->ioc, &cfg);
3988 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pcfg1Data, cfg1_dma_addr);
3991 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3993 * mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
3994 * @hd: Pointer to a SCSI HOST structure
3995 * @vtarget: per device private data
3998 * Uses the ISR, but with special processing.
3999 * MUST be single-threaded.
4003 mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
4007 /* Following parameters will not change
4010 iocmd.cmd = SYNCHRONIZE_CACHE;
4012 iocmd.physDiskNum = -1;
4014 iocmd.data_dma = -1;
4016 iocmd.rsvd = iocmd.rsvd2 = 0;
4017 iocmd.bus = vdevice->bus_id;
4018 iocmd.id = vdevice->target_id;
4019 iocmd.lun = (u8)vdevice->lun;
4021 if ((vdevice->vtarget->type & TYPE_DISK) &&
4022 (vdevice->configured_lun))
4023 mptscsih_do_cmd(hd, &iocmd);
4026 /* Search IOC page 3 to determine if this is hidden physical disk
4029 mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id)
4033 if (!ioc->raid_data.isRaid || !ioc->raid_data.pIocPg3)
4036 for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
4037 if (id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID)
4044 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
4045 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4047 * mptscsih_domainValidation - Top level handler for domain validation.
4048 * @hd: Pointer to MPT_SCSI_HOST structure.
4050 * Uses the ISR, but with special processing.
4051 * Called from schedule, should not be in interrupt mode.
4052 * While thread alive, do dv for all devices needing dv
4057 mptscsih_domainValidation(void *arg)
4061 unsigned long flags;
4062 int id, maxid, dvStatus, did;
4065 spin_lock_irqsave(&dvtaskQ_lock, flags);
4067 if (dvtaskQ_release) {
4069 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4072 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4074 /* For this ioc, loop through all devices and do dv to each device.
4075 * When complete with this ioc, search through the ioc list, and
4076 * for each scsi ioc found, do dv for all devices. Exit when no
4082 list_for_each_entry(ioc, &ioc_list, list) {
4083 spin_lock_irqsave(&dvtaskQ_lock, flags);
4084 if (dvtaskQ_release) {
4086 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4089 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4093 /* DV only to SPI adapters */
4094 if (ioc->bus_type != SPI)
4097 /* Make sure everything looks ok */
4098 if (ioc->sh == NULL)
4101 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
4105 if ((ioc->spi_data.forceDv & MPT_SCSICFG_RELOAD_IOC_PG3) != 0) {
4106 mpt_read_ioc_pg_3(ioc);
4107 if (ioc->raid_data.pIocPg3) {
4108 Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
4109 int numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
4112 if (ioc->spi_data.dvStatus[pPDisk->PhysDiskID] & MPT_SCSICFG_DV_NOT_DONE)
4113 ioc->spi_data.dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV;
4119 ioc->spi_data.forceDv &= ~MPT_SCSICFG_RELOAD_IOC_PG3;
4122 maxid = min_t(int, ioc->sh->max_id, MPT_MAX_SCSI_DEVICES);
4124 for (id = 0; id < maxid; id++) {
4125 spin_lock_irqsave(&dvtaskQ_lock, flags);
4126 if (dvtaskQ_release) {
4128 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4131 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4132 dvStatus = hd->ioc->spi_data.dvStatus[id];
4134 if (dvStatus & MPT_SCSICFG_NEED_DV) {
4136 hd->ioc->spi_data.dvStatus[id] |= MPT_SCSICFG_DV_PENDING;
4137 hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_NEED_DV;
4141 /* If hidden phys disk, block IO's to all
4143 * else, process normally
4145 isPhysDisk = mptscsih_is_phys_disk(ioc, id);
4147 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4148 if (hd->ioc->raid_data.isRaid & (1 << ii)) {
4149 hd->ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_DV_PENDING;
4154 if(mpt_alt_ioc_wait(hd->ioc)!=0) {
4155 ddvprintk((MYIOC_s_WARN_FMT "alt_ioc busy!\n",
4160 if (mptscsih_doDv(hd, 0, id) == 1) {
4161 /* Untagged device was busy, try again
4163 hd->ioc->spi_data.dvStatus[id] |= MPT_SCSICFG_NEED_DV;
4164 hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_PENDING;
4166 /* DV is complete. Clear flags.
4168 hd->ioc->spi_data.dvStatus[id] &= ~(MPT_SCSICFG_DV_NOT_DONE | MPT_SCSICFG_DV_PENDING);
4171 spin_lock(&hd->ioc->initializing_hba_lock);
4172 hd->ioc->initializing_hba_lock_flag=0;
4173 spin_unlock(&hd->ioc->initializing_hba_lock);
4176 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4177 if (hd->ioc->raid_data.isRaid & (1 << ii)) {
4178 hd->ioc->spi_data.dvStatus[ii] &= ~MPT_SCSICFG_DV_PENDING;
4183 if (hd->ioc->spi_data.noQas)
4184 mptscsih_qas_check(hd, id);
4190 spin_lock_irqsave(&dvtaskQ_lock, flags);
4192 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4197 /* Write SDP1 if no QAS has been enabled
4200 mptscsih_qas_check(MPT_SCSI_HOST *hd, int id)
4202 VirtTarget *vtarget;
4205 if (hd->Targets == NULL)
4208 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4212 if ((hd->ioc->spi_data.dvStatus[ii] & MPT_SCSICFG_DV_NOT_DONE) != 0)
4215 vtarget = hd->Targets[ii];
4217 if ((vtarget != NULL) && (!vtarget->raidVolume)) {
4218 if ((vtarget->negoFlags & hd->ioc->spi_data.noQas) == 0) {
4219 vtarget->negoFlags |= hd->ioc->spi_data.noQas;
4220 dnegoprintk(("writeSDP1: id=%d flags=0\n", id));
4221 mptscsih_writeSDP1(hd, 0, ii, 0);
4224 if (mptscsih_is_phys_disk(hd->ioc, ii) == 1) {
4225 dnegoprintk(("writeSDP1: id=%d SCSICFG_USE_NVRAM\n", id));
4226 mptscsih_writeSDP1(hd, 0, ii, MPT_SCSICFG_USE_NVRAM);
4235 #define MPT_GET_NVRAM_VALS 0x01
4236 #define MPT_UPDATE_MAX 0x02
4237 #define MPT_SET_MAX 0x04
4238 #define MPT_SET_MIN 0x08
4239 #define MPT_FALLBACK 0x10
4240 #define MPT_SAVE 0x20
4242 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4244 * mptscsih_doDv - Perform domain validation to a target.
4245 * @hd: Pointer to MPT_SCSI_HOST structure.
4246 * @portnum: IOC port number.
4247 * @target: Physical ID of this target
4249 * Uses the ISR, but with special processing.
4250 * MUST be single-threaded.
4251 * Test will exit if target is at async & narrow.
4256 mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
4258 MPT_ADAPTER *ioc = hd->ioc;
4259 VirtTarget *vtarget;
4260 SCSIDevicePage1_t *pcfg1Data;
4261 SCSIDevicePage0_t *pcfg0Data;
4265 dma_addr_t dvbuf_dma = -1;
4266 dma_addr_t buf1_dma = -1;
4267 dma_addr_t buf2_dma = -1;
4268 dma_addr_t cfg1_dma_addr = -1;
4269 dma_addr_t cfg0_dma_addr = -1;
4270 ConfigPageHeader_t header1;
4271 ConfigPageHeader_t header0;
4278 int dataBufSize = 0;
4279 int echoBufSize = 0;
4284 int nfactor = MPT_ULTRA320;
4286 char doFallback = 0;
4291 if (ioc->spi_data.sdp1length == 0)
4294 if (ioc->spi_data.sdp0length == 0)
4297 /* If multiple buses are used, require that the initiator
4298 * id be the same on all buses.
4300 if (id == ioc->pfacts[0].PortSCSIID)
4304 bus = (u8) bus_number;
4305 ddvtprintk((MYIOC_s_NOTE_FMT
4306 "DV started: bus=%d, id=%d dv @ %p\n",
4307 ioc->name, bus, id, &dv));
4309 /* Prep DV structure
4311 memset (&dv, 0, sizeof(DVPARAMETERS));
4314 /* Populate tmax with the current maximum
4315 * transfer parameters for this target.
4316 * Exit if narrow and async.
4318 dv.cmd = MPT_GET_NVRAM_VALS;
4319 mptscsih_dv_parms(hd, &dv, NULL);
4321 /* Prep SCSI IO structure
4327 iocmd.physDiskNum = -1;
4328 iocmd.rsvd = iocmd.rsvd2 = 0;
4330 vtarget = hd->Targets[id];
4332 /* Use tagged commands if possible.
4335 if (vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)
4336 iocmd.flags |= MPT_ICFLAG_TAGGED_CMD;
4338 if (hd->ioc->facts.FWVersion.Word < 0x01000600)
4341 if ((hd->ioc->facts.FWVersion.Word >= 0x01010000) &&
4342 (hd->ioc->facts.FWVersion.Word < 0x01010B00))
4347 /* Prep cfg structure
4349 cfg.pageAddr = (bus<<8) | id;
4350 cfg.cfghdr.hdr = NULL;
4354 header0.PageVersion = ioc->spi_data.sdp0version;
4355 header0.PageLength = ioc->spi_data.sdp0length;
4356 header0.PageNumber = 0;
4357 header0.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4361 header1.PageVersion = ioc->spi_data.sdp1version;
4362 header1.PageLength = ioc->spi_data.sdp1length;
4363 header1.PageNumber = 1;
4364 header1.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4366 if (header0.PageLength & 1)
4367 dv_alloc = (header0.PageLength * 4) + 4;
4369 dv_alloc += (2048 + (header1.PageLength * 4));
4371 pDvBuf = pci_alloc_consistent(ioc->pcidev, dv_alloc, &dvbuf_dma);
4376 pbuf1 = (u8 *)pDvBuf;
4377 buf1_dma = dvbuf_dma;
4380 pbuf2 = (u8 *) (pDvBuf + sz);
4381 buf2_dma = dvbuf_dma + sz;
4384 pcfg0Data = (SCSIDevicePage0_t *) (pDvBuf + sz);
4385 cfg0_dma_addr = dvbuf_dma + sz;
4386 sz += header0.PageLength * 4;
4390 if (header0.PageLength & 1)
4393 pcfg1Data = (SCSIDevicePage1_t *) (pDvBuf + sz);
4394 cfg1_dma_addr = dvbuf_dma + sz;
4396 /* Skip this ID? Set cfg.cfghdr.hdr to force config page write
4399 SpiCfgData *pspi_data = &hd->ioc->spi_data;
4400 if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
4401 /* Set the factor from nvram */
4402 nfactor = (pspi_data->nvram[id] & MPT_NVRAM_SYNC_MASK) >> 8;
4403 if (nfactor < pspi_data->minSyncFactor )
4404 nfactor = pspi_data->minSyncFactor;
4406 if (!(pspi_data->nvram[id] & MPT_NVRAM_ID_SCAN_ENABLE) ||
4407 (pspi_data->PortFlags == MPI_SCSIPORTPAGE2_PORT_FLAGS_OFF_DV) ) {
4409 ddvprintk((MYIOC_s_NOTE_FMT "DV Skipped: bus, id, lun (%d, %d, %d)\n",
4410 ioc->name, bus, id, lun));
4412 dv.cmd = MPT_SET_MAX;
4413 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
4414 cfg.cfghdr.hdr = &header1;
4416 /* Save the final negotiated settings to
4417 * SCSI device page 1.
4419 cfg.physAddr = cfg1_dma_addr;
4420 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4422 mpt_config(hd->ioc, &cfg);
4428 /* Finish iocmd inititialization - hidden or visible disk? */
4429 if (ioc->raid_data.pIocPg3) {
4430 /* Search IOC page 3 for matching id
4432 Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
4433 int numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
4436 if (pPDisk->PhysDiskID == id) {
4438 iocmd.flags |= MPT_ICFLAG_PHYS_DISK;
4439 iocmd.physDiskNum = pPDisk->PhysDiskNum;
4443 if (mptscsih_do_raid(hd, MPI_RAID_ACTION_QUIESCE_PHYS_IO, &iocmd) < 0) {
4444 ddvprintk((MYIOC_s_ERR_FMT "RAID Queisce FAILED!\n", ioc->name));
4454 /* RAID Volume ID's may double for a physical device. If RAID but
4455 * not a physical ID as well, skip DV.
4457 if ((hd->ioc->raid_data.isRaid & (1 << id)) && !(iocmd.flags & MPT_ICFLAG_PHYS_DISK))
4462 * Async & Narrow - Inquiry
4463 * Async & Narrow - Inquiry
4464 * Maximum transfer rate - Inquiry
4466 * If compare, test complete.
4467 * If miscompare and first pass, repeat
4468 * If miscompare and not first pass, fall back and repeat
4472 sz = SCSI_MAX_INQUIRY_BYTES;
4473 rc = MPT_SCANDV_GOOD;
4475 ddvprintk((MYIOC_s_NOTE_FMT "DV: Start Basic test on id=%d\n", ioc->name, id));
4477 dv.cmd = MPT_SET_MIN;
4478 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
4480 cfg.cfghdr.hdr = &header1;
4481 cfg.physAddr = cfg1_dma_addr;
4482 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4484 if (mpt_config(hd->ioc, &cfg) != 0)
4487 /* Wide - narrow - wide workaround case
4489 if ((rc == MPT_SCANDV_ISSUE_SENSE) && dv.max.width) {
4490 /* Send an untagged command to reset disk Qs corrupted
4491 * when a parity error occurs on a Request Sense.
4493 if ((hd->ioc->facts.FWVersion.Word >= 0x01000600) ||
4494 ((hd->ioc->facts.FWVersion.Word >= 0x01010000) &&
4495 (hd->ioc->facts.FWVersion.Word < 0x01010B00)) ) {
4497 iocmd.cmd = REQUEST_SENSE;
4498 iocmd.data_dma = buf1_dma;
4501 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4504 if (hd->pLocal == NULL)
4506 rc = hd->pLocal->completion;
4507 if ((rc == MPT_SCANDV_GOOD) || (rc == MPT_SCANDV_SENSE)) {
4517 iocmd.cmd = INQUIRY;
4518 iocmd.data_dma = buf1_dma;
4521 memset(pbuf1, 0x00, sz);
4522 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4525 if (hd->pLocal == NULL)
4527 rc = hd->pLocal->completion;
4528 if (rc == MPT_SCANDV_GOOD) {
4529 if (hd->pLocal->scsiStatus == SAM_STAT_BUSY) {
4530 if ((iocmd.flags & MPT_ICFLAG_TAGGED_CMD) == 0)
4537 } else if (rc == MPT_SCANDV_SENSE) {
4540 /* If first command doesn't complete
4541 * with a good status or with a check condition,
4548 /* Reset the size for disks
4550 inq0 = (*pbuf1) & 0x1F;
4551 if ((inq0 == 0) && vtarget && !vtarget->raidVolume) {
4556 /* Another GEM workaround. Check peripheral device type,
4557 * if PROCESSOR, quit DV.
4559 if (inq0 == TYPE_PROCESSOR) {
4560 mptscsih_initTarget(hd,
4571 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4575 if ((vtarget->maxWidth == 1) && (vtarget->maxOffset) && (nfactor < 0x0A)
4576 && (vtarget->minSyncFactor > 0x09)) {
4577 if ((pbuf1[56] & 0x04) == 0)
4579 else if ((pbuf1[56] & 0x01) == 1) {
4580 vtarget->minSyncFactor =
4581 nfactor > MPT_ULTRA320 ? nfactor : MPT_ULTRA320;
4583 vtarget->minSyncFactor =
4584 nfactor > MPT_ULTRA160 ? nfactor : MPT_ULTRA160;
4587 dv.max.factor = vtarget->minSyncFactor;
4589 if ((pbuf1[56] & 0x02) == 0) {
4590 vtarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
4591 hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS;
4592 ddvprintk((MYIOC_s_NOTE_FMT
4593 "DV: Start Basic noQas on id=%d due to pbuf1[56]=%x\n",
4594 ioc->name, id, pbuf1[56]));
4600 dv.cmd = MPT_FALLBACK;
4602 dv.cmd = MPT_SET_MAX;
4604 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
4605 if (mpt_config(hd->ioc, &cfg) != 0)
4608 if ((!dv.now.width) && (!dv.now.offset))
4611 iocmd.cmd = INQUIRY;
4612 iocmd.data_dma = buf2_dma;
4615 memset(pbuf2, 0x00, sz);
4616 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4618 else if (hd->pLocal == NULL)
4621 /* Save the return code.
4622 * If this is the first pass,
4623 * read SCSI Device Page 0
4624 * and update the target max parameters.
4626 rc = hd->pLocal->completion;
4628 if (rc == MPT_SCANDV_GOOD) {
4633 cfg.cfghdr.hdr = &header0;
4634 cfg.physAddr = cfg0_dma_addr;
4635 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4638 if (mpt_config(hd->ioc, &cfg) != 0)
4641 sdp0_info = le32_to_cpu(pcfg0Data->Information) & 0x0E;
4642 sdp0_nego = (le32_to_cpu(pcfg0Data->NegotiatedParameters) & 0xFF00 ) >> 8;
4644 /* Quantum and Fujitsu workarounds.
4645 * Quantum: PPR U320 -> PPR reply with Ultra2 and wide
4646 * Fujitsu: PPR U320 -> Msg Reject and Ultra2 and wide
4647 * Resetart with a request for U160.
4649 if ((dv.now.factor == MPT_ULTRA320) && (sdp0_nego == MPT_ULTRA2)) {
4652 dv.cmd = MPT_UPDATE_MAX;
4653 mptscsih_dv_parms(hd, &dv, (void *)pcfg0Data);
4654 /* Update the SCSI device page 1 area
4656 pcfg1Data->RequestedParameters = pcfg0Data->NegotiatedParameters;
4661 /* Quantum workaround. Restart this test will the fallback
4664 if (doFallback == 0) {
4665 if (memcmp(pbuf1, pbuf2, sz) != 0) {
4669 ddvprintk((MYIOC_s_NOTE_FMT
4670 "DV:Inquiry compared id=%d, calling initTarget\n", ioc->name, id));
4671 hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_NOT_DONE;
4672 mptscsih_initTarget(hd,
4677 break; /* test complete */
4682 } else if (rc == MPT_SCANDV_ISSUE_SENSE)
4683 doFallback = 1; /* set fallback flag */
4684 else if ((rc == MPT_SCANDV_DID_RESET) ||
4685 (rc == MPT_SCANDV_SENSE) ||
4686 (rc == MPT_SCANDV_FALLBACK))
4687 doFallback = 1; /* set fallback flag */
4694 ddvprintk((MYIOC_s_NOTE_FMT "DV: Basic test on id=%d completed OK.\n", ioc->name, id));
4696 if (ioc->spi_data.mpt_dv == 0)
4699 inq0 = (*pbuf1) & 0x1F;
4701 /* Continue only for disks
4706 if ( ioc->spi_data.PortFlags == MPI_SCSIPORTPAGE2_PORT_FLAGS_BASIC_DV_ONLY )
4709 /* Start the Enhanced Test.
4710 * 0) issue TUR to clear out check conditions
4711 * 1) read capacity of echo (regular) buffer
4713 * 3) do write-read-compare data pattern test
4715 * 5) update nego parms to target struct
4717 cfg.cfghdr.hdr = &header1;
4718 cfg.physAddr = cfg1_dma_addr;
4719 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4722 iocmd.cmd = TEST_UNIT_READY;
4723 iocmd.data_dma = -1;
4728 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4731 if (hd->pLocal == NULL)
4734 rc = hd->pLocal->completion;
4735 if (rc == MPT_SCANDV_GOOD)
4737 else if (rc == MPT_SCANDV_SENSE) {
4738 u8 skey = hd->pLocal->sense[2] & 0x0F;
4739 u8 asc = hd->pLocal->sense[12];
4740 u8 ascq = hd->pLocal->sense[13];
4741 ddvprintk((MYIOC_s_INFO_FMT
4742 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
4743 ioc->name, skey, asc, ascq));
4745 if (skey == UNIT_ATTENTION)
4746 notDone++; /* repeat */
4747 else if ((skey == NOT_READY) &&
4748 (asc == 0x04)&&(ascq == 0x01)) {
4749 /* wait then repeat */
4752 } else if ((skey == NOT_READY) && (asc == 0x3A)) {
4753 /* no medium, try read test anyway */
4756 /* All other errors are fatal.
4758 ddvprintk((MYIOC_s_INFO_FMT "DV: fatal error.",
4766 iocmd.cmd = READ_BUFFER;
4767 iocmd.data_dma = buf1_dma;
4770 iocmd.flags |= MPT_ICFLAG_BUF_CAP;
4774 for (patt = 0; patt < 2; patt++) {
4776 iocmd.flags |= MPT_ICFLAG_ECHO;
4778 iocmd.flags &= ~MPT_ICFLAG_ECHO;
4784 /* If not ready after 8 trials,
4785 * give up on this device.
4790 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4792 else if (hd->pLocal == NULL)
4795 rc = hd->pLocal->completion;
4796 ddvprintk(("ReadBuffer Comp Code %d", rc));
4797 ddvprintk((" buff: %0x %0x %0x %0x\n",
4798 pbuf1[0], pbuf1[1], pbuf1[2], pbuf1[3]));
4800 if (rc == MPT_SCANDV_GOOD) {
4802 if (iocmd.flags & MPT_ICFLAG_ECHO) {
4803 bufsize = ((pbuf1[2] & 0x1F) <<8) | pbuf1[3];
4804 if (pbuf1[0] & 0x01)
4805 iocmd.flags |= MPT_ICFLAG_EBOS;
4807 bufsize = pbuf1[1]<<16 | pbuf1[2]<<8 | pbuf1[3];
4809 } else if (rc == MPT_SCANDV_SENSE) {
4810 u8 skey = hd->pLocal->sense[2] & 0x0F;
4811 u8 asc = hd->pLocal->sense[12];
4812 u8 ascq = hd->pLocal->sense[13];
4813 ddvprintk((MYIOC_s_INFO_FMT
4814 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
4815 ioc->name, skey, asc, ascq));
4816 if (skey == ILLEGAL_REQUEST) {
4818 } else if (skey == UNIT_ATTENTION) {
4819 notDone++; /* repeat */
4820 } else if ((skey == NOT_READY) &&
4821 (asc == 0x04)&&(ascq == 0x01)) {
4822 /* wait then repeat */
4826 /* All other errors are fatal.
4828 ddvprintk((MYIOC_s_INFO_FMT "DV: fatal error.",
4833 /* All other errors are fatal
4840 if (iocmd.flags & MPT_ICFLAG_ECHO)
4841 echoBufSize = bufsize;
4843 dataBufSize = bufsize;
4846 iocmd.flags &= ~MPT_ICFLAG_BUF_CAP;
4848 /* Use echo buffers if possible,
4849 * Exit if both buffers are 0.
4851 if (echoBufSize > 0) {
4852 iocmd.flags |= MPT_ICFLAG_ECHO;
4853 if (dataBufSize > 0)
4854 bufsize = min(echoBufSize, dataBufSize);
4856 bufsize = echoBufSize;
4857 } else if (dataBufSize == 0)
4860 ddvprintk((MYIOC_s_INFO_FMT "%s Buffer Capacity %d\n", ioc->name,
4861 (iocmd.flags & MPT_ICFLAG_ECHO) ? "Echo" : " ", bufsize));
4863 /* Data buffers for write-read-compare test max 1K.
4865 sz = min(bufsize, 1024);
4868 * On first pass, always issue a reserve.
4869 * On additional loops, only if a reset has occurred.
4870 * iocmd.flags indicates if echo or regular buffer
4872 for (patt = 0; patt < 4; patt++) {
4873 ddvprintk(("Pattern %d\n", patt));
4874 if ((iocmd.flags & MPT_ICFLAG_RESERVED) && (iocmd.flags & MPT_ICFLAG_DID_RESET)) {
4875 iocmd.cmd = TEST_UNIT_READY;
4876 iocmd.data_dma = -1;
4879 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4882 iocmd.cmd = RELEASE;
4883 iocmd.data_dma = -1;
4886 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4888 else if (hd->pLocal == NULL)
4891 rc = hd->pLocal->completion;
4892 ddvprintk(("Release rc %d\n", rc));
4893 if (rc == MPT_SCANDV_GOOD)
4894 iocmd.flags &= ~MPT_ICFLAG_RESERVED;
4898 iocmd.flags &= ~MPT_ICFLAG_RESERVED;
4900 iocmd.flags &= ~MPT_ICFLAG_DID_RESET;
4902 if (iocmd.flags & MPT_ICFLAG_EBOS)
4906 while (repeat && (!(iocmd.flags & MPT_ICFLAG_RESERVED))) {
4907 iocmd.cmd = RESERVE;
4908 iocmd.data_dma = -1;
4911 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4913 else if (hd->pLocal == NULL)
4916 rc = hd->pLocal->completion;
4917 if (rc == MPT_SCANDV_GOOD) {
4918 iocmd.flags |= MPT_ICFLAG_RESERVED;
4919 } else if (rc == MPT_SCANDV_SENSE) {
4920 /* Wait if coming ready
4922 u8 skey = hd->pLocal->sense[2] & 0x0F;
4923 u8 asc = hd->pLocal->sense[12];
4924 u8 ascq = hd->pLocal->sense[13];
4925 ddvprintk((MYIOC_s_INFO_FMT
4926 "DV: Reserve Failed: ", ioc->name));
4927 ddvprintk(("SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
4930 if ((skey == NOT_READY) && (asc == 0x04)&&
4932 /* wait then repeat */
4936 ddvprintk((MYIOC_s_INFO_FMT
4937 "DV: Reserved Failed.", ioc->name));
4941 ddvprintk((MYIOC_s_INFO_FMT "DV: Reserved Failed.",
4949 mptscsih_fillbuf(pbuf1, sz, patt, 1);
4950 iocmd.cmd = WRITE_BUFFER;
4951 iocmd.data_dma = buf1_dma;
4954 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4956 else if (hd->pLocal == NULL)
4959 rc = hd->pLocal->completion;
4960 if (rc == MPT_SCANDV_GOOD)
4961 ; /* Issue read buffer */
4962 else if (rc == MPT_SCANDV_DID_RESET) {
4963 /* If using echo buffers, reset to data buffers.
4964 * Else do Fallback and restart
4965 * this test (re-issue reserve
4966 * because of bus reset).
4968 if ((iocmd.flags & MPT_ICFLAG_ECHO) && (dataBufSize >= bufsize)) {
4969 iocmd.flags &= ~MPT_ICFLAG_ECHO;
4971 dv.cmd = MPT_FALLBACK;
4972 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
4974 if (mpt_config(hd->ioc, &cfg) != 0)
4977 if ((!dv.now.width) && (!dv.now.offset))
4981 iocmd.flags |= MPT_ICFLAG_DID_RESET;
4984 } else if (rc == MPT_SCANDV_SENSE) {
4985 /* Restart data test if UA, else quit.
4987 u8 skey = hd->pLocal->sense[2] & 0x0F;
4988 ddvprintk((MYIOC_s_INFO_FMT
4989 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n", ioc->name, skey,
4990 hd->pLocal->sense[12], hd->pLocal->sense[13]));
4991 if (skey == UNIT_ATTENTION) {
4994 } else if (skey == ILLEGAL_REQUEST) {
4995 if (iocmd.flags & MPT_ICFLAG_ECHO) {
4996 if (dataBufSize >= bufsize) {
4997 iocmd.flags &= ~MPT_ICFLAG_ECHO;
5012 iocmd.cmd = READ_BUFFER;
5013 iocmd.data_dma = buf2_dma;
5016 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5018 else if (hd->pLocal == NULL)
5021 rc = hd->pLocal->completion;
5022 if (rc == MPT_SCANDV_GOOD) {
5023 /* If buffers compare,
5024 * go to next pattern,
5025 * else, do a fallback and restart
5026 * data transfer test.
5028 if (memcmp (pbuf1, pbuf2, sz) == 0) {
5029 ; /* goto next pattern */
5031 /* Miscompare with Echo buffer, go to data buffer,
5032 * if that buffer exists.
5033 * Miscompare with Data buffer, check first 4 bytes,
5034 * some devices return capacity. Exit in this case.
5036 if (iocmd.flags & MPT_ICFLAG_ECHO) {
5037 if (dataBufSize >= bufsize)
5038 iocmd.flags &= ~MPT_ICFLAG_ECHO;
5042 if (dataBufSize == (pbuf2[1]<<16 | pbuf2[2]<<8 | pbuf2[3])) {
5043 /* Argh. Device returning wrong data.
5044 * Quit DV for this device.
5049 /* Had an actual miscompare. Slow down.*/
5050 dv.cmd = MPT_FALLBACK;
5051 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5053 if (mpt_config(hd->ioc, &cfg) != 0)
5056 if ((!dv.now.width) && (!dv.now.offset))
5063 } else if (rc == MPT_SCANDV_DID_RESET) {
5064 /* Do Fallback and restart
5065 * this test (re-issue reserve
5066 * because of bus reset).
5068 dv.cmd = MPT_FALLBACK;
5069 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5071 if (mpt_config(hd->ioc, &cfg) != 0)
5074 if ((!dv.now.width) && (!dv.now.offset))
5077 iocmd.flags |= MPT_ICFLAG_DID_RESET;
5080 } else if (rc == MPT_SCANDV_SENSE) {
5081 /* Restart data test if UA, else quit.
5083 u8 skey = hd->pLocal->sense[2] & 0x0F;
5084 ddvprintk((MYIOC_s_INFO_FMT
5085 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n", ioc->name, skey,
5086 hd->pLocal->sense[12], hd->pLocal->sense[13]));
5087 if (skey == UNIT_ATTENTION) {
5099 } /* --- end of patt loop ---- */
5102 if (iocmd.flags & MPT_ICFLAG_RESERVED) {
5103 iocmd.cmd = RELEASE;
5104 iocmd.data_dma = -1;
5107 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5108 printk(MYIOC_s_INFO_FMT "DV: Release failed. id %d",
5110 else if (hd->pLocal) {
5111 if (hd->pLocal->completion == MPT_SCANDV_GOOD)
5112 iocmd.flags &= ~MPT_ICFLAG_RESERVED;
5114 printk(MYIOC_s_INFO_FMT "DV: Release failed. id %d",
5120 /* Set if cfg1_dma_addr contents is valid
5122 if ((cfg.cfghdr.hdr != NULL) && (retcode == 0)){
5123 /* If disk, not U320, disable QAS
5125 if ((inq0 == 0) && (dv.now.factor > MPT_ULTRA320)) {
5126 hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS;
5127 ddvprintk((MYIOC_s_NOTE_FMT
5128 "noQas set due to id=%d has factor=%x\n", ioc->name, id, dv.now.factor));
5132 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5134 /* Double writes to SDP1 can cause problems,
5135 * skip save of the final negotiated settings to
5136 * SCSI device page 1.
5138 cfg.cfghdr.hdr = &header1;
5139 cfg.physAddr = cfg1_dma_addr;
5140 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5142 mpt_config(hd->ioc, &cfg);
5146 /* If this is a RAID Passthrough, enable internal IOs
5148 if (iocmd.flags & MPT_ICFLAG_PHYS_DISK) {
5149 if (mptscsih_do_raid(hd, MPI_RAID_ACTION_ENABLE_PHYS_IO, &iocmd) < 0)
5150 ddvprintk((MYIOC_s_ERR_FMT "RAID Enable FAILED!\n", ioc->name));
5153 /* Done with the DV scan of the current target
5156 pci_free_consistent(ioc->pcidev, dv_alloc, pDvBuf, dvbuf_dma);
5158 ddvtprintk((MYIOC_s_INFO_FMT "DV Done id=%d\n",
5164 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5165 /* mptscsih_dv_parms - perform a variety of operations on the
5166 * parameters used for negotiation.
5167 * @hd: Pointer to a SCSI host.
5168 * @dv: Pointer to a structure that contains the maximum and current
5169 * negotiated parameters.
5172 mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
5174 VirtTarget *vtarget;
5175 SCSIDevicePage0_t *pPage0;
5176 SCSIDevicePage1_t *pPage1;
5177 int val = 0, data, configuration;
5186 case MPT_GET_NVRAM_VALS:
5187 ddvprintk((MYIOC_s_NOTE_FMT "Getting NVRAM: ",
5189 /* Get the NVRAM values and save in tmax
5190 * If not an LVD bus, the adapter minSyncFactor has been
5191 * already throttled back.
5193 negoFlags = hd->ioc->spi_data.noQas;
5194 if ((hd->Targets)&&((vtarget = hd->Targets[(int)id]) != NULL) && !vtarget->raidVolume) {
5195 width = vtarget->maxWidth;
5196 offset = vtarget->maxOffset;
5197 factor = vtarget->minSyncFactor;
5198 negoFlags |= vtarget->negoFlags;
5200 if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
5201 data = hd->ioc->spi_data.nvram[id];
5202 width = data & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
5203 if ((offset = hd->ioc->spi_data.maxSyncOffset) == 0)
5206 factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT;
5207 if ((factor == 0) || (factor == MPT_ASYNC)){
5218 /* Set the negotiation flags */
5220 negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
5223 negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
5226 /* limit by adapter capabilities */
5227 width = min(width, hd->ioc->spi_data.maxBusWidth);
5228 offset = min(offset, hd->ioc->spi_data.maxSyncOffset);
5229 factor = max(factor, hd->ioc->spi_data.minSyncFactor);
5231 /* Check Consistency */
5232 if (offset && (factor < MPT_ULTRA2) && !width)
5233 factor = MPT_ULTRA2;
5235 dv->max.width = width;
5236 dv->max.offset = offset;
5237 dv->max.factor = factor;
5238 dv->max.flags = negoFlags;
5239 ddvprintk((" id=%d width=%d factor=%x offset=%x flags=%x\n",
5240 id, width, factor, offset, negoFlags));
5243 case MPT_UPDATE_MAX:
5244 ddvprintk((MYIOC_s_NOTE_FMT
5245 "Updating with SDP0 Data: ", hd->ioc->name));
5246 /* Update tmax values with those from Device Page 0.*/
5247 pPage0 = (SCSIDevicePage0_t *) pPage;
5249 val = le32_to_cpu(pPage0->NegotiatedParameters);
5250 dv->max.width = val & MPI_SCSIDEVPAGE0_NP_WIDE ? 1 : 0;
5251 dv->max.offset = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK) >> 16;
5252 dv->max.factor = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK) >> 8;
5255 dv->now.width = dv->max.width;
5256 dv->now.offset = dv->max.offset;
5257 dv->now.factor = dv->max.factor;
5258 ddvprintk(("id=%d width=%d factor=%x offset=%x flags=%x\n",
5259 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags));
5263 ddvprintk((MYIOC_s_NOTE_FMT "Setting Max: ",
5265 /* Set current to the max values. Update the config page.*/
5266 dv->now.width = dv->max.width;
5267 dv->now.offset = dv->max.offset;
5268 dv->now.factor = dv->max.factor;
5269 dv->now.flags = dv->max.flags;
5271 pPage1 = (SCSIDevicePage1_t *)pPage;
5273 mptscsih_setDevicePage1Flags (dv->now.width, dv->now.factor,
5274 dv->now.offset, &val, &configuration, dv->now.flags);
5275 dnegoprintk(("Setting Max: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
5276 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags, val, configuration));
5277 pPage1->RequestedParameters = cpu_to_le32(val);
5278 pPage1->Reserved = 0;
5279 pPage1->Configuration = cpu_to_le32(configuration);
5282 ddvprintk(("id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x configuration=%x\n",
5283 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags, val, configuration));
5287 ddvprintk((MYIOC_s_NOTE_FMT "Setting Min: ",
5289 /* Set page to asynchronous and narrow
5290 * Do not update now, breaks fallback routine. */
5294 negoFlags = dv->max.flags;
5296 pPage1 = (SCSIDevicePage1_t *)pPage;
5298 mptscsih_setDevicePage1Flags (width, factor,
5299 offset, &val, &configuration, negoFlags);
5300 dnegoprintk(("Setting Min: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
5301 id, width, factor, offset, negoFlags, val, configuration));
5302 pPage1->RequestedParameters = cpu_to_le32(val);
5303 pPage1->Reserved = 0;
5304 pPage1->Configuration = cpu_to_le32(configuration);
5306 ddvprintk(("id=%d width=%d factor=%x offset=%x request=%x config=%x negoFlags=%x\n",
5307 id, width, factor, offset, val, configuration, negoFlags));
5311 ddvprintk((MYIOC_s_NOTE_FMT
5312 "Fallback: Start: offset %d, factor %x, width %d \n",
5313 hd->ioc->name, dv->now.offset,
5314 dv->now.factor, dv->now.width));
5315 width = dv->now.width;
5316 offset = dv->now.offset;
5317 factor = dv->now.factor;
5318 if ((offset) && (dv->max.width)) {
5319 if (factor < MPT_ULTRA160)
5320 factor = MPT_ULTRA160;
5321 else if (factor < MPT_ULTRA2) {
5322 factor = MPT_ULTRA2;
5324 } else if ((factor == MPT_ULTRA2) && width) {
5325 factor = MPT_ULTRA2;
5327 } else if (factor < MPT_ULTRA) {
5330 } else if ((factor == MPT_ULTRA) && width) {
5332 } else if (factor < MPT_FAST) {
5335 } else if ((factor == MPT_FAST) && width) {
5338 } else if (factor < MPT_SCSI) {
5341 } else if ((factor == MPT_SCSI) && width) {
5349 } else if (offset) {
5351 if (factor < MPT_ULTRA)
5353 else if (factor < MPT_FAST)
5355 else if (factor < MPT_SCSI)
5366 dv->max.flags |= MPT_TARGET_NO_NEGO_QAS;
5367 dv->max.flags &= ~MPT_TAPE_NEGO_IDP;
5369 dv->now.width = width;
5370 dv->now.offset = offset;
5371 dv->now.factor = factor;
5372 dv->now.flags = dv->max.flags;
5374 pPage1 = (SCSIDevicePage1_t *)pPage;
5376 mptscsih_setDevicePage1Flags (width, factor, offset, &val,
5377 &configuration, dv->now.flags);
5378 dnegoprintk(("Finish: id=%d width=%d offset=%d factor=%x negoFlags=%x request=%x config=%x\n",
5379 id, width, offset, factor, dv->now.flags, val, configuration));
5381 pPage1->RequestedParameters = cpu_to_le32(val);
5382 pPage1->Reserved = 0;
5383 pPage1->Configuration = cpu_to_le32(configuration);
5386 ddvprintk(("Finish: id=%d offset=%d factor=%x width=%d request=%x config=%x\n",
5387 id, dv->now.offset, dv->now.factor, dv->now.width, val, configuration));
5391 ddvprintk((MYIOC_s_NOTE_FMT
5392 "Saving to Target structure: ", hd->ioc->name));
5393 ddvprintk(("id=%d width=%x factor=%x offset=%d flags=%x\n",
5394 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags));
5396 /* Save these values to target structures
5397 * or overwrite nvram (phys disks only).
5400 if ((hd->Targets)&&((vtarget = hd->Targets[(int)id]) != NULL) && !vtarget->raidVolume ) {
5401 vtarget->maxWidth = dv->now.width;
5402 vtarget->maxOffset = dv->now.offset;
5403 vtarget->minSyncFactor = dv->now.factor;
5404 vtarget->negoFlags = dv->now.flags;
5406 /* Preserv all flags, use
5407 * read-modify-write algorithm
5409 if (hd->ioc->spi_data.nvram) {
5410 data = hd->ioc->spi_data.nvram[id];
5413 data &= ~MPT_NVRAM_WIDE_DISABLE;
5415 data |= MPT_NVRAM_WIDE_DISABLE;
5417 if (!dv->now.offset)
5420 data &= ~MPT_NVRAM_SYNC_MASK;
5421 data |= (dv->now.factor << MPT_NVRAM_SYNC_SHIFT) & MPT_NVRAM_SYNC_MASK;
5423 hd->ioc->spi_data.nvram[id] = data;
5430 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5431 /* mptscsih_fillbuf - fill a buffer with a special data pattern
5432 * cleanup. For bus scan only.
5434 * @buffer: Pointer to data buffer to be filled.
5435 * @size: Number of bytes to fill
5436 * @index: Pattern index
5437 * @width: bus width, 0 (8 bits) or 1 (16 bits)
5440 mptscsih_fillbuf(char *buffer, int size, int index, int width)
5451 /* Pattern: 0000 FFFF 0000 FFFF
5453 for (ii=0; ii < size; ii++, ptr++) {
5460 /* Pattern: 00 FF 00 FF
5462 for (ii=0; ii < size; ii++, ptr++) {
5473 /* Pattern: 5555 AAAA 5555 AAAA 5555
5475 for (ii=0; ii < size; ii++, ptr++) {
5482 /* Pattern: 55 AA 55 AA 55
5484 for (ii=0; ii < size; ii++, ptr++) {
5494 /* Pattern: 00 01 02 03 04 05
5497 for (ii=0; ii < size; ii++, ptr++)
5503 /* Wide Pattern: FFFE 0001 FFFD 0002
5504 * ... 4000 DFFF 8000 EFFF
5507 for (ii=0; ii < size/2; ii++) {
5508 /* Create the base pattern
5511 /* every 64 (0x40) bytes flip the pattern
5512 * since we fill 2 bytes / iteration,
5513 * test for ii = 0x20
5519 *ptr = (char)( (val & 0xFF00) >> 8);
5521 *ptr = (char)(val & 0xFF);
5526 *ptr = (char)( (val & 0xFF00) >> 8);
5528 *ptr = (char)(val & 0xFF);
5534 /* Narrow Pattern: FE 01 FD 02 FB 04
5535 * .. 7F 80 01 FE 02 FD ... 80 7F
5538 for (ii=0; ii < size; ii++, ptr++) {
5539 /* Base pattern - first 32 bytes
5546 *ptr = (char) (~(1 << byte));
5549 /* Flip the pattern every 32 bytes
5559 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5560 /* If DV disabled (negoNvram set to USE_NVARM) or if not LUN 0, return.
5561 * Else set the NEED_DV flag after Read Capacity Issued (disks)
5562 * or Mode Sense (cdroms).
5564 * Tapes, initTarget will set this flag on completion of Inquiry command.
5565 * Called only if DV_NOT_DONE flag is set
5568 mptscsih_set_dvflags(MPT_SCSI_HOST *hd, struct scsi_cmnd *sc)
5570 MPT_ADAPTER *ioc = hd->ioc;
5574 ddvtprintk((MYIOC_s_NOTE_FMT
5575 " set_dvflags: id=%d lun=%d negoNvram=%x cmd=%x\n",
5576 hd->ioc->name, sc->device->id, sc->device->lun , hd->negoNvram, sc->cmnd[0]));
5578 if ((sc->device->lun != 0) || (hd->negoNvram != 0))
5583 if ((cmd == READ_CAPACITY) || (cmd == MODE_SENSE)) {
5584 pSpi = &ioc->spi_data;
5585 if ((ioc->raid_data.isRaid & (1 << sc->device->id)) && ioc->raid_data.pIocPg3) {
5586 /* Set NEED_DV for all hidden disks
5588 Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
5589 int numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
5592 pSpi->dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV;
5593 ddvtprintk(("NEED_DV set for phys disk id %d\n", pPDisk->PhysDiskID));
5598 pSpi->dvStatus[sc->device->id] |= MPT_SCSICFG_NEED_DV;
5599 ddvtprintk(("NEED_DV set for visible disk id %d\n", sc->device->id));
5603 /* mptscsih_raid_set_dv_flags()
5605 * New or replaced disk. Set DV flag and schedule DV.
5608 mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id)
5610 MPT_ADAPTER *ioc = hd->ioc;
5611 SpiCfgData *pSpi = &ioc->spi_data;
5612 Ioc3PhysDisk_t *pPDisk;
5615 if (hd->negoNvram != 0)
5618 ddvtprintk(("DV requested for phys disk id %d\n", id));
5619 if (ioc->raid_data.pIocPg3) {
5620 pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
5621 numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
5623 if (id == pPDisk->PhysDiskNum) {
5624 pSpi->dvStatus[pPDisk->PhysDiskID] =
5625 (MPT_SCSICFG_NEED_DV | MPT_SCSICFG_DV_NOT_DONE);
5626 pSpi->forceDv = MPT_SCSICFG_NEED_DV;
5627 ddvtprintk(("NEED_DV set for phys disk id %d\n",
5628 pPDisk->PhysDiskID));
5635 if (numPDisk == 0) {
5636 /* The physical disk that needs DV was not found
5637 * in the stored IOC Page 3. The driver must reload
5638 * this page. DV routine will set the NEED_DV flag for
5639 * all phys disks that have DV_NOT_DONE set.
5641 pSpi->forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
5642 ddvtprintk(("phys disk %d not found. Setting reload IOC Pg3 Flag\n",id));
5646 #endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */
5648 EXPORT_SYMBOL(mptscsih_remove);
5649 EXPORT_SYMBOL(mptscsih_shutdown);
5651 EXPORT_SYMBOL(mptscsih_suspend);
5652 EXPORT_SYMBOL(mptscsih_resume);
5654 EXPORT_SYMBOL(mptscsih_proc_info);
5655 EXPORT_SYMBOL(mptscsih_info);
5656 EXPORT_SYMBOL(mptscsih_qcmd);
5657 EXPORT_SYMBOL(mptscsih_target_alloc);
5658 EXPORT_SYMBOL(mptscsih_slave_alloc);
5659 EXPORT_SYMBOL(mptscsih_target_destroy);
5660 EXPORT_SYMBOL(mptscsih_slave_destroy);
5661 EXPORT_SYMBOL(mptscsih_slave_configure);
5662 EXPORT_SYMBOL(mptscsih_abort);
5663 EXPORT_SYMBOL(mptscsih_dev_reset);
5664 EXPORT_SYMBOL(mptscsih_bus_reset);
5665 EXPORT_SYMBOL(mptscsih_host_reset);
5666 EXPORT_SYMBOL(mptscsih_bios_param);
5667 EXPORT_SYMBOL(mptscsih_io_done);
5668 EXPORT_SYMBOL(mptscsih_taskmgmt_complete);
5669 EXPORT_SYMBOL(mptscsih_scandv_complete);
5670 EXPORT_SYMBOL(mptscsih_event_process);
5671 EXPORT_SYMBOL(mptscsih_ioc_reset);
5672 EXPORT_SYMBOL(mptscsih_change_queue_depth);
5673 EXPORT_SYMBOL(mptscsih_timer_expired);
5674 EXPORT_SYMBOL(mptscsih_TMHandler);
5676 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/