2 * linux/drivers/message/fusion/mptscsih.c
3 * High performance SCSI / Fibre Channel SCSI Host device driver.
4 * For use with PCI chip/adapter(s):
5 * LSIFC9xx/LSI409xx Fibre Channel
6 * running LSI Logic Fusion MPT (Message Passing Technology) firmware.
9 * This driver would not exist if not for Alan Cox's development
10 * of the linux i2o driver.
12 * A special thanks to Pamela Delaney (LSI Logic) for tons of work
13 * and countless enhancements while adding support for the 1030
14 * chip family. Pam has been instrumental in the development of
15 * of the 2.xx.xx series fusion drivers, and her contributions are
16 * far too numerous to hope to list in one place.
18 * A huge debt of gratitude is owed to David S. Miller (DaveM)
19 * for fixing much of the stupid and broken stuff in the early
20 * driver while porting to sparc64 platform. THANK YOU!
24 * Copyright (c) 1999-2004 LSI Logic Corporation
25 * Original author: Steven J. Ralston
26 * (mailto:sjralston1@netscape.net)
27 * (mailto:mpt_linux_developer@lsil.com)
29 * $Id: mptscsih.c,v 1.104 2002/12/03 21:26:34 pdelaney Exp $
31 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
33 This program is free software; you can redistribute it and/or modify
34 it under the terms of the GNU General Public License as published by
35 the Free Software Foundation; version 2 of the License.
37 This program is distributed in the hope that it will be useful,
38 but WITHOUT ANY WARRANTY; without even the implied warranty of
39 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
40 GNU General Public License for more details.
43 THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
44 CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
45 LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
46 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
47 solely responsible for determining the appropriateness of using and
48 distributing the Program and assumes all risks associated with its
49 exercise of rights under this Agreement, including but not limited to
50 the risks and costs of program errors, damage to or loss of data,
51 programs or equipment, and unavailability or interruption of operations.
53 DISCLAIMER OF LIABILITY
54 NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
55 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
56 DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
57 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
58 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
59 USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
60 HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
62 You should have received a copy of the GNU General Public License
63 along with this program; if not, write to the Free Software
64 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
66 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
68 #include "linux_compat.h" /* linux-2.6 tweaks */
69 #include <linux/module.h>
70 #include <linux/kernel.h>
71 #include <linux/init.h>
72 #include <linux/errno.h>
73 #include <linux/kdev_t.h>
74 #include <linux/blkdev.h>
75 #include <linux/delay.h> /* for mdelay */
76 #include <linux/interrupt.h> /* needed for in_interrupt() proto */
77 #include <linux/reboot.h> /* notifier code */
78 #include <linux/sched.h>
79 #include <linux/workqueue.h>
81 #include <scsi/scsi.h>
82 #include <scsi/scsi_cmnd.h>
83 #include <scsi/scsi_device.h>
84 #include <scsi/scsi_host.h>
85 #include <scsi/scsi_tcq.h>
90 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
91 #define my_NAME "Fusion MPT SCSI Host driver"
92 #define my_VERSION MPT_LINUX_VERSION_COMMON
93 #define MYNAM "mptscsih"
95 MODULE_AUTHOR(MODULEAUTHOR);
96 MODULE_DESCRIPTION(my_NAME);
97 MODULE_LICENSE("GPL");
99 /* Set string for command line args from insmod */
101 char *mptscsih = NULL;
102 MODULE_PARM(mptscsih, "s");
105 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
107 typedef struct _BIG_SENSE_BUF {
108 u8 data[MPT_SENSE_BUFFER_ALLOC];
111 #define MPT_SCANDV_GOOD (0x00000000) /* must be 0 */
112 #define MPT_SCANDV_DID_RESET (0x00000001)
113 #define MPT_SCANDV_SENSE (0x00000002)
114 #define MPT_SCANDV_SOME_ERROR (0x00000004)
115 #define MPT_SCANDV_SELECTION_TIMEOUT (0x00000008)
116 #define MPT_SCANDV_ISSUE_SENSE (0x00000010)
117 #define MPT_SCANDV_FALLBACK (0x00000020)
119 #define MPT_SCANDV_MAX_RETRIES (10)
121 #define MPT_ICFLAG_BUF_CAP 0x01 /* ReadBuffer Read Capacity format */
122 #define MPT_ICFLAG_ECHO 0x02 /* ReadBuffer Echo buffer format */
123 #define MPT_ICFLAG_PHYS_DISK 0x04 /* Any SCSI IO but do Phys Disk Format */
124 #define MPT_ICFLAG_TAGGED_CMD 0x08 /* Do tagged IO */
125 #define MPT_ICFLAG_DID_RESET 0x20 /* Bus Reset occurred with this command */
126 #define MPT_ICFLAG_RESERVED 0x40 /* Reserved has been issued */
128 typedef struct _internal_cmd {
129 char *data; /* data pointer */
130 dma_addr_t data_dma; /* data dma address */
131 int size; /* transfer size */
132 u8 cmd; /* SCSI Op Code */
133 u8 bus; /* bus number */
134 u8 id; /* SCSI ID (virtual) */
136 u8 flags; /* Bit Field - See above */
137 u8 physDiskNum; /* Phys disk number, -1 else */
142 typedef struct _negoparms {
149 typedef struct _dv_parameters {
159 * Other private/forward protos...
161 static int mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
162 static void mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq);
163 static int mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
165 static int mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
166 SCSIIORequest_t *pReq, int req_idx);
167 static void mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx);
168 static void copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply);
169 static int mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd);
170 static u32 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc);
172 static int mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout, int sleepFlag);
173 static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout, int sleepFlag);
175 static int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
176 static int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
178 static void mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *data, int dlen);
179 static void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56);
180 static void mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq);
181 static void mptscsih_setDevicePage1Flags (u8 width, u8 factor, u8 offset, int *requestedPtr, int *configurationPtr, u8 flags);
182 static void mptscsih_no_negotiate(MPT_SCSI_HOST *hd, int target_id);
183 static int mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target, int flags);
184 static int mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus);
185 static int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
186 static void mptscsih_timer_expired(unsigned long data);
187 static void mptscsih_taskmgmt_timeout(unsigned long data);
188 static void mptscsih_schedule_reset(void *hd);
189 static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
190 static int mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum);
192 static struct work_struct mptscsih_rstTask;
194 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
195 static int mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io);
196 static void mptscsih_domainValidation(void *hd);
197 static int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id);
198 static void mptscsih_qas_check(MPT_SCSI_HOST *hd, int id);
199 static int mptscsih_doDv(MPT_SCSI_HOST *hd, int channel, int target);
200 static void mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage);
201 static void mptscsih_fillbuf(char *buffer, int size, int index, int width);
204 static int mptscsih_setup(char *str);
206 /* module entry point */
207 static int __init mptscsih_init (void);
208 static void __exit mptscsih_exit (void);
210 static int mptscsih_probe (struct pci_dev *, const struct pci_device_id *);
211 static void mptscsih_remove(struct pci_dev *);
212 static void mptscsih_shutdown(struct device *);
214 static int mptscsih_suspend(struct pci_dev *pdev, u32 state);
215 static int mptscsih_resume(struct pci_dev *pdev);
223 static int mpt_scsi_hosts = 0;
225 static int ScsiDoneCtx = -1;
226 static int ScsiTaskCtx = -1;
227 static int ScsiScanDvCtx = -1; /* Used only for bus scan and dv */
229 #define SNS_LEN(scp) sizeof((scp)->sense_buffer)
231 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
233 * Domain Validation task structure
235 static spinlock_t dvtaskQ_lock = SPIN_LOCK_UNLOCKED;
236 static int dvtaskQ_active = 0;
237 static int dvtaskQ_release = 0;
238 static struct work_struct mptscsih_dvTask;
244 static DECLARE_WAIT_QUEUE_HEAD (scandv_waitq);
245 static int scandv_wait_done = 1;
248 /* Driver default setup
250 static struct mptscsih_driver_setup
251 driver_setup = MPTSCSIH_DRIVER_SETUP;
253 #ifdef MPTSCSIH_DBG_TIMEOUT
254 static struct scsi_cmnd *foo_to[8];
257 static struct scsi_host_template driver_template;
259 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
261 * mptscsih_add_sge - Place a simple SGE at address pAddr.
262 * @pAddr: virtual address for SGE
263 * @flagslength: SGE flags and data transfer length
264 * @dma_addr: Physical address
266 * This routine places a MPT request frame back on the MPT adapter's
270 mptscsih_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
272 if (sizeof(dma_addr_t) == sizeof(u64)) {
273 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
274 u32 tmp = dma_addr & 0xFFFFFFFF;
276 pSge->FlagsLength = cpu_to_le32(flagslength);
277 pSge->Address.Low = cpu_to_le32(tmp);
278 tmp = (u32) ((u64)dma_addr >> 32);
279 pSge->Address.High = cpu_to_le32(tmp);
282 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
283 pSge->FlagsLength = cpu_to_le32(flagslength);
284 pSge->Address = cpu_to_le32(dma_addr);
286 } /* mptscsih_add_sge() */
288 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
290 * mptscsih_add_chain - Place a chain SGE at address pAddr.
291 * @pAddr: virtual address for SGE
292 * @next: nextChainOffset value (u32's)
293 * @length: length of next SGL segment
294 * @dma_addr: Physical address
296 * This routine places a MPT request frame back on the MPT adapter's
300 mptscsih_add_chain(char *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
302 if (sizeof(dma_addr_t) == sizeof(u64)) {
303 SGEChain64_t *pChain = (SGEChain64_t *) pAddr;
304 u32 tmp = dma_addr & 0xFFFFFFFF;
306 pChain->Length = cpu_to_le16(length);
307 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size();
309 pChain->NextChainOffset = next;
311 pChain->Address.Low = cpu_to_le32(tmp);
312 tmp = (u32) ((u64)dma_addr >> 32);
313 pChain->Address.High = cpu_to_le32(tmp);
315 SGEChain32_t *pChain = (SGEChain32_t *) pAddr;
316 pChain->Length = cpu_to_le16(length);
317 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size();
318 pChain->NextChainOffset = next;
319 pChain->Address = cpu_to_le32(dma_addr);
321 } /* mptscsih_add_chain() */
323 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
325 * mptscsih_getFreeChainBuffer - Function to get a free chain
326 * from the MPT_SCSI_HOST FreeChainQ.
327 * @ioc: Pointer to MPT_ADAPTER structure
328 * @req_idx: Index of the SCSI IO request frame. (output)
330 * return SUCCESS or FAILED
333 mptscsih_getFreeChainBuffer(MPT_ADAPTER *ioc, int *retIndex)
335 MPT_FRAME_HDR *chainBuf;
340 dsgprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer called\n",
342 spin_lock_irqsave(&ioc->FreeQlock, flags);
343 if (!Q_IS_EMPTY(&ioc->FreeChainQ)) {
347 chainBuf = ioc->FreeChainQ.head;
348 Q_DEL_ITEM(&chainBuf->u.frame.linkage);
349 offset = (u8 *)chainBuf - (u8 *)ioc->ChainBuffer;
350 chain_idx = offset / ioc->req_sz;
352 dsgprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer (index %d), got buf=%p\n",
353 ioc->name, *retIndex, chainBuf));
357 chain_idx = MPT_HOST_NO_CHAIN;
358 dfailprintk((MYIOC_s_ERR_FMT "getFreeChainBuffer failed\n",
361 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
364 *retIndex = chain_idx;
367 } /* mptscsih_getFreeChainBuffer() */
369 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
371 * mptscsih_AddSGE - Add a SGE (plus chain buffers) to the
372 * SCSIIORequest_t Message Frame.
373 * @ioc: Pointer to MPT_ADAPTER structure
374 * @SCpnt: Pointer to scsi_cmnd structure
375 * @pReq: Pointer to SCSIIORequest_t structure
380 mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
381 SCSIIORequest_t *pReq, int req_idx)
385 struct scatterlist *sg;
387 int sges_left, sg_done;
388 int chain_idx = MPT_HOST_NO_CHAIN;
390 int numSgeSlots, numSgeThisFrame;
391 u32 sgflags, sgdir, thisxfer = 0;
392 int chain_dma_off = 0;
398 sgdir = le32_to_cpu(pReq->Control) & MPI_SCSIIO_CONTROL_DATADIRECTION_MASK;
399 if (sgdir == MPI_SCSIIO_CONTROL_WRITE) {
400 sgdir = MPT_TRANSFER_HOST_TO_IOC;
402 sgdir = MPT_TRANSFER_IOC_TO_HOST;
405 psge = (char *) &pReq->SGL;
406 frm_sz = ioc->req_sz;
408 /* Map the data portion, if any.
409 * sges_left = 0 if no data transfer.
411 if ( (sges_left = SCpnt->use_sg) ) {
412 sges_left = pci_map_sg(ioc->pcidev,
413 (struct scatterlist *) SCpnt->request_buffer,
415 SCpnt->sc_data_direction);
418 } else if (SCpnt->request_bufflen) {
419 SCpnt->SCp.dma_handle = pci_map_single(ioc->pcidev,
420 SCpnt->request_buffer,
421 SCpnt->request_bufflen,
422 SCpnt->sc_data_direction);
423 dsgprintk((MYIOC_s_INFO_FMT "SG: non-SG for %p, len=%d\n",
424 ioc->name, SCpnt, SCpnt->request_bufflen));
425 mptscsih_add_sge((char *) &pReq->SGL,
426 0xD1000000|MPT_SGE_FLAGS_ADDRESSING|sgdir|SCpnt->request_bufflen,
427 SCpnt->SCp.dma_handle);
432 /* Handle the SG case.
434 sg = (struct scatterlist *) SCpnt->request_buffer;
436 sgeOffset = sizeof(SCSIIORequest_t) - sizeof(SGE_IO_UNION);
439 /* Prior to entering this loop - the following must be set
440 * current MF: sgeOffset (bytes)
441 * chainSge (Null if original MF is not a chain buffer)
442 * sg_done (num SGE done for this MF)
446 numSgeSlots = ((frm_sz - sgeOffset) / (sizeof(u32) + sizeof(dma_addr_t)) );
447 numSgeThisFrame = (sges_left < numSgeSlots) ? sges_left : numSgeSlots;
449 sgflags = MPT_SGE_FLAGS_SIMPLE_ELEMENT | MPT_SGE_FLAGS_ADDRESSING | sgdir;
451 /* Get first (num - 1) SG elements
452 * Skip any SG entries with a length of 0
453 * NOTE: at finish, sg and psge pointed to NEXT data/location positions
455 for (ii=0; ii < (numSgeThisFrame-1); ii++) {
456 thisxfer = sg_dma_len(sg);
458 sg ++; /* Get next SG element from the OS */
463 v2 = sg_dma_address(sg);
464 mptscsih_add_sge(psge, sgflags | thisxfer, v2);
466 sg++; /* Get next SG element from the OS */
467 psge += (sizeof(u32) + sizeof(dma_addr_t));
468 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
472 if (numSgeThisFrame == sges_left) {
473 /* Add last element, end of buffer and end of list flags.
475 sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT |
476 MPT_SGE_FLAGS_END_OF_BUFFER |
477 MPT_SGE_FLAGS_END_OF_LIST;
479 /* Add last SGE and set termination flags.
480 * Note: Last SGE may have a length of 0 - which should be ok.
482 thisxfer = sg_dma_len(sg);
484 v2 = sg_dma_address(sg);
485 mptscsih_add_sge(psge, sgflags | thisxfer, v2);
488 psge += (sizeof(u32) + sizeof(dma_addr_t));
490 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
494 /* The current buffer is a chain buffer,
495 * but there is not another one.
496 * Update the chain element
497 * Offset and Length fields.
499 mptscsih_add_chain((char *)chainSge, 0, sgeOffset, ioc->ChainBufferDMA + chain_dma_off);
501 /* The current buffer is the original MF
502 * and there is no Chain buffer.
504 pReq->ChainOffset = 0;
505 RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor) + 1) & 0x03;
506 dsgprintk((MYIOC_s_ERR_FMT
507 "Single Buffer RequestNB=%x, sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
508 ioc->RequestNB[req_idx] = RequestNB;
511 /* At least one chain buffer is needed.
512 * Complete the first MF
513 * - last SGE element, set the LastElement bit
514 * - set ChainOffset (words) for orig MF
515 * (OR finish previous MF chain buffer)
516 * - update MFStructPtr ChainIndex
517 * - Populate chain element
522 dsgprintk((MYIOC_s_INFO_FMT "SG: Chain Required! sg done %d\n",
523 ioc->name, sg_done));
525 /* Set LAST_ELEMENT flag for last non-chain element
526 * in the buffer. Since psge points at the NEXT
527 * SGE element, go back one SGE element, update the flags
528 * and reset the pointer. (Note: sgflags & thisxfer are already
532 u32 *ptmp = (u32 *) (psge - (sizeof(u32) + sizeof(dma_addr_t)));
533 sgflags = le32_to_cpu(*ptmp);
534 sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT;
535 *ptmp = cpu_to_le32(sgflags);
539 /* The current buffer is a chain buffer.
540 * chainSge points to the previous Chain Element.
541 * Update its chain element Offset and Length (must
542 * include chain element size) fields.
543 * Old chain element is now complete.
545 u8 nextChain = (u8) (sgeOffset >> 2);
546 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
547 mptscsih_add_chain((char *)chainSge, nextChain, sgeOffset, ioc->ChainBufferDMA + chain_dma_off);
549 /* The original MF buffer requires a chain buffer -
551 * Last element in this MF is a chain element.
553 pReq->ChainOffset = (u8) (sgeOffset >> 2);
554 RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor) + 1) & 0x03;
555 dsgprintk((MYIOC_s_ERR_FMT "Chain Buffer Needed, RequestNB=%x sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
556 ioc->RequestNB[req_idx] = RequestNB;
559 sges_left -= sg_done;
562 /* NOTE: psge points to the beginning of the chain element
563 * in current buffer. Get a chain buffer.
565 dsgprintk((MYIOC_s_INFO_FMT
566 "calling getFreeChainBuffer SCSI cmd=%02x (%p)\n",
567 ioc->name, pReq->CDB[0], SCpnt));
568 if ((mptscsih_getFreeChainBuffer(ioc, &newIndex)) == FAILED)
571 /* Update the tracking arrays.
572 * If chainSge == NULL, update ReqToChain, else ChainToChain
575 ioc->ChainToChain[chain_idx] = newIndex;
577 ioc->ReqToChain[req_idx] = newIndex;
579 chain_idx = newIndex;
580 chain_dma_off = ioc->req_sz * chain_idx;
582 /* Populate the chainSGE for the current buffer.
583 * - Set chain buffer pointer to psge and fill
584 * out the Address and Flags fields.
586 chainSge = (char *) psge;
587 dsgprintk((KERN_INFO " Current buff @ %p (index 0x%x)",
590 /* Start the SGE for the next buffer
592 psge = (char *) (ioc->ChainBuffer + chain_dma_off);
596 dsgprintk((KERN_INFO " Chain buff @ %p (index 0x%x)\n",
599 /* Start the SGE for the next buffer
606 } /* mptscsih_AddSGE() */
608 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
610 * mptscsih_io_done - Main SCSI IO callback routine registered to
611 * Fusion MPT (base) driver
612 * @ioc: Pointer to MPT_ADAPTER structure
613 * @mf: Pointer to original MPT request frame
614 * @r: Pointer to MPT reply frame (NULL if TurboReply)
616 * This routine is called from mpt.c::mpt_interrupt() at the completion
617 * of any SCSI IO request.
618 * This routine is registered with the Fusion MPT (base) driver at driver
619 * load/init time via the mpt_register() API call.
621 * Returns 1 indicating alloc'd request frame ptr should be freed.
624 mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
626 struct scsi_cmnd *sc;
628 SCSIIORequest_t *pScsiReq;
629 SCSIIOReply_t *pScsiReply;
632 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
634 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
635 sc = hd->ScsiLookup[req_idx];
637 MPIHeader_t *hdr = (MPIHeader_t *)mf;
639 /* Remark: writeSDP1 will use the ScsiDoneCtx
640 * If a SCSI I/O cmd, device disabled by OS and
641 * completion done. Cannot touch sc struct. Just free mem.
643 if (hdr->Function == MPI_FUNCTION_SCSI_IO_REQUEST)
644 printk(MYIOC_s_ERR_FMT "NULL ScsiCmd ptr!\n",
647 mptscsih_freeChainBuffers(ioc, req_idx);
651 dmfprintk((MYIOC_s_INFO_FMT
652 "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n",
653 ioc->name, mf, mr, sc, req_idx));
655 sc->result = DID_OK << 16; /* Set default reply as OK */
656 pScsiReq = (SCSIIORequest_t *) mf;
657 pScsiReply = (SCSIIOReply_t *) mr;
659 #ifdef MPTSCSIH_DBG_TIMEOUT
660 if (ioc->timeout_cnt > 0) {
663 for (ii=0; ii < 8; ii++) {
664 if (sc == foo_to[ii]) {
665 printk(MYIOC_s_INFO_FMT "complete (%p, %ld)\n",
666 ioc->name, sc, jiffies);
669 if (foo_to[ii] != NULL)
674 ioc->timeout_maxcnt = 0;
675 ioc->timeout_cnt = 0;
680 if (pScsiReply == NULL) {
681 /* special context reply handling */
686 u8 scsi_state, scsi_status;
688 status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK;
689 scsi_state = pScsiReply->SCSIState;
690 scsi_status = pScsiReply->SCSIStatus;
691 xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
693 dreplyprintk((KERN_NOTICE " Reply (%d:%d:%d) mf=%p, mr=%p, sc=%p\n",
694 ioc->id, pScsiReq->TargetID, pScsiReq->LUN[1],
696 dreplyprintk((KERN_NOTICE "IOCStatus=%04xh SCSIState=%02xh"
697 " SCSIStatus=%02xh xfer_cnt=%08xh\n",
698 status, scsi_state, scsi_status, xfer_cnt));
700 if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)
701 copy_sense_data(sc, hd, mf, pScsiReply);
704 * Look for + dump FCP ResponseInfo[]!
706 if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID) {
707 printk(KERN_NOTICE " FCP_ResponseInfo=%08xh\n",
708 le32_to_cpu(pScsiReply->ResponseInfo));
712 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
714 * Maybe: DRIVER_BUSY | SUGGEST_RETRY | DID_SOFT_ERROR (retry)
715 * But not: DID_BUS_BUSY lest one risk
716 * killing interrupt handler:-(
718 sc->result = SAM_STAT_BUSY;
721 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
722 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
723 sc->result = DID_BAD_TARGET << 16;
726 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
727 /* Spoof to SCSI Selection Timeout! */
728 sc->result = DID_NO_CONNECT << 16;
730 if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF)
731 hd->sel_timeout[pScsiReq->TargetID]++;
734 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
735 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
736 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
737 /* Linux handles an unsolicited DID_RESET better
738 * than an unsolicited DID_ABORT.
740 sc->result = DID_RESET << 16;
742 /* GEM Workaround. */
744 mptscsih_no_negotiate(hd, sc->device->id);
747 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
748 sc->resid = sc->request_bufflen - xfer_cnt;
749 if ( xfer_cnt >= sc->underflow ) {
750 /* Sufficient data transfer occurred */
751 sc->result = (DID_OK << 16) | scsi_status;
752 } else if ( xfer_cnt == 0 ) {
753 /* A CRC Error causes this condition; retry */
754 sc->result = (DRIVER_SENSE << 24) | (DID_OK << 16) |
755 (CHECK_CONDITION << 1);
756 sc->sense_buffer[0] = 0x70;
757 sc->sense_buffer[2] = NO_SENSE;
758 sc->sense_buffer[12] = 0;
759 sc->sense_buffer[13] = 0;
761 sc->result = DID_SOFT_ERROR << 16;
763 dreplyprintk((KERN_NOTICE "RESIDUAL_MISMATCH: result=%x on id=%d\n", sc->result, sc->target));
766 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
768 * Do upfront check for valid SenseData and give it
771 sc->result = (DID_OK << 16) | scsi_status;
772 if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
773 /* Have already saved the status and sense data
777 if ( (xfer_cnt == 0) || (sc->underflow > xfer_cnt)) {
778 sc->result = DID_SOFT_ERROR << 16;
780 if (scsi_state & (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)) {
783 sc->result = DID_SOFT_ERROR << 16;
785 else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
786 /* Not real sure here either... */
787 sc->result = DID_RESET << 16;
791 /* Give report and update residual count.
793 dreplyprintk((KERN_NOTICE " sc->underflow={report ERR if < %02xh bytes xfer'd}\n",
795 dreplyprintk((KERN_NOTICE " ActBytesXferd=%02xh\n", xfer_cnt));
797 sc->resid = sc->request_bufflen - xfer_cnt;
798 dreplyprintk((KERN_NOTICE " SET sc->resid=%02xh\n", sc->resid));
802 if (scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)
803 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
807 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
808 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
809 scsi_status = pScsiReply->SCSIStatus;
810 sc->result = (DID_OK << 16) | scsi_status;
811 if (scsi_state == 0) {
813 } else if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
815 * If running against circa 200003dd 909 MPT f/w,
816 * may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL
817 * (QUEUE_FULL) returned from device! --> get 0x0000?128
818 * and with SenseBytes set to 0.
820 if (pScsiReply->SCSIStatus == MPI_SCSI_STATUS_TASK_SET_FULL)
821 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
824 else if (scsi_state &
825 (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)
830 sc->result = DID_SOFT_ERROR << 16;
832 else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
833 /* Not real sure here either... */
834 sc->result = DID_RESET << 16;
836 else if (scsi_state & MPI_SCSI_STATE_QUEUE_TAG_REJECTED) {
837 /* Device Inq. data indicates that it supports
838 * QTags, but rejects QTag messages.
839 * This command completed OK.
841 * Not real sure here either so do nothing... */
844 if (sc->result == MPI_SCSI_STATUS_TASK_SET_FULL)
845 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
848 * Reservation Conflict, Busy,
849 * Command Terminated, CHECK
853 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
854 sc->result = DID_SOFT_ERROR << 16;
857 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
858 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
859 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
860 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
861 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
862 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
863 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
864 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
865 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
866 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
871 sc->result = DID_SOFT_ERROR << 16;
874 } /* switch(status) */
876 dreplyprintk((KERN_NOTICE " sc->result is %08xh\n", sc->result));
877 } /* end of address reply case */
879 /* Unmap the DMA buffers, if any. */
881 pci_unmap_sg(ioc->pcidev, (struct scatterlist *) sc->request_buffer,
882 sc->use_sg, sc->sc_data_direction);
883 } else if (sc->request_bufflen) {
884 pci_unmap_single(ioc->pcidev, sc->SCp.dma_handle,
885 sc->request_bufflen, sc->sc_data_direction);
888 hd->ScsiLookup[req_idx] = NULL;
890 sc->scsi_done(sc); /* Issue the command callback */
892 /* Free Chain buffers */
893 mptscsih_freeChainBuffers(ioc, req_idx);
899 * mptscsih_flush_running_cmds - For each command found, search
900 * Scsi_Host instance taskQ and reply to OS.
901 * Called only if recovering from a FW reload.
902 * @hd: Pointer to a SCSI HOST structure
906 * Must be called while new I/Os are being queued.
909 mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
911 MPT_ADAPTER *ioc = hd->ioc;
912 struct scsi_cmnd *SCpnt;
915 int max = ioc->req_depth;
917 dprintk((KERN_INFO MYNAM ": flush_ScsiLookup called\n"));
918 for (ii= 0; ii < max; ii++) {
919 if ((SCpnt = hd->ScsiLookup[ii]) != NULL) {
924 /* Null ScsiLookup index
926 hd->ScsiLookup[ii] = NULL;
928 mf = MPT_INDEX_2_MFPTR(ioc, ii);
929 dmfprintk(( "flush: ScsiDone (mf=%p,sc=%p)\n",
932 /* Set status, free OS resources (SG DMA buffers)
934 * Free driver resources (chain, msg buffers)
936 if (scsi_device_online(SCpnt->device)) {
938 pci_unmap_sg(ioc->pcidev,
939 (struct scatterlist *) SCpnt->request_buffer,
941 SCpnt->sc_data_direction);
942 } else if (SCpnt->request_bufflen) {
943 pci_unmap_single(ioc->pcidev,
944 SCpnt->SCp.dma_handle,
945 SCpnt->request_bufflen,
946 SCpnt->sc_data_direction);
949 SCpnt->result = DID_RESET << 16;
950 SCpnt->host_scribble = NULL;
952 /* Free Chain buffers */
953 mptscsih_freeChainBuffers(ioc, ii);
955 /* Free Message frames */
956 mpt_free_msg_frame(ioc, mf);
958 SCpnt->scsi_done(SCpnt); /* Issue the command callback */
966 * mptscsih_search_running_cmds - Delete any commands associated
967 * with the specified target and lun. Function called only
968 * when a lun is disable by mid-layer.
969 * Do NOT access the referenced scsi_cmnd structure or
970 * members. Will cause either a paging or NULL ptr error.
971 * @hd: Pointer to a SCSI HOST structure
977 * Called from slave_destroy.
980 mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, uint target, uint lun)
982 SCSIIORequest_t *mf = NULL;
984 int max = hd->ioc->req_depth;
986 dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n",
989 for (ii=0; ii < max; ii++) {
990 if (hd->ScsiLookup[ii] != NULL) {
992 mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii);
994 dsprintk(( "search_running: found (sc=%p, mf = %p) target %d, lun %d \n",
995 hd->ScsiLookup[ii], mf, mf->TargetID, mf->LUN[1]));
997 if ((mf->TargetID != ((u8)target)) || (mf->LUN[1] != ((u8) lun)))
1002 hd->ScsiLookup[ii] = NULL;
1003 mptscsih_freeChainBuffers(hd->ioc, ii);
1004 mpt_free_msg_frame(hd->ioc, (MPT_FRAME_HDR *)mf);
1011 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1013 * Hack! It might be nice to report if a device is returning QUEUE_FULL
1014 * but maybe not each and every time...
1016 static long last_queue_full = 0;
1018 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1020 * mptscsih_report_queue_full - Report QUEUE_FULL status returned
1021 * from a SCSI target device.
1022 * @sc: Pointer to scsi_cmnd structure
1023 * @pScsiReply: Pointer to SCSIIOReply_t
1024 * @pScsiReq: Pointer to original SCSI request
1026 * This routine periodically reports QUEUE_FULL status returned from a
1027 * SCSI target device. It reports this to the console via kernel
1028 * printk() API call, not more than once every 10 seconds.
1031 mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq)
1033 long time = jiffies;
1035 if (time - last_queue_full > 10 * HZ) {
1036 char *ioc_str = "ioc?";
1038 if (sc->device && sc->device->host != NULL && sc->device->host->hostdata != NULL)
1039 ioc_str = ((MPT_SCSI_HOST *)sc->device->host->hostdata)->ioc->name;
1040 dprintk((MYIOC_s_WARN_FMT "Device (%d:%d:%d) reported QUEUE_FULL!\n",
1041 ioc_str, 0, sc->device->id, sc->device->lun));
1042 last_queue_full = time;
1046 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1047 static char *info_kbuf = NULL;
1049 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1050 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1052 * mptscsih_probe - Installs scsi devices per bus.
1053 * @pdev: Pointer to pci_dev structure
1055 * Returns 0 for success, non-zero for failure.
1060 mptscsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1062 struct Scsi_Host *sh;
1064 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1065 unsigned long flags;
1074 /* 20010202 -sralston
1075 * Added sanity check on readiness of the MPT adapter.
1077 if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
1078 printk(MYIOC_s_WARN_FMT
1079 "Skipping because it's not operational!\n",
1085 printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
1090 /* Sanity check - ensure at least 1 port is INITIATOR capable
1093 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
1094 if (ioc->pfacts[ii].ProtocolFlags &
1095 MPI_PORTFACTS_PROTOCOL_INITIATOR)
1100 printk(MYIOC_s_WARN_FMT
1101 "Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n",
1106 sh = scsi_host_alloc(&driver_template, sizeof(MPT_SCSI_HOST));
1109 printk(MYIOC_s_WARN_FMT
1110 "Unable to register controller with SCSI subsystem\n",
1115 spin_lock_irqsave(&ioc->FreeQlock, flags);
1117 /* Attach the SCSI Host to the IOC structure
1125 /* set 16 byte cdb's */
1126 sh->max_cmd_len = 16;
1128 /* Yikes! This is important!
1129 * Otherwise, by default, linux
1130 * only scans target IDs 0-7!
1131 * pfactsN->MaxDevices unreliable
1132 * (not supported in early
1133 * versions of the FW).
1134 * max_id = 1 + actual max id,
1135 * max_lun = 1 + actual last lun,
1138 if ((int)ioc->chip_type > (int)FC929) {
1139 sh->max_id = MPT_MAX_SCSI_DEVICES;
1141 /* For FC, increase the queue depth
1142 * from MPT_SCSI_CAN_QUEUE (31)
1143 * to MPT_FC_CAN_QUEUE (63).
1145 sh->can_queue = MPT_FC_CAN_QUEUE;
1147 MPT_MAX_FC_DEVICES<256 ? MPT_MAX_FC_DEVICES : 255;
1150 sh->max_lun = MPT_LAST_LUN + 1;
1151 sh->max_channel = 0;
1152 sh->this_id = ioc->pfacts[0].PortSCSIID;
1156 sh->unique_id = ioc->id;
1158 /* Verify that we won't exceed the maximum
1159 * number of chain buffers
1160 * We can optimize: ZZ = req_sz/sizeof(SGE)
1162 * numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
1163 * + (req_sz - 64)/sizeof(SGE)
1164 * A slightly different algorithm is required for
1167 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
1168 if (sizeof(dma_addr_t) == sizeof(u64)) {
1169 numSGE = (scale - 1) *
1170 (ioc->facts.MaxChainDepth-1) + scale +
1171 (ioc->req_sz - 60) / (sizeof(dma_addr_t) +
1174 numSGE = 1 + (scale - 1) *
1175 (ioc->facts.MaxChainDepth-1) + scale +
1176 (ioc->req_sz - 64) / (sizeof(dma_addr_t) +
1180 if (numSGE < sh->sg_tablesize) {
1181 /* Reset this value */
1182 dprintk((MYIOC_s_INFO_FMT
1183 "Resetting sg_tablesize to %d from %d\n",
1184 ioc->name, numSGE, sh->sg_tablesize));
1185 sh->sg_tablesize = numSGE;
1188 /* Set the pci device pointer in Scsi_Host structure.
1190 scsi_set_device(sh, &ioc->pcidev->dev);
1192 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1194 hd = (MPT_SCSI_HOST *) sh->hostdata;
1197 if ((int)ioc->chip_type > (int)FC929)
1200 if (DmpService && (ioc->chip_type == FC919 ||
1201 ioc->chip_type == FC929)) {
1202 hd->is_multipath = 1;
1205 /* SCSI needs scsi_cmnd lookup table!
1206 * (with size equal to req_depth*PtrSz!)
1208 sz = ioc->req_depth * sizeof(void *);
1209 mem = kmalloc(sz, GFP_ATOMIC);
1212 goto mptscsih_probe_failed;
1216 hd->ScsiLookup = (struct scsi_cmnd **) mem;
1218 dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n",
1219 ioc->name, hd->ScsiLookup, sz));
1221 /* Initialize this Scsi_Host
1224 Q_INIT(&hd->taskQ, MPT_FRAME_HDR);
1227 /* Allocate memory for the device structures.
1228 * A non-Null pointer at an offset
1229 * indicates a device exists.
1230 * max_id = 1 + maximum id (hosts.h)
1232 sz = sh->max_id * sizeof(void *);
1233 mem = kmalloc(sz, GFP_ATOMIC);
1236 goto mptscsih_probe_failed;
1240 hd->Targets = (VirtDevice **) mem;
1243 " Targets @ %p, sz=%d\n", hd->Targets, sz));
1245 /* Clear the TM flags
1248 hd->tmState = TM_STATE_NONE;
1249 hd->resetPending = 0;
1250 hd->abortSCpnt = NULL;
1253 /* Clear the pointer used to store
1254 * single-threaded commands, i.e., those
1255 * issued during a bus scan, dv and
1256 * configuration pages.
1260 /* Initialize this SCSI Hosts' timers
1261 * To use, set the timer expires field
1264 init_timer(&hd->timer);
1265 hd->timer.data = (unsigned long) hd;
1266 hd->timer.function = mptscsih_timer_expired;
1268 init_timer(&hd->TMtimer);
1269 hd->TMtimer.data = (unsigned long) hd;
1270 hd->TMtimer.function = mptscsih_taskmgmt_timeout;
1271 hd->qtag_tick = jiffies;
1273 /* Moved Earlier Pam D */
1276 #ifdef MPTSCSIH_DBG_TIMEOUT
1277 ioc->timeout_hard = 0;
1278 ioc->timeout_delta = 30 * HZ;
1279 ioc->timeout_maxcnt = 0;
1280 ioc->timeout_cnt = 0;
1281 for (ii=0; ii < 8; ii++)
1285 /* Update with the driver setup
1288 if (ioc->spi_data.maxBusWidth >
1289 driver_setup.max_width) {
1290 ioc->spi_data.maxBusWidth =
1291 driver_setup.max_width;
1294 if (ioc->spi_data.minSyncFactor <
1295 driver_setup.min_sync_fac) {
1296 ioc->spi_data.minSyncFactor =
1297 driver_setup.min_sync_fac;
1300 if (ioc->spi_data.minSyncFactor == MPT_ASYNC) {
1301 ioc->spi_data.maxSyncOffset = 0;
1304 ioc->spi_data.Saf_Te = driver_setup.saf_te;
1307 #ifndef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1308 hd->negoNvram = MPT_SCSICFG_USE_NVRAM;
1310 ioc->spi_data.forceDv = 0;
1311 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
1312 ioc->spi_data.dvStatus[ii] =
1313 MPT_SCSICFG_NEGOTIATE;
1316 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++)
1317 ioc->spi_data.dvStatus[ii] |=
1318 MPT_SCSICFG_DV_NOT_DONE;
1320 ddvprintk((MYIOC_s_INFO_FMT
1321 "dv %x width %x factor %x saf_te %x\n",
1322 ioc->name, driver_setup.dv,
1323 driver_setup.max_width,
1324 driver_setup.min_sync_fac,
1325 driver_setup.saf_te));
1330 error = scsi_add_host (sh, &ioc->pcidev->dev);
1332 dprintk((KERN_ERR MYNAM
1333 "scsi_add_host failed\n"));
1334 goto mptscsih_probe_failed;
1340 mptscsih_probe_failed:
1342 mptscsih_remove(pdev);
1347 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1349 * mptscsih_remove - Removed scsi devices
1350 * @pdev: Pointer to pci_dev structure
1355 mptscsih_remove(struct pci_dev *pdev)
1357 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1358 struct Scsi_Host *host = ioc->sh;
1361 unsigned long flags;
1366 scsi_remove_host(host);
1368 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1369 /* Check DV thread active */
1371 spin_lock_irqsave(&dvtaskQ_lock, flags);
1372 if (dvtaskQ_active) {
1373 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
1374 while(dvtaskQ_active && --count) {
1375 set_current_state(TASK_INTERRUPTIBLE);
1376 schedule_timeout(1);
1379 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
1382 printk(KERN_ERR MYNAM ": ERROR - DV thread still active!\n");
1383 #if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY)
1385 printk(KERN_ERR MYNAM ": DV thread orig %d, count %d\n", 10 * HZ, count);
1389 hd = (MPT_SCSI_HOST *)host->hostdata;
1391 int sz1, sz3, sztarget=0;
1393 mptscsih_shutdown(&pdev->dev);
1397 if (hd->ScsiLookup != NULL) {
1398 sz1 = hd->ioc->req_depth * sizeof(void *);
1399 kfree(hd->ScsiLookup);
1400 hd->ScsiLookup = NULL;
1403 if (hd->Targets != NULL) {
1407 * Free any target structures that were allocated.
1410 max = MPT_MAX_SCSI_DEVICES;
1412 max = MPT_MAX_FC_DEVICES<256 ? MPT_MAX_FC_DEVICES : 255;
1414 for (ii=0; ii < max; ii++) {
1415 if (hd->Targets[ii]) {
1416 kfree(hd->Targets[ii]);
1417 hd->Targets[ii] = NULL;
1418 sztarget += sizeof(VirtDevice);
1423 * Free pointer array.
1425 sz3 = max * sizeof(void *);
1430 dprintk((MYIOC_s_INFO_FMT
1431 "Free'd ScsiLookup (%d) Target (%d+%d) memory\n",
1432 hd->ioc->name, sz1, sz3, sztarget));
1433 dprintk(("Free'd done and free Q (%d) memory\n", szQ));
1435 /* NULL the Scsi_Host pointer
1440 scsi_host_put(host);
1445 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1447 * mptscsih_shutdown - reboot notifier
1451 mptscsih_shutdown(struct device * dev)
1453 MPT_ADAPTER *ioc = pci_get_drvdata(to_pci_dev(dev));
1454 struct Scsi_Host *host = ioc->sh;
1460 hd = (MPT_SCSI_HOST *)host->hostdata;
1462 /* Flush the cache of this adapter
1465 mptscsih_synchronize_cache(hd, 0);
1470 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1472 * mptscsih_suspend - Fusion MPT scsie driver suspend routine.
1477 mptscsih_suspend(struct pci_dev *pdev, u32 state)
1479 mptscsih_shutdown(&pdev->dev);
1483 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1485 * mptscsih_resume - Fusion MPT scsi driver resume routine.
1490 mptscsih_resume(struct pci_dev *pdev)
1492 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1493 struct Scsi_Host *host = ioc->sh;
1499 hd = (MPT_SCSI_HOST *)host->hostdata;
1503 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1505 unsigned long lflags;
1506 spin_lock_irqsave(&dvtaskQ_lock, lflags);
1507 if (!dvtaskQ_active) {
1509 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1510 INIT_WORK(&mptscsih_dvTask,
1511 mptscsih_domainValidation, (void *) hd);
1512 schedule_work(&mptscsih_dvTask);
1514 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1523 static struct mpt_pci_driver mptscsih_driver = {
1524 .probe = mptscsih_probe,
1525 .remove = mptscsih_remove,
1526 .shutdown = mptscsih_shutdown,
1528 .suspend = mptscsih_suspend,
1529 .resume = mptscsih_resume,
1533 /* SCSI host fops start here... */
1534 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1536 * mptscsih_init - Register MPT adapter(s) as SCSI host(s) with
1537 * linux scsi mid-layer.
1539 * Returns 0 for success, non-zero for failure.
1545 show_mptmod_ver(my_NAME, my_VERSION);
1547 ScsiDoneCtx = mpt_register(mptscsih_io_done, MPTSCSIH_DRIVER);
1548 ScsiTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSCSIH_DRIVER);
1549 ScsiScanDvCtx = mpt_register(mptscsih_scandv_complete, MPTSCSIH_DRIVER);
1551 if (mpt_event_register(ScsiDoneCtx, mptscsih_event_process) == 0) {
1552 devtprintk((KERN_INFO MYNAM
1553 ": Registered for IOC event notifications\n"));
1556 if (mpt_reset_register(ScsiDoneCtx, mptscsih_ioc_reset) == 0) {
1557 dprintk((KERN_INFO MYNAM
1558 ": Registered for IOC reset notifications\n"));
1562 /* Evaluate the command line arguments, if any */
1564 mptscsih_setup(mptscsih);
1567 if(mpt_device_driver_register(&mptscsih_driver,
1568 MPTSCSIH_DRIVER) != 0 ) {
1569 dprintk((KERN_INFO MYNAM
1570 ": failed to register dd callbacks\n"));
1577 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1578 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1580 * mptscsih_exit - Unregisters MPT adapter(s)
1586 mpt_device_driver_deregister(MPTSCSIH_DRIVER);
1588 mpt_reset_deregister(ScsiDoneCtx);
1589 dprintk((KERN_INFO MYNAM
1590 ": Deregistered for IOC reset notifications\n"));
1592 mpt_event_deregister(ScsiDoneCtx);
1593 dprintk((KERN_INFO MYNAM
1594 ": Deregistered for IOC event notifications\n"));
1596 mpt_deregister(ScsiScanDvCtx);
1597 mpt_deregister(ScsiTaskCtx);
1598 mpt_deregister(ScsiDoneCtx);
1600 if (info_kbuf != NULL)
1605 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1607 * mptscsih_info - Return information about MPT adapter
1608 * @SChost: Pointer to Scsi_Host structure
1610 * (linux scsi_host_template.info routine)
1612 * Returns pointer to buffer where information was written.
1615 mptscsih_info(struct Scsi_Host *SChost)
1620 if (info_kbuf == NULL)
1621 if ((info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)
1624 h = (MPT_SCSI_HOST *)SChost->hostdata;
1625 info_kbuf[0] = '\0';
1627 mpt_print_ioc_summary(h->ioc, info_kbuf, &size, 0, 0);
1628 info_kbuf[size-1] = '\0';
1641 static void copy_mem_info(struct info_str *info, char *data, int len)
1643 if (info->pos + len > info->length)
1644 len = info->length - info->pos;
1646 if (info->pos + len < info->offset) {
1651 if (info->pos < info->offset) {
1652 data += (info->offset - info->pos);
1653 len -= (info->offset - info->pos);
1657 memcpy(info->buffer + info->pos, data, len);
1662 static int copy_info(struct info_str *info, char *fmt, ...)
1668 va_start(args, fmt);
1669 len = vsprintf(buf, fmt, args);
1672 copy_mem_info(info, buf, len);
1676 static int mptscsih_host_info(MPT_ADAPTER *ioc, char *pbuf, off_t offset, int len)
1678 struct info_str info;
1682 info.offset = offset;
1685 copy_info(&info, "%s: %s, ", ioc->name, ioc->prod_name);
1686 copy_info(&info, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING, ioc->facts.FWVersion.Word);
1687 copy_info(&info, "Ports=%d, ", ioc->facts.NumberOfPorts);
1688 copy_info(&info, "MaxQ=%d\n", ioc->req_depth);
1690 return ((info.pos > info.offset) ? info.pos - info.offset : 0);
1693 #ifndef MPTSCSIH_DBG_TIMEOUT
1694 static int mptscsih_user_command(MPT_ADAPTER *ioc, char *pbuf, int len)
1696 /* Not yet implemented */
1700 #define is_digit(c) ((c) >= '0' && (c) <= '9')
1701 #define digit_to_bin(c) ((c) - '0')
1702 #define is_space(c) ((c) == ' ' || (c) == '\t')
1704 #define UC_DBG_TIMEOUT 0x01
1705 #define UC_DBG_HARDRESET 0x02
1707 static int skip_spaces(char *ptr, int len)
1711 for (cnt = len; cnt > 0 && (c = *ptr++) && is_space(c); cnt --);
1716 static int get_int_arg(char *ptr, int len, ulong *pv)
1720 for (v = 0, cnt = len; cnt > 0 && (c=*ptr++) && is_digit(c); cnt --) {
1721 v = (v * 10) + digit_to_bin(c);
1731 static int is_keyword(char *ptr, int len, char *verb)
1733 int verb_len = strlen(verb);
1735 if (len >= strlen(verb) && !memcmp(verb, ptr, verb_len))
1741 #define SKIP_SPACES(min_spaces) \
1742 if ((arg_len = skip_spaces(ptr,len)) < (min_spaces)) \
1747 #define GET_INT_ARG(v) \
1748 if (!(arg_len = get_int_arg(ptr,len, &(v)))) \
1753 static int mptscsih_user_command(MPT_ADAPTER *ioc, char *buffer, int length)
1756 char btmp[24]; /* REMOVE */
1763 if ((len > 0) && (ptr[len -1] == '\n'))
1767 strncpy(btmp, buffer, len);
1770 strncpy(btmp, buffer, 22);
1773 printk("user_command: ioc %d, buffer %s, length %d\n",
1774 ioc->id, btmp, length);
1776 if ((arg_len = is_keyword(ptr, len, "timeout")) != 0)
1777 cmd = UC_DBG_TIMEOUT;
1778 else if ((arg_len = is_keyword(ptr, len, "hardreset")) != 0)
1779 cmd = UC_DBG_HARDRESET;
1787 case UC_DBG_TIMEOUT:
1789 GET_INT_ARG(number);
1795 printk("user_command: cnt=%ld delta=%ld\n", number, delta);
1800 if (cmd == UC_DBG_HARDRESET) {
1801 ioc->timeout_hard = 1;
1802 } else if (cmd == UC_DBG_TIMEOUT) {
1803 /* process this command ...
1805 ioc->timeout_maxcnt = 0;
1806 ioc->timeout_delta = delta < 2 ? 2 : delta;
1807 ioc->timeout_cnt = 0;
1808 ioc->timeout_maxcnt = number < 8 ? number: 8;
1811 /* Not yet implemented */
1816 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1818 * mptscsih_proc_info - Return information about MPT adapter
1820 * (linux scsi_host_template.info routine)
1822 * buffer: if write, user data; if read, buffer for user
1823 * length: if write, return length;
1824 * offset: if write, 0; if read, the current offset into the buffer from
1825 * the previous read.
1826 * hostno: scsi host number
1827 * func: if write = 1; if read = 0
1830 mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
1831 int length, int func)
1833 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
1834 MPT_ADAPTER *ioc = hd->ioc;
1838 size = mptscsih_user_command(ioc, buffer, length);
1843 size = mptscsih_host_info(ioc, buffer, offset, length);
1850 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1851 #define ADD_INDEX_LOG(req_ent) do { } while(0)
1853 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1855 * mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine.
1856 * @SCpnt: Pointer to scsi_cmnd structure
1857 * @done: Pointer SCSI mid-layer IO completion function
1859 * (linux scsi_host_template.queuecommand routine)
1860 * This is the primary SCSI IO start routine. Create a MPI SCSIIORequest
1861 * from a linux scsi_cmnd request and send it to the IOC.
1863 * Returns 0. (rtn value discarded by linux scsi mid-layer)
1866 mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1870 SCSIIORequest_t *pScsiReq;
1871 VirtDevice *pTarget;
1885 hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata;
1886 target = SCpnt->device->id;
1887 lun = SCpnt->device->lun;
1888 SCpnt->scsi_done = done;
1890 pTarget = hd->Targets[target];
1892 dmfprintk((MYIOC_s_INFO_FMT "qcmd: SCpnt=%p, done()=%p\n",
1893 (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt, done));
1895 if (hd->resetPending) {
1896 dtmprintk((MYIOC_s_WARN_FMT "qcmd: SCpnt=%p timeout + 60HZ\n",
1897 (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt));
1898 return SCSI_MLQUEUE_HOST_BUSY;
1902 * Put together a MPT SCSI request...
1904 if ((mf = mpt_get_msg_frame(ScsiDoneCtx, hd->ioc)) == NULL) {
1905 dprintk((MYIOC_s_WARN_FMT "QueueCmd, no msg frames!!\n",
1907 return SCSI_MLQUEUE_HOST_BUSY;
1910 pScsiReq = (SCSIIORequest_t *) mf;
1912 my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
1914 ADD_INDEX_LOG(my_idx);
1916 /* BUG FIX! 19991030 -sralston
1917 * TUR's being issued with scsictl=0x02000000 (DATA_IN)!
1918 * Seems we may receive a buffer (datalen>0) even when there
1919 * will be no data transfer! GRRRRR...
1921 if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
1922 datalen = SCpnt->request_bufflen;
1923 scsidir = MPI_SCSIIO_CONTROL_READ; /* DATA IN (host<--ioc<--dev) */
1924 } else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
1925 datalen = SCpnt->request_bufflen;
1926 scsidir = MPI_SCSIIO_CONTROL_WRITE; /* DATA OUT (host-->ioc-->dev) */
1929 scsidir = MPI_SCSIIO_CONTROL_NODATATRANSFER;
1932 /* Default to untagged. Once a target structure has been allocated,
1933 * use the Inquiry data to determine if device supports tagged.
1936 && (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)
1937 && (SCpnt->device->tagged_supported)) {
1938 scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
1940 scsictl = scsidir | MPI_SCSIIO_CONTROL_UNTAGGED;
1943 /* Use the above information to set up the message frame
1945 pScsiReq->TargetID = (u8) target;
1946 pScsiReq->Bus = (u8) SCpnt->device->channel;
1947 pScsiReq->ChainOffset = 0;
1948 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
1949 pScsiReq->CDBLength = SCpnt->cmd_len;
1950 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
1951 pScsiReq->Reserved = 0;
1952 pScsiReq->MsgFlags = mpt_msg_flags();
1953 pScsiReq->LUN[0] = 0;
1954 pScsiReq->LUN[1] = lun;
1955 pScsiReq->LUN[2] = 0;
1956 pScsiReq->LUN[3] = 0;
1957 pScsiReq->LUN[4] = 0;
1958 pScsiReq->LUN[5] = 0;
1959 pScsiReq->LUN[6] = 0;
1960 pScsiReq->LUN[7] = 0;
1961 pScsiReq->Control = cpu_to_le32(scsictl);
1964 * Write SCSI CDB into the message
1966 cmd_len = SCpnt->cmd_len;
1967 for (ii=0; ii < cmd_len; ii++)
1968 pScsiReq->CDB[ii] = SCpnt->cmnd[ii];
1970 for (ii=cmd_len; ii < 16; ii++)
1971 pScsiReq->CDB[ii] = 0;
1974 pScsiReq->DataLength = cpu_to_le32(datalen);
1976 /* SenseBuffer low address */
1977 pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
1978 + (my_idx * MPT_SENSE_BUFFER_ALLOC));
1980 /* Now add the SG list
1981 * Always have a SGE even if null length.
1985 /* Add a NULL SGE */
1986 mptscsih_add_sge((char *)&pScsiReq->SGL, MPT_SGE_FLAGS_SSIMPLE_READ | 0,
1989 /* Add a 32 or 64 bit SGE */
1990 rc = mptscsih_AddSGE(hd->ioc, SCpnt, pScsiReq, my_idx);
1994 if (rc == SUCCESS) {
1995 hd->ScsiLookup[my_idx] = SCpnt;
1996 SCpnt->host_scribble = NULL;
1998 /* SCSI specific processing */
2001 int dvStatus = hd->ioc->spi_data.dvStatus[target];
2003 if (dvStatus || hd->ioc->spi_data.forceDv) {
2005 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
2006 if ((dvStatus & MPT_SCSICFG_NEED_DV) ||
2007 (hd->ioc->spi_data.forceDv & MPT_SCSICFG_NEED_DV)) {
2008 unsigned long lflags;
2009 /* Schedule DV if necessary */
2010 spin_lock_irqsave(&dvtaskQ_lock, lflags);
2011 if (!dvtaskQ_active) {
2013 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
2014 INIT_WORK(&mptscsih_dvTask, mptscsih_domainValidation, (void *) hd);
2016 schedule_work(&mptscsih_dvTask);
2018 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
2020 hd->ioc->spi_data.forceDv &= ~MPT_SCSICFG_NEED_DV;
2023 /* Trying to do DV to this target, extend timeout.
2024 * Wait to issue until flag is clear
2026 if (dvStatus & MPT_SCSICFG_DV_PENDING) {
2027 mod_timer(&SCpnt->eh_timeout, jiffies + 40 * HZ);
2031 /* Set the DV flags.
2033 if (dvStatus & MPT_SCSICFG_DV_NOT_DONE)
2034 mptscsih_set_dvflags(hd, pScsiReq);
2039 #ifdef MPTSCSIH_DBG_TIMEOUT
2040 if (hd->ioc->timeout_cnt < hd->ioc->timeout_maxcnt) {
2041 foo_to[hd->ioc->timeout_cnt] = SCpnt;
2042 hd->ioc->timeout_cnt++;
2043 //mod_timer(&SCpnt->eh_timeout, jiffies + hd->ioc->timeout_delta);
2045 printk(MYIOC_s_WARN_FMT
2046 "to pendingQ: (sc=%p, mf=%p, time=%ld)\n",
2047 hd->ioc->name, SCpnt, mf, jiffies);
2052 mpt_put_msg_frame(ScsiDoneCtx, hd->ioc, mf);
2053 dmfprintk((MYIOC_s_INFO_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n",
2054 hd->ioc->name, SCpnt, mf, my_idx));
2055 DBG_DUMP_REQUEST_FRAME(mf)
2064 mptscsih_freeChainBuffers(hd->ioc, my_idx);
2065 mpt_free_msg_frame(hd->ioc, mf);
2066 return SCSI_MLQUEUE_HOST_BUSY;
2069 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2071 * mptscsih_freeChainBuffers - Function to free chain buffers associated
2072 * with a SCSI IO request
2073 * @hd: Pointer to the MPT_SCSI_HOST instance
2074 * @req_idx: Index of the SCSI IO request frame.
2076 * Called if SG chain buffer allocation fails and mptscsih callbacks.
2080 mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
2082 MPT_FRAME_HDR *chain;
2083 unsigned long flags;
2087 /* Get the first chain index and reset
2090 chain_idx = ioc->ReqToChain[req_idx];
2091 ioc->ReqToChain[req_idx] = MPT_HOST_NO_CHAIN;
2093 while (chain_idx != MPT_HOST_NO_CHAIN) {
2095 /* Save the next chain buffer index */
2096 next = ioc->ChainToChain[chain_idx];
2098 /* Free this chain buffer and reset
2101 ioc->ChainToChain[chain_idx] = MPT_HOST_NO_CHAIN;
2103 chain = (MPT_FRAME_HDR *) (ioc->ChainBuffer
2104 + (chain_idx * ioc->req_sz));
2105 spin_lock_irqsave(&ioc->FreeQlock, flags);
2106 Q_ADD_TAIL(&ioc->FreeChainQ.head,
2107 &chain->u.frame.linkage, MPT_FRAME_HDR);
2108 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2110 dmfprintk((MYIOC_s_INFO_FMT "FreeChainBuffers (index %d)\n",
2111 ioc->name, chain_idx));
2119 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2124 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2126 * mptscsih_TMHandler - Generic handler for SCSI Task Management.
2127 * Fall through to mpt_HardResetHandler if: not operational, too many
2128 * failed TM requests or handshake failure.
2130 * @ioc: Pointer to MPT_ADAPTER structure
2131 * @type: Task Management type
2132 * @target: Logical Target ID for reset (if appropriate)
2133 * @lun: Logical Unit for reset (if appropriate)
2134 * @ctx2abort: Context for the task to be aborted (if appropriate)
2135 * @sleepFlag: If set, use udelay instead of schedule in handshake code.
2137 * Remark: Currently invoked from a non-interrupt thread (_bh).
2139 * Remark: With old EH code, at most 1 SCSI TaskMgmt function per IOC
2142 * Returns 0 for SUCCESS or -1 if FAILED.
2145 mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout, int sleepFlag)
2151 unsigned long flags;
2153 /* If FW is being reloaded currently, return success to
2154 * the calling function.
2161 printk(KERN_ERR MYNAM " TMHandler" " NULL ioc!\n");
2164 dtmprintk((MYIOC_s_INFO_FMT "TMHandler Entered!\n", ioc->name));
2166 // SJR - CHECKME - Can we avoid this here?
2167 // (mpt_HardResetHandler has this check...)
2168 spin_lock_irqsave(&ioc->diagLock, flags);
2169 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)) {
2170 spin_unlock_irqrestore(&ioc->diagLock, flags);
2173 spin_unlock_irqrestore(&ioc->diagLock, flags);
2175 /* Wait a fixed amount of time for the TM pending flag to be cleared.
2176 * If we time out and not bus reset, then we return a FAILED status to the caller.
2177 * The call to mptscsih_tm_pending_wait() will set the pending flag if we are
2178 * successful. Otherwise, reload the FW.
2180 if (mptscsih_tm_pending_wait(hd) == FAILED) {
2181 if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
2182 dtmprintk((KERN_WARNING MYNAM ": %s: TMHandler abort: "
2183 "Timed out waiting for last TM (%d) to complete! \n",
2184 hd->ioc->name, hd->tmPending));
2186 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) {
2187 dtmprintk((KERN_WARNING MYNAM ": %s: TMHandler target reset: "
2188 "Timed out waiting for last TM (%d) to complete! \n",
2189 hd->ioc->name, hd->tmPending));
2191 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
2192 dtmprintk((KERN_WARNING MYNAM ": %s: TMHandler bus reset: "
2193 "Timed out waiting for last TM (%d) to complete! \n",
2194 hd->ioc->name, hd->tmPending));
2195 if (hd->tmPending & (1 << MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS))
2201 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
2202 hd->tmPending |= (1 << type);
2203 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2208 ioc_raw_state = mpt_GetIocState(hd->ioc, 0);
2210 #ifdef MPT_DEBUG_RESET
2211 if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) {
2212 printk(MYIOC_s_WARN_FMT
2213 "TM Handler: IOC Not operational(0x%x)!\n",
2214 hd->ioc->name, ioc_raw_state);
2218 if (doTask && ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL)
2219 && !(ioc_raw_state & MPI_DOORBELL_ACTIVE)) {
2221 /* Isse the Task Mgmt request.
2223 if (hd->hard_resets < -1)
2225 rc = mptscsih_IssueTaskMgmt(hd, type, channel, target, lun, ctx2abort, timeout, sleepFlag);
2227 printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n", hd->ioc->name);
2229 dtmprintk((MYIOC_s_INFO_FMT "Issue of TaskMgmt Successful!\n", hd->ioc->name));
2233 #ifdef MPTSCSIH_DBG_TIMEOUT
2234 if (hd->ioc->timeout_hard)
2238 /* Only fall through to the HRH if this is a bus reset
2240 if ((type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) && (rc ||
2241 ioc->reload_fw || (ioc->alt_ioc && ioc->alt_ioc->reload_fw))) {
2242 dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
2244 rc = mpt_HardResetHandler(hd->ioc, sleepFlag);
2247 dtmprintk((MYIOC_s_INFO_FMT "TMHandler rc = %d!\n", hd->ioc->name, rc));
2253 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2255 * mptscsih_IssueTaskMgmt - Generic send Task Management function.
2256 * @hd: Pointer to MPT_SCSI_HOST structure
2257 * @type: Task Management type
2258 * @target: Logical Target ID for reset (if appropriate)
2259 * @lun: Logical Unit for reset (if appropriate)
2260 * @ctx2abort: Context for the task to be aborted (if appropriate)
2261 * @sleepFlag: If set, use udelay instead of schedule in handshake code.
2263 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
2264 * or a non-interrupt thread. In the former, must not call schedule().
2266 * Not all fields are meaningfull for all task types.
2268 * Returns 0 for SUCCESS, -999 for "no msg frames",
2269 * else other non-zero value returned.
2272 mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout, int sleepFlag)
2275 SCSITaskMgmt_t *pScsiTm;
2279 /* Return Fail to calling function if no message frames available.
2281 if ((mf = mpt_get_msg_frame(ScsiTaskCtx, hd->ioc)) == NULL) {
2282 dfailprintk((MYIOC_s_ERR_FMT "IssueTaskMgmt, no msg frames!!\n",
2287 dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt request @ %p\n",
2288 hd->ioc->name, mf));
2290 /* Format the Request
2292 pScsiTm = (SCSITaskMgmt_t *) mf;
2293 pScsiTm->TargetID = target;
2294 pScsiTm->Bus = channel;
2295 pScsiTm->ChainOffset = 0;
2296 pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
2298 pScsiTm->Reserved = 0;
2299 pScsiTm->TaskType = type;
2300 pScsiTm->Reserved1 = 0;
2301 pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)
2302 ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0;
2304 for (ii= 0; ii < 8; ii++) {
2305 pScsiTm->LUN[ii] = 0;
2307 pScsiTm->LUN[1] = lun;
2309 for (ii=0; ii < 7; ii++)
2310 pScsiTm->Reserved2[ii] = 0;
2312 pScsiTm->TaskMsgContext = ctx2abort;
2314 /* MPI v0.10 requires SCSITaskMgmt requests be sent via Doorbell/handshake
2315 mpt_put_msg_frame(hd->ioc->id, mf);
2316 * Save the MF pointer in case the request times out.
2319 hd->TMtimer.expires = jiffies + timeout;
2320 add_timer(&hd->TMtimer);
2322 dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt: ctx2abort (0x%08x) type=%d\n",
2323 hd->ioc->name, ctx2abort, type));
2325 DBG_DUMP_TM_REQUEST_FRAME((u32 *)pScsiTm);
2327 if ((retval = mpt_send_handshake_request(ScsiTaskCtx, hd->ioc,
2328 sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, sleepFlag))
2330 dfailprintk((MYIOC_s_ERR_FMT "_send_handshake FAILED!"
2331 " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd, hd->ioc, mf));
2333 del_timer(&hd->TMtimer);
2334 mpt_free_msg_frame(hd->ioc, mf);
2340 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2342 * mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant
2343 * @SCpnt: Pointer to scsi_cmnd structure, IO to be aborted
2345 * (linux scsi_host_template.eh_abort_handler routine)
2347 * Returns SUCCESS or FAILED.
2350 mptscsih_abort(struct scsi_cmnd * SCpnt)
2357 spinlock_t *host_lock = SCpnt->device->host->host_lock;
2359 /* If we can't locate our host adapter structure, return FAILED status.
2361 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL) {
2362 SCpnt->result = DID_RESET << 16;
2363 SCpnt->scsi_done(SCpnt);
2364 dfailprintk((KERN_WARNING MYNAM ": mptscsih_abort: "
2365 "Can't locate host! (sc=%p)\n",
2371 if (hd->resetPending)
2374 printk(KERN_WARNING MYNAM ": %s: >> Attempting task abort! (sc=%p)\n",
2375 hd->ioc->name, SCpnt);
2377 if (hd->timeouts < -1)
2380 /* Find this command
2382 if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) {
2383 /* Cmd not found in ScsiLookup.
2386 SCpnt->result = DID_RESET << 16;
2387 dtmprintk((KERN_WARNING MYNAM ": %s: mptscsih_abort: "
2388 "Command not in the active list! (sc=%p)\n",
2389 hd->ioc->name, SCpnt));
2393 /* Most important! Set TaskMsgContext to SCpnt's MsgContext!
2394 * (the IO to be ABORT'd)
2396 * NOTE: Since we do not byteswap MsgContext, we do not
2397 * swap it here either. It is an opaque cookie to
2398 * the controller, so it does not matter. -DaveM
2400 mf = MPT_INDEX_2_MFPTR(hd->ioc, scpnt_idx);
2401 ctx2abort = mf->u.frame.hwhdr.msgctxu.MsgContext;
2403 hd->abortSCpnt = SCpnt;
2405 spin_unlock_irq(host_lock);
2406 if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
2407 SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun,
2408 ctx2abort, (HZ*2) /* 2 second timeout */,CAN_SLEEP)
2411 /* The TM request failed and the subsequent FW-reload failed!
2414 printk(MYIOC_s_WARN_FMT "Error issuing abort task! (sc=%p)\n",
2415 hd->ioc->name, SCpnt);
2417 /* We must clear our pending flag before clearing our state.
2420 hd->tmState = TM_STATE_NONE;
2422 spin_lock_irq(host_lock);
2424 /* Unmap the DMA buffers, if any. */
2425 if (SCpnt->use_sg) {
2426 pci_unmap_sg(ioc->pcidev, (struct scatterlist *) SCpnt->request_buffer,
2427 SCpnt->use_sg, SCpnt->sc_data_direction);
2428 } else if (SCpnt->request_bufflen) {
2429 pci_unmap_single(ioc->pcidev, SCpnt->SCp.dma_handle,
2430 SCpnt->request_bufflen, SCpnt->sc_data_direction);
2432 hd->ScsiLookup[scpnt_idx] = NULL;
2433 SCpnt->result = DID_RESET << 16;
2434 SCpnt->scsi_done(SCpnt); /* Issue the command callback */
2435 mptscsih_freeChainBuffers(ioc, scpnt_idx);
2436 mpt_free_msg_frame(ioc, mf);
2439 spin_lock_irq(host_lock);
2444 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2446 * mptscsih_dev_reset - Perform a SCSI TARGET_RESET! new_eh variant
2447 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
2449 * (linux scsi_host_template.eh_dev_reset_handler routine)
2451 * Returns SUCCESS or FAILED.
2454 mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
2457 spinlock_t *host_lock = SCpnt->device->host->host_lock;
2459 /* If we can't locate our host adapter structure, return FAILED status.
2461 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
2462 dtmprintk((KERN_WARNING MYNAM ": mptscsih_dev_reset: "
2463 "Can't locate host! (sc=%p)\n",
2468 if (hd->resetPending)
2471 printk(KERN_WARNING MYNAM ": %s: >> Attempting target reset! (sc=%p)\n",
2472 hd->ioc->name, SCpnt);
2474 /* Unsupported for SCSI. Supported for FCP
2479 spin_unlock_irq(host_lock);
2480 if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
2481 SCpnt->device->channel, SCpnt->device->id,
2482 0, 0, (HZ*5) /* 5 second timeout */, CAN_SLEEP)
2484 /* The TM request failed and the subsequent FW-reload failed!
2487 printk(MYIOC_s_WARN_FMT "Error processing TaskMgmt request (sc=%p)\n",
2488 hd->ioc->name, SCpnt);
2490 hd->tmState = TM_STATE_NONE;
2491 spin_lock_irq(host_lock);
2494 spin_lock_irq(host_lock);
2499 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2501 * mptscsih_bus_reset - Perform a SCSI BUS_RESET! new_eh variant
2502 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
2504 * (linux scsi_host_template.eh_bus_reset_handler routine)
2506 * Returns SUCCESS or FAILED.
2509 mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
2512 spinlock_t *host_lock = SCpnt->device->host->host_lock;
2514 /* If we can't locate our host adapter structure, return FAILED status.
2516 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
2517 dtmprintk((KERN_WARNING MYNAM ": mptscsih_bus_reset: "
2518 "Can't locate host! (sc=%p)\n",
2523 printk(KERN_WARNING MYNAM ": %s: >> Attempting bus reset! (sc=%p)\n",
2524 hd->ioc->name, SCpnt);
2526 if (hd->timeouts < -1)
2529 /* We are now ready to execute the task management request. */
2530 spin_unlock_irq(host_lock);
2531 if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
2532 SCpnt->device->channel, 0, 0, 0, (HZ*5) /* 5 second timeout */, CAN_SLEEP)
2535 /* The TM request failed and the subsequent FW-reload failed!
2538 printk(MYIOC_s_WARN_FMT
2539 "Error processing TaskMgmt request (sc=%p)\n",
2540 hd->ioc->name, SCpnt);
2542 hd->tmState = TM_STATE_NONE;
2543 spin_lock_irq(host_lock);
2546 spin_lock_irq(host_lock);
2550 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2552 * mptscsih_host_reset - Perform a SCSI host adapter RESET!
2554 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
2556 * (linux scsi_host_template.eh_host_reset_handler routine)
2558 * Returns SUCCESS or FAILED.
2561 mptscsih_host_reset(struct scsi_cmnd *SCpnt)
2564 int status = SUCCESS;
2565 spinlock_t *host_lock = SCpnt->device->host->host_lock;
2567 /* If we can't locate the host to reset, then we failed. */
2568 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
2569 dtmprintk( ( KERN_WARNING MYNAM ": mptscsih_host_reset: "
2570 "Can't locate host! (sc=%p)\n",
2575 printk(KERN_WARNING MYNAM ": %s: >> Attempting host reset! (sc=%p)\n",
2576 hd->ioc->name, SCpnt);
2578 /* If our attempts to reset the host failed, then return a failed
2579 * status. The host will be taken off line by the SCSI mid-layer.
2581 spin_unlock_irq(host_lock);
2582 if (mpt_HardResetHandler(hd->ioc, CAN_SLEEP) < 0){
2585 /* Make sure TM pending is cleared and TM state is set to
2589 hd->tmState = TM_STATE_NONE;
2591 spin_lock_irq(host_lock);
2594 dtmprintk( ( KERN_WARNING MYNAM ": mptscsih_host_reset: "
2596 (status == SUCCESS) ? "SUCCESS" : "FAILED" ) );
2601 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2603 * mptscsih_tm_pending_wait - wait for pending task management request to
2605 * @hd: Pointer to MPT host structure.
2607 * Returns {SUCCESS,FAILED}.
2610 mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd)
2612 unsigned long flags;
2613 int loop_count = 10 * 4; /* Wait 10 seconds */
2614 int status = FAILED;
2617 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
2618 if (hd->tmState == TM_STATE_NONE) {
2619 hd->tmState = TM_STATE_IN_PROGRESS;
2621 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2625 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2627 } while (--loop_count);
2632 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2634 * mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
2635 * @ioc: Pointer to MPT_ADAPTER structure
2636 * @mf: Pointer to SCSI task mgmt request frame
2637 * @mr: Pointer to SCSI task mgmt reply frame
2639 * This routine is called from mptbase.c::mpt_interrupt() at the completion
2640 * of any SCSI task management request.
2641 * This routine is registered with the MPT (base) driver at driver
2642 * load/init time via the mpt_register() API call.
2644 * Returns 1 indicating alloc'd request frame ptr should be freed.
2647 mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
2649 SCSITaskMgmtReply_t *pScsiTmReply;
2650 SCSITaskMgmt_t *pScsiTmReq;
2652 unsigned long flags;
2656 dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt completed (mf=%p,mr=%p)\n",
2657 ioc->name, mf, mr));
2659 /* Depending on the thread, a timer is activated for
2660 * the TM request. Delete this timer on completion of TM.
2661 * Decrement count of outstanding TM requests.
2663 hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
2665 del_timer(&hd->TMtimer);
2667 dtmprintk((MYIOC_s_WARN_FMT "taskQcnt (%d)\n",
2668 ioc->name, hd->taskQcnt));
2670 dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt Complete: NULL Scsi Host Ptr\n",
2676 dtmprintk((MYIOC_s_WARN_FMT "ERROR! TaskMgmt Reply: NULL Request %p\n",
2680 pScsiTmReply = (SCSITaskMgmtReply_t*)mr;
2681 pScsiTmReq = (SCSITaskMgmt_t*)mf;
2683 /* Figure out if this was ABORT_TASK, TARGET_RESET, or BUS_RESET! */
2684 tmType = pScsiTmReq->TaskType;
2686 dtmprintk((MYIOC_s_WARN_FMT " TaskType = %d, TerminationCount=%d\n",
2687 ioc->name, tmType, le32_to_cpu(pScsiTmReply->TerminationCount)));
2688 DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply);
2690 iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2691 dtmprintk((MYIOC_s_WARN_FMT " SCSI TaskMgmt (%d) IOCStatus=%04x IOCLogInfo=%08x\n",
2692 ioc->name, tmType, iocstatus, le32_to_cpu(pScsiTmReply->IOCLogInfo)));
2693 /* Error? (anything non-zero?) */
2696 /* clear flags and continue.
2698 if (tmType == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK)
2699 hd->abortSCpnt = NULL;
2701 /* If an internal command is present
2702 * or the TM failed - reload the FW.
2703 * FC FW may respond FAILED to an ABORT
2705 if (tmType == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
2707 (iocstatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED)) {
2708 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0) {
2709 printk((KERN_WARNING
2710 " Firmware Reload FAILED!!\n"));
2715 dtmprintk((MYIOC_s_WARN_FMT " TaskMgmt SUCCESS\n", ioc->name));
2717 hd->abortSCpnt = NULL;
2723 spin_lock_irqsave(&ioc->FreeQlock, flags);
2725 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2726 hd->tmState = TM_STATE_NONE;
2731 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2733 * This is anyones guess quite frankly.
2736 mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
2737 sector_t capacity, int geom[])
2747 dummy = heads * sectors;
2748 cylinders = capacity;
2749 sector_div(cylinders,dummy);
2752 * Handle extended translation size for logical drives
2755 if ((ulong)capacity >= 0x200000) {
2758 dummy = heads * sectors;
2759 cylinders = capacity;
2760 sector_div(cylinders,dummy);
2766 geom[2] = cylinders;
2768 dprintk((KERN_NOTICE
2769 ": bios_param: Id=%i Lun=%i Channel=%i CHS=%i/%i/%i\n",
2770 sdev->id, sdev->lun,sdev->channel,(int)cylinders,heads,sectors));
2775 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2777 * OS entry point to allow host driver to alloc memory
2778 * for each scsi device. Called once per device the bus scan.
2779 * Return non-zero if allocation fails.
2780 * Init memory once per id (not LUN).
2783 mptscsih_slave_alloc(struct scsi_device *device)
2785 struct Scsi_Host *host = device->host;
2789 hd = (MPT_SCSI_HOST *)host->hostdata;
2794 if ((vdev = hd->Targets[device->id]) == NULL) {
2795 if ((vdev = kmalloc(sizeof(VirtDevice), GFP_ATOMIC)) == NULL) {
2796 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%d) FAILED!\n",
2797 hd->ioc->name, (int)sizeof(VirtDevice));
2800 memset(vdev, 0, sizeof(VirtDevice));
2801 rwlock_init(&vdev->VdevLock);
2802 Q_INIT(&vdev->WaitQ, void);
2803 Q_INIT(&vdev->SentQ, void);
2804 Q_INIT(&vdev->DoneQ, void);
2805 vdev->tflags = MPT_TARGET_FLAGS_Q_YES;
2806 vdev->ioc_id = hd->ioc->id;
2807 vdev->target_id = device->id;
2808 vdev->bus_id = device->channel;
2809 vdev->raidVolume = 0;
2810 hd->Targets[device->id] = vdev;
2812 if (hd->ioc->spi_data.isRaid & (1 << device->id)) {
2813 vdev->raidVolume = 1;
2814 ddvtprintk((KERN_INFO
2815 "RAID Volume @ id %d\n", device->id));
2818 vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
2828 * OS entry point to allow for host driver to free allocated memory
2829 * Called if no device present or device being unloaded
2832 mptscsih_slave_destroy(struct scsi_device *device)
2834 struct Scsi_Host *host = device->host;
2839 hd = (MPT_SCSI_HOST *)host->hostdata;
2844 mptscsih_search_running_cmds(hd, device->id, device->lun);
2846 /* Free memory and reset all flags for this target
2848 if ((vdev = hd->Targets[device->id]) != NULL) {
2851 if (vdev->luns[0] & (1 << device->lun))
2852 vdev->luns[0] &= ~(1 << device->lun);
2854 /* Free device structure only if number of luns is 0.
2856 if (vdev->num_luns == 0) {
2857 kfree(hd->Targets[device->id]);
2858 hd->Targets[device->id] = NULL;
2863 if((hd->ioc->spi_data.isRaid) && (hd->ioc->spi_data.pIocPg3)) {
2865 for(i=0;i<hd->ioc->spi_data.pIocPg3->NumPhysDisks &&
2869 hd->ioc->spi_data.pIocPg3->PhysDisk[i].PhysDiskID) {
2871 hd->ioc->spi_data.forceDv |=
2872 MPT_SCSICFG_RELOAD_IOC_PG3;
2877 hd->ioc->spi_data.dvStatus[device->id] =
2878 MPT_SCSICFG_NEGOTIATE;
2880 if (hd->negoNvram == 0)
2881 hd->ioc->spi_data.dvStatus[device->id]
2882 |= MPT_SCSICFG_DV_NOT_DONE;
2891 * OS entry point to adjust the queue_depths on a per-device basis.
2892 * Called once per device the bus scan. Use it to force the queue_depth
2893 * member to 1 if a device does not support Q tags.
2894 * Return non-zero if fails.
2897 mptscsih_slave_configure(struct scsi_device *device)
2899 struct Scsi_Host *sh = device->host;
2900 VirtDevice *pTarget;
2901 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sh->hostdata;
2903 if ((hd == NULL) || (hd->Targets == NULL)) {
2907 dsprintk((MYIOC_s_INFO_FMT
2908 "device @ %p, id=%d, LUN=%d, channel=%d\n",
2909 hd->ioc->name, device, device->id, device->lun, device->channel));
2910 dsprintk((MYIOC_s_INFO_FMT
2911 "sdtr %d wdtr %d ppr %d inq length=%d\n",
2912 hd->ioc->name, device->sdtr, device->wdtr,
2913 device->ppr, device->inquiry_len));
2915 if (device->id > sh->max_id) {
2916 /* error case, should never happen */
2917 scsi_adjust_queue_depth(device, 0, 1);
2918 goto slave_configure_exit;
2921 pTarget = hd->Targets[device->id];
2923 if (pTarget == NULL) {
2924 /* Driver doesn't know about this device.
2925 * Kernel may generate a "Dummy Lun 0" which
2926 * may become a real Lun if a
2927 * "scsi add-single-device" command is executed
2928 * while the driver is active (hot-plug a
2929 * device). LSI Raid controllers need
2930 * queue_depth set to DEV_HIGH for this reason.
2932 scsi_adjust_queue_depth(device, MSG_SIMPLE_TAG,
2933 MPT_SCSI_CMD_PER_DEV_HIGH);
2934 goto slave_configure_exit;
2937 mptscsih_initTarget(hd, device->channel, device->id, device->lun,
2938 device->inquiry, device->inquiry_len );
2939 scsi_adjust_queue_depth(device, MSG_SIMPLE_TAG,
2940 MPT_SCSI_CMD_PER_DEV_HIGH);
2942 if (pTarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) {
2943 if (!(pTarget->tflags & MPT_TARGET_FLAGS_Q_YES))
2944 scsi_adjust_queue_depth(device, 0, 1);
2945 else if (((pTarget->inq_data[0] & 0x1f) == 0x00)
2946 && (pTarget->minSyncFactor <= MPT_ULTRA160 ))
2947 scsi_adjust_queue_depth(device, MSG_SIMPLE_TAG,
2948 MPT_SCSI_CMD_PER_DEV_HIGH);
2950 scsi_adjust_queue_depth(device, MSG_SIMPLE_TAG,
2951 MPT_SCSI_CMD_PER_DEV_LOW);
2953 /* error case - No Inq. Data */
2954 scsi_adjust_queue_depth(device, 0, 1);
2958 dsprintk((MYIOC_s_INFO_FMT
2959 "Queue depth=%d, tflags=%x\n",
2960 hd->ioc->name, device->queue_depth, pTarget->tflags));
2962 dsprintk((MYIOC_s_INFO_FMT
2963 "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
2964 hd->ioc->name, pTarget->negoFlags, pTarget->maxOffset, pTarget->minSyncFactor));
2966 slave_configure_exit:
2968 dsprintk((MYIOC_s_INFO_FMT
2969 "tagged %d, simple %d, ordered %d\n",
2970 hd->ioc->name,device->tagged_supported, device->simple_tags,
2971 device->ordered_tags));
2977 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2979 * Private routines...
2982 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2983 /* Utility function to copy sense data from the scsi_cmnd buffer
2984 * to the FC and SCSI target structures.
2988 copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
2991 SCSIIORequest_t *pReq;
2992 u32 sense_count = le32_to_cpu(pScsiReply->SenseCount);
2995 /* Get target structure
2997 pReq = (SCSIIORequest_t *) mf;
2998 index = (int) pReq->TargetID;
2999 target = hd->Targets[index];
3000 if (hd->is_multipath && sc->device->hostdata)
3001 target = (VirtDevice *) sc->device->hostdata;
3007 /* Copy the sense received into the scsi command block. */
3008 req_index = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3009 sense_data = ((u8 *)hd->ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC));
3010 memcpy(sc->sense_buffer, sense_data, SNS_LEN(sc));
3012 /* Log SMART data (asc = 0x5D, non-IM case only) if required.
3014 if ((hd->ioc->events) && (hd->ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) {
3015 if ((sense_data[12] == 0x5D) && (target->raidVolume == 0)) {
3017 MPT_ADAPTER *ioc = hd->ioc;
3019 idx = ioc->eventContext % ioc->eventLogSize;
3020 ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
3021 ioc->events[idx].eventContext = ioc->eventContext;
3023 ioc->events[idx].data[0] = (pReq->LUN[1] << 24) ||
3024 (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) ||
3025 (pReq->Bus << 8) || pReq->TargetID;
3027 ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12];
3029 ioc->eventContext++;
3033 dprintk((MYIOC_s_INFO_FMT "Hmmm... SenseData len=0! (?)\n",
3039 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc)
3044 hd = (MPT_SCSI_HOST *) sc->device->host->hostdata;
3046 for (i = 0; i < hd->ioc->req_depth; i++) {
3047 if (hd->ScsiLookup[i] == sc) {
3055 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3057 mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
3060 unsigned long flags;
3062 dtmprintk((KERN_WARNING MYNAM
3063 ": IOC %s_reset routed to SCSI host driver!\n",
3064 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
3065 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
3067 /* If a FW reload request arrives after base installed but
3068 * before all scsi hosts have been attached, then an alt_ioc
3069 * may have a NULL sh pointer.
3071 if ((ioc->sh == NULL) || (ioc->sh->hostdata == NULL))
3074 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
3076 if (reset_phase == MPT_IOC_SETUP_RESET) {
3077 dtmprintk((MYIOC_s_WARN_FMT "Setup-Diag Reset\n", ioc->name));
3080 * 1. Set Hard Reset Pending Flag
3081 * All new commands go to doneQ
3083 hd->resetPending = 1;
3085 } else if (reset_phase == MPT_IOC_PRE_RESET) {
3086 dtmprintk((MYIOC_s_WARN_FMT "Pre-Diag Reset\n", ioc->name));
3088 /* 2. Flush running commands
3089 * Clean ScsiLookup (and associated memory)
3093 /* 2b. Reply to OS all known outstanding I/O commands.
3095 mptscsih_flush_running_cmds(hd);
3097 /* 2c. If there was an internal command that
3098 * has not completed, configuration or io request,
3099 * free these resources.
3102 del_timer(&hd->timer);
3103 mpt_free_msg_frame(ioc, hd->cmdPtr);
3106 /* 2d. If a task management has not completed,
3107 * free resources associated with this request.
3110 del_timer(&hd->TMtimer);
3111 mpt_free_msg_frame(ioc, hd->tmPtr);
3114 #ifdef MPTSCSIH_DBG_TIMEOUT
3115 ioc->timeout_hard = 0;
3118 dtmprintk((MYIOC_s_WARN_FMT "Pre-Reset complete.\n", ioc->name));
3121 dtmprintk((MYIOC_s_WARN_FMT "Post-Diag Reset\n", ioc->name));
3123 /* Once a FW reload begins, all new OS commands are
3124 * redirected to the doneQ w/ a reset status.
3125 * Init all control structures.
3128 /* ScsiLookup initialization
3132 for (ii=0; ii < hd->ioc->req_depth; ii++)
3133 hd->ScsiLookup[ii] = NULL;
3136 /* 2. Chain Buffer initialization
3145 /* 4. Renegotiate to all devices, if SCSI
3148 dnegoprintk(("writeSDP1: ALL_IDS USE_NVRAM\n"));
3149 mptscsih_writeSDP1(hd, 0, 0, MPT_SCSICFG_ALL_IDS | MPT_SCSICFG_USE_NVRAM);
3152 /* 5. Enable new commands to be posted
3154 spin_lock_irqsave(&ioc->FreeQlock, flags);
3156 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
3157 hd->resetPending = 0;
3158 hd->tmState = TM_STATE_NONE;
3160 /* 6. If there was an internal command,
3161 * wake this process up.
3165 * Wake up the original calling thread
3167 hd->pLocal = &hd->localReply;
3168 hd->pLocal->completion = MPT_SCANDV_DID_RESET;
3169 scandv_wait_done = 1;
3170 wake_up(&scandv_waitq);
3174 /* 7. Set flag to force DV and re-read IOC Page 3
3177 ioc->spi_data.forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
3178 ddvtprintk(("Set reload IOC Pg3 Flag\n"));
3181 dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name));
3185 return 1; /* currently means nothing really */
3188 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3190 mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
3193 u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
3195 devtprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
3199 case MPI_EVENT_UNIT_ATTENTION: /* 03 */
3202 case MPI_EVENT_IOC_BUS_RESET: /* 04 */
3203 case MPI_EVENT_EXT_BUS_RESET: /* 05 */
3206 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
3207 if (hd && (hd->is_spi) && (hd->soft_resets < -1))
3211 case MPI_EVENT_LOGOUT: /* 09 */
3216 * CHECKME! Don't think we need to do
3217 * anything for these, but...
3219 case MPI_EVENT_RESCAN: /* 06 */
3220 case MPI_EVENT_LINK_STATUS_CHANGE: /* 07 */
3221 case MPI_EVENT_LOOP_STATE_CHANGE: /* 08 */
3223 * CHECKME! Falling thru...
3227 case MPI_EVENT_INTEGRATED_RAID: /* 0B */
3228 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
3229 /* negoNvram set to 0 if DV enabled and to USE_NVRAM if
3230 * if DV disabled. Need to check for target mode.
3234 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
3236 if (hd && (hd->is_spi) && (hd->negoNvram == 0)) {
3238 Ioc3PhysDisk_t *pPDisk;
3243 reason = (le32_to_cpu(pEvReply->Data[0]) & 0x00FF0000) >> 16;
3244 if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
3245 /* New or replaced disk.
3246 * Set DV flag and schedule DV.
3248 pSpi = &ioc->spi_data;
3249 physDiskNum = (le32_to_cpu(pEvReply->Data[0]) & 0xFF000000) >> 24;
3250 ddvtprintk(("DV requested for phys disk id %d\n", physDiskNum));
3251 if (pSpi->pIocPg3) {
3252 pPDisk = pSpi->pIocPg3->PhysDisk;
3253 numPDisk =pSpi->pIocPg3->NumPhysDisks;
3256 if (physDiskNum == pPDisk->PhysDiskNum) {
3257 pSpi->dvStatus[pPDisk->PhysDiskID] = (MPT_SCSICFG_NEED_DV | MPT_SCSICFG_DV_NOT_DONE);
3258 pSpi->forceDv = MPT_SCSICFG_NEED_DV;
3259 ddvtprintk(("NEED_DV set for phys disk id %d\n", pPDisk->PhysDiskID));
3266 if (numPDisk == 0) {
3267 /* The physical disk that needs DV was not found
3268 * in the stored IOC Page 3. The driver must reload
3269 * this page. DV routine will set the NEED_DV flag for
3270 * all phys disks that have DV_NOT_DONE set.
3272 pSpi->forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
3273 ddvtprintk(("phys disk %d not found. Setting reload IOC Pg3 Flag\n", physDiskNum));
3280 #if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY)
3281 printk("Raid Event RF: ");
3283 u32 *m = (u32 *)pEvReply;
3285 int n = (int)pEvReply->MsgLength;
3286 for (ii=6; ii < n; ii++)
3287 printk(" %08x", le32_to_cpu(m[ii]));
3293 case MPI_EVENT_NONE: /* 00 */
3294 case MPI_EVENT_LOG_DATA: /* 01 */
3295 case MPI_EVENT_STATE_CHANGE: /* 02 */
3296 case MPI_EVENT_EVENT_CHANGE: /* 0A */
3298 dprintk((KERN_INFO " Ignoring event (=%02Xh)\n", event));
3302 return 1; /* currently means nothing really */
3305 static struct scsi_host_template driver_template = {
3306 .proc_name = "mptscsih",
3307 .proc_info = mptscsih_proc_info,
3308 .name = "MPT SCSI Host",
3309 .info = mptscsih_info,
3310 .queuecommand = mptscsih_qcmd,
3311 .slave_alloc = mptscsih_slave_alloc,
3312 .slave_configure = mptscsih_slave_configure,
3313 .slave_destroy = mptscsih_slave_destroy,
3314 .eh_abort_handler = mptscsih_abort,
3315 .eh_device_reset_handler = mptscsih_dev_reset,
3316 .eh_bus_reset_handler = mptscsih_bus_reset,
3317 .eh_host_reset_handler = mptscsih_host_reset,
3318 .bios_param = mptscsih_bios_param,
3319 .can_queue = MPT_SCSI_CAN_QUEUE,
3321 .sg_tablesize = MPT_SCSI_SG_DEPTH,
3322 .max_sectors = 8192,
3324 .use_clustering = ENABLE_CLUSTERING,
3327 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3329 * mptscsih_initTarget - Target, LUN alloc/free functionality.
3330 * @hd: Pointer to MPT_SCSI_HOST structure
3331 * @bus_id: Bus number (?)
3332 * @target_id: SCSI target id
3334 * @data: Pointer to data
3335 * @dlen: Number of INQUIRY bytes
3337 * NOTE: It's only SAFE to call this routine if data points to
3338 * sane & valid STANDARD INQUIRY data!
3340 * Allocate and initialize memory for this target.
3341 * Save inquiry data.
3345 mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *data, int dlen)
3347 int indexed_lun, lun_index;
3352 dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n",
3353 hd->ioc->name, bus_id, target_id, lun, hd));
3355 /* Is LUN supported? If so, upper 2 bits will be 0
3356 * in first byte of inquiry data.
3361 if ((vdev = hd->Targets[target_id]) == NULL) {
3365 lun_index = (lun >> 5); /* 32 luns per lun_index */
3366 indexed_lun = (lun % 32);
3367 vdev->luns[lun_index] |= (1 << indexed_lun);
3370 if ((data[0] == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) {
3371 /* Treat all Processors as SAF-TE if
3372 * command line option is set */
3373 vdev->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
3374 mptscsih_writeIOCPage4(hd, target_id, bus_id);
3375 }else if ((data[0] == TYPE_PROCESSOR) &&
3376 !(vdev->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) {
3378 vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
3379 if ( data[44] == 'S' &&
3385 vdev->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
3386 mptscsih_writeIOCPage4(hd, target_id, bus_id);
3390 if (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY)) {
3392 memcpy (vdev->inq_data, data, 8);
3394 memcpy (vdev->inq_data, data, dlen);
3397 /* If have not done DV, set the DV flag.
3399 pSpi = &hd->ioc->spi_data;
3400 if ((data[0] == TYPE_TAPE) || (data[0] == TYPE_PROCESSOR)) {
3401 if (pSpi->dvStatus[target_id] & MPT_SCSICFG_DV_NOT_DONE)
3402 pSpi->dvStatus[target_id] |= MPT_SCSICFG_NEED_DV;
3405 vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
3408 data_56 = 0x0F; /* Default to full capabilities if Inq data length is < 57 */
3410 if ( (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_56))) {
3411 /* Update the target capabilities
3414 vdev->tflags |= MPT_TARGET_FLAGS_VALID_56;
3417 mptscsih_setTargetNegoParms(hd, vdev, data_56);
3419 /* Initial Inquiry may not request enough data bytes to
3420 * obtain byte 57. DV will; if target doesn't return
3421 * at least 57 bytes, data[56] will be zero. */
3423 if ( (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_56))) {
3424 /* Update the target capabilities
3427 vdev->tflags |= MPT_TARGET_FLAGS_VALID_56;
3428 mptscsih_setTargetNegoParms(hd, vdev, data_56);
3435 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3437 * Update the target negotiation parameters based on the
3438 * the Inquiry data, adapter capabilities, and NVRAM settings.
3442 mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56)
3444 ScsiCfgData *pspi_data = &hd->ioc->spi_data;
3445 int id = (int) target->target_id;
3449 u8 width = MPT_NARROW;
3450 u8 factor = MPT_ASYNC;
3452 u8 version, nfactor;
3455 target->negoFlags = pspi_data->noQas;
3457 /* noQas == 0 => device supports QAS. Need byte 56 of Inq to determine
3458 * support. If available, default QAS to off and allow enabling.
3459 * If not available, default QAS to on, turn off for non-disks.
3462 /* Set flags based on Inquiry data
3464 version = target->inq_data[2] & 0x07;
3467 factor = MPT_ULTRA2;
3468 offset = pspi_data->maxSyncOffset;
3469 target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
3471 if (target->inq_data[7] & 0x20) {
3475 if (target->inq_data[7] & 0x10) {
3476 factor = pspi_data->minSyncFactor;
3477 if (target->tflags & MPT_TARGET_FLAGS_VALID_56) {
3478 /* bits 2 & 3 show Clocking support */
3479 if ((byte56 & 0x0C) == 0)
3480 factor = MPT_ULTRA2;
3482 if ((byte56 & 0x03) == 0)
3483 factor = MPT_ULTRA160;
3485 factor = MPT_ULTRA320;
3488 ddvtprintk((KERN_INFO "Enabling QAS due to byte56=%02x on id=%d!\n", byte56, id));
3491 if (target->inq_data[0] == TYPE_TAPE) {
3493 target->negoFlags |= MPT_TAPE_NEGO_IDP;
3498 ddvtprintk((KERN_INFO "Enabling QAS on id=%d due to ~TARGET_FLAGS_VALID_56!\n", id));
3502 offset = pspi_data->maxSyncOffset;
3504 /* If RAID, never disable QAS
3505 * else if non RAID, do not disable
3506 * QAS if bit 1 is set
3507 * bit 1 QAS support, non-raid only
3510 if (target->raidVolume == 1) {
3519 if ( (target->inq_data[7] & 0x02) == 0) {
3520 target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
3523 /* Update tflags based on NVRAM settings. (SCSI only)
3525 if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
3526 nvram = pspi_data->nvram[id];
3527 nfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
3530 width = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
3533 /* Ensure factor is set to the
3534 * maximum of: adapter, nvram, inquiry
3537 if (nfactor < pspi_data->minSyncFactor )
3538 nfactor = pspi_data->minSyncFactor;
3540 factor = max(factor, nfactor);
3541 if (factor == MPT_ASYNC)
3552 /* Make sure data is consistent
3554 if ((!width) && (factor < MPT_ULTRA2)) {
3555 factor = MPT_ULTRA2;
3558 /* Save the data to the target structure.
3560 target->minSyncFactor = factor;
3561 target->maxOffset = offset;
3562 target->maxWidth = width;
3564 target->tflags |= MPT_TARGET_FLAGS_VALID_NEGO;
3566 /* Disable unused features.
3569 target->negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
3572 target->negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
3574 if ( factor > MPT_ULTRA320 )
3577 /* GEM, processor WORKAROUND
3579 if ((target->inq_data[0] == TYPE_PROCESSOR) || (target->inq_data[0] > 0x08)) {
3580 target->negoFlags |= (MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC);
3581 pspi_data->dvStatus[id] |= MPT_SCSICFG_BLK_NEGO;
3583 if (noQas && (pspi_data->noQas == 0)) {
3584 pspi_data->noQas |= MPT_TARGET_NO_NEGO_QAS;
3585 target->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
3587 /* Disable QAS in a mixed configuration case
3590 ddvtprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id));
3591 for (ii = 0; ii < id; ii++) {
3592 if ( (vdev = hd->Targets[ii]) ) {
3593 vdev->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
3594 mptscsih_writeSDP1(hd, 0, ii, vdev->negoFlags);
3600 /* Write SDP1 on this I/O to this target */
3601 if (pspi_data->dvStatus[id] & MPT_SCSICFG_NEGOTIATE) {
3602 ddvtprintk((KERN_INFO "MPT_SCSICFG_NEGOTIATE on id=%d!\n", id));
3603 mptscsih_writeSDP1(hd, 0, id, hd->negoNvram);
3604 pspi_data->dvStatus[id] &= ~MPT_SCSICFG_NEGOTIATE;
3605 } else if (pspi_data->dvStatus[id] & MPT_SCSICFG_BLK_NEGO) {
3606 ddvtprintk((KERN_INFO "MPT_SCSICFG_BLK_NEGO on id=%d!\n", id));
3607 mptscsih_writeSDP1(hd, 0, id, MPT_SCSICFG_BLK_NEGO);
3608 pspi_data->dvStatus[id] &= ~MPT_SCSICFG_BLK_NEGO;
3612 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3613 /* If DV disabled (negoNvram set to USE_NVARM) or if not LUN 0, return.
3614 * Else set the NEED_DV flag after Read Capacity Issued (disks)
3615 * or Mode Sense (cdroms).
3617 * Tapes, initTarget will set this flag on completion of Inquiry command.
3618 * Called only if DV_NOT_DONE flag is set
3620 static void mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq)
3625 ddvtprintk((" set_dvflags: id=%d lun=%d negoNvram=%x cmd=%x\n",
3626 pReq->TargetID, pReq->LUN[1], hd->negoNvram, pReq->CDB[0]));
3628 if ((pReq->LUN[1] != 0) || (hd->negoNvram != 0))
3633 if ((cmd == READ_CAPACITY) || (cmd == MODE_SENSE)) {
3634 pSpi = &hd->ioc->spi_data;
3635 if ((pSpi->isRaid & (1 << pReq->TargetID)) && pSpi->pIocPg3) {
3636 /* Set NEED_DV for all hidden disks
3638 Ioc3PhysDisk_t *pPDisk = pSpi->pIocPg3->PhysDisk;
3639 int numPDisk = pSpi->pIocPg3->NumPhysDisks;
3642 pSpi->dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV;
3643 ddvtprintk(("NEED_DV set for phys disk id %d\n", pPDisk->PhysDiskID));
3648 pSpi->dvStatus[pReq->TargetID] |= MPT_SCSICFG_NEED_DV;
3649 ddvtprintk(("NEED_DV set for visible disk id %d\n", pReq->TargetID));
3653 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3655 * If no Target, bus reset on 1st I/O. Set the flag to
3656 * prevent any future negotiations to this device.
3658 static void mptscsih_no_negotiate(MPT_SCSI_HOST *hd, int target_id)
3661 if ((hd->Targets) && (hd->Targets[target_id] == NULL))
3662 hd->ioc->spi_data.dvStatus[target_id] |= MPT_SCSICFG_BLK_NEGO;
3667 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3669 * SCSI Config Page functionality ...
3671 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3672 /* mptscsih_setDevicePage1Flags - add Requested and Configuration fields flags
3673 * based on width, factor and offset parameters.
3675 * @factor: sync factor
3676 * @offset: sync offset
3677 * @requestedPtr: pointer to requested values (updated)
3678 * @configurationPtr: pointer to configuration values (updated)
3679 * @flags: flags to block WDTR or SDTR negotiation
3683 * Remark: Called by writeSDP1 and _dv_params
3686 mptscsih_setDevicePage1Flags (u8 width, u8 factor, u8 offset, int *requestedPtr, int *configurationPtr, u8 flags)
3688 u8 nowide = flags & MPT_TARGET_NO_NEGO_WIDE;
3689 u8 nosync = flags & MPT_TARGET_NO_NEGO_SYNC;
3691 *configurationPtr = 0;
3692 *requestedPtr = width ? MPI_SCSIDEVPAGE1_RP_WIDE : 0;
3693 *requestedPtr |= (offset << 16) | (factor << 8);
3695 if (width && offset && !nowide && !nosync) {
3696 if (factor < MPT_ULTRA160) {
3697 *requestedPtr |= (MPI_SCSIDEVPAGE1_RP_IU + MPI_SCSIDEVPAGE1_RP_DT);
3698 if ((flags & MPT_TARGET_NO_NEGO_QAS) == 0)
3699 *requestedPtr |= MPI_SCSIDEVPAGE1_RP_QAS;
3700 if (flags & MPT_TAPE_NEGO_IDP)
3701 *requestedPtr |= 0x08000000;
3702 } else if (factor < MPT_ULTRA2) {
3703 *requestedPtr |= MPI_SCSIDEVPAGE1_RP_DT;
3708 *configurationPtr |= MPI_SCSIDEVPAGE1_CONF_WDTR_DISALLOWED;
3711 *configurationPtr |= MPI_SCSIDEVPAGE1_CONF_SDTR_DISALLOWED;
3716 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3717 /* mptscsih_writeSDP1 - write SCSI Device Page 1
3718 * @hd: Pointer to a SCSI Host Strucutre
3719 * @portnum: IOC port number
3720 * @target_id: writeSDP1 for single ID
3721 * @flags: MPT_SCSICFG_ALL_IDS, MPT_SCSICFG_USE_NVRAM, MPT_SCSICFG_BLK_NEGO
3723 * Return: -EFAULT if read of config page header fails
3726 * Remark: If a target has been found, the settings from the
3727 * target structure are used, else the device is set
3730 * Remark: Called during init and after a FW reload.
3731 * Remark: We do not wait for a return, write pages sequentially.
3734 mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
3736 MPT_ADAPTER *ioc = hd->ioc;
3738 SCSIDevicePage1_t *pData;
3739 VirtDevice *pTarget;
3744 u32 requested, configuration, flagsLength;
3746 int id = 0, maxid = 0;
3752 u8 maxwidth, maxoffset, maxfactor;
3754 if (ioc->spi_data.sdp1length == 0)
3757 if (flags & MPT_SCSICFG_ALL_IDS) {
3759 maxid = ioc->sh->max_id - 1;
3760 } else if (ioc->sh) {
3762 maxid = min_t(int, id, ioc->sh->max_id - 1);
3765 for (; id <= maxid; id++) {
3767 if (id == ioc->pfacts[portnum].PortSCSIID)
3770 /* Use NVRAM to get adapter and target maximums
3771 * Data over-riden by target structure information, if present
3773 maxwidth = ioc->spi_data.maxBusWidth;
3774 maxoffset = ioc->spi_data.maxSyncOffset;
3775 maxfactor = ioc->spi_data.minSyncFactor;
3776 if (ioc->spi_data.nvram && (ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
3777 nvram = ioc->spi_data.nvram[id];
3780 maxwidth = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
3782 if (maxoffset > 0) {
3783 maxfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
3784 if (maxfactor == 0) {
3786 maxfactor = MPT_ASYNC;
3788 } else if (maxfactor < ioc->spi_data.minSyncFactor) {
3789 maxfactor = ioc->spi_data.minSyncFactor;
3792 maxfactor = MPT_ASYNC;
3795 /* Set the negotiation flags.
3797 negoFlags = ioc->spi_data.noQas;
3799 negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
3802 negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
3804 if (flags & MPT_SCSICFG_USE_NVRAM) {
3813 //negoFlags = MPT_TARGET_NO_NEGO_SYNC;
3816 /* If id is not a raid volume, get the updated
3817 * transmission settings from the target structure.
3819 if (hd->Targets && (pTarget = hd->Targets[id]) && !pTarget->raidVolume) {
3820 width = pTarget->maxWidth;
3821 factor = pTarget->minSyncFactor;
3822 offset = pTarget->maxOffset;
3823 negoFlags = pTarget->negoFlags;
3826 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
3827 /* Force to async and narrow if DV has not been executed
3830 if ((hd->ioc->spi_data.dvStatus[id] & MPT_SCSICFG_DV_NOT_DONE) != 0) {
3837 if (flags & MPT_SCSICFG_BLK_NEGO)
3838 negoFlags = MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC;
3840 mptscsih_setDevicePage1Flags(width, factor, offset,
3841 &requested, &configuration, negoFlags);
3842 dnegoprintk(("writeSDP1: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
3843 target_id, width, factor, offset, negoFlags, requested, configuration));
3845 /* Get a MF for this command.
3847 if ((mf = mpt_get_msg_frame(ScsiDoneCtx, ioc)) == NULL) {
3848 dprintk((MYIOC_s_WARN_FMT "write SDP1: no msg frames!\n",
3853 ddvprintk((MYIOC_s_INFO_FMT "WriteSDP1 (mf=%p, id=%d, req=0x%x, cfg=0x%x)\n",
3854 hd->ioc->name, mf, id, requested, configuration));
3857 /* Set the request and the data pointers.
3858 * Request takes: 36 bytes (32 bit SGE)
3859 * SCSI Device Page 1 requires 16 bytes
3860 * 40 + 16 <= size of SCSI IO Request = 56 bytes
3861 * and MF size >= 64 bytes.
3862 * Place data at end of MF.
3864 pReq = (Config_t *)mf;
3866 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3867 frameOffset = ioc->req_sz - sizeof(SCSIDevicePage1_t);
3869 pData = (SCSIDevicePage1_t *)((u8 *) mf + frameOffset);
3870 dataDma = ioc->req_frames_dma + (req_idx * ioc->req_sz) + frameOffset;
3872 /* Complete the request frame (same for all requests).
3874 pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
3876 pReq->ChainOffset = 0;
3877 pReq->Function = MPI_FUNCTION_CONFIG;
3878 pReq->ExtPageLength = 0;
3879 pReq->ExtPageType = 0;
3881 for (ii=0; ii < 8; ii++) {
3882 pReq->Reserved2[ii] = 0;
3884 pReq->Header.PageVersion = ioc->spi_data.sdp1version;
3885 pReq->Header.PageLength = ioc->spi_data.sdp1length;
3886 pReq->Header.PageNumber = 1;
3887 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
3888 pReq->PageAddress = cpu_to_le32(id | (bus << 8 ));
3890 /* Add a SGE to the config request.
3892 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE | ioc->spi_data.sdp1length * 4;
3894 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma);
3896 /* Set up the common data portion
3898 pData->Header.PageVersion = pReq->Header.PageVersion;
3899 pData->Header.PageLength = pReq->Header.PageLength;
3900 pData->Header.PageNumber = pReq->Header.PageNumber;
3901 pData->Header.PageType = pReq->Header.PageType;
3902 pData->RequestedParameters = cpu_to_le32(requested);
3903 pData->Reserved = 0;
3904 pData->Configuration = cpu_to_le32(configuration);
3906 dprintk((MYIOC_s_INFO_FMT
3907 "write SDP1: id %d pgaddr 0x%x req 0x%x config 0x%x\n",
3908 ioc->name, id, (id | (bus<<8)),
3909 requested, configuration));
3911 mpt_put_msg_frame(ScsiDoneCtx, ioc, mf);
3917 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3918 /* mptscsih_writeIOCPage4 - write IOC Page 4
3919 * @hd: Pointer to a SCSI Host Structure
3920 * @target_id: write IOC Page4 for this ID & Bus
3922 * Return: -EAGAIN if unable to obtain a Message Frame
3925 * Remark: We do not wait for a return, write pages sequentially.
3928 mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus)
3930 MPT_ADAPTER *ioc = hd->ioc;
3932 IOCPage4_t *IOCPage4Ptr;
3940 /* Get a MF for this command.
3942 if ((mf = mpt_get_msg_frame(ScsiDoneCtx, ioc)) == NULL) {
3943 dprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n",
3948 /* Set the request and the data pointers.
3949 * Place data at end of MF.
3951 pReq = (Config_t *)mf;
3953 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3954 frameOffset = ioc->req_sz - sizeof(IOCPage4_t);
3956 /* Complete the request frame (same for all requests).
3958 pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
3960 pReq->ChainOffset = 0;
3961 pReq->Function = MPI_FUNCTION_CONFIG;
3962 pReq->ExtPageLength = 0;
3963 pReq->ExtPageType = 0;
3965 for (ii=0; ii < 8; ii++) {
3966 pReq->Reserved2[ii] = 0;
3969 IOCPage4Ptr = ioc->spi_data.pIocPg4;
3970 dataDma = ioc->spi_data.IocPg4_dma;
3971 ii = IOCPage4Ptr->ActiveSEP++;
3972 IOCPage4Ptr->SEP[ii].SEPTargetID = target_id;
3973 IOCPage4Ptr->SEP[ii].SEPBus = bus;
3974 pReq->Header = IOCPage4Ptr->Header;
3975 pReq->PageAddress = cpu_to_le32(target_id | (bus << 8 ));
3977 /* Add a SGE to the config request.
3979 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE |
3980 (IOCPage4Ptr->Header.PageLength + ii) * 4;
3982 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma);
3984 dinitprintk((MYIOC_s_INFO_FMT
3985 "writeIOCPage4: MaxSEP=%d ActiveSEP=%d id=%d bus=%d\n",
3986 ioc->name, IOCPage4Ptr->MaxSEP, IOCPage4Ptr->ActiveSEP, target_id, bus));
3988 mpt_put_msg_frame(ScsiDoneCtx, ioc, mf);
3993 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3994 /* mptscsih_taskmgmt_timeout - Call back for timeout on a
3995 * task management request.
3996 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
3999 static void mptscsih_taskmgmt_timeout(unsigned long data)
4001 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) data;
4003 dtmprintk((KERN_WARNING MYNAM ": %s: mptscsih_taskmgmt_timeout: "
4004 "TM request timed out!\n", hd->ioc->name));
4006 /* Delete the timer that triggered this callback.
4007 * Remark: del_timer checks to make sure timer is active
4010 del_timer(&hd->TMtimer);
4012 /* Call the reset handler. Already had a TM request
4013 * timeout - so issue a diagnostic reset
4015 INIT_WORK(&mptscsih_rstTask, mptscsih_schedule_reset, (void *)hd);
4016 schedule_work(&mptscsih_rstTask);
4020 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4021 /* mptscsih_schedule_reset - Call back for timeout on a
4022 * task management request.
4023 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
4027 mptscsih_schedule_reset(void *arg)
4030 hd = (MPT_SCSI_HOST *) arg;
4032 if (mpt_HardResetHandler(hd->ioc, CAN_SLEEP) < 0) {
4033 printk((KERN_WARNING " Firmware Reload FAILED!!\n"));
4035 /* Because we have reset the IOC, no TM requests can be
4036 * pending. So let's make sure the tmPending flag is reset.
4038 dtmprintk((KERN_WARNING MYNAM
4039 ": %s: mptscsih_taskmgmt_timeout\n",
4047 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4049 * Bus Scan and Domain Validation functionality ...
4052 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4054 * mptscsih_scandv_complete - Scan and DV callback routine registered
4055 * to Fustion MPT (base) driver.
4057 * @ioc: Pointer to MPT_ADAPTER structure
4058 * @mf: Pointer to original MPT request frame
4059 * @mr: Pointer to MPT reply frame (NULL if TurboReply)
4061 * This routine is called from mpt.c::mpt_interrupt() at the completion
4062 * of any SCSI IO request.
4063 * This routine is registered with the Fusion MPT (base) driver at driver
4064 * load/init time via the mpt_register() API call.
4066 * Returns 1 indicating alloc'd request frame ptr should be freed.
4068 * Remark: Sets a completion code and (possibly) saves sense data
4069 * in the IOC member localReply structure.
4070 * Used ONLY for DV and other internal commands.
4073 mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
4076 SCSIIORequest_t *pReq;
4081 (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) {
4082 printk(MYIOC_s_ERR_FMT
4083 "ScanDvComplete, %s req frame ptr! (=%p)\n",
4084 ioc->name, mf?"BAD":"NULL", (void *) mf);
4088 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
4089 del_timer(&hd->timer);
4090 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
4091 hd->ScsiLookup[req_idx] = NULL;
4092 pReq = (SCSIIORequest_t *) mf;
4094 if (mf != hd->cmdPtr) {
4095 printk(MYIOC_s_WARN_FMT "ScanDvComplete (mf=%p, cmdPtr=%p, idx=%d)\n",
4096 hd->ioc->name, (void *)mf, (void *) hd->cmdPtr, req_idx);
4100 ddvprintk((MYIOC_s_INFO_FMT "ScanDvComplete (mf=%p,mr=%p,idx=%d)\n",
4101 hd->ioc->name, mf, mr, req_idx));
4103 hd->pLocal = &hd->localReply;
4104 hd->pLocal->scsiStatus = 0;
4106 /* If target struct exists, clear sense valid flag.
4109 completionCode = MPT_SCANDV_GOOD;
4111 SCSIIOReply_t *pReply;
4115 pReply = (SCSIIOReply_t *) mr;
4117 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
4118 scsi_status = pReply->SCSIStatus;
4120 ddvtprintk((KERN_NOTICE " IOCStatus=%04xh, SCSIState=%02xh, SCSIStatus=%02xh, IOCLogInfo=%08xh\n",
4121 status, pReply->SCSIState, scsi_status,
4122 le32_to_cpu(pReply->IOCLogInfo)));
4126 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
4127 completionCode = MPT_SCANDV_SELECTION_TIMEOUT;
4130 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
4131 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
4132 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
4133 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
4134 completionCode = MPT_SCANDV_DID_RESET;
4137 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
4138 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
4139 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
4140 if (pReply->Function == MPI_FUNCTION_CONFIG) {
4141 ConfigReply_t *pr = (ConfigReply_t *)mr;
4142 completionCode = MPT_SCANDV_GOOD;
4143 hd->pLocal->header.PageVersion = pr->Header.PageVersion;
4144 hd->pLocal->header.PageLength = pr->Header.PageLength;
4145 hd->pLocal->header.PageNumber = pr->Header.PageNumber;
4146 hd->pLocal->header.PageType = pr->Header.PageType;
4148 } else if (pReply->Function == MPI_FUNCTION_RAID_ACTION) {
4149 /* If the RAID Volume request is successful,
4150 * return GOOD, else indicate that
4151 * some type of error occurred.
4153 MpiRaidActionReply_t *pr = (MpiRaidActionReply_t *)mr;
4154 if (pr->ActionStatus == MPI_RAID_ACTION_ASTATUS_SUCCESS)
4155 completionCode = MPT_SCANDV_GOOD;
4157 completionCode = MPT_SCANDV_SOME_ERROR;
4159 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID) {
4163 /* save sense data in global structure
4165 completionCode = MPT_SCANDV_SENSE;
4166 hd->pLocal->scsiStatus = scsi_status;
4167 sense_data = ((u8 *)hd->ioc->sense_buf_pool +
4168 (req_idx * MPT_SENSE_BUFFER_ALLOC));
4170 sz = min_t(int, pReq->SenseBufferLength,
4171 SCSI_STD_SENSE_BYTES);
4172 memcpy(hd->pLocal->sense, sense_data, sz);
4174 ddvprintk((KERN_NOTICE " Check Condition, sense ptr %p\n",
4176 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_FAILED) {
4177 if (pReq->CDB[0] == INQUIRY)
4178 completionCode = MPT_SCANDV_ISSUE_SENSE;
4180 completionCode = MPT_SCANDV_DID_RESET;
4182 else if (pReply->SCSIState & MPI_SCSI_STATE_NO_SCSI_STATUS)
4183 completionCode = MPT_SCANDV_DID_RESET;
4184 else if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
4185 completionCode = MPT_SCANDV_DID_RESET;
4187 completionCode = MPT_SCANDV_GOOD;
4188 hd->pLocal->scsiStatus = scsi_status;
4192 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
4193 if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
4194 completionCode = MPT_SCANDV_DID_RESET;
4196 completionCode = MPT_SCANDV_SOME_ERROR;
4200 completionCode = MPT_SCANDV_SOME_ERROR;
4203 } /* switch(status) */
4205 ddvtprintk((KERN_NOTICE " completionCode set to %08xh\n",
4207 } /* end of address reply case */
4209 hd->pLocal->completion = completionCode;
4211 /* MF and RF are freed in mpt_interrupt
4214 /* Free Chain buffers (will never chain) in scan or dv */
4215 //mptscsih_freeChainBuffers(ioc, req_idx);
4218 * Wake up the original calling thread
4220 scandv_wait_done = 1;
4221 wake_up(&scandv_waitq);
4226 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4227 /* mptscsih_timer_expired - Call back for timer process.
4228 * Used only for dv functionality.
4229 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
4232 static void mptscsih_timer_expired(unsigned long data)
4234 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) data;
4236 ddvprintk((MYIOC_s_WARN_FMT "Timer Expired! Cmd %p\n", hd->ioc->name, hd->cmdPtr));
4239 MPIHeader_t *cmd = (MPIHeader_t *)hd->cmdPtr;
4241 if (cmd->Function == MPI_FUNCTION_SCSI_IO_REQUEST) {
4242 /* Desire to issue a task management request here.
4243 * TM requests MUST be single threaded.
4244 * If old eh code and no TM current, issue request.
4245 * If new eh code, do nothing. Wait for OS cmd timeout
4248 ddvtprintk((MYIOC_s_NOTE_FMT "DV Cmd Timeout: NoOp\n", hd->ioc->name));
4250 /* Perform a FW reload */
4251 if (mpt_HardResetHandler(hd->ioc, NO_SLEEP) < 0) {
4252 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", hd->ioc->name);
4256 /* This should NEVER happen */
4257 printk(MYIOC_s_WARN_FMT "Null cmdPtr!!!!\n", hd->ioc->name);
4260 /* No more processing.
4261 * TM call will generate an interrupt for SCSI TM Management.
4262 * The FW will reply to all outstanding commands, callback will finish cleanup.
4263 * Hard reset clean-up will free all resources.
4265 ddvprintk((MYIOC_s_WARN_FMT "Timer Expired Complete!\n", hd->ioc->name));
4270 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
4271 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4272 /* mptscsih_do_raid - Format and Issue a RAID volume request message.
4273 * @hd: Pointer to scsi host structure
4274 * @action: What do be done.
4275 * @id: Logical target id.
4276 * @bus: Target locations bus.
4278 * Returns: < 0 on a fatal error
4281 * Remark: Wait to return until reply processed by the ISR.
4284 mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io)
4286 MpiRaidActionRequest_t *pReq;
4290 in_isr = in_interrupt();
4292 dprintk((MYIOC_s_WARN_FMT "Internal raid request not allowed in ISR context!\n",
4297 /* Get and Populate a free Frame
4299 if ((mf = mpt_get_msg_frame(ScsiScanDvCtx, hd->ioc)) == NULL) {
4300 ddvprintk((MYIOC_s_WARN_FMT "_do_raid: no msg frames!\n",
4304 pReq = (MpiRaidActionRequest_t *)mf;
4305 pReq->Action = action;
4306 pReq->Reserved1 = 0;
4307 pReq->ChainOffset = 0;
4308 pReq->Function = MPI_FUNCTION_RAID_ACTION;
4309 pReq->VolumeID = io->id;
4310 pReq->VolumeBus = io->bus;
4311 pReq->PhysDiskNum = io->physDiskNum;
4313 pReq->Reserved2 = 0;
4314 pReq->ActionDataWord = 0; /* Reserved for this action */
4315 //pReq->ActionDataSGE = 0;
4317 mpt_add_sge((char *)&pReq->ActionDataSGE,
4318 MPT_SGE_FLAGS_SSIMPLE_READ | 0, (dma_addr_t) -1);
4320 ddvprintk((MYIOC_s_INFO_FMT "RAID Volume action %x id %d\n",
4321 hd->ioc->name, action, io->id));
4324 hd->timer.expires = jiffies + HZ*10; /* 10 second timeout */
4325 scandv_wait_done = 0;
4327 /* Save cmd pointer, for resource free if timeout or
4332 add_timer(&hd->timer);
4333 mpt_put_msg_frame(ScsiScanDvCtx, hd->ioc, mf);
4334 wait_event(scandv_waitq, scandv_wait_done);
4336 if ((hd->pLocal == NULL) || (hd->pLocal->completion != MPT_SCANDV_GOOD))
4341 #endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */
4343 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4345 * mptscsih_do_cmd - Do internal command.
4346 * @hd: MPT_SCSI_HOST pointer
4347 * @io: INTERNAL_CMD pointer.
4349 * Issue the specified internally generated command and do command
4350 * specific cleanup. For bus scan / DV only.
4351 * NOTES: If command is Inquiry and status is good,
4352 * initialize a target structure, save the data
4354 * Remark: Single threaded access only.
4357 * < 0 if an illegal command or no resources
4361 * > 0 if command complete but some type of completion error.
4364 mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
4367 SCSIIORequest_t *pScsiReq;
4368 SCSIIORequest_t ReqCopy;
4369 int my_idx, ii, dir;
4373 char CDB[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
4376 in_isr = in_interrupt();
4378 dprintk((MYIOC_s_WARN_FMT "Internal SCSI IO request not allowed in ISR context!\n",
4384 /* Set command specific information
4389 dir = MPI_SCSIIO_CONTROL_READ;
4395 case TEST_UNIT_READY:
4397 dir = MPI_SCSIIO_CONTROL_READ;
4403 dir = MPI_SCSIIO_CONTROL_READ;
4405 CDB[4] = 1; /*Spin up the disk */
4413 dir = MPI_SCSIIO_CONTROL_READ;
4419 dir = MPI_SCSIIO_CONTROL_READ;
4421 if (io->flags & MPT_ICFLAG_ECHO) {
4427 if (io->flags & MPT_ICFLAG_BUF_CAP) {
4430 CDB[6] = (io->size >> 16) & 0xFF;
4431 CDB[7] = (io->size >> 8) & 0xFF;
4432 CDB[8] = io->size & 0xFF;
4438 dir = MPI_SCSIIO_CONTROL_WRITE;
4440 if (io->flags & MPT_ICFLAG_ECHO) {
4445 CDB[6] = (io->size >> 16) & 0xFF;
4446 CDB[7] = (io->size >> 8) & 0xFF;
4447 CDB[8] = io->size & 0xFF;
4453 dir = MPI_SCSIIO_CONTROL_READ;
4460 dir = MPI_SCSIIO_CONTROL_READ;
4465 case SYNCHRONIZE_CACHE:
4467 dir = MPI_SCSIIO_CONTROL_READ;
4469 // CDB[1] = 0x02; /* set immediate bit */
4478 /* Get and Populate a free Frame
4480 if ((mf = mpt_get_msg_frame(ScsiScanDvCtx, hd->ioc)) == NULL) {
4481 ddvprintk((MYIOC_s_WARN_FMT "No msg frames!\n",
4486 pScsiReq = (SCSIIORequest_t *) mf;
4488 /* Get the request index */
4489 my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
4490 ADD_INDEX_LOG(my_idx); /* for debug */
4492 if (io->flags & MPT_ICFLAG_PHYS_DISK) {
4493 pScsiReq->TargetID = io->physDiskNum;
4495 pScsiReq->ChainOffset = 0;
4496 pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
4498 pScsiReq->TargetID = io->id;
4499 pScsiReq->Bus = io->bus;
4500 pScsiReq->ChainOffset = 0;
4501 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
4504 pScsiReq->CDBLength = cmdLen;
4505 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
4507 pScsiReq->Reserved = 0;
4509 pScsiReq->MsgFlags = mpt_msg_flags();
4510 /* MsgContext set in mpt_get_msg_fram call */
4512 for (ii=0; ii < 8; ii++)
4513 pScsiReq->LUN[ii] = 0;
4514 pScsiReq->LUN[1] = io->lun;
4516 if (io->flags & MPT_ICFLAG_TAGGED_CMD)
4517 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ);
4519 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
4521 if (cmd == REQUEST_SENSE) {
4522 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
4523 ddvprintk((MYIOC_s_INFO_FMT "Untagged! 0x%2x\n",
4524 hd->ioc->name, cmd));
4527 for (ii=0; ii < 16; ii++)
4528 pScsiReq->CDB[ii] = CDB[ii];
4530 pScsiReq->DataLength = cpu_to_le32(io->size);
4531 pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
4532 + (my_idx * MPT_SENSE_BUFFER_ALLOC));
4534 ddvprintk((MYIOC_s_INFO_FMT "Sending Command 0x%x for (%d:%d:%d)\n",
4535 hd->ioc->name, cmd, io->bus, io->id, io->lun));
4537 if (dir == MPI_SCSIIO_CONTROL_READ) {
4538 mpt_add_sge((char *) &pScsiReq->SGL,
4539 MPT_SGE_FLAGS_SSIMPLE_READ | io->size,
4542 mpt_add_sge((char *) &pScsiReq->SGL,
4543 MPT_SGE_FLAGS_SSIMPLE_WRITE | io->size,
4547 /* The ISR will free the request frame, but we need
4548 * the information to initialize the target. Duplicate.
4550 memcpy(&ReqCopy, pScsiReq, sizeof(SCSIIORequest_t));
4552 /* Issue this command after:
4555 * Wait until the reply has been received
4556 * ScsiScanDvCtx callback function will
4558 * set scandv_wait_done and call wake_up
4561 hd->timer.expires = jiffies + HZ*cmdTimeout;
4562 scandv_wait_done = 0;
4564 /* Save cmd pointer, for resource free if timeout or
4569 add_timer(&hd->timer);
4570 mpt_put_msg_frame(ScsiScanDvCtx, hd->ioc, mf);
4571 wait_event(scandv_waitq, scandv_wait_done);
4574 rc = hd->pLocal->completion;
4575 hd->pLocal->skip = 0;
4577 /* Always set fatal error codes in some cases.
4579 if (rc == MPT_SCANDV_SELECTION_TIMEOUT)
4581 else if (rc == MPT_SCANDV_SOME_ERROR)
4585 /* This should never happen. */
4586 ddvprintk((MYIOC_s_INFO_FMT "_do_cmd: Null pLocal!!!\n",
4593 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4595 * mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
4596 * @hd: Pointer to MPT_SCSI_HOST structure
4597 * @portnum: IOC port number
4599 * Uses the ISR, but with special processing.
4600 * MUST be single-threaded.
4602 * Return: 0 on completion
4605 mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum)
4607 MPT_ADAPTER *ioc= hd->ioc;
4608 VirtDevice *pTarget;
4609 SCSIDevicePage1_t *pcfg1Data = NULL;
4612 dma_addr_t cfg1_dma_addr = -1;
4613 ConfigPageHeader_t header1;
4617 int indexed_lun, lun_index;
4618 int hostId = ioc->pfacts[portnum].PortSCSIID;
4620 int requested, configuration, data;
4624 max_id = ioc->sh->max_id - 1;
4626 /* Following parameters will not change
4629 iocmd.cmd = SYNCHRONIZE_CACHE;
4631 iocmd.physDiskNum = -1;
4633 iocmd.data_dma = -1;
4635 iocmd.rsvd = iocmd.rsvd2 = 0;
4639 if (hd->Targets == NULL)
4647 /* Write SDP1 for all SCSI devices
4648 * Alloc memory and set up config buffer
4651 if (ioc->spi_data.sdp1length > 0) {
4652 pcfg1Data = (SCSIDevicePage1_t *)pci_alloc_consistent(ioc->pcidev,
4653 ioc->spi_data.sdp1length * 4, &cfg1_dma_addr);
4655 if (pcfg1Data != NULL) {
4657 header1.PageVersion = ioc->spi_data.sdp1version;
4658 header1.PageLength = ioc->spi_data.sdp1length;
4659 header1.PageNumber = 1;
4660 header1.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4662 cfg.physAddr = cfg1_dma_addr;
4663 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4670 /* loop through all devices on this port
4672 while (bus < MPT_MAX_BUS) {
4675 pTarget = hd->Targets[(int)id];
4679 /* Set the negotiation flags */
4680 if (pTarget && (pTarget = hd->Targets[id]) && !pTarget->raidVolume) {
4681 flags = pTarget->negoFlags;
4683 flags = hd->ioc->spi_data.noQas;
4684 if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
4685 data = hd->ioc->spi_data.nvram[id];
4687 if (data & MPT_NVRAM_WIDE_DISABLE)
4688 flags |= MPT_TARGET_NO_NEGO_WIDE;
4690 factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT;
4691 if ((factor == 0) || (factor == MPT_ASYNC))
4692 flags |= MPT_TARGET_NO_NEGO_SYNC;
4696 /* Force to async, narrow */
4697 mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested,
4698 &configuration, flags);
4699 dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC "
4700 "offset=0 negoFlags=%x request=%x config=%x\n",
4701 id, flags, requested, configuration));
4702 pcfg1Data->RequestedParameters = le32_to_cpu(requested);
4703 pcfg1Data->Reserved = 0;
4704 pcfg1Data->Configuration = le32_to_cpu(configuration);
4705 cfg.pageAddr = (bus<<8) | id;
4706 mpt_config(hd->ioc, &cfg);
4709 /* If target Ptr NULL or if this target is NOT a disk, skip.
4711 if ((pTarget) && (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)){
4712 for (lun=0; lun <= MPT_LAST_LUN; lun++) {
4713 /* If LUN present, issue the command
4715 lun_index = (lun >> 5); /* 32 luns per lun_index */
4716 indexed_lun = (lun % 32);
4717 if (pTarget->luns[lun_index] & (1<<indexed_lun)) {
4719 (void) mptscsih_do_cmd(hd, &iocmd);
4724 /* get next relevant device */
4737 pci_free_consistent(ioc->pcidev, header1.PageLength * 4, pcfg1Data, cfg1_dma_addr);
4743 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
4744 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4746 * mptscsih_domainValidation - Top level handler for domain validation.
4747 * @hd: Pointer to MPT_SCSI_HOST structure.
4749 * Uses the ISR, but with special processing.
4750 * Called from schedule, should not be in interrupt mode.
4751 * While thread alive, do dv for all devices needing dv
4756 mptscsih_domainValidation(void *arg)
4760 unsigned long flags;
4761 int id, maxid, dvStatus, did;
4764 spin_lock_irqsave(&dvtaskQ_lock, flags);
4766 if (dvtaskQ_release) {
4768 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4771 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4773 /* For this ioc, loop through all devices and do dv to each device.
4774 * When complete with this ioc, search through the ioc list, and
4775 * for each scsi ioc found, do dv for all devices. Exit when no
4781 list_for_each_entry(ioc, &ioc_list, list) {
4782 spin_lock_irqsave(&dvtaskQ_lock, flags);
4783 if (dvtaskQ_release) {
4785 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4788 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4792 /* DV only to SCSI adapters */
4793 if ((int)ioc->chip_type <= (int)FC929)
4796 /* Make sure everything looks ok */
4797 if (ioc->sh == NULL)
4800 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
4804 if ((ioc->spi_data.forceDv & MPT_SCSICFG_RELOAD_IOC_PG3) != 0) {
4805 mpt_read_ioc_pg_3(ioc);
4806 if (ioc->spi_data.pIocPg3) {
4807 Ioc3PhysDisk_t *pPDisk = ioc->spi_data.pIocPg3->PhysDisk;
4808 int numPDisk = ioc->spi_data.pIocPg3->NumPhysDisks;
4811 if (ioc->spi_data.dvStatus[pPDisk->PhysDiskID] & MPT_SCSICFG_DV_NOT_DONE)
4812 ioc->spi_data.dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV;
4818 ioc->spi_data.forceDv &= ~MPT_SCSICFG_RELOAD_IOC_PG3;
4821 maxid = min_t(int, ioc->sh->max_id, MPT_MAX_SCSI_DEVICES);
4823 for (id = 0; id < maxid; id++) {
4824 spin_lock_irqsave(&dvtaskQ_lock, flags);
4825 if (dvtaskQ_release) {
4827 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4830 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4831 dvStatus = hd->ioc->spi_data.dvStatus[id];
4833 if (dvStatus & MPT_SCSICFG_NEED_DV) {
4835 hd->ioc->spi_data.dvStatus[id] |= MPT_SCSICFG_DV_PENDING;
4836 hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_NEED_DV;
4840 /* If hidden phys disk, block IO's to all
4842 * else, process normally
4844 isPhysDisk = mptscsih_is_phys_disk(ioc, id);
4846 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4847 if (hd->ioc->spi_data.isRaid & (1 << ii)) {
4848 hd->ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_DV_PENDING;
4853 if (mptscsih_doDv(hd, 0, id) == 1) {
4854 /* Untagged device was busy, try again
4856 hd->ioc->spi_data.dvStatus[id] |= MPT_SCSICFG_NEED_DV;
4857 hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_PENDING;
4859 /* DV is complete. Clear flags.
4861 hd->ioc->spi_data.dvStatus[id] &= ~(MPT_SCSICFG_DV_NOT_DONE | MPT_SCSICFG_DV_PENDING);
4865 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4866 if (hd->ioc->spi_data.isRaid & (1 << ii)) {
4867 hd->ioc->spi_data.dvStatus[ii] &= ~MPT_SCSICFG_DV_PENDING;
4872 if (hd->ioc->spi_data.noQas)
4873 mptscsih_qas_check(hd, id);
4879 spin_lock_irqsave(&dvtaskQ_lock, flags);
4881 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4886 /* Search IOC page 3 to determine if this is hidden physical disk
4888 static int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id)
4890 if (ioc->spi_data.pIocPg3) {
4891 Ioc3PhysDisk_t *pPDisk = ioc->spi_data.pIocPg3->PhysDisk;
4892 int numPDisk = ioc->spi_data.pIocPg3->NumPhysDisks;
4895 if (pPDisk->PhysDiskID == id) {
4905 /* Write SDP1 if no QAS has been enabled
4907 static void mptscsih_qas_check(MPT_SCSI_HOST *hd, int id)
4909 VirtDevice *pTarget;
4912 if (hd->Targets == NULL)
4915 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4919 if ((hd->ioc->spi_data.dvStatus[ii] & MPT_SCSICFG_DV_NOT_DONE) != 0)
4922 pTarget = hd->Targets[ii];
4924 if ((pTarget != NULL) && (!pTarget->raidVolume)) {
4925 if ((pTarget->negoFlags & hd->ioc->spi_data.noQas) == 0) {
4926 pTarget->negoFlags |= hd->ioc->spi_data.noQas;
4927 dnegoprintk(("writeSDP1: id=%d flags=0\n", id));
4928 mptscsih_writeSDP1(hd, 0, ii, 0);
4931 if (mptscsih_is_phys_disk(hd->ioc, ii) == 1) {
4932 dnegoprintk(("writeSDP1: id=%d SCSICFG_USE_NVRAM\n", id));
4933 mptscsih_writeSDP1(hd, 0, ii, MPT_SCSICFG_USE_NVRAM);
4942 #define MPT_GET_NVRAM_VALS 0x01
4943 #define MPT_UPDATE_MAX 0x02
4944 #define MPT_SET_MAX 0x04
4945 #define MPT_SET_MIN 0x08
4946 #define MPT_FALLBACK 0x10
4947 #define MPT_SAVE 0x20
4949 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4951 * mptscsih_doDv - Perform domain validation to a target.
4952 * @hd: Pointer to MPT_SCSI_HOST structure.
4953 * @portnum: IOC port number.
4954 * @target: Physical ID of this target
4956 * Uses the ISR, but with special processing.
4957 * MUST be single-threaded.
4958 * Test will exit if target is at async & narrow.
4963 mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
4965 MPT_ADAPTER *ioc = hd->ioc;
4966 VirtDevice *pTarget;
4967 SCSIDevicePage1_t *pcfg1Data;
4968 SCSIDevicePage0_t *pcfg0Data;
4972 dma_addr_t dvbuf_dma = -1;
4973 dma_addr_t buf1_dma = -1;
4974 dma_addr_t buf2_dma = -1;
4975 dma_addr_t cfg1_dma_addr = -1;
4976 dma_addr_t cfg0_dma_addr = -1;
4977 ConfigPageHeader_t header1;
4978 ConfigPageHeader_t header0;
4985 int dataBufSize = 0;
4986 int echoBufSize = 0;
4991 int nfactor = MPT_ULTRA320;
4993 char doFallback = 0;
4998 if (ioc->spi_data.sdp1length == 0)
5001 if (ioc->spi_data.sdp0length == 0)
5004 /* If multiple buses are used, require that the initiator
5005 * id be the same on all buses.
5007 if (id == ioc->pfacts[0].PortSCSIID)
5011 bus = (u8) bus_number;
5012 ddvtprintk((MYIOC_s_NOTE_FMT
5013 "DV started: bus=%d, id=%d dv @ %p\n",
5014 ioc->name, bus, id, &dv));
5016 /* Prep DV structure
5018 memset (&dv, 0, sizeof(DVPARAMETERS));
5021 /* Populate tmax with the current maximum
5022 * transfer parameters for this target.
5023 * Exit if narrow and async.
5025 dv.cmd = MPT_GET_NVRAM_VALS;
5026 mptscsih_dv_parms(hd, &dv, NULL);
5028 /* Prep SCSI IO structure
5034 iocmd.physDiskNum = -1;
5035 iocmd.rsvd = iocmd.rsvd2 = 0;
5037 pTarget = hd->Targets[id];
5039 /* Use tagged commands if possible.
5042 if (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)
5043 iocmd.flags |= MPT_ICFLAG_TAGGED_CMD;
5045 if (hd->ioc->facts.FWVersion.Word < 0x01000600)
5048 if ((hd->ioc->facts.FWVersion.Word >= 0x01010000) &&
5049 (hd->ioc->facts.FWVersion.Word < 0x01010B00))
5054 /* Prep cfg structure
5056 cfg.pageAddr = (bus<<8) | id;
5061 header0.PageVersion = ioc->spi_data.sdp0version;
5062 header0.PageLength = ioc->spi_data.sdp0length;
5063 header0.PageNumber = 0;
5064 header0.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5068 header1.PageVersion = ioc->spi_data.sdp1version;
5069 header1.PageLength = ioc->spi_data.sdp1length;
5070 header1.PageNumber = 1;
5071 header1.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5073 if (header0.PageLength & 1)
5074 dv_alloc = (header0.PageLength * 4) + 4;
5076 dv_alloc += (2048 + (header1.PageLength * 4));
5078 pDvBuf = pci_alloc_consistent(ioc->pcidev, dv_alloc, &dvbuf_dma);
5083 pbuf1 = (u8 *)pDvBuf;
5084 buf1_dma = dvbuf_dma;
5087 pbuf2 = (u8 *) (pDvBuf + sz);
5088 buf2_dma = dvbuf_dma + sz;
5091 pcfg0Data = (SCSIDevicePage0_t *) (pDvBuf + sz);
5092 cfg0_dma_addr = dvbuf_dma + sz;
5093 sz += header0.PageLength * 4;
5097 if (header0.PageLength & 1)
5100 pcfg1Data = (SCSIDevicePage1_t *) (pDvBuf + sz);
5101 cfg1_dma_addr = dvbuf_dma + sz;
5103 /* Skip this ID? Set cfg.hdr to force config page write
5106 ScsiCfgData *pspi_data = &hd->ioc->spi_data;
5107 if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
5108 /* Set the factor from nvram */
5109 nfactor = (pspi_data->nvram[id] & MPT_NVRAM_SYNC_MASK) >> 8;
5110 if (nfactor < pspi_data->minSyncFactor )
5111 nfactor = pspi_data->minSyncFactor;
5113 if (!(pspi_data->nvram[id] & MPT_NVRAM_ID_SCAN_ENABLE) ||
5114 (pspi_data->PortFlags == MPI_SCSIPORTPAGE2_PORT_FLAGS_OFF_DV) ) {
5116 ddvprintk((MYIOC_s_NOTE_FMT "DV Skipped: bus, id, lun (%d, %d, %d)\n",
5117 ioc->name, bus, id, lun));
5119 dv.cmd = MPT_SET_MAX;
5120 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5123 /* Save the final negotiated settings to
5124 * SCSI device page 1.
5126 cfg.physAddr = cfg1_dma_addr;
5127 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5129 mpt_config(hd->ioc, &cfg);
5135 /* Finish iocmd inititialization - hidden or visible disk? */
5136 if (ioc->spi_data.pIocPg3) {
5137 /* Search IOC page 3 for matching id
5139 Ioc3PhysDisk_t *pPDisk = ioc->spi_data.pIocPg3->PhysDisk;
5140 int numPDisk = ioc->spi_data.pIocPg3->NumPhysDisks;
5143 if (pPDisk->PhysDiskID == id) {
5145 iocmd.flags |= MPT_ICFLAG_PHYS_DISK;
5146 iocmd.physDiskNum = pPDisk->PhysDiskNum;
5150 if (mptscsih_do_raid(hd, MPI_RAID_ACTION_QUIESCE_PHYS_IO, &iocmd) < 0) {
5151 ddvprintk((MYIOC_s_ERR_FMT "RAID Queisce FAILED!\n", ioc->name));
5161 /* RAID Volume ID's may double for a physical device. If RAID but
5162 * not a physical ID as well, skip DV.
5164 if ((hd->ioc->spi_data.isRaid & (1 << id)) && !(iocmd.flags & MPT_ICFLAG_PHYS_DISK))
5169 * Async & Narrow - Inquiry
5170 * Async & Narrow - Inquiry
5171 * Maximum transfer rate - Inquiry
5173 * If compare, test complete.
5174 * If miscompare and first pass, repeat
5175 * If miscompare and not first pass, fall back and repeat
5179 sz = SCSI_MAX_INQUIRY_BYTES;
5180 rc = MPT_SCANDV_GOOD;
5182 ddvprintk((MYIOC_s_NOTE_FMT "DV: Start Basic test on id=%d\n", ioc->name, id));
5184 dv.cmd = MPT_SET_MIN;
5185 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5188 cfg.physAddr = cfg1_dma_addr;
5189 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5191 if (mpt_config(hd->ioc, &cfg) != 0)
5194 /* Wide - narrow - wide workaround case
5196 if ((rc == MPT_SCANDV_ISSUE_SENSE) && dv.max.width) {
5197 /* Send an untagged command to reset disk Qs corrupted
5198 * when a parity error occurs on a Request Sense.
5200 if ((hd->ioc->facts.FWVersion.Word >= 0x01000600) ||
5201 ((hd->ioc->facts.FWVersion.Word >= 0x01010000) &&
5202 (hd->ioc->facts.FWVersion.Word < 0x01010B00)) ) {
5204 iocmd.cmd = REQUEST_SENSE;
5205 iocmd.data_dma = buf1_dma;
5208 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5211 if (hd->pLocal == NULL)
5213 rc = hd->pLocal->completion;
5214 if ((rc == MPT_SCANDV_GOOD) || (rc == MPT_SCANDV_SENSE)) {
5224 iocmd.cmd = INQUIRY;
5225 iocmd.data_dma = buf1_dma;
5228 memset(pbuf1, 0x00, sz);
5229 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5232 if (hd->pLocal == NULL)
5234 rc = hd->pLocal->completion;
5235 if (rc == MPT_SCANDV_GOOD) {
5236 if (hd->pLocal->scsiStatus == SAM_STAT_BUSY) {
5237 if ((iocmd.flags & MPT_ICFLAG_TAGGED_CMD) == 0)
5244 } else if (rc == MPT_SCANDV_SENSE) {
5247 /* If first command doesn't complete
5248 * with a good status or with a check condition,
5255 /* Reset the size for disks
5257 inq0 = (*pbuf1) & 0x1F;
5258 if ((inq0 == 0) && pTarget && !pTarget->raidVolume) {
5263 /* Another GEM workaround. Check peripheral device type,
5264 * if PROCESSOR, quit DV.
5266 if (inq0 == TYPE_PROCESSOR) {
5267 mptscsih_initTarget(hd,
5279 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5283 if ((pTarget->maxWidth == 1) && (pTarget->maxOffset) && (nfactor < 0x0A)
5284 && (pTarget->minSyncFactor > 0x09)) {
5285 if ((pbuf1[56] & 0x04) == 0)
5287 else if ((pbuf1[56] & 0x01) == 1) {
5288 pTarget->minSyncFactor =
5289 nfactor > MPT_ULTRA320 ? nfactor : MPT_ULTRA320;
5291 pTarget->minSyncFactor =
5292 nfactor > MPT_ULTRA160 ? nfactor : MPT_ULTRA160;
5295 dv.max.factor = pTarget->minSyncFactor;
5297 if ((pbuf1[56] & 0x02) == 0) {
5298 pTarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
5299 hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS;
5300 ddvprintk((MYIOC_s_NOTE_FMT
5301 "DV: Start Basic noQas on id=%d due to pbuf1[56]=%x\n",
5302 ioc->name, id, pbuf1[56]));
5308 dv.cmd = MPT_FALLBACK;
5310 dv.cmd = MPT_SET_MAX;
5312 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5313 if (mpt_config(hd->ioc, &cfg) != 0)
5316 if ((!dv.now.width) && (!dv.now.offset))
5319 iocmd.cmd = INQUIRY;
5320 iocmd.data_dma = buf2_dma;
5323 memset(pbuf2, 0x00, sz);
5324 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5326 else if (hd->pLocal == NULL)
5329 /* Save the return code.
5330 * If this is the first pass,
5331 * read SCSI Device Page 0
5332 * and update the target max parameters.
5334 rc = hd->pLocal->completion;
5336 if (rc == MPT_SCANDV_GOOD) {
5342 cfg.physAddr = cfg0_dma_addr;
5343 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5346 if (mpt_config(hd->ioc, &cfg) != 0)
5349 sdp0_info = le32_to_cpu(pcfg0Data->Information) & 0x0E;
5350 sdp0_nego = (le32_to_cpu(pcfg0Data->NegotiatedParameters) & 0xFF00 ) >> 8;
5352 /* Quantum and Fujitsu workarounds.
5353 * Quantum: PPR U320 -> PPR reply with Ultra2 and wide
5354 * Fujitsu: PPR U320 -> Msg Reject and Ultra2 and wide
5355 * Resetart with a request for U160.
5357 if ((dv.now.factor == MPT_ULTRA320) && (sdp0_nego == MPT_ULTRA2)) {
5360 dv.cmd = MPT_UPDATE_MAX;
5361 mptscsih_dv_parms(hd, &dv, (void *)pcfg0Data);
5362 /* Update the SCSI device page 1 area
5364 pcfg1Data->RequestedParameters = pcfg0Data->NegotiatedParameters;
5369 /* Quantum workaround. Restart this test will the fallback
5372 if (doFallback == 0) {
5373 if (memcmp(pbuf1, pbuf2, sz) != 0) {
5377 ddvprintk((MYIOC_s_NOTE_FMT
5378 "DV:Inquiry compared id=%d, calling initTarget\n", ioc->name, id));
5379 hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_NOT_DONE;
5380 mptscsih_initTarget(hd,
5386 break; /* test complete */
5391 } else if (rc == MPT_SCANDV_ISSUE_SENSE)
5392 doFallback = 1; /* set fallback flag */
5393 else if ((rc == MPT_SCANDV_DID_RESET) ||
5394 (rc == MPT_SCANDV_SENSE) ||
5395 (rc == MPT_SCANDV_FALLBACK))
5396 doFallback = 1; /* set fallback flag */
5403 ddvprintk((MYIOC_s_NOTE_FMT "DV: Basic test on id=%d completed OK.\n", ioc->name, id));
5405 if (driver_setup.dv == 0)
5408 inq0 = (*pbuf1) & 0x1F;
5410 /* Continue only for disks
5415 if ( ioc->spi_data.PortFlags == MPI_SCSIPORTPAGE2_PORT_FLAGS_BASIC_DV_ONLY )
5418 /* Start the Enhanced Test.
5419 * 0) issue TUR to clear out check conditions
5420 * 1) read capacity of echo (regular) buffer
5422 * 3) do write-read-compare data pattern test
5424 * 5) update nego parms to target struct
5427 cfg.physAddr = cfg1_dma_addr;
5428 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5431 iocmd.cmd = TEST_UNIT_READY;
5432 iocmd.data_dma = -1;
5437 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5440 if (hd->pLocal == NULL)
5443 rc = hd->pLocal->completion;
5444 if (rc == MPT_SCANDV_GOOD)
5446 else if (rc == MPT_SCANDV_SENSE) {
5447 u8 skey = hd->pLocal->sense[2] & 0x0F;
5448 u8 asc = hd->pLocal->sense[12];
5449 u8 ascq = hd->pLocal->sense[13];
5450 ddvprintk((MYIOC_s_INFO_FMT
5451 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
5452 ioc->name, skey, asc, ascq));
5454 if (skey == UNIT_ATTENTION)
5455 notDone++; /* repeat */
5456 else if ((skey == NOT_READY) &&
5457 (asc == 0x04)&&(ascq == 0x01)) {
5458 /* wait then repeat */
5461 } else if ((skey == NOT_READY) && (asc == 0x3A)) {
5462 /* no medium, try read test anyway */
5465 /* All other errors are fatal.
5467 ddvprintk((MYIOC_s_INFO_FMT "DV: fatal error.",
5475 iocmd.cmd = READ_BUFFER;
5476 iocmd.data_dma = buf1_dma;
5479 iocmd.flags |= MPT_ICFLAG_BUF_CAP;
5483 for (patt = 0; patt < 2; patt++) {
5485 iocmd.flags |= MPT_ICFLAG_ECHO;
5487 iocmd.flags &= ~MPT_ICFLAG_ECHO;
5493 /* If not ready after 8 trials,
5494 * give up on this device.
5499 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5501 else if (hd->pLocal == NULL)
5504 rc = hd->pLocal->completion;
5505 ddvprintk(("ReadBuffer Comp Code %d", rc));
5506 ddvprintk((" buff: %0x %0x %0x %0x\n",
5507 pbuf1[0], pbuf1[1], pbuf1[2], pbuf1[3]));
5509 if (rc == MPT_SCANDV_GOOD) {
5511 if (iocmd.flags & MPT_ICFLAG_ECHO) {
5512 bufsize = ((pbuf1[2] & 0x1F) <<8) | pbuf1[3];
5514 bufsize = pbuf1[1]<<16 | pbuf1[2]<<8 | pbuf1[3];
5516 } else if (rc == MPT_SCANDV_SENSE) {
5517 u8 skey = hd->pLocal->sense[2] & 0x0F;
5518 u8 asc = hd->pLocal->sense[12];
5519 u8 ascq = hd->pLocal->sense[13];
5520 ddvprintk((MYIOC_s_INFO_FMT
5521 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
5522 ioc->name, skey, asc, ascq));
5523 if (skey == ILLEGAL_REQUEST) {
5525 } else if (skey == UNIT_ATTENTION) {
5526 notDone++; /* repeat */
5527 } else if ((skey == NOT_READY) &&
5528 (asc == 0x04)&&(ascq == 0x01)) {
5529 /* wait then repeat */
5533 /* All other errors are fatal.
5535 ddvprintk((MYIOC_s_INFO_FMT "DV: fatal error.",
5540 /* All other errors are fatal
5547 if (iocmd.flags & MPT_ICFLAG_ECHO)
5548 echoBufSize = bufsize;
5550 dataBufSize = bufsize;
5553 iocmd.flags &= ~MPT_ICFLAG_BUF_CAP;
5555 /* Use echo buffers if possible,
5556 * Exit if both buffers are 0.
5558 if (echoBufSize > 0) {
5559 iocmd.flags |= MPT_ICFLAG_ECHO;
5560 if (dataBufSize > 0)
5561 bufsize = min(echoBufSize, dataBufSize);
5563 bufsize = echoBufSize;
5564 } else if (dataBufSize == 0)
5567 ddvprintk((MYIOC_s_INFO_FMT "%s Buffer Capacity %d\n", ioc->name,
5568 (iocmd.flags & MPT_ICFLAG_ECHO) ? "Echo" : " ", bufsize));
5570 /* Data buffers for write-read-compare test max 1K.
5572 sz = min(bufsize, 1024);
5575 * On first pass, always issue a reserve.
5576 * On additional loops, only if a reset has occurred.
5577 * iocmd.flags indicates if echo or regular buffer
5579 for (patt = 0; patt < 4; patt++) {
5580 ddvprintk(("Pattern %d\n", patt));
5581 if ((iocmd.flags & MPT_ICFLAG_RESERVED) && (iocmd.flags & MPT_ICFLAG_DID_RESET)) {
5582 iocmd.cmd = TEST_UNIT_READY;
5583 iocmd.data_dma = -1;
5586 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5589 iocmd.cmd = RELEASE;
5590 iocmd.data_dma = -1;
5593 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5595 else if (hd->pLocal == NULL)
5598 rc = hd->pLocal->completion;
5599 ddvprintk(("Release rc %d\n", rc));
5600 if (rc == MPT_SCANDV_GOOD)
5601 iocmd.flags &= ~MPT_ICFLAG_RESERVED;
5605 iocmd.flags &= ~MPT_ICFLAG_RESERVED;
5607 iocmd.flags &= ~MPT_ICFLAG_DID_RESET;
5610 while (repeat && (!(iocmd.flags & MPT_ICFLAG_RESERVED))) {
5611 iocmd.cmd = RESERVE;
5612 iocmd.data_dma = -1;
5615 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5617 else if (hd->pLocal == NULL)
5620 rc = hd->pLocal->completion;
5621 if (rc == MPT_SCANDV_GOOD) {
5622 iocmd.flags |= MPT_ICFLAG_RESERVED;
5623 } else if (rc == MPT_SCANDV_SENSE) {
5624 /* Wait if coming ready
5626 u8 skey = hd->pLocal->sense[2] & 0x0F;
5627 u8 asc = hd->pLocal->sense[12];
5628 u8 ascq = hd->pLocal->sense[13];
5629 ddvprintk((MYIOC_s_INFO_FMT
5630 "DV: Reserve Failed: ", ioc->name));
5631 ddvprintk(("SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
5634 if ((skey == NOT_READY) && (asc == 0x04)&&
5636 /* wait then repeat */
5640 ddvprintk((MYIOC_s_INFO_FMT
5641 "DV: Reserved Failed.", ioc->name));
5645 ddvprintk((MYIOC_s_INFO_FMT "DV: Reserved Failed.",
5652 mptscsih_fillbuf(pbuf1, sz, patt, 1);
5653 iocmd.cmd = WRITE_BUFFER;
5654 iocmd.data_dma = buf1_dma;
5657 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5659 else if (hd->pLocal == NULL)
5662 rc = hd->pLocal->completion;
5663 if (rc == MPT_SCANDV_GOOD)
5664 ; /* Issue read buffer */
5665 else if (rc == MPT_SCANDV_DID_RESET) {
5666 /* If using echo buffers, reset to data buffers.
5667 * Else do Fallback and restart
5668 * this test (re-issue reserve
5669 * because of bus reset).
5671 if ((iocmd.flags & MPT_ICFLAG_ECHO) && (dataBufSize >= bufsize)) {
5672 iocmd.flags &= ~MPT_ICFLAG_ECHO;
5674 dv.cmd = MPT_FALLBACK;
5675 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5677 if (mpt_config(hd->ioc, &cfg) != 0)
5680 if ((!dv.now.width) && (!dv.now.offset))
5684 iocmd.flags |= MPT_ICFLAG_DID_RESET;
5687 } else if (rc == MPT_SCANDV_SENSE) {
5688 /* Restart data test if UA, else quit.
5690 u8 skey = hd->pLocal->sense[2] & 0x0F;
5691 ddvprintk((MYIOC_s_INFO_FMT
5692 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n", ioc->name, skey,
5693 hd->pLocal->sense[12], hd->pLocal->sense[13]));
5694 if (skey == UNIT_ATTENTION) {
5697 } else if (skey == ILLEGAL_REQUEST) {
5698 if (iocmd.flags & MPT_ICFLAG_ECHO) {
5699 if (dataBufSize >= bufsize) {
5700 iocmd.flags &= ~MPT_ICFLAG_ECHO;
5715 iocmd.cmd = READ_BUFFER;
5716 iocmd.data_dma = buf2_dma;
5719 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5721 else if (hd->pLocal == NULL)
5724 rc = hd->pLocal->completion;
5725 if (rc == MPT_SCANDV_GOOD) {
5726 /* If buffers compare,
5727 * go to next pattern,
5728 * else, do a fallback and restart
5729 * data transfer test.
5731 if (memcmp (pbuf1, pbuf2, sz) == 0) {
5732 ; /* goto next pattern */
5734 /* Miscompare with Echo buffer, go to data buffer,
5735 * if that buffer exists.
5736 * Miscompare with Data buffer, check first 4 bytes,
5737 * some devices return capacity. Exit in this case.
5739 if (iocmd.flags & MPT_ICFLAG_ECHO) {
5740 if (dataBufSize >= bufsize)
5741 iocmd.flags &= ~MPT_ICFLAG_ECHO;
5745 if (dataBufSize == (pbuf2[1]<<16 | pbuf2[2]<<8 | pbuf2[3])) {
5746 /* Argh. Device returning wrong data.
5747 * Quit DV for this device.
5752 /* Had an actual miscompare. Slow down.*/
5753 dv.cmd = MPT_FALLBACK;
5754 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5756 if (mpt_config(hd->ioc, &cfg) != 0)
5759 if ((!dv.now.width) && (!dv.now.offset))
5766 } else if (rc == MPT_SCANDV_DID_RESET) {
5767 /* Do Fallback and restart
5768 * this test (re-issue reserve
5769 * because of bus reset).
5771 dv.cmd = MPT_FALLBACK;
5772 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5774 if (mpt_config(hd->ioc, &cfg) != 0)
5777 if ((!dv.now.width) && (!dv.now.offset))
5780 iocmd.flags |= MPT_ICFLAG_DID_RESET;
5783 } else if (rc == MPT_SCANDV_SENSE) {
5784 /* Restart data test if UA, else quit.
5786 u8 skey = hd->pLocal->sense[2] & 0x0F;
5787 ddvprintk((MYIOC_s_INFO_FMT
5788 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n", ioc->name, skey,
5789 hd->pLocal->sense[12], hd->pLocal->sense[13]));
5790 if (skey == UNIT_ATTENTION) {
5802 } /* --- end of patt loop ---- */
5805 if (iocmd.flags & MPT_ICFLAG_RESERVED) {
5806 iocmd.cmd = RELEASE;
5807 iocmd.data_dma = -1;
5810 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5811 printk(MYIOC_s_INFO_FMT "DV: Release failed. id %d",
5813 else if (hd->pLocal) {
5814 if (hd->pLocal->completion == MPT_SCANDV_GOOD)
5815 iocmd.flags &= ~MPT_ICFLAG_RESERVED;
5817 printk(MYIOC_s_INFO_FMT "DV: Release failed. id %d",
5823 /* Set if cfg1_dma_addr contents is valid
5825 if ((cfg.hdr != NULL) && (retcode == 0)){
5826 /* If disk, not U320, disable QAS
5828 if ((inq0 == 0) && (dv.now.factor > MPT_ULTRA320)) {
5829 hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS;
5830 ddvprintk((MYIOC_s_NOTE_FMT
5831 "noQas set due to id=%d has factor=%x\n", ioc->name, id, dv.now.factor));
5835 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5837 /* Double writes to SDP1 can cause problems,
5838 * skip save of the final negotiated settings to
5839 * SCSI device page 1.
5842 cfg.physAddr = cfg1_dma_addr;
5843 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5845 mpt_config(hd->ioc, &cfg);
5849 /* If this is a RAID Passthrough, enable internal IOs
5851 if (iocmd.flags & MPT_ICFLAG_PHYS_DISK) {
5852 if (mptscsih_do_raid(hd, MPI_RAID_ACTION_ENABLE_PHYS_IO, &iocmd) < 0)
5853 ddvprintk((MYIOC_s_ERR_FMT "RAID Enable FAILED!\n", ioc->name));
5856 /* Done with the DV scan of the current target
5859 pci_free_consistent(ioc->pcidev, dv_alloc, pDvBuf, dvbuf_dma);
5861 ddvtprintk((MYIOC_s_INFO_FMT "DV Done id=%d\n",
5867 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5868 /* mptscsih_dv_parms - perform a variety of operations on the
5869 * parameters used for negotiation.
5870 * @hd: Pointer to a SCSI host.
5871 * @dv: Pointer to a structure that contains the maximum and current
5872 * negotiated parameters.
5875 mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
5877 VirtDevice *pTarget;
5878 SCSIDevicePage0_t *pPage0;
5879 SCSIDevicePage1_t *pPage1;
5880 int val = 0, data, configuration;
5889 case MPT_GET_NVRAM_VALS:
5890 ddvprintk((MYIOC_s_NOTE_FMT "Getting NVRAM: ",
5892 /* Get the NVRAM values and save in tmax
5893 * If not an LVD bus, the adapter minSyncFactor has been
5894 * already throttled back.
5896 if ((hd->Targets)&&((pTarget = hd->Targets[(int)id]) != NULL) && !pTarget->raidVolume) {
5897 width = pTarget->maxWidth;
5898 offset = pTarget->maxOffset;
5899 factor = pTarget->minSyncFactor;
5900 negoFlags = pTarget->negoFlags;
5902 if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
5903 data = hd->ioc->spi_data.nvram[id];
5904 width = data & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
5905 if ((offset = hd->ioc->spi_data.maxSyncOffset) == 0)
5908 factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT;
5909 if ((factor == 0) || (factor == MPT_ASYNC)){
5920 /* Set the negotiation flags */
5921 negoFlags = hd->ioc->spi_data.noQas;
5923 negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
5926 negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
5929 /* limit by adapter capabilities */
5930 width = min(width, hd->ioc->spi_data.maxBusWidth);
5931 offset = min(offset, hd->ioc->spi_data.maxSyncOffset);
5932 factor = max(factor, hd->ioc->spi_data.minSyncFactor);
5934 /* Check Consistency */
5935 if (offset && (factor < MPT_ULTRA2) && !width)
5936 factor = MPT_ULTRA2;
5938 dv->max.width = width;
5939 dv->max.offset = offset;
5940 dv->max.factor = factor;
5941 dv->max.flags = negoFlags;
5942 ddvprintk((" id=%d width=%d factor=%x offset=%x flags=%x\n",
5943 id, width, factor, offset, negoFlags));
5946 case MPT_UPDATE_MAX:
5947 ddvprintk((MYIOC_s_NOTE_FMT
5948 "Updating with SDP0 Data: ", hd->ioc->name));
5949 /* Update tmax values with those from Device Page 0.*/
5950 pPage0 = (SCSIDevicePage0_t *) pPage;
5952 val = cpu_to_le32(pPage0->NegotiatedParameters);
5953 dv->max.width = val & MPI_SCSIDEVPAGE0_NP_WIDE ? 1 : 0;
5954 dv->max.offset = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK) >> 16;
5955 dv->max.factor = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK) >> 8;
5958 dv->now.width = dv->max.width;
5959 dv->now.offset = dv->max.offset;
5960 dv->now.factor = dv->max.factor;
5961 ddvprintk(("id=%d width=%d factor=%x offset=%x flags=%x\n",
5962 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags));
5966 ddvprintk((MYIOC_s_NOTE_FMT "Setting Max: ",
5968 /* Set current to the max values. Update the config page.*/
5969 dv->now.width = dv->max.width;
5970 dv->now.offset = dv->max.offset;
5971 dv->now.factor = dv->max.factor;
5972 dv->now.flags = dv->max.flags;
5974 pPage1 = (SCSIDevicePage1_t *)pPage;
5976 mptscsih_setDevicePage1Flags (dv->now.width, dv->now.factor,
5977 dv->now.offset, &val, &configuration, dv->now.flags);
5978 dnegoprintk(("Setting Max: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
5979 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags, val, configuration));
5980 pPage1->RequestedParameters = le32_to_cpu(val);
5981 pPage1->Reserved = 0;
5982 pPage1->Configuration = le32_to_cpu(configuration);
5985 ddvprintk(("id=%d width=%d factor=%x offset=%x flags=%x request=%x configuration=%x\n",
5986 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags, val, configuration));
5990 ddvprintk((MYIOC_s_NOTE_FMT "Setting Min: ",
5992 /* Set page to asynchronous and narrow
5993 * Do not update now, breaks fallback routine. */
5997 negoFlags = dv->max.flags;
5999 pPage1 = (SCSIDevicePage1_t *)pPage;
6001 mptscsih_setDevicePage1Flags (width, factor,
6002 offset, &val, &configuration, negoFlags);
6003 dnegoprintk(("Setting Min: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
6004 id, width, factor, offset, negoFlags, val, configuration));
6005 pPage1->RequestedParameters = le32_to_cpu(val);
6006 pPage1->Reserved = 0;
6007 pPage1->Configuration = le32_to_cpu(configuration);
6009 ddvprintk(("id=%d width=%d factor=%x offset=%x request=%x config=%x negoFlags=%x\n",
6010 id, width, factor, offset, val, configuration, negoFlags));
6014 ddvprintk((MYIOC_s_NOTE_FMT
6015 "Fallback: Start: offset %d, factor %x, width %d \n",
6016 hd->ioc->name, dv->now.offset,
6017 dv->now.factor, dv->now.width));
6018 width = dv->now.width;
6019 offset = dv->now.offset;
6020 factor = dv->now.factor;
6021 if ((offset) && (dv->max.width)) {
6022 if (factor < MPT_ULTRA160)
6023 factor = MPT_ULTRA160;
6024 else if (factor < MPT_ULTRA2) {
6025 factor = MPT_ULTRA2;
6027 } else if ((factor == MPT_ULTRA2) && width) {
6028 factor = MPT_ULTRA2;
6030 } else if (factor < MPT_ULTRA) {
6033 } else if ((factor == MPT_ULTRA) && width) {
6035 } else if (factor < MPT_FAST) {
6038 } else if ((factor == MPT_FAST) && width) {
6041 } else if (factor < MPT_SCSI) {
6044 } else if ((factor == MPT_SCSI) && width) {
6052 } else if (offset) {
6054 if (factor < MPT_ULTRA)
6056 else if (factor < MPT_FAST)
6058 else if (factor < MPT_SCSI)
6069 dv->max.flags |= MPT_TARGET_NO_NEGO_QAS;
6070 dv->max.flags &= ~MPT_TAPE_NEGO_IDP;
6072 dv->now.width = width;
6073 dv->now.offset = offset;
6074 dv->now.factor = factor;
6075 dv->now.flags = dv->max.flags;
6077 pPage1 = (SCSIDevicePage1_t *)pPage;
6079 mptscsih_setDevicePage1Flags (width, factor, offset, &val,
6080 &configuration, dv->now.flags);
6081 dnegoprintk(("Finish: id=%d width=%d offset=%d factor=%x flags=%x request=%x config=%x\n",
6082 id, width, offset, factor, dv->now.flags, val, configuration));
6084 pPage1->RequestedParameters = le32_to_cpu(val);
6085 pPage1->Reserved = 0;
6086 pPage1->Configuration = le32_to_cpu(configuration);
6089 ddvprintk(("Finish: id=%d offset=%d factor=%x width=%d request=%x config=%x\n",
6090 id, dv->now.offset, dv->now.factor, dv->now.width, val, configuration));
6094 ddvprintk((MYIOC_s_NOTE_FMT
6095 "Saving to Target structure: ", hd->ioc->name));
6096 ddvprintk(("id=%d width=%x factor=%x offset=%d flags=%x\n",
6097 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags));
6099 /* Save these values to target structures
6100 * or overwrite nvram (phys disks only).
6103 if ((hd->Targets)&&((pTarget = hd->Targets[(int)id]) != NULL) && !pTarget->raidVolume ) {
6104 pTarget->maxWidth = dv->now.width;
6105 pTarget->maxOffset = dv->now.offset;
6106 pTarget->minSyncFactor = dv->now.factor;
6107 pTarget->negoFlags = dv->now.flags;
6109 /* Preserv all flags, use
6110 * read-modify-write algorithm
6112 if (hd->ioc->spi_data.nvram) {
6113 data = hd->ioc->spi_data.nvram[id];
6116 data &= ~MPT_NVRAM_WIDE_DISABLE;
6118 data |= MPT_NVRAM_WIDE_DISABLE;
6120 if (!dv->now.offset)
6123 data &= ~MPT_NVRAM_SYNC_MASK;
6124 data |= (dv->now.factor << MPT_NVRAM_SYNC_SHIFT) & MPT_NVRAM_SYNC_MASK;
6126 hd->ioc->spi_data.nvram[id] = data;
6133 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6134 /* mptscsih_fillbuf - fill a buffer with a special data pattern
6135 * cleanup. For bus scan only.
6137 * @buffer: Pointer to data buffer to be filled.
6138 * @size: Number of bytes to fill
6139 * @index: Pattern index
6140 * @width: bus width, 0 (8 bits) or 1 (16 bits)
6143 mptscsih_fillbuf(char *buffer, int size, int index, int width)
6154 /* Pattern: 0000 FFFF 0000 FFFF
6156 for (ii=0; ii < size; ii++, ptr++) {
6163 /* Pattern: 00 FF 00 FF
6165 for (ii=0; ii < size; ii++, ptr++) {
6176 /* Pattern: 5555 AAAA 5555 AAAA 5555
6178 for (ii=0; ii < size; ii++, ptr++) {
6185 /* Pattern: 55 AA 55 AA 55
6187 for (ii=0; ii < size; ii++, ptr++) {
6197 /* Pattern: 00 01 02 03 04 05
6200 for (ii=0; ii < size; ii++, ptr++)
6206 /* Wide Pattern: FFFE 0001 FFFD 0002
6207 * ... 4000 DFFF 8000 EFFF
6210 for (ii=0; ii < size/2; ii++) {
6211 /* Create the base pattern
6214 /* every 64 (0x40) bytes flip the pattern
6215 * since we fill 2 bytes / iteration,
6216 * test for ii = 0x20
6222 *ptr = (char)( (val & 0xFF00) >> 8);
6224 *ptr = (char)(val & 0xFF);
6229 *ptr = (char)( (val & 0xFF00) >> 8);
6231 *ptr = (char)(val & 0xFF);
6237 /* Narrow Pattern: FE 01 FD 02 FB 04
6238 * .. 7F 80 01 FE 02 FD ... 80 7F
6241 for (ii=0; ii < size; ii++, ptr++) {
6242 /* Base pattern - first 32 bytes
6249 *ptr = (char) (~(1 << byte));
6252 /* Flip the pattern every 32 bytes
6261 #endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */
6263 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6264 /* Commandline Parsing routines and defines.
6267 * insmod mptscsih mptscsih="width:1 dv:n factor:0x09 saf-te:1"
6269 * mptscsih=width:1,dv:n,factor:0x8,saf-te:1
6279 static char setup_token[] __initdata =
6284 ; /* DO NOT REMOVE THIS ';' */
6288 #define OPT_MAX_WIDTH 2
6289 #define OPT_MIN_SYNC_FACTOR 3
6290 #define OPT_SAF_TE 4
6292 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6295 get_setup_token(char *p)
6297 char *cur = setup_token;
6301 while (cur != NULL && (pc = strchr(cur, ':')) != NULL) {
6304 if (!strncmp(p, cur, pc - cur))
6311 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6313 mptscsih_setup(char *str)
6320 while (cur != NULL && (pc = strchr(cur, ':')) != NULL) {
6332 val = (int) simple_strtoul(pv, &pe, 0);
6334 printk("Found Token: %s, value %x\n", cur, (int)val);
6335 switch (get_setup_token(cur)) {
6337 driver_setup.dv = val;
6341 driver_setup.max_width = val;
6344 case OPT_MIN_SYNC_FACTOR:
6345 driver_setup.min_sync_fac = val;
6349 driver_setup.saf_te = val;
6353 printk("mptscsih_setup: unexpected boot option '%.*s' ignored\n", (int)(pc-cur+1), cur);
6357 if ((cur = strchr(cur, ARG_SEP)) != NULL)
6363 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6366 module_init(mptscsih_init);
6367 module_exit(mptscsih_exit);