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>
91 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
92 #define my_NAME "Fusion MPT SCSI Host driver"
93 #define my_VERSION MPT_LINUX_VERSION_COMMON
94 #define MYNAM "mptscsih"
96 MODULE_AUTHOR(MODULEAUTHOR);
97 MODULE_DESCRIPTION(my_NAME);
98 MODULE_LICENSE("GPL");
100 /* Set string for command line args from insmod */
102 char *mptscsih = NULL;
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)
118 #define MPT_SCANDV_MAX_RETRIES (10)
120 #define MPT_ICFLAG_BUF_CAP 0x01 /* ReadBuffer Read Capacity format */
121 #define MPT_ICFLAG_ECHO 0x02 /* ReadBuffer Echo buffer format */
122 #define MPT_ICFLAG_PHYS_DISK 0x04 /* Any SCSI IO but do Phys Disk Format */
123 #define MPT_ICFLAG_TAGGED_CMD 0x08 /* Do tagged IO */
124 #define MPT_ICFLAG_DID_RESET 0x20 /* Bus Reset occurred with this command */
125 #define MPT_ICFLAG_RESERVED 0x40 /* Reserved has been issued */
127 typedef struct _internal_cmd {
128 char *data; /* data pointer */
129 dma_addr_t data_dma; /* data dma address */
130 int size; /* transfer size */
131 u8 cmd; /* SCSI Op Code */
132 u8 bus; /* bus number */
133 u8 id; /* SCSI ID (virtual) */
135 u8 flags; /* Bit Field - See above */
136 u8 physDiskNum; /* Phys disk number, -1 else */
141 typedef struct _negoparms {
148 typedef struct _dv_parameters {
158 * Other private/forward protos...
160 static int mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
161 static void mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq);
162 static int mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
164 static int mptscsih_AddSGE(MPT_SCSI_HOST *hd, struct scsi_cmnd *SCpnt,
165 SCSIIORequest_t *pReq, int req_idx);
166 static void mptscsih_freeChainBuffers(MPT_SCSI_HOST *hd, int req_idx);
167 static int mptscsih_initChainBuffers (MPT_SCSI_HOST *hd, int init);
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);
171 static MPT_FRAME_HDR *mptscsih_search_pendingQ(MPT_SCSI_HOST *hd, int scpnt_idx);
172 static void post_pendingQ_commands(MPT_SCSI_HOST *hd);
174 static int mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout, int sleepFlag);
175 static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout, int sleepFlag);
177 static int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
178 static int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
180 static void mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *data, int dlen);
181 void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56);
182 static void mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq);
183 static void mptscsih_setDevicePage1Flags (u8 width, u8 factor, u8 offset, int *requestedPtr, int *configurationPtr, u8 flags);
184 static void mptscsih_no_negotiate(MPT_SCSI_HOST *hd, int target_id);
185 static int mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target, int flags);
186 static int mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus);
187 static int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
188 static void mptscsih_timer_expired(unsigned long data);
189 static void mptscsih_taskmgmt_timeout(unsigned long data);
190 static void mptscsih_schedule_reset(void *hd);
191 static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
192 static int mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum);
194 static struct work_struct mptscsih_rstTask;
196 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
197 static int mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io);
198 static void mptscsih_domainValidation(void *hd);
199 static int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id);
200 static void mptscsih_qas_check(MPT_SCSI_HOST *hd, int id);
201 static int mptscsih_doDv(MPT_SCSI_HOST *hd, int channel, int target);
202 static void mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage);
203 static void mptscsih_fillbuf(char *buffer, int size, int index, int width);
206 static int mptscsih_setup(char *str);
208 /* module entry point */
209 static int __init mptscsih_init (void);
210 static void __exit mptscsih_exit (void);
212 static int mptscsih_probe (struct pci_dev *, const struct pci_device_id *);
213 static void mptscsih_remove(struct pci_dev *);
214 static void mptscsih_shutdown(struct device *);
216 static int mptscsih_suspend(struct pci_dev *pdev, u32 state);
217 static int mptscsih_resume(struct pci_dev *pdev);
225 static int mpt_scsi_hosts = 0;
227 static int ScsiDoneCtx = -1;
228 static int ScsiTaskCtx = -1;
229 static int ScsiScanDvCtx = -1; /* Used only for bus scan and dv */
231 #define SNS_LEN(scp) sizeof((scp)->sense_buffer)
233 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
235 * Domain Validation task structure
237 static spinlock_t dvtaskQ_lock = SPIN_LOCK_UNLOCKED;
238 static int dvtaskQ_active = 0;
239 static int dvtaskQ_release = 0;
240 static struct work_struct mptscsih_dvTask;
246 static DECLARE_WAIT_QUEUE_HEAD (scandv_waitq);
247 static int scandv_wait_done = 1;
249 /* Driver default setup
251 static struct mptscsih_driver_setup
252 driver_setup = MPTSCSIH_DRIVER_SETUP;
254 #ifdef MPTSCSIH_DBG_TIMEOUT
255 static struct scsi_cmnd *foo_to[8];
258 static struct scsi_host_template driver_template;
260 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
262 * mptscsih_add_sge - Place a simple SGE at address pAddr.
263 * @pAddr: virtual address for SGE
264 * @flagslength: SGE flags and data transfer length
265 * @dma_addr: Physical address
267 * This routine places a MPT request frame back on the MPT adapter's
271 mptscsih_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
273 if (sizeof(dma_addr_t) == sizeof(u64)) {
274 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
275 u32 tmp = dma_addr & 0xFFFFFFFF;
277 pSge->FlagsLength = cpu_to_le32(flagslength);
278 pSge->Address.Low = cpu_to_le32(tmp);
279 tmp = (u32) ((u64)dma_addr >> 32);
280 pSge->Address.High = cpu_to_le32(tmp);
283 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
284 pSge->FlagsLength = cpu_to_le32(flagslength);
285 pSge->Address = cpu_to_le32(dma_addr);
287 } /* mptscsih_add_sge() */
289 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
291 * mptscsih_add_chain - Place a chain SGE at address pAddr.
292 * @pAddr: virtual address for SGE
293 * @next: nextChainOffset value (u32's)
294 * @length: length of next SGL segment
295 * @dma_addr: Physical address
297 * This routine places a MPT request frame back on the MPT adapter's
301 mptscsih_add_chain(char *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
303 if (sizeof(dma_addr_t) == sizeof(u64)) {
304 SGEChain64_t *pChain = (SGEChain64_t *) pAddr;
305 u32 tmp = dma_addr & 0xFFFFFFFF;
307 pChain->Length = cpu_to_le16(length);
308 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size();
310 pChain->NextChainOffset = next;
312 pChain->Address.Low = cpu_to_le32(tmp);
313 tmp = (u32) ((u64)dma_addr >> 32);
314 pChain->Address.High = cpu_to_le32(tmp);
316 SGEChain32_t *pChain = (SGEChain32_t *) pAddr;
317 pChain->Length = cpu_to_le16(length);
318 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size();
319 pChain->NextChainOffset = next;
320 pChain->Address = cpu_to_le32(dma_addr);
322 } /* mptscsih_add_chain() */
324 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
326 * mptscsih_getFreeChainBuffes - Function to get a free chain
327 * from the MPT_SCSI_HOST FreeChainQ.
328 * @hd: Pointer to the MPT_SCSI_HOST instance
329 * @req_idx: Index of the SCSI IO request frame. (output)
331 * return SUCCESS or FAILED
334 mptscsih_getFreeChainBuffer(MPT_SCSI_HOST *hd, int *retIndex)
336 MPT_FRAME_HDR *chainBuf;
341 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
342 if (!Q_IS_EMPTY(&hd->FreeChainQ)) {
346 chainBuf = hd->FreeChainQ.head;
347 Q_DEL_ITEM(&chainBuf->u.frame.linkage);
348 offset = (u8 *)chainBuf - (u8 *)hd->ChainBuffer;
349 chain_idx = offset / hd->ioc->req_sz;
354 chain_idx = MPT_HOST_NO_CHAIN;
356 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
359 *retIndex = chain_idx;
361 dsgprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer (index %d), got buf=%p\n",
362 hd->ioc->name, *retIndex, chainBuf));
365 } /* mptscsih_getFreeChainBuffer() */
367 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
369 * mptscsih_AddSGE - Add a SGE (plus chain buffers) to the
370 * SCSIIORequest_t Message Frame.
371 * @hd: Pointer to MPT_SCSI_HOST structure
372 * @SCpnt: Pointer to scsi_cmnd structure
373 * @pReq: Pointer to SCSIIORequest_t structure
378 mptscsih_AddSGE(MPT_SCSI_HOST *hd, struct scsi_cmnd *SCpnt,
379 SCSIIORequest_t *pReq, int req_idx)
383 struct scatterlist *sg;
385 int sges_left, sg_done;
386 int chain_idx = MPT_HOST_NO_CHAIN;
388 int numSgeSlots, numSgeThisFrame;
389 u32 sgflags, sgdir, thisxfer = 0;
390 int chain_dma_off = 0;
395 sgdir = le32_to_cpu(pReq->Control) & MPI_SCSIIO_CONTROL_DATADIRECTION_MASK;
396 if (sgdir == MPI_SCSIIO_CONTROL_WRITE) {
397 sgdir = MPT_TRANSFER_HOST_TO_IOC;
399 sgdir = MPT_TRANSFER_IOC_TO_HOST;
402 psge = (char *) &pReq->SGL;
403 frm_sz = hd->ioc->req_sz;
405 /* Map the data portion, if any.
406 * sges_left = 0 if no data transfer.
408 if ( (sges_left = SCpnt->use_sg) ) {
409 sges_left = pci_map_sg(hd->ioc->pcidev,
410 (struct scatterlist *) SCpnt->request_buffer,
412 SCpnt->sc_data_direction);
415 } else if (SCpnt->request_bufflen) {
416 SCpnt->SCp.dma_handle = pci_map_single(hd->ioc->pcidev,
417 SCpnt->request_buffer,
418 SCpnt->request_bufflen,
419 SCpnt->sc_data_direction);
420 dsgprintk((MYIOC_s_INFO_FMT "SG: non-SG for %p, len=%d\n",
421 hd->ioc->name, SCpnt, SCpnt->request_bufflen));
422 mptscsih_add_sge((char *) &pReq->SGL,
423 0xD1000000|MPT_SGE_FLAGS_ADDRESSING|sgdir|SCpnt->request_bufflen,
424 SCpnt->SCp.dma_handle);
429 /* Handle the SG case.
431 sg = (struct scatterlist *) SCpnt->request_buffer;
433 sgeOffset = sizeof(SCSIIORequest_t) - sizeof(SGE_IO_UNION);
436 /* Prior to entering this loop - the following must be set
437 * current MF: sgeOffset (bytes)
438 * chainSge (Null if original MF is not a chain buffer)
439 * sg_done (num SGE done for this MF)
443 numSgeSlots = ((frm_sz - sgeOffset) / (sizeof(u32) + sizeof(dma_addr_t)) );
444 numSgeThisFrame = (sges_left < numSgeSlots) ? sges_left : numSgeSlots;
446 sgflags = MPT_SGE_FLAGS_SIMPLE_ELEMENT | MPT_SGE_FLAGS_ADDRESSING | sgdir;
448 /* Get first (num - 1) SG elements
449 * Skip any SG entries with a length of 0
450 * NOTE: at finish, sg and psge pointed to NEXT data/location positions
452 for (ii=0; ii < (numSgeThisFrame-1); ii++) {
453 thisxfer = sg_dma_len(sg);
455 sg ++; /* Get next SG element from the OS */
460 v2 = sg_dma_address(sg);
461 mptscsih_add_sge(psge, sgflags | thisxfer, v2);
463 sg++; /* Get next SG element from the OS */
464 psge += (sizeof(u32) + sizeof(dma_addr_t));
465 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
469 if (numSgeThisFrame == sges_left) {
470 /* Add last element, end of buffer and end of list flags.
472 sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT |
473 MPT_SGE_FLAGS_END_OF_BUFFER |
474 MPT_SGE_FLAGS_END_OF_LIST;
476 /* Add last SGE and set termination flags.
477 * Note: Last SGE may have a length of 0 - which should be ok.
479 thisxfer = sg_dma_len(sg);
481 v2 = sg_dma_address(sg);
482 mptscsih_add_sge(psge, sgflags | thisxfer, v2);
485 psge += (sizeof(u32) + sizeof(dma_addr_t));
487 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
491 /* The current buffer is a chain buffer,
492 * but there is not another one.
493 * Update the chain element
494 * Offset and Length fields.
496 mptscsih_add_chain((char *)chainSge, 0, sgeOffset, hd->ChainBufferDMA + chain_dma_off);
498 /* The current buffer is the original MF
499 * and there is no Chain buffer.
501 pReq->ChainOffset = 0;
504 /* At least one chain buffer is needed.
505 * Complete the first MF
506 * - last SGE element, set the LastElement bit
507 * - set ChainOffset (words) for orig MF
508 * (OR finish previous MF chain buffer)
509 * - update MFStructPtr ChainIndex
510 * - Populate chain element
515 dsgprintk((MYIOC_s_INFO_FMT "SG: Chain Required! sg done %d\n",
516 hd->ioc->name, sg_done));
518 /* Set LAST_ELEMENT flag for last non-chain element
519 * in the buffer. Since psge points at the NEXT
520 * SGE element, go back one SGE element, update the flags
521 * and reset the pointer. (Note: sgflags & thisxfer are already
525 u32 *ptmp = (u32 *) (psge - (sizeof(u32) + sizeof(dma_addr_t)));
526 sgflags = le32_to_cpu(*ptmp);
527 sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT;
528 *ptmp = cpu_to_le32(sgflags);
532 /* The current buffer is a chain buffer.
533 * chainSge points to the previous Chain Element.
534 * Update its chain element Offset and Length (must
535 * include chain element size) fields.
536 * Old chain element is now complete.
538 u8 nextChain = (u8) (sgeOffset >> 2);
539 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
540 mptscsih_add_chain((char *)chainSge, nextChain, sgeOffset, hd->ChainBufferDMA + chain_dma_off);
542 /* The original MF buffer requires a chain buffer -
544 * Last element in this MF is a chain element.
546 pReq->ChainOffset = (u8) (sgeOffset >> 2);
549 sges_left -= sg_done;
552 /* NOTE: psge points to the beginning of the chain element
553 * in current buffer. Get a chain buffer.
555 if ((mptscsih_getFreeChainBuffer(hd, &newIndex)) == FAILED)
558 /* Update the tracking arrays.
559 * If chainSge == NULL, update ReqToChain, else ChainToChain
562 hd->ChainToChain[chain_idx] = newIndex;
564 hd->ReqToChain[req_idx] = newIndex;
566 chain_idx = newIndex;
567 chain_dma_off = hd->ioc->req_sz * chain_idx;
569 /* Populate the chainSGE for the current buffer.
570 * - Set chain buffer pointer to psge and fill
571 * out the Address and Flags fields.
573 chainSge = (char *) psge;
574 dsgprintk((KERN_INFO " Current buff @ %p (index 0x%x)",
577 /* Start the SGE for the next buffer
579 psge = (char *) (hd->ChainBuffer + chain_dma_off);
583 dsgprintk((KERN_INFO " Chain buff @ %p (index 0x%x)\n",
586 /* Start the SGE for the next buffer
593 } /* mptscsih_AddSGE() */
595 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
597 * mptscsih_io_done - Main SCSI IO callback routine registered to
598 * Fusion MPT (base) driver
599 * @ioc: Pointer to MPT_ADAPTER structure
600 * @mf: Pointer to original MPT request frame
601 * @r: Pointer to MPT reply frame (NULL if TurboReply)
603 * This routine is called from mpt.c::mpt_interrupt() at the completion
604 * of any SCSI IO request.
605 * This routine is registered with the Fusion MPT (base) driver at driver
606 * load/init time via the mpt_register() API call.
608 * Returns 1 indicating alloc'd request frame ptr should be freed.
611 mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
613 struct scsi_cmnd *sc;
615 SCSIIORequest_t *pScsiReq;
616 SCSIIOReply_t *pScsiReply;
619 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
621 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
622 sc = hd->ScsiLookup[req_idx];
624 MPIHeader_t *hdr = (MPIHeader_t *)mf;
626 /* Remark: writeSDP1 will use the ScsiDoneCtx
627 * If a SCSI I/O cmd, device disabled by OS and
628 * completion done. Cannot touch sc struct. Just free mem.
630 if (hdr->Function == MPI_FUNCTION_SCSI_IO_REQUEST)
631 printk(MYIOC_s_ERR_FMT "NULL ScsiCmd ptr!\n",
634 mptscsih_freeChainBuffers(hd, req_idx);
638 dmfprintk((MYIOC_s_INFO_FMT
639 "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n",
640 ioc->name, mf, mr, sc, req_idx));
642 sc->result = DID_OK << 16; /* Set default reply as OK */
643 pScsiReq = (SCSIIORequest_t *) mf;
644 pScsiReply = (SCSIIOReply_t *) mr;
646 #ifdef MPTSCSIH_DBG_TIMEOUT
647 if (ioc->timeout_cnt > 0) {
650 for (ii=0; ii < 8; ii++) {
651 if (sc == foo_to[ii]) {
652 printk(MYIOC_s_INFO_FMT "complete (%p, %ld)\n",
653 ioc->name, sc, jiffies);
656 if (foo_to[ii] != NULL)
661 ioc->timeout_maxcnt = 0;
662 ioc->timeout_cnt = 0;
667 if (pScsiReply == NULL) {
668 /* special context reply handling */
673 u8 scsi_state, scsi_status;
675 status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK;
676 scsi_state = pScsiReply->SCSIState;
678 dprintk((KERN_NOTICE " Uh-Oh! (%d:%d:%d) mf=%p, mr=%p, sc=%p\n",
679 ioc->id, pScsiReq->TargetID, pScsiReq->LUN[1],
681 dprintk((KERN_NOTICE " IOCStatus=%04xh, SCSIState=%02xh"
682 ", SCSIStatus=%02xh, IOCLogInfo=%08xh\n",
683 status, scsi_state, pScsiReply->SCSIStatus,
684 le32_to_cpu(pScsiReply->IOCLogInfo)));
686 if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)
687 copy_sense_data(sc, hd, mf, pScsiReply);
690 * Look for + dump FCP ResponseInfo[]!
692 if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID) {
693 printk(KERN_NOTICE " FCP_ResponseInfo=%08xh\n",
694 le32_to_cpu(pScsiReply->ResponseInfo));
698 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
700 * Maybe: DRIVER_BUSY | SUGGEST_RETRY | DID_SOFT_ERROR (retry)
701 * But not: DID_BUS_BUSY lest one risk
702 * killing interrupt handler:-(
704 sc->result = STS_BUSY;
707 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
708 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
709 sc->result = DID_BAD_TARGET << 16;
712 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
713 /* Spoof to SCSI Selection Timeout! */
714 sc->result = DID_NO_CONNECT << 16;
716 if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF)
717 hd->sel_timeout[pScsiReq->TargetID]++;
720 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
721 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
722 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
723 /* Linux handles an unsolicited DID_RESET better
724 * than an unsolicited DID_ABORT.
726 sc->result = DID_RESET << 16;
728 /* GEM Workaround. */
730 mptscsih_no_negotiate(hd, sc->device->id);
733 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
734 sc->result = (DRIVER_SENSE << 24) | (DID_OK << 16) |
735 (CHECK_CONDITION << 1);
736 sc->sense_buffer[0] = 0x70;
737 sc->sense_buffer[2] = NO_SENSE;
738 sc->sense_buffer[12] = 0;
739 sc->sense_buffer[13] = 0;
740 dprintk((KERN_NOTICE "RESIDUAL_MISMATCH: result=%x on id=%d\n", sc->result, sc->target));
743 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
745 * Do upfront check for valid SenseData and give it
748 scsi_status = pScsiReply->SCSIStatus;
749 sc->result = (DID_OK << 16) | scsi_status;
750 xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
751 if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
752 /* Have already saved the status and sense data
756 if ( (xfer_cnt == 0) || (sc->underflow > xfer_cnt)) {
757 sc->result = DID_SOFT_ERROR << 16;
759 if (scsi_state & (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)) {
762 sc->result = DID_SOFT_ERROR << 16;
764 else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
765 /* Not real sure here either... */
766 sc->result = DID_RESET << 16;
770 /* Give report and update residual count.
772 dprintk((KERN_NOTICE " sc->underflow={report ERR if < %02xh bytes xfer'd}\n",
774 dprintk((KERN_NOTICE " ActBytesXferd=%02xh\n", xfer_cnt));
776 sc->resid = sc->request_bufflen - xfer_cnt;
777 dprintk((KERN_NOTICE " SET sc->resid=%02xh\n", sc->resid));
781 if (scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)
782 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
786 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
787 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
788 sc->result = (DID_OK << 16) | pScsiReply->SCSIStatus;
789 if (scsi_state == 0) {
791 } else if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
793 * If running against circa 200003dd 909 MPT f/w,
794 * may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL
795 * (QUEUE_FULL) returned from device! --> get 0x0000?128
796 * and with SenseBytes set to 0.
798 if (pScsiReply->SCSIStatus == MPI_SCSI_STATUS_TASK_SET_FULL)
799 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
802 else if (scsi_state &
803 (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)
808 sc->result = DID_SOFT_ERROR << 16;
810 else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
811 /* Not real sure here either... */
812 sc->result = DID_RESET << 16;
814 else if (scsi_state & MPI_SCSI_STATE_QUEUE_TAG_REJECTED) {
815 /* Device Inq. data indicates that it supports
816 * QTags, but rejects QTag messages.
817 * This command completed OK.
819 * Not real sure here either so do nothing... */
822 if (sc->result == MPI_SCSI_STATUS_TASK_SET_FULL)
823 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
826 * Reservation Conflict, Busy,
827 * Command Terminated, CHECK
831 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
832 sc->result = DID_SOFT_ERROR << 16;
835 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
836 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
837 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
838 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
839 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
840 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
841 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
842 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
843 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
844 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
849 sc->result = DID_SOFT_ERROR << 16;
852 } /* switch(status) */
854 dprintk((KERN_NOTICE " sc->result set to %08xh\n", sc->result));
855 } /* end of address reply case */
857 /* Unmap the DMA buffers, if any. */
859 pci_unmap_sg(ioc->pcidev, (struct scatterlist *) sc->request_buffer,
860 sc->use_sg, sc->sc_data_direction);
861 } else if (sc->request_bufflen) {
862 pci_unmap_single(ioc->pcidev, sc->SCp.dma_handle,
863 sc->request_bufflen, sc->sc_data_direction);
866 hd->ScsiLookup[req_idx] = NULL;
868 sc->scsi_done(sc); /* Issue the command callback */
870 /* Free Chain buffers */
871 mptscsih_freeChainBuffers(hd, req_idx);
876 * Flush all commands on the doneQ.
877 * Lock Q when deleting/adding members
878 * Lock io_request_lock for OS callback.
881 flush_doneQ(MPT_SCSI_HOST *hd)
884 struct scsi_cmnd *SCpnt;
889 dtmprintk((KERN_INFO MYNAM ": flush_doneQ called\n"));
891 spin_lock_irqsave(&hd->freedoneQlock, flags);
892 if (Q_IS_EMPTY(&hd->doneQ)) {
893 spin_unlock_irqrestore(&hd->freedoneQlock, flags);
897 buffer = hd->doneQ.head;
902 /* Set the struct scsi_cmnd pointer
904 SCpnt = (struct scsi_cmnd *) buffer->argp;
909 Q_ADD_TAIL(&hd->freeQ.head, buffer, MPT_DONE_Q);
910 spin_unlock_irqrestore(&hd->freedoneQlock, flags);
912 /* Do the OS callback.
914 SCpnt->scsi_done(SCpnt);
921 * Search the doneQ for a specific command. If found, delete from Q.
922 * Calling function will finish processing.
925 search_doneQ_for_cmd(MPT_SCSI_HOST *hd, struct scsi_cmnd *SCpnt)
930 spin_lock_irqsave(&hd->freedoneQlock, flags);
931 if (!Q_IS_EMPTY(&hd->doneQ)) {
932 buffer = hd->doneQ.head;
934 struct scsi_cmnd *sc = (struct scsi_cmnd *) buffer->argp;
937 SCpnt->result = sc->result;
939 /* Set the struct scsi_cmnd pointer
945 Q_ADD_TAIL(&hd->freeQ.head, buffer, MPT_DONE_Q);
948 } while ((buffer = buffer->forw) != (MPT_DONE_Q *) &hd->doneQ);
950 spin_unlock_irqrestore(&hd->freedoneQlock, flags);
955 * mptscsih_flush_running_cmds - For each command found, search
956 * Scsi_Host instance taskQ and reply to OS.
957 * Called only if recovering from a FW reload.
958 * @hd: Pointer to a SCSI HOST structure
962 * Must be called while new I/Os are being queued.
965 mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
967 struct scsi_cmnd *SCpnt;
971 int max = hd->ioc->req_depth;
974 dprintk((KERN_INFO MYNAM ": flush_ScsiLookup called\n"));
975 for (ii= 0; ii < max; ii++) {
976 if ((SCpnt = hd->ScsiLookup[ii]) != NULL) {
981 /* Search pendingQ, if found,
984 mptscsih_search_pendingQ(hd, ii);
986 /* Null ScsiLookup index
988 hd->ScsiLookup[ii] = NULL;
990 mf = MPT_INDEX_2_MFPTR(hd->ioc, ii);
991 dmfprintk(( "flush: ScsiDone (mf=%p,sc=%p)\n",
994 /* Set status, free OS resources (SG DMA buffers)
996 * Free driver resources (chain, msg buffers)
998 if (scsi_device_online(SCpnt->device)) {
1000 pci_unmap_sg(hd->ioc->pcidev,
1001 (struct scatterlist *) SCpnt->request_buffer,
1003 SCpnt->sc_data_direction);
1004 } else if (SCpnt->request_bufflen) {
1005 pci_unmap_single(hd->ioc->pcidev,
1006 SCpnt->SCp.dma_handle,
1007 SCpnt->request_bufflen,
1008 SCpnt->sc_data_direction);
1011 SCpnt->result = DID_RESET << 16;
1012 SCpnt->host_scribble = NULL;
1014 /* Free Chain buffers */
1015 mptscsih_freeChainBuffers(hd, ii);
1017 /* Free Message frames */
1018 mpt_free_msg_frame(ScsiDoneCtx, hd->ioc, mf);
1021 /* Post to doneQ, do not reply until POST phase
1022 * of reset handler....prevents new commands from
1025 spin_lock_irqsave(&hd->freedoneQlock, flags);
1026 if (!Q_IS_EMPTY(&hd->freeQ)) {
1027 buffer = hd->freeQ.head;
1030 /* Set the struct scsi_cmnd pointer
1032 buffer->argp = (void *)SCpnt;
1036 Q_ADD_TAIL(&hd->doneQ.head, buffer, MPT_DONE_Q);
1037 spin_unlock_irqrestore(&hd->freedoneQlock, flags);
1039 spin_unlock_irqrestore(&hd->freedoneQlock, flags);
1040 SCpnt->scsi_done(SCpnt);
1043 SCpnt->scsi_done(SCpnt); /* Issue the command callback */
1053 * mptscsih_search_running_cmds - Delete any commands associated
1054 * with the specified target and lun. Function called only
1055 * when a lun is disable by mid-layer.
1056 * Do NOT access the referenced scsi_cmnd structure or
1057 * members. Will cause either a paging or NULL ptr error.
1058 * @hd: Pointer to a SCSI HOST structure
1059 * @target: target id
1064 * Called from slave_destroy.
1067 mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, uint target, uint lun)
1069 SCSIIORequest_t *mf = NULL;
1071 int max = hd->ioc->req_depth;
1073 dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n",
1076 for (ii=0; ii < max; ii++) {
1077 if (hd->ScsiLookup[ii] != NULL) {
1079 mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii);
1081 dsprintk(( "search_running: found (sc=%p, mf = %p) target %d, lun %d \n",
1082 hd->ScsiLookup[ii], mf, mf->TargetID, mf->LUN[1]));
1084 if ((mf->TargetID != ((u8)target)) || (mf->LUN[1] != ((u8) lun)))
1089 hd->ScsiLookup[ii] = NULL;
1090 mptscsih_freeChainBuffers(hd, ii);
1091 mpt_free_msg_frame(ScsiDoneCtx, hd->ioc, (MPT_FRAME_HDR *)mf);
1098 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1100 * mptscsih_initChainBuffers - Allocate memory for and initialize
1101 * chain buffers, chain buffer control arrays and spinlock.
1102 * @hd: Pointer to MPT_SCSI_HOST structure
1103 * @init: If set, initialize the spin lock.
1106 mptscsih_initChainBuffers (MPT_SCSI_HOST *hd, int init)
1108 MPT_FRAME_HDR *chain;
1110 unsigned long flags;
1111 int sz, ii, num_chain;
1114 /* chain buffer allocation done from PrimeIocFifos */
1115 if (hd->ioc->fifo_pool == NULL)
1118 hd->ChainBuffer = hd->ioc->chain_alloc;
1119 hd->ChainBufferDMA = hd->ioc->chain_alloc_dma;
1121 dprintk((KERN_INFO " ChainBuffer @ %p(%p), sz=%d\n",
1122 hd->ChainBuffer, (void *)(ulong)hd->ChainBufferDMA, hd->ioc->chain_alloc_sz));
1124 /* ReqToChain size must equal the req_depth
1127 if (hd->ReqToChain == NULL) {
1128 sz = hd->ioc->req_depth * sizeof(int);
1129 mem = kmalloc(sz, GFP_ATOMIC);
1133 hd->ReqToChain = (int *) mem;
1135 for (ii = 0; ii < hd->ioc->req_depth; ii++)
1136 hd->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
1138 /* ChainToChain size must equal the total number
1139 * of chain buffers to be allocated.
1142 * Calculate the number of chain buffers needed(plus 1) per I/O
1143 * then multiply the the maximum number of simultaneous cmds
1145 * num_sge = num sge in request frame + last chain buffer
1146 * scale = num sge per chain buffer if no chain element
1148 scale = hd->ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
1149 if (sizeof(dma_addr_t) == sizeof(u64))
1150 num_sge = scale + (hd->ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
1152 num_sge = 1+ scale + (hd->ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
1155 while (hd->max_sge - num_sge > 0) {
1157 num_sge += (scale - 1);
1161 if ((int) hd->ioc->chip_type > (int) FC929)
1162 num_chain *= MPT_SCSI_CAN_QUEUE;
1164 num_chain *= MPT_FC_CAN_QUEUE;
1166 hd->num_chain = num_chain;
1168 sz = num_chain * sizeof(int);
1169 if (hd->ChainToChain == NULL) {
1170 mem = kmalloc(sz, GFP_ATOMIC);
1174 hd->ChainToChain = (int *) mem;
1176 mem = (u8 *) hd->ChainToChain;
1178 memset(mem, 0xFF, sz);
1181 /* Initialize the free chain Q.
1184 spin_lock_init(&hd->FreeChainQlock);
1187 spin_lock_irqsave (&hd->FreeChainQlock, flags);
1188 Q_INIT(&hd->FreeChainQ, MPT_FRAME_HDR);
1190 /* Post the chain buffers to the FreeChainQ.
1192 mem = (u8 *)hd->ChainBuffer;
1193 for (ii=0; ii < num_chain; ii++) {
1194 chain = (MPT_FRAME_HDR *) mem;
1195 Q_ADD_TAIL(&hd->FreeChainQ.head, &chain->u.frame.linkage, MPT_FRAME_HDR);
1196 mem += hd->ioc->req_sz;
1198 spin_unlock_irqrestore(&hd->FreeChainQlock, flags);
1203 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1205 * Hack! It might be nice to report if a device is returning QUEUE_FULL
1206 * but maybe not each and every time...
1208 static long last_queue_full = 0;
1210 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1212 * mptscsih_report_queue_full - Report QUEUE_FULL status returned
1213 * from a SCSI target device.
1214 * @sc: Pointer to scsi_cmnd structure
1215 * @pScsiReply: Pointer to SCSIIOReply_t
1216 * @pScsiReq: Pointer to original SCSI request
1218 * This routine periodically reports QUEUE_FULL status returned from a
1219 * SCSI target device. It reports this to the console via kernel
1220 * printk() API call, not more than once every 10 seconds.
1223 mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq)
1225 long time = jiffies;
1227 if (time - last_queue_full > 10 * HZ) {
1228 char *ioc_str = "ioc?";
1230 if (sc->device && sc->device->host != NULL && sc->device->host->hostdata != NULL)
1231 ioc_str = ((MPT_SCSI_HOST *)sc->device->host->hostdata)->ioc->name;
1232 dprintk((MYIOC_s_WARN_FMT "Device (%d:%d:%d) reported QUEUE_FULL!\n",
1233 ioc_str, 0, sc->device->id, sc->device->lun));
1234 last_queue_full = time;
1238 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1239 static char *info_kbuf = NULL;
1241 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1242 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1244 * mptscsih_probe - Installs scsi devices per bus.
1245 * @pdev: Pointer to pci_dev structure
1247 * Returns 0 for success, non-zero for failure.
1252 mptscsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1254 struct Scsi_Host *sh;
1256 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1257 MPT_DONE_Q *freedoneQ;
1258 unsigned long flags;
1267 /* 20010202 -sralston
1268 * Added sanity check on readiness of the MPT adapter.
1270 if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
1271 printk(MYIOC_s_WARN_FMT
1272 "Skipping because it's not operational!\n",
1278 printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
1283 /* Sanity check - ensure at least 1 port is INITIATOR capable
1286 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
1287 if (ioc->pfacts[ii].ProtocolFlags &
1288 MPI_PORTFACTS_PROTOCOL_INITIATOR)
1293 printk(MYIOC_s_WARN_FMT
1294 "Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n",
1299 sh = scsi_host_alloc(&driver_template, sizeof(MPT_SCSI_HOST));
1302 printk(MYIOC_s_WARN_FMT
1303 "Unable to register controller with SCSI subsystem\n",
1308 spin_lock_irqsave(&ioc->FreeQlock, flags);
1310 /* Attach the SCSI Host to the IOC structure
1318 /* set 16 byte cdb's */
1319 sh->max_cmd_len = 16;
1321 /* Yikes! This is important!
1322 * Otherwise, by default, linux
1323 * only scans target IDs 0-7!
1324 * pfactsN->MaxDevices unreliable
1325 * (not supported in early
1326 * versions of the FW).
1327 * max_id = 1 + actual max id,
1328 * max_lun = 1 + actual last lun,
1331 if ((int)ioc->chip_type > (int)FC929) {
1332 sh->max_id = MPT_MAX_SCSI_DEVICES;
1334 /* For FC, increase the queue depth
1335 * from MPT_SCSI_CAN_QUEUE (31)
1336 * to MPT_FC_CAN_QUEUE (63).
1338 sh->can_queue = MPT_FC_CAN_QUEUE;
1340 MPT_MAX_FC_DEVICES<256 ? MPT_MAX_FC_DEVICES : 255;
1343 sh->max_lun = MPT_LAST_LUN + 1;
1344 sh->max_channel = 0;
1345 sh->this_id = ioc->pfacts[0].PortSCSIID;
1349 sh->unique_id = ioc->id;
1351 /* Verify that we won't exceed the maximum
1352 * number of chain buffers
1353 * We can optimize: ZZ = req_sz/sizeof(SGE)
1355 * numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
1356 * + (req_sz - 64)/sizeof(SGE)
1357 * A slightly different algorithm is required for
1360 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
1361 if (sizeof(dma_addr_t) == sizeof(u64)) {
1362 numSGE = (scale - 1) *
1363 (ioc->facts.MaxChainDepth-1) + scale +
1364 (ioc->req_sz - 60) / (sizeof(dma_addr_t) +
1367 numSGE = 1 + (scale - 1) *
1368 (ioc->facts.MaxChainDepth-1) + scale +
1369 (ioc->req_sz - 64) / (sizeof(dma_addr_t) +
1373 if (numSGE < sh->sg_tablesize) {
1374 /* Reset this value */
1375 dprintk((MYIOC_s_INFO_FMT
1376 "Resetting sg_tablesize to %d from %d\n",
1377 ioc->name, numSGE, sh->sg_tablesize));
1378 sh->sg_tablesize = numSGE;
1381 /* Set the pci device pointer in Scsi_Host structure.
1383 scsi_set_device(sh, &ioc->pcidev->dev);
1385 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1387 hd = (MPT_SCSI_HOST *) sh->hostdata;
1389 hd->max_sge = sh->sg_tablesize;
1391 if ((int)ioc->chip_type > (int)FC929)
1394 if (DmpService && (ioc->chip_type == FC919 ||
1395 ioc->chip_type == FC929)) {
1396 hd->is_multipath = 1;
1399 /* SCSI needs scsi_cmnd lookup table!
1400 * (with size equal to req_depth*PtrSz!)
1402 sz = hd->ioc->req_depth * sizeof(void *);
1403 mem = kmalloc(sz, GFP_ATOMIC);
1406 goto mptscsih_probe_failed;
1410 hd->ScsiLookup = (struct scsi_cmnd **) mem;
1412 dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n",
1413 ioc->name, hd->ScsiLookup, sz));
1415 if (mptscsih_initChainBuffers(hd, 1) < 0) {
1417 goto mptscsih_probe_failed;
1420 /* Allocate memory for free and doneQ's
1422 sz = sh->can_queue * sizeof(MPT_DONE_Q);
1423 mem = kmalloc(sz, GFP_ATOMIC);
1426 goto mptscsih_probe_failed;
1429 memset(mem, 0xFF, sz);
1432 /* Initialize the free, done and pending Qs.
1434 Q_INIT(&hd->freeQ, MPT_DONE_Q);
1435 Q_INIT(&hd->doneQ, MPT_DONE_Q);
1436 Q_INIT(&hd->pendingQ, MPT_DONE_Q);
1437 spin_lock_init(&hd->freedoneQlock);
1440 for (ii=0; ii < sh->can_queue; ii++) {
1441 freedoneQ = (MPT_DONE_Q *) mem;
1442 Q_ADD_TAIL(&hd->freeQ.head, freedoneQ, MPT_DONE_Q);
1443 mem += sizeof(MPT_DONE_Q);
1446 /* Initialize this Scsi_Host
1449 Q_INIT(&hd->taskQ, MPT_FRAME_HDR);
1452 /* Allocate memory for the device structures.
1453 * A non-Null pointer at an offset
1454 * indicates a device exists.
1455 * max_id = 1 + maximum id (hosts.h)
1457 sz = sh->max_id * sizeof(void *);
1458 mem = kmalloc(sz, GFP_ATOMIC);
1461 goto mptscsih_probe_failed;
1465 hd->Targets = (VirtDevice **) mem;
1468 " Targets @ %p, sz=%d\n", hd->Targets, sz));
1470 /* Clear the TM flags
1473 hd->tmState = TM_STATE_NONE;
1474 hd->resetPending = 0;
1475 hd->abortSCpnt = NULL;
1477 hd->numTMrequests = 0;
1479 /* Clear the pointer used to store
1480 * single-threaded commands, i.e., those
1481 * issued during a bus scan, dv and
1482 * configuration pages.
1486 /* Initialize this SCSI Hosts' timers
1487 * To use, set the timer expires field
1490 init_timer(&hd->timer);
1491 hd->timer.data = (unsigned long) hd;
1492 hd->timer.function = mptscsih_timer_expired;
1494 init_timer(&hd->TMtimer);
1495 hd->TMtimer.data = (unsigned long) hd;
1496 hd->TMtimer.function = mptscsih_taskmgmt_timeout;
1497 hd->qtag_tick = jiffies;
1499 /* Moved Earlier Pam D */
1502 #ifdef MPTSCSIH_DBG_TIMEOUT
1503 hd->ioc->timeout_hard = 0;
1504 hd->ioc->timeout_delta = 30 * HZ;
1505 hd->ioc->timeout_maxcnt = 0;
1506 hd->ioc->timeout_cnt = 0;
1507 for (ii=0; ii < 8; ii++)
1511 /* Update with the driver setup
1514 if (hd->ioc->spi_data.maxBusWidth >
1515 driver_setup.max_width) {
1516 hd->ioc->spi_data.maxBusWidth =
1517 driver_setup.max_width;
1520 if (hd->ioc->spi_data.minSyncFactor <
1521 driver_setup.min_sync_fac) {
1522 hd->ioc->spi_data.minSyncFactor =
1523 driver_setup.min_sync_fac;
1526 if (hd->ioc->spi_data.minSyncFactor == MPT_ASYNC) {
1527 hd->ioc->spi_data.maxSyncOffset = 0;
1530 hd->ioc->spi_data.Saf_Te = driver_setup.saf_te;
1533 #ifndef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1534 hd->negoNvram = MPT_SCSICFG_USE_NVRAM;
1536 if (driver_setup.dv == 0) {
1537 hd->negoNvram = MPT_SCSICFG_USE_NVRAM;
1540 hd->ioc->spi_data.forceDv = 0;
1541 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
1542 hd->ioc->spi_data.dvStatus[ii] =
1543 MPT_SCSICFG_NEGOTIATE;
1546 if (hd->negoNvram == 0) {
1547 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++)
1548 hd->ioc->spi_data.dvStatus[ii] |=
1549 MPT_SCSICFG_DV_NOT_DONE;
1552 ddvprintk((MYIOC_s_INFO_FMT
1553 "dv %x width %x factor %x saf_te %x\n",
1554 hd->ioc->name, driver_setup.dv,
1555 driver_setup.max_width,
1556 driver_setup.min_sync_fac,
1557 driver_setup.saf_te));
1562 error = scsi_add_host (sh, &ioc->pcidev->dev);
1564 dprintk((KERN_ERR MYNAM
1565 "scsi_add_host failed\n"));
1566 goto mptscsih_probe_failed;
1572 mptscsih_probe_failed:
1574 mptscsih_remove(pdev);
1579 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1581 * mptscsih_remove - Removed scsi devices
1582 * @pdev: Pointer to pci_dev structure
1587 mptscsih_remove(struct pci_dev *pdev)
1589 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1590 struct Scsi_Host *host = ioc->sh;
1593 unsigned long flags;
1598 scsi_remove_host(host);
1600 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1601 /* Check DV thread active */
1603 spin_lock_irqsave(&dvtaskQ_lock, flags);
1604 if (dvtaskQ_active) {
1605 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
1606 while(dvtaskQ_active && --count) {
1607 set_current_state(TASK_INTERRUPTIBLE);
1608 schedule_timeout(1);
1611 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
1614 printk(KERN_ERR MYNAM ": ERROR - DV thread still active!\n");
1615 #if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY)
1617 printk(KERN_ERR MYNAM ": DV thread orig %d, count %d\n", 10 * HZ, count);
1621 hd = (MPT_SCSI_HOST *)host->hostdata;
1623 int sz1, sz2, sz3, sztarget=0;
1628 mptscsih_shutdown(&pdev->dev);
1630 sz1 = sz2 = sz3 = 0;
1632 if (hd->ScsiLookup != NULL) {
1633 sz1 = hd->ioc->req_depth * sizeof(void *);
1634 kfree(hd->ScsiLookup);
1635 hd->ScsiLookup = NULL;
1638 if (hd->ReqToChain != NULL) {
1639 szr2chain = hd->ioc->req_depth * sizeof(int);
1640 kfree(hd->ReqToChain);
1641 hd->ReqToChain = NULL;
1644 if (hd->ChainToChain != NULL) {
1645 szc2chain = hd->num_chain * sizeof(int);
1646 kfree(hd->ChainToChain);
1647 hd->ChainToChain = NULL;
1650 if (hd->memQ != NULL) {
1651 szQ = host->can_queue * sizeof(MPT_DONE_Q);
1656 if (hd->Targets != NULL) {
1660 * Free any target structures that were allocated.
1663 max = MPT_MAX_SCSI_DEVICES;
1665 max = MPT_MAX_FC_DEVICES<256 ? MPT_MAX_FC_DEVICES : 255;
1667 for (ii=0; ii < max; ii++) {
1668 if (hd->Targets[ii]) {
1669 kfree(hd->Targets[ii]);
1670 hd->Targets[ii] = NULL;
1671 sztarget += sizeof(VirtDevice);
1676 * Free pointer array.
1678 sz3 = max * sizeof(void *);
1683 dprintk((MYIOC_s_INFO_FMT
1684 "Free'd ScsiLookup (%d) Target (%d+%d) memory\n",
1685 hd->ioc->name, sz1, sz3, sztarget));
1686 dprintk(("Free'd done and free Q (%d) memory\n", szQ));
1688 /* NULL the Scsi_Host pointer
1693 scsi_host_put(host);
1698 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1700 * mptscsih_shutdown - reboot notifier
1704 mptscsih_shutdown(struct device * dev)
1706 MPT_ADAPTER *ioc = pci_get_drvdata(to_pci_dev(dev));
1707 struct Scsi_Host *host = ioc->sh;
1713 hd = (MPT_SCSI_HOST *)host->hostdata;
1715 /* Flush the cache of this adapter
1718 mptscsih_synchronize_cache(hd, 0);
1723 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1725 * mptscsih_suspend - Fusion MPT scsie driver suspend routine.
1730 mptscsih_suspend(struct pci_dev *pdev, u32 state)
1732 mptscsih_shutdown(&pdev->dev);
1736 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1738 * mptscsih_resume - Fusion MPT scsi driver resume routine.
1743 mptscsih_resume(struct pci_dev *pdev)
1745 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1746 struct Scsi_Host *host = ioc->sh;
1752 hd = (MPT_SCSI_HOST *)host->hostdata;
1756 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1758 unsigned long lflags;
1759 spin_lock_irqsave(&dvtaskQ_lock, lflags);
1760 if (!dvtaskQ_active) {
1762 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1763 INIT_WORK(&mptscsih_dvTask,
1764 mptscsih_domainValidation, (void *) hd);
1765 schedule_work(&mptscsih_dvTask);
1767 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1776 static struct mpt_pci_driver mptscsih_driver = {
1777 .probe = mptscsih_probe,
1778 .remove = mptscsih_remove,
1779 .shutdown = mptscsih_shutdown,
1781 .suspend = mptscsih_suspend,
1782 .resume = mptscsih_resume,
1786 /* SCSI host fops start here... */
1787 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1789 * mptscsih_init - Register MPT adapter(s) as SCSI host(s) with
1790 * linux scsi mid-layer.
1792 * Returns 0 for success, non-zero for failure.
1798 show_mptmod_ver(my_NAME, my_VERSION);
1800 ScsiDoneCtx = mpt_register(mptscsih_io_done, MPTSCSIH_DRIVER);
1801 ScsiTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSCSIH_DRIVER);
1802 ScsiScanDvCtx = mpt_register(mptscsih_scandv_complete, MPTSCSIH_DRIVER);
1804 if (mpt_event_register(ScsiDoneCtx, mptscsih_event_process) == 0) {
1805 dprintk((KERN_INFO MYNAM
1806 ": Registered for IOC event notifications\n"));
1809 if (mpt_reset_register(ScsiDoneCtx, mptscsih_ioc_reset) == 0) {
1810 dprintk((KERN_INFO MYNAM
1811 ": Registered for IOC reset notifications\n"));
1815 /* Evaluate the command line arguments, if any */
1817 mptscsih_setup(mptscsih);
1820 if(mpt_device_driver_register(&mptscsih_driver,
1821 MPTSCSIH_DRIVER) != 0 ) {
1822 dprintk((KERN_INFO MYNAM
1823 ": failed to register dd callbacks\n"));
1830 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1831 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1833 * mptscsih_exit - Unregisters MPT adapter(s)
1839 mpt_device_driver_deregister(MPTSCSIH_DRIVER);
1841 mpt_reset_deregister(ScsiDoneCtx);
1842 dprintk((KERN_INFO MYNAM
1843 ": Deregistered for IOC reset notifications\n"));
1845 mpt_event_deregister(ScsiDoneCtx);
1846 dprintk((KERN_INFO MYNAM
1847 ": Deregistered for IOC event notifications\n"));
1849 mpt_deregister(ScsiScanDvCtx);
1850 mpt_deregister(ScsiTaskCtx);
1851 mpt_deregister(ScsiDoneCtx);
1853 if (info_kbuf != NULL)
1858 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1860 * mptscsih_info - Return information about MPT adapter
1861 * @SChost: Pointer to Scsi_Host structure
1863 * (linux scsi_host_template.info routine)
1865 * Returns pointer to buffer where information was written.
1868 mptscsih_info(struct Scsi_Host *SChost)
1873 if (info_kbuf == NULL)
1874 if ((info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)
1877 h = (MPT_SCSI_HOST *)SChost->hostdata;
1878 info_kbuf[0] = '\0';
1880 mpt_print_ioc_summary(h->ioc, info_kbuf, &size, 0, 0);
1881 info_kbuf[size-1] = '\0';
1894 static void copy_mem_info(struct info_str *info, char *data, int len)
1896 if (info->pos + len > info->length)
1897 len = info->length - info->pos;
1899 if (info->pos + len < info->offset) {
1904 if (info->pos < info->offset) {
1905 data += (info->offset - info->pos);
1906 len -= (info->offset - info->pos);
1910 memcpy(info->buffer + info->pos, data, len);
1915 static int copy_info(struct info_str *info, char *fmt, ...)
1921 va_start(args, fmt);
1922 len = vsprintf(buf, fmt, args);
1925 copy_mem_info(info, buf, len);
1929 static int mptscsih_host_info(MPT_ADAPTER *ioc, char *pbuf, off_t offset, int len)
1931 struct info_str info;
1935 info.offset = offset;
1938 copy_info(&info, "%s: %s, ", ioc->name, ioc->prod_name);
1939 copy_info(&info, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING, ioc->facts.FWVersion.Word);
1940 copy_info(&info, "Ports=%d, ", ioc->facts.NumberOfPorts);
1941 copy_info(&info, "MaxQ=%d\n", ioc->req_depth);
1943 return ((info.pos > info.offset) ? info.pos - info.offset : 0);
1946 #ifndef MPTSCSIH_DBG_TIMEOUT
1947 static int mptscsih_user_command(MPT_ADAPTER *ioc, char *pbuf, int len)
1949 /* Not yet implemented */
1953 #define is_digit(c) ((c) >= '0' && (c) <= '9')
1954 #define digit_to_bin(c) ((c) - '0')
1955 #define is_space(c) ((c) == ' ' || (c) == '\t')
1957 #define UC_DBG_TIMEOUT 0x01
1958 #define UC_DBG_HARDRESET 0x02
1960 static int skip_spaces(char *ptr, int len)
1964 for (cnt = len; cnt > 0 && (c = *ptr++) && is_space(c); cnt --);
1969 static int get_int_arg(char *ptr, int len, ulong *pv)
1973 for (v = 0, cnt = len; cnt > 0 && (c=*ptr++) && is_digit(c); cnt --) {
1974 v = (v * 10) + digit_to_bin(c);
1984 static int is_keyword(char *ptr, int len, char *verb)
1986 int verb_len = strlen(verb);
1988 if (len >= strlen(verb) && !memcmp(verb, ptr, verb_len))
1994 #define SKIP_SPACES(min_spaces) \
1995 if ((arg_len = skip_spaces(ptr,len)) < (min_spaces)) \
2000 #define GET_INT_ARG(v) \
2001 if (!(arg_len = get_int_arg(ptr,len, &(v)))) \
2006 static int mptscsih_user_command(MPT_ADAPTER *ioc, char *buffer, int length)
2009 char btmp[24]; /* REMOVE */
2016 if ((len > 0) && (ptr[len -1] == '\n'))
2020 strncpy(btmp, buffer, len);
2023 strncpy(btmp, buffer, 22);
2026 printk("user_command: ioc %d, buffer %s, length %d\n",
2027 ioc->id, btmp, length);
2029 if ((arg_len = is_keyword(ptr, len, "timeout")) != 0)
2030 cmd = UC_DBG_TIMEOUT;
2031 else if ((arg_len = is_keyword(ptr, len, "hardreset")) != 0)
2032 cmd = UC_DBG_HARDRESET;
2040 case UC_DBG_TIMEOUT:
2042 GET_INT_ARG(number);
2048 printk("user_command: cnt=%ld delta=%ld\n", number, delta);
2053 if (cmd == UC_DBG_HARDRESET) {
2054 ioc->timeout_hard = 1;
2055 } else if (cmd == UC_DBG_TIMEOUT) {
2056 /* process this command ...
2058 ioc->timeout_maxcnt = 0;
2059 ioc->timeout_delta = delta < 2 ? 2 : delta;
2060 ioc->timeout_cnt = 0;
2061 ioc->timeout_maxcnt = number < 8 ? number: 8;
2064 /* Not yet implemented */
2069 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2071 * mptscsih_proc_info - Return information about MPT adapter
2073 * (linux scsi_host_template.info routine)
2075 * buffer: if write, user data; if read, buffer for user
2076 * length: if write, return length;
2077 * offset: if write, 0; if read, the current offset into the buffer from
2078 * the previous read.
2079 * hostno: scsi host number
2080 * func: if write = 1; if read = 0
2082 int mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
2083 int length, int func)
2085 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
2086 MPT_ADAPTER *ioc = hd->ioc;
2090 size = mptscsih_user_command(ioc, buffer, length);
2095 size = mptscsih_host_info(ioc, buffer, offset, length);
2102 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2103 #define ADD_INDEX_LOG(req_ent) do { } while(0)
2105 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2107 * mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine.
2108 * @SCpnt: Pointer to scsi_cmnd structure
2109 * @done: Pointer SCSI mid-layer IO completion function
2111 * (linux scsi_host_template.queuecommand routine)
2112 * This is the primary SCSI IO start routine. Create a MPI SCSIIORequest
2113 * from a linux scsi_cmnd request and send it to the IOC.
2115 * Returns 0. (rtn value discarded by linux scsi mid-layer)
2118 mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
2122 SCSIIORequest_t *pScsiReq;
2123 VirtDevice *pTarget;
2125 unsigned long flags;
2139 hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata;
2140 target = SCpnt->device->id;
2141 lun = SCpnt->device->lun;
2142 SCpnt->scsi_done = done;
2144 pTarget = hd->Targets[target];
2146 dmfprintk((MYIOC_s_INFO_FMT "qcmd: SCpnt=%p, done()=%p\n",
2147 (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt, done));
2149 if (hd->resetPending) {
2150 /* Prevent new commands from being issued
2151 * while reloading the FW. Reset timer to 60 seconds,
2152 * as the FW can take some time to come ready.
2153 * For New EH, cmds on doneQ posted to FW.
2156 mod_timer(&SCpnt->eh_timeout, jiffies + (HZ * 60));
2157 dtmprintk((MYIOC_s_WARN_FMT "qcmd: SCpnt=%p timeout + 60HZ\n",
2158 (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt));
2163 * Put together a MPT SCSI request...
2165 if ((mf = mpt_get_msg_frame(ScsiDoneCtx, hd->ioc)) == NULL) {
2166 dprintk((MYIOC_s_WARN_FMT "QueueCmd, no msg frames!!\n",
2172 pScsiReq = (SCSIIORequest_t *) mf;
2174 my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2176 ADD_INDEX_LOG(my_idx);
2178 /* BUG FIX! 19991030 -sralston
2179 * TUR's being issued with scsictl=0x02000000 (DATA_IN)!
2180 * Seems we may receive a buffer (datalen>0) even when there
2181 * will be no data transfer! GRRRRR...
2183 if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
2184 datalen = SCpnt->request_bufflen;
2185 scsidir = MPI_SCSIIO_CONTROL_READ; /* DATA IN (host<--ioc<--dev) */
2186 } else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
2187 datalen = SCpnt->request_bufflen;
2188 scsidir = MPI_SCSIIO_CONTROL_WRITE; /* DATA OUT (host-->ioc-->dev) */
2191 scsidir = MPI_SCSIIO_CONTROL_NODATATRANSFER;
2194 /* Default to untagged. Once a target structure has been allocated,
2195 * use the Inquiry data to determine if device supports tagged.
2198 && (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)
2199 && (SCpnt->device->tagged_supported)) {
2200 scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
2202 scsictl = scsidir | MPI_SCSIIO_CONTROL_UNTAGGED;
2205 /* Use the above information to set up the message frame
2207 pScsiReq->TargetID = (u8) target;
2208 pScsiReq->Bus = (u8) SCpnt->device->channel;
2209 pScsiReq->ChainOffset = 0;
2210 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
2211 pScsiReq->CDBLength = SCpnt->cmd_len;
2212 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
2213 pScsiReq->Reserved = 0;
2214 pScsiReq->MsgFlags = mpt_msg_flags();
2215 pScsiReq->LUN[0] = 0;
2216 pScsiReq->LUN[1] = lun;
2217 pScsiReq->LUN[2] = 0;
2218 pScsiReq->LUN[3] = 0;
2219 pScsiReq->LUN[4] = 0;
2220 pScsiReq->LUN[5] = 0;
2221 pScsiReq->LUN[6] = 0;
2222 pScsiReq->LUN[7] = 0;
2223 pScsiReq->Control = cpu_to_le32(scsictl);
2226 * Write SCSI CDB into the message
2228 cmd_len = SCpnt->cmd_len;
2229 for (ii=0; ii < cmd_len; ii++)
2230 pScsiReq->CDB[ii] = SCpnt->cmnd[ii];
2232 for (ii=cmd_len; ii < 16; ii++)
2233 pScsiReq->CDB[ii] = 0;
2236 pScsiReq->DataLength = cpu_to_le32(datalen);
2238 /* SenseBuffer low address */
2239 pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
2240 + (my_idx * MPT_SENSE_BUFFER_ALLOC));
2242 /* Now add the SG list
2243 * Always have a SGE even if null length.
2247 /* Add a NULL SGE */
2248 mptscsih_add_sge((char *)&pScsiReq->SGL, MPT_SGE_FLAGS_SSIMPLE_READ | 0,
2251 /* Add a 32 or 64 bit SGE */
2252 rc = mptscsih_AddSGE(hd, SCpnt, pScsiReq, my_idx);
2256 if (rc == SUCCESS) {
2257 hd->ScsiLookup[my_idx] = SCpnt;
2258 SCpnt->host_scribble = NULL;
2260 /* SCSI specific processing */
2263 int dvStatus = hd->ioc->spi_data.dvStatus[target];
2265 if (dvStatus || hd->ioc->spi_data.forceDv) {
2267 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
2268 if ((dvStatus & MPT_SCSICFG_NEED_DV) ||
2269 (hd->ioc->spi_data.forceDv & MPT_SCSICFG_NEED_DV)) {
2270 unsigned long lflags;
2271 /* Schedule DV if necessary */
2272 spin_lock_irqsave(&dvtaskQ_lock, lflags);
2273 if (!dvtaskQ_active) {
2275 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
2276 INIT_WORK(&mptscsih_dvTask, mptscsih_domainValidation, (void *) hd);
2278 schedule_work(&mptscsih_dvTask);
2280 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
2282 hd->ioc->spi_data.forceDv &= ~MPT_SCSICFG_NEED_DV;
2285 /* Trying to do DV to this target, extend timeout.
2286 * Wait to issue intil flag is clear
2288 if (dvStatus & MPT_SCSICFG_DV_PENDING) {
2289 mod_timer(&SCpnt->eh_timeout, jiffies + 40 * HZ);
2293 /* Set the DV flags.
2295 if (dvStatus & MPT_SCSICFG_DV_NOT_DONE)
2296 mptscsih_set_dvflags(hd, pScsiReq);
2301 #ifdef MPTSCSIH_DBG_TIMEOUT
2302 if (hd->ioc->timeout_cnt < hd->ioc->timeout_maxcnt) {
2303 foo_to[hd->ioc->timeout_cnt] = SCpnt;
2304 hd->ioc->timeout_cnt++;
2305 //mod_timer(&SCpnt->eh_timeout, jiffies + hd->ioc->timeout_delta);
2307 printk(MYIOC_s_WARN_FMT
2308 "to pendingQ: (sc=%p, mf=%p, time=%ld)\n",
2309 hd->ioc->name, SCpnt, mf, jiffies);
2314 mpt_put_msg_frame(ScsiDoneCtx, hd->ioc, mf);
2315 dmfprintk((MYIOC_s_INFO_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n",
2316 hd->ioc->name, SCpnt, mf, my_idx));
2318 ddvtprintk((MYIOC_s_INFO_FMT "Pending cmd=%p idx %d\n",
2319 hd->ioc->name, SCpnt, my_idx));
2320 /* Place this command on the pendingQ if possible */
2321 spin_lock_irqsave(&hd->freedoneQlock, flags);
2322 if (!Q_IS_EMPTY(&hd->freeQ)) {
2323 buffer = hd->freeQ.head;
2326 /* Save the mf pointer
2328 buffer->argp = (void *)mf;
2330 /* Add to the pendingQ
2332 Q_ADD_TAIL(&hd->pendingQ.head, buffer, MPT_DONE_Q);
2333 spin_unlock_irqrestore(&hd->freedoneQlock, flags);
2335 spin_unlock_irqrestore(&hd->freedoneQlock, flags);
2336 SCpnt->result = (DID_BUS_BUSY << 16);
2337 SCpnt->scsi_done(SCpnt);
2341 mptscsih_freeChainBuffers(hd, my_idx);
2342 mpt_free_msg_frame(ScsiDoneCtx, hd->ioc, mf);
2350 dprintk((MYIOC_s_WARN_FMT "_qcmd did_errcode=%d (sc=%p)\n",
2351 hd->ioc->name, did_errcode, SCpnt));
2352 /* Just wish OS to issue a retry */
2353 SCpnt->result = (DID_BUS_BUSY << 16);
2354 spin_lock_irqsave(&hd->freedoneQlock, flags);
2355 if (!Q_IS_EMPTY(&hd->freeQ)) {
2356 dtmprintk((MYIOC_s_WARN_FMT "SCpnt=%p to doneQ\n",
2357 (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt));
2358 buffer = hd->freeQ.head;
2361 /* Set the scsi_cmnd pointer
2363 buffer->argp = (void *)SCpnt;
2367 Q_ADD_TAIL(&hd->doneQ.head, buffer, MPT_DONE_Q);
2368 spin_unlock_irqrestore(&hd->freedoneQlock, flags);
2370 spin_unlock_irqrestore(&hd->freedoneQlock, flags);
2371 SCpnt->scsi_done(SCpnt);
2377 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2379 * mptscsih_freeChainBuffers - Function to free chain buffers associated
2380 * with a SCSI IO request
2381 * @hd: Pointer to the MPT_SCSI_HOST instance
2382 * @req_idx: Index of the SCSI IO request frame.
2384 * Called if SG chain buffer allocation fails and mptscsih callbacks.
2388 mptscsih_freeChainBuffers(MPT_SCSI_HOST *hd, int req_idx)
2390 MPT_FRAME_HDR *chain;
2391 unsigned long flags;
2395 /* Get the first chain index and reset
2398 chain_idx = hd->ReqToChain[req_idx];
2399 hd->ReqToChain[req_idx] = MPT_HOST_NO_CHAIN;
2401 while (chain_idx != MPT_HOST_NO_CHAIN) {
2403 /* Save the next chain buffer index */
2404 next = hd->ChainToChain[chain_idx];
2406 /* Free this chain buffer and reset
2409 hd->ChainToChain[chain_idx] = MPT_HOST_NO_CHAIN;
2411 chain = (MPT_FRAME_HDR *) (hd->ChainBuffer
2412 + (chain_idx * hd->ioc->req_sz));
2413 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
2414 Q_ADD_TAIL(&hd->FreeChainQ.head,
2415 &chain->u.frame.linkage, MPT_FRAME_HDR);
2416 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2418 dmfprintk((MYIOC_s_INFO_FMT "FreeChainBuffers (index %d)\n",
2419 hd->ioc->name, chain_idx));
2427 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2432 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2434 * mptscsih_TMHandler - Generic handler for SCSI Task Management.
2435 * Fall through to mpt_HardResetHandler if: not operational, too many
2436 * failed TM requests or handshake failure.
2438 * @ioc: Pointer to MPT_ADAPTER structure
2439 * @type: Task Management type
2440 * @target: Logical Target ID for reset (if appropriate)
2441 * @lun: Logical Unit for reset (if appropriate)
2442 * @ctx2abort: Context for the task to be aborted (if appropriate)
2443 * @sleepFlag: If set, use udelay instead of schedule in handshake code.
2445 * Remark: Currently invoked from a non-interrupt thread (_bh).
2447 * Remark: With old EH code, at most 1 SCSI TaskMgmt function per IOC
2450 * Returns 0 for SUCCESS or -1 if FAILED.
2453 mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout, int sleepFlag)
2459 unsigned long flags;
2461 /* If FW is being reloaded currently, return success to
2462 * the calling function.
2469 printk(KERN_ERR MYNAM " TMHandler" " NULL ioc!\n");
2472 dtmprintk((MYIOC_s_INFO_FMT "TMHandler Entered!\n", ioc->name));
2474 // SJR - CHECKME - Can we avoid this here?
2475 // (mpt_HardResetHandler has this check...)
2476 spin_lock_irqsave(&ioc->diagLock, flags);
2477 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)) {
2478 spin_unlock_irqrestore(&ioc->diagLock, flags);
2481 spin_unlock_irqrestore(&ioc->diagLock, flags);
2483 /* Do not do a Task Management if there are
2484 * too many failed TMs on this adapter.
2486 if (hd->numTMrequests > MPT_HOST_TOO_MANY_TM)
2489 /* Wait a fixed amount of time for the TM pending flag to be cleared.
2490 * If we time out and not bus reset, then we return a FAILED status to the caller.
2491 * The call to mptscsih_tm_pending_wait() will set the pending flag if we are
2492 * successful. Otherwise, reload the FW.
2494 if (mptscsih_tm_pending_wait(hd) == FAILED) {
2495 if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
2496 dtmprintk((KERN_WARNING MYNAM ": %s: TMHandler abort: "
2497 "Timed out waiting for last TM (%d) to complete! \n",
2498 hd->ioc->name, hd->tmPending));
2500 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) {
2501 dtmprintk((KERN_WARNING MYNAM ": %s: TMHandler target reset: "
2502 "Timed out waiting for last TM (%d) to complete! \n",
2503 hd->ioc->name, hd->tmPending));
2505 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
2506 dtmprintk((KERN_WARNING MYNAM ": %s: TMHandler bus reset: "
2507 "Timed out waiting for last TM (%d) to complete! \n",
2508 hd->ioc->name, hd->tmPending));
2509 if (hd->tmPending & (1 << MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS))
2515 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
2516 hd->tmPending |= (1 << type);
2517 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2522 ioc_raw_state = mpt_GetIocState(hd->ioc, 0);
2524 #ifdef MPT_DEBUG_RESET
2525 if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) {
2526 printk(MYIOC_s_WARN_FMT
2527 "TM Handler: IOC Not operational(0x%x)!\n",
2528 hd->ioc->name, ioc_raw_state);
2532 if (doTask && ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL)
2533 && !(ioc_raw_state & MPI_DOORBELL_ACTIVE)) {
2535 /* Isse the Task Mgmt request.
2537 if (hd->hard_resets < -1)
2539 rc = mptscsih_IssueTaskMgmt(hd, type, channel, target, lun, ctx2abort, timeout, sleepFlag);
2541 printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n", hd->ioc->name);
2543 dtmprintk((MYIOC_s_INFO_FMT "Issue of TaskMgmt Successful!\n", hd->ioc->name));
2547 #ifdef MPTSCSIH_DBG_TIMEOUT
2548 if (hd->ioc->timeout_hard)
2552 /* Only fall through to the HRH if this is a bus reset
2554 if ((type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) && (rc ||
2555 ioc->reload_fw || (ioc->alt_ioc && ioc->alt_ioc->reload_fw))) {
2556 dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
2558 rc = mpt_HardResetHandler(hd->ioc, sleepFlag);
2561 dtmprintk((MYIOC_s_INFO_FMT "TMHandler rc = %d!\n", hd->ioc->name, rc));
2567 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2569 * mptscsih_IssueTaskMgmt - Generic send Task Management function.
2570 * @hd: Pointer to MPT_SCSI_HOST structure
2571 * @type: Task Management type
2572 * @target: Logical Target ID for reset (if appropriate)
2573 * @lun: Logical Unit for reset (if appropriate)
2574 * @ctx2abort: Context for the task to be aborted (if appropriate)
2575 * @sleepFlag: If set, use udelay instead of schedule in handshake code.
2577 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
2578 * or a non-interrupt thread. In the former, must not call schedule().
2580 * Not all fields are meaningfull for all task types.
2582 * Returns 0 for SUCCESS, -999 for "no msg frames",
2583 * else other non-zero value returned.
2586 mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout, int sleepFlag)
2589 SCSITaskMgmt_t *pScsiTm;
2593 /* Return Fail to calling function if no message frames available.
2595 if ((mf = mpt_get_msg_frame(ScsiTaskCtx, hd->ioc)) == NULL) {
2596 dtmprintk((MYIOC_s_WARN_FMT "IssueTaskMgmt, no msg frames!!\n",
2601 dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt request @ %p\n",
2602 hd->ioc->name, mf));
2604 /* Format the Request
2606 pScsiTm = (SCSITaskMgmt_t *) mf;
2607 pScsiTm->TargetID = target;
2608 pScsiTm->Bus = channel;
2609 pScsiTm->ChainOffset = 0;
2610 pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
2612 pScsiTm->Reserved = 0;
2613 pScsiTm->TaskType = type;
2614 pScsiTm->Reserved1 = 0;
2615 pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)
2616 ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0;
2618 for (ii= 0; ii < 8; ii++) {
2619 pScsiTm->LUN[ii] = 0;
2621 pScsiTm->LUN[1] = lun;
2623 for (ii=0; ii < 7; ii++)
2624 pScsiTm->Reserved2[ii] = 0;
2626 pScsiTm->TaskMsgContext = ctx2abort;
2627 dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt, ctx2abort (0x%08x), type (%d)\n",
2628 hd->ioc->name, ctx2abort, type));
2630 /* MPI v0.10 requires SCSITaskMgmt requests be sent via Doorbell/handshake
2631 mpt_put_msg_frame(hd->ioc->id, mf);
2632 * Save the MF pointer in case the request times out.
2635 hd->numTMrequests++;
2636 hd->TMtimer.expires = jiffies + timeout;
2637 add_timer(&hd->TMtimer);
2639 if ((retval = mpt_send_handshake_request(ScsiTaskCtx, hd->ioc,
2640 sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, sleepFlag))
2642 dtmprintk((MYIOC_s_WARN_FMT "_send_handshake FAILED!"
2643 " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd, hd->ioc, mf));
2644 hd->numTMrequests--;
2646 del_timer(&hd->TMtimer);
2647 mpt_free_msg_frame(ScsiTaskCtx, hd->ioc, mf);
2653 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2655 * mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant
2656 * @SCpnt: Pointer to scsi_cmnd structure, IO to be aborted
2658 * (linux scsi_host_template.eh_abort_handler routine)
2660 * Returns SUCCESS or FAILED.
2663 mptscsih_abort(struct scsi_cmnd * SCpnt)
2669 spinlock_t *host_lock = SCpnt->device->host->host_lock;
2671 /* If we can't locate our host adapter structure, return FAILED status.
2673 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL) {
2674 SCpnt->result = DID_RESET << 16;
2675 SCpnt->scsi_done(SCpnt);
2676 dtmprintk((KERN_WARNING MYNAM ": mptscsih_abort: "
2677 "Can't locate host! (sc=%p)\n",
2682 if (hd->resetPending)
2685 printk(KERN_WARNING MYNAM ": %s: >> Attempting task abort! (sc=%p)\n",
2686 hd->ioc->name, SCpnt);
2688 if (hd->timeouts < -1)
2691 /* Find this command
2693 if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) {
2694 /* Cmd not found in ScsiLookup. If found in
2695 * doneQ, delete from Q. Do OS callback.
2697 search_doneQ_for_cmd(hd, SCpnt);
2699 SCpnt->result = DID_RESET << 16;
2700 dtmprintk((KERN_WARNING MYNAM ": %s: mptscsih_abort: "
2701 "Command not in the active list! (sc=%p)\n",
2702 hd->ioc->name, SCpnt));
2706 /* If this command is pended, then timeout/hang occurred
2707 * during DV. Post command and flush pending Q
2708 * and then following up with the reset request.
2710 if ((mf = mptscsih_search_pendingQ(hd, scpnt_idx)) != NULL) {
2711 mpt_put_msg_frame(ScsiDoneCtx, hd->ioc, mf);
2712 post_pendingQ_commands(hd);
2713 dtmprintk((KERN_WARNING MYNAM ": %s: mptscsih_abort: "
2714 "Posting pended cmd! (sc=%p)\n",
2715 hd->ioc->name, SCpnt));
2718 /* Most important! Set TaskMsgContext to SCpnt's MsgContext!
2719 * (the IO to be ABORT'd)
2721 * NOTE: Since we do not byteswap MsgContext, we do not
2722 * swap it here either. It is an opaque cookie to
2723 * the controller, so it does not matter. -DaveM
2725 mf = MPT_INDEX_2_MFPTR(hd->ioc, scpnt_idx);
2726 ctx2abort = mf->u.frame.hwhdr.msgctxu.MsgContext;
2728 hd->abortSCpnt = SCpnt;
2730 spin_unlock_irq(host_lock);
2731 if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
2732 SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun,
2733 ctx2abort, (HZ*2) /* 2 second timeout */,CAN_SLEEP)
2736 /* The TM request failed and the subsequent FW-reload failed!
2739 printk(MYIOC_s_WARN_FMT "Error issuing abort task! (sc=%p)\n",
2740 hd->ioc->name, SCpnt);
2742 /* We must clear our pending flag before clearing our state.
2745 hd->tmState = TM_STATE_NONE;
2747 spin_lock_irq(host_lock);
2750 spin_lock_irq(host_lock);
2755 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2757 * mptscsih_dev_reset - Perform a SCSI TARGET_RESET! new_eh variant
2758 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
2760 * (linux scsi_host_template.eh_dev_reset_handler routine)
2762 * Returns SUCCESS or FAILED.
2765 mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
2768 spinlock_t *host_lock = SCpnt->device->host->host_lock;
2770 /* If we can't locate our host adapter structure, return FAILED status.
2772 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
2773 dtmprintk((KERN_WARNING MYNAM ": mptscsih_dev_reset: "
2774 "Can't locate host! (sc=%p)\n",
2779 if (hd->resetPending)
2782 printk(KERN_WARNING MYNAM ": %s: >> Attempting target reset! (sc=%p)\n",
2783 hd->ioc->name, SCpnt);
2785 /* Unsupported for SCSI. Supported for FCP
2790 spin_unlock_irq(host_lock);
2791 if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
2792 SCpnt->device->channel, SCpnt->device->id,
2793 0, 0, (HZ*5) /* 5 second timeout */, CAN_SLEEP)
2795 /* The TM request failed and the subsequent FW-reload failed!
2798 printk(MYIOC_s_WARN_FMT "Error processing TaskMgmt request (sc=%p)\n",
2799 hd->ioc->name, SCpnt);
2801 hd->tmState = TM_STATE_NONE;
2802 spin_lock_irq(host_lock);
2805 spin_lock_irq(host_lock);
2810 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2812 * mptscsih_bus_reset - Perform a SCSI BUS_RESET! new_eh variant
2813 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
2815 * (linux scsi_host_template.eh_bus_reset_handler routine)
2817 * Returns SUCCESS or FAILED.
2820 mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
2823 spinlock_t *host_lock = SCpnt->device->host->host_lock;
2825 /* If we can't locate our host adapter structure, return FAILED status.
2827 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
2828 dtmprintk((KERN_WARNING MYNAM ": mptscsih_bus_reset: "
2829 "Can't locate host! (sc=%p)\n",
2834 printk(KERN_WARNING MYNAM ": %s: >> Attempting bus reset! (sc=%p)\n",
2835 hd->ioc->name, SCpnt);
2837 if (hd->timeouts < -1)
2840 /* We are now ready to execute the task management request. */
2841 spin_unlock_irq(host_lock);
2842 // printk("testing start : mptscsih_schedule_reset\n");
2843 // mptscsih_schedule_reset(hd);
2844 // printk("testing end: mptscsih_schedule_reset\n");
2845 if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
2846 SCpnt->device->channel, 0, 0, 0, (HZ*5) /* 5 second timeout */, CAN_SLEEP)
2849 /* The TM request failed and the subsequent FW-reload failed!
2852 printk(MYIOC_s_WARN_FMT
2853 "Error processing TaskMgmt request (sc=%p)\n",
2854 hd->ioc->name, SCpnt);
2856 hd->tmState = TM_STATE_NONE;
2857 spin_lock_irq(host_lock);
2860 spin_lock_irq(host_lock);
2864 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2866 * mptscsih_host_reset - Perform a SCSI host adapter RESET!
2868 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
2870 * (linux scsi_host_template.eh_host_reset_handler routine)
2872 * Returns SUCCESS or FAILED.
2875 mptscsih_host_reset(struct scsi_cmnd *SCpnt)
2878 int status = SUCCESS;
2879 spinlock_t *host_lock = SCpnt->device->host->host_lock;
2881 /* If we can't locate the host to reset, then we failed. */
2882 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
2883 dtmprintk( ( KERN_WARNING MYNAM ": mptscsih_host_reset: "
2884 "Can't locate host! (sc=%p)\n",
2889 printk(KERN_WARNING MYNAM ": %s: >> Attempting host reset! (sc=%p)\n",
2890 hd->ioc->name, SCpnt);
2892 /* If our attempts to reset the host failed, then return a failed
2893 * status. The host will be taken off line by the SCSI mid-layer.
2895 spin_unlock_irq(host_lock);
2896 if (mpt_HardResetHandler(hd->ioc, CAN_SLEEP) < 0){
2899 /* Make sure TM pending is cleared and TM state is set to
2903 hd->tmState = TM_STATE_NONE;
2905 spin_lock_irq(host_lock);
2908 dtmprintk( ( KERN_WARNING MYNAM ": mptscsih_host_reset: "
2910 (status == SUCCESS) ? "SUCCESS" : "FAILED" ) );
2915 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2917 * mptscsih_tm_pending_wait - wait for pending task management request to
2919 * @hd: Pointer to MPT host structure.
2921 * Returns {SUCCESS,FAILED}.
2924 mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd)
2926 unsigned long flags;
2927 int loop_count = 10 * 4; /* Wait 10 seconds */
2928 int status = FAILED;
2931 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
2932 if (hd->tmState == TM_STATE_NONE) {
2933 hd->tmState = TM_STATE_IN_PROGRESS;
2935 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2939 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2940 set_current_state(TASK_INTERRUPTIBLE);
2941 schedule_timeout(HZ/4);
2942 } while (--loop_count);
2947 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2949 * mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
2950 * @ioc: Pointer to MPT_ADAPTER structure
2951 * @mf: Pointer to SCSI task mgmt request frame
2952 * @mr: Pointer to SCSI task mgmt reply frame
2954 * This routine is called from mptbase.c::mpt_interrupt() at the completion
2955 * of any SCSI task management request.
2956 * This routine is registered with the MPT (base) driver at driver
2957 * load/init time via the mpt_register() API call.
2959 * Returns 1 indicating alloc'd request frame ptr should be freed.
2962 mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
2964 SCSITaskMgmtReply_t *pScsiTmReply;
2965 SCSITaskMgmt_t *pScsiTmReq;
2967 unsigned long flags;
2970 dtmprintk((MYIOC_s_INFO_FMT "SCSI TaskMgmt completed (mf=%p,r=%p)\n",
2971 ioc->name, mf, mr));
2973 /* Depending on the thread, a timer is activated for
2974 * the TM request. Delete this timer on completion of TM.
2975 * Decrement count of outstanding TM requests.
2977 hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
2979 del_timer(&hd->TMtimer);
2981 dtmprintk((MYIOC_s_INFO_FMT "taskQcnt (%d)\n",
2982 ioc->name, hd->taskQcnt));
2984 dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt Complete: NULL Scsi Host Ptr\n",
2990 dtmprintk((MYIOC_s_WARN_FMT "ERROR! TaskMgmt Reply: NULL Request %p\n",
2994 pScsiTmReply = (SCSITaskMgmtReply_t*)mr;
2995 pScsiTmReq = (SCSITaskMgmt_t*)mf;
2997 /* Figure out if this was ABORT_TASK, TARGET_RESET, or BUS_RESET! */
2998 tmType = pScsiTmReq->TaskType;
3000 dtmprintk((KERN_INFO " TaskType = %d, TerminationCount=%d\n",
3001 tmType, le32_to_cpu(pScsiTmReply->TerminationCount)));
3003 /* Error? (anything non-zero?) */
3004 if (*(u32 *)&pScsiTmReply->Reserved2[0]) {
3007 iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
3008 dtmprintk((KERN_INFO " SCSI TaskMgmt (%d) - Oops!\n", tmType));
3009 dtmprintk((KERN_INFO " IOCStatus = %04xh\n", iocstatus));
3010 dtmprintk((KERN_INFO " IOCLogInfo = %08xh\n",
3011 le32_to_cpu(pScsiTmReply->IOCLogInfo)));
3013 /* clear flags and continue.
3015 if (tmType == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK)
3016 hd->abortSCpnt = NULL;
3018 /* If an internal command is present
3019 * or the TM failed - reload the FW.
3020 * FC FW may respond FAILED to an ABORT
3022 if (tmType == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
3024 (iocstatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED)) {
3025 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0) {
3026 printk((KERN_WARNING
3027 " Firmware Reload FAILED!!\n"));
3032 dtmprintk((KERN_INFO " SCSI TaskMgmt SUCCESS!\n"));
3034 hd->numTMrequests--;
3035 hd->abortSCpnt = NULL;
3042 spin_lock_irqsave(&ioc->FreeQlock, flags);
3044 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
3045 hd->tmState = TM_STATE_NONE;
3050 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3052 * This is anyones guess quite frankly.
3055 mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
3056 sector_t capacity, int geom[])
3068 dummy = heads * sectors;
3069 cylinders = capacity;
3070 sector_div(cylinders,dummy);
3072 cylinders = (ulong)capacity / (heads * sectors);
3076 * Handle extended translation size for logical drives
3079 if ((ulong)capacity >= 0x200000) {
3083 dummy = heads * sectors;
3084 cylinders = capacity;
3085 sector_div(cylinders,dummy);
3087 cylinders = (ulong)capacity / (heads * sectors);
3094 geom[2] = cylinders;
3096 dprintk((KERN_NOTICE
3097 ": bios_param: Id=%i Lun=%i Channel=%i CHS=%i/%i/%i\n",
3098 sdev->id, sdev->lun,sdev->channel,(int)cylinders,heads,sectors));
3103 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3105 * OS entry point to allow host driver to alloc memory
3106 * for each scsi device. Called once per device the bus scan.
3107 * Return non-zero if allocation fails.
3108 * Init memory once per id (not LUN).
3111 mptscsih_slave_alloc(struct scsi_device *device)
3113 struct Scsi_Host *host = device->host;
3117 hd = (MPT_SCSI_HOST *)host->hostdata;
3122 if ((vdev = hd->Targets[device->id]) == NULL) {
3123 if ((vdev = kmalloc(sizeof(VirtDevice), GFP_ATOMIC)) == NULL) {
3124 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%d) FAILED!\n",
3125 hd->ioc->name, (int)sizeof(VirtDevice));
3128 memset(vdev, 0, sizeof(VirtDevice));
3129 rwlock_init(&vdev->VdevLock);
3130 Q_INIT(&vdev->WaitQ, void);
3131 Q_INIT(&vdev->SentQ, void);
3132 Q_INIT(&vdev->DoneQ, void);
3134 vdev->ioc_id = hd->ioc->id;
3135 vdev->target_id = device->id;
3136 vdev->bus_id = hd->port;
3138 hd->Targets[device->id] = vdev;
3147 * OS entry point to allow for host driver to free allocated memory
3148 * Called if no device present or device being unloaded
3151 mptscsih_slave_destroy(struct scsi_device *device)
3153 struct Scsi_Host *host = device->host;
3158 hd = (MPT_SCSI_HOST *)host->hostdata;
3163 mptscsih_search_running_cmds(hd, device->id, device->lun);
3165 /* Free memory and reset all flags for this target
3167 if ((vdev = hd->Targets[device->id]) != NULL) {
3170 if (vdev->luns[0] & (1 << device->lun))
3171 vdev->luns[0] &= ~(1 << device->lun);
3173 /* Free device structure only if number of luns is 0.
3175 if (vdev->num_luns == 0) {
3176 kfree(hd->Targets[device->id]);
3177 hd->Targets[device->id] = NULL;
3182 if((hd->ioc->spi_data.isRaid) && (hd->ioc->spi_data.pIocPg3)) {
3184 for(i=0;i<hd->ioc->spi_data.pIocPg3->NumPhysDisks &&
3188 hd->ioc->spi_data.pIocPg3->PhysDisk[i].PhysDiskID) {
3190 hd->ioc->spi_data.forceDv |=
3191 MPT_SCSICFG_RELOAD_IOC_PG3;
3196 hd->ioc->spi_data.dvStatus[device->id] =
3197 MPT_SCSICFG_NEGOTIATE;
3199 if (hd->negoNvram == 0)
3200 hd->ioc->spi_data.dvStatus[device->id]
3201 |= MPT_SCSICFG_DV_NOT_DONE;
3210 * OS entry point to adjust the queue_depths on a per-device basis.
3211 * Called once per device the bus scan. Use it to force the queue_depth
3212 * member to 1 if a device does not support Q tags.
3213 * Return non-zero if fails.
3216 mptscsih_slave_configure(struct scsi_device *device)
3218 struct Scsi_Host *sh = device->host;
3219 VirtDevice *pTarget;
3220 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sh->hostdata;
3222 if ((hd == NULL) || (hd->Targets == NULL)) {
3226 dsprintk((MYIOC_s_INFO_FMT
3227 "device @ %p, id=%d, LUN=%d, channel=%d\n",
3228 hd->ioc->name, device, device->id, device->lun, device->channel));
3229 dsprintk((MYIOC_s_INFO_FMT
3230 "sdtr %d wdtr %d ppr %d inq length=%d\n",
3231 hd->ioc->name, device->sdtr, device->wdtr,
3232 device->ppr, device->inquiry_len));
3234 if (device->id > sh->max_id) {
3235 /* error case, should never happen */
3236 scsi_adjust_queue_depth(device, 0, 1);
3237 goto slave_configure_exit;
3240 pTarget = hd->Targets[device->id];
3242 if (pTarget == NULL) {
3243 /* error case - don't know about this device */
3244 scsi_adjust_queue_depth(device, 0, 1);
3245 goto slave_configure_exit;
3248 mptscsih_initTarget(hd, device->channel, device->id, device->lun,
3249 device->inquiry, device->inquiry_len );
3250 scsi_adjust_queue_depth(device, MSG_SIMPLE_TAG,
3251 MPT_SCSI_CMD_PER_DEV_HIGH);
3253 if (pTarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) {
3254 if (!(pTarget->tflags & MPT_TARGET_FLAGS_Q_YES))
3255 scsi_adjust_queue_depth(device, 0, 1);
3256 else if (((pTarget->inq_data[0] & 0x1f) == 0x00)
3257 && (pTarget->minSyncFactor <= MPT_ULTRA160 ))
3258 scsi_adjust_queue_depth(device, MSG_SIMPLE_TAG,
3259 MPT_SCSI_CMD_PER_DEV_HIGH);
3261 scsi_adjust_queue_depth(device, MSG_SIMPLE_TAG,
3262 MPT_SCSI_CMD_PER_DEV_LOW);
3264 /* error case - No Inq. Data */
3265 scsi_adjust_queue_depth(device, 0, 1);
3269 dsprintk((MYIOC_s_INFO_FMT
3270 "Queue depth=%d, tflags=%x\n",
3271 hd->ioc->name, device->queue_depth, pTarget->tflags));
3273 dsprintk((MYIOC_s_INFO_FMT
3274 "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
3275 hd->ioc->name, pTarget->negoFlags, pTarget->maxOffset, pTarget->minSyncFactor));
3277 slave_configure_exit:
3279 dsprintk((MYIOC_s_INFO_FMT
3280 "tagged %d, simple %d, ordered %d\n",
3281 hd->ioc->name,device->tagged_supported, device->simple_tags,
3282 device->ordered_tags));
3288 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3290 * Private routines...
3293 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3294 /* Utility function to copy sense data from the scsi_cmnd buffer
3295 * to the FC and SCSI target structures.
3299 copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
3302 SCSIIORequest_t *pReq;
3303 u32 sense_count = le32_to_cpu(pScsiReply->SenseCount);
3308 /* Get target structure
3310 pReq = (SCSIIORequest_t *) mf;
3311 index = (int) pReq->TargetID;
3312 target = hd->Targets[index];
3313 if (hd->is_multipath && sc->device->hostdata)
3314 target = (VirtDevice *) sc->device->hostdata;
3320 /* Copy the sense received into the scsi command block. */
3321 req_index = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3322 sense_data = ((u8 *)hd->ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC));
3323 memcpy(sc->sense_buffer, sense_data, SNS_LEN(sc));
3325 /* Log SMART data (asc = 0x5D, non-IM case only) if required.
3327 if ((hd->ioc->events) && (hd->ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) {
3328 if ((sense_data[12] == 0x5D) && (target->raidVolume == 0)) {
3330 MPT_ADAPTER *ioc = hd->ioc;
3332 idx = ioc->eventContext % ioc->eventLogSize;
3333 ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
3334 ioc->events[idx].eventContext = ioc->eventContext;
3336 ioc->events[idx].data[0] = (pReq->LUN[1] << 24) ||
3337 (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) ||
3338 (pReq->Bus << 8) || pReq->TargetID;
3340 ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12];
3342 ioc->eventContext++;
3346 /* Print an error report for the user.
3348 thisIo.cdbPtr = sc->cmnd;
3349 thisIo.sensePtr = sc->sense_buffer;
3350 thisIo.SCSIStatus = pScsiReply->SCSIStatus;
3351 thisIo.DoDisplay = 1;
3352 if (hd->is_multipath)
3353 sprintf(devFoo, "%d:%d:%d",
3358 sprintf(devFoo, "%d:%d:%d", hd->ioc->id, sc->device->id, sc->device->lun);
3359 thisIo.DevIDStr = devFoo;
3361 thisIo.dataPtr = NULL;
3362 thisIo.inqPtr = NULL;
3364 thisIo.inqPtr = sc->device->vendor-8; /* FIXME!!! */
3366 (void) mpt_ScsiHost_ErrorReport(&thisIo);
3369 dprintk((MYIOC_s_INFO_FMT "Hmmm... SenseData len=0! (?)\n",
3377 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc)
3382 hd = (MPT_SCSI_HOST *) sc->device->host->hostdata;
3384 for (i = 0; i < hd->ioc->req_depth; i++) {
3385 if (hd->ScsiLookup[i] == sc) {
3394 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3395 /* Search the pendingQ for a command with specific index.
3396 * If found, delete and return mf pointer
3397 * If not found, return NULL
3399 static MPT_FRAME_HDR *
3400 mptscsih_search_pendingQ(MPT_SCSI_HOST *hd, int scpnt_idx)
3402 unsigned long flags;
3404 MPT_FRAME_HDR *mf = NULL;
3405 MPT_FRAME_HDR *cmdMfPtr;
3407 ddvtprintk((MYIOC_s_INFO_FMT ": search_pendingQ ...", hd->ioc->name));
3408 cmdMfPtr = MPT_INDEX_2_MFPTR(hd->ioc, scpnt_idx);
3409 spin_lock_irqsave(&hd->freedoneQlock, flags);
3410 if (!Q_IS_EMPTY(&hd->pendingQ)) {
3411 buffer = hd->pendingQ.head;
3413 mf = (MPT_FRAME_HDR *) buffer->argp;
3414 if (mf == cmdMfPtr) {
3417 /* clear the arg pointer
3419 buffer->argp = NULL;
3423 Q_ADD_TAIL(&hd->freeQ.head, buffer, MPT_DONE_Q);
3427 } while ((buffer = buffer->forw) != (MPT_DONE_Q *) &hd->pendingQ);
3429 spin_unlock_irqrestore(&hd->freedoneQlock, flags);
3430 ddvtprintk((" ...return %p\n", mf));
3434 /* Post all commands on the pendingQ to the FW.
3435 * Lock Q when deleting/adding members
3436 * Lock io_request_lock for OS callback.
3439 post_pendingQ_commands(MPT_SCSI_HOST *hd)
3443 unsigned long flags;
3445 /* Flush the pendingQ.
3447 ddvtprintk((MYIOC_s_INFO_FMT ": post_pendingQ_commands\n", hd->ioc->name));
3449 spin_lock_irqsave(&hd->freedoneQlock, flags);
3450 if (Q_IS_EMPTY(&hd->pendingQ)) {
3451 spin_unlock_irqrestore(&hd->freedoneQlock, flags);
3455 buffer = hd->pendingQ.head;
3460 mf = (MPT_FRAME_HDR *) buffer->argp;
3461 buffer->argp = NULL;
3465 Q_ADD_TAIL(&hd->freeQ.head, buffer, MPT_DONE_Q);
3466 spin_unlock_irqrestore(&hd->freedoneQlock, flags);
3469 /* This should never happen */
3470 printk(MYIOC_s_WARN_FMT "post_pendingQ_commands: mf %p\n", hd->ioc->name, (void *) mf);
3474 mpt_put_msg_frame(ScsiDoneCtx, hd->ioc, mf);
3476 #if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY)
3478 u16 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3479 struct scsi_cmnd *sc = hd->ScsiLookup[req_idx];
3480 printk(MYIOC_s_INFO_FMT "Issued SCSI cmd (sc=%p) idx=%d (mf=%p)\n",
3481 hd->ioc->name, sc, req_idx, mf);
3489 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3491 mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
3494 unsigned long flags;
3496 dtmprintk((KERN_WARNING MYNAM
3497 ": IOC %s_reset routed to SCSI host driver!\n",
3498 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
3499 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
3501 /* If a FW reload request arrives after base installed but
3502 * before all scsi hosts have been attached, then an alt_ioc
3503 * may have a NULL sh pointer.
3505 if ((ioc->sh == NULL) || (ioc->sh->hostdata == NULL))
3508 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
3510 if (reset_phase == MPT_IOC_SETUP_RESET) {
3511 dtmprintk((MYIOC_s_WARN_FMT "Setup-Diag Reset\n", ioc->name));
3514 * 1. Set Hard Reset Pending Flag
3515 * All new commands go to doneQ
3517 hd->resetPending = 1;
3519 } else if (reset_phase == MPT_IOC_PRE_RESET) {
3520 dtmprintk((MYIOC_s_WARN_FMT "Pre-Diag Reset\n", ioc->name));
3522 /* 2. Flush running commands
3523 * Clean drop test code - if compiled
3524 * Clean ScsiLookup (and associated memory)
3528 /* 2a. Drop Test Command.
3531 /* 2b. Reply to OS all known outstanding I/O commands.
3533 mptscsih_flush_running_cmds(hd);
3535 /* 2c. If there was an internal command that
3536 * has not completed, configuration or io request,
3537 * free these resources.
3540 del_timer(&hd->timer);
3541 mpt_free_msg_frame(ScsiScanDvCtx, ioc, hd->cmdPtr);
3544 /* 2d. If a task management has not completed,
3545 * free resources associated with this request.
3548 del_timer(&hd->TMtimer);
3549 mpt_free_msg_frame(ScsiTaskCtx, ioc, hd->tmPtr);
3552 #ifdef MPTSCSIH_DBG_TIMEOUT
3553 ioc->timeout_hard = 0;
3556 dtmprintk((MYIOC_s_WARN_FMT "Pre-Reset complete.\n", ioc->name));
3559 dtmprintk((MYIOC_s_WARN_FMT "Post-Diag Reset\n", ioc->name));
3561 /* Once a FW reload begins, all new OS commands are
3562 * redirected to the doneQ w/ a reset status.
3563 * Init all control structures.
3566 /* ScsiLookup initialization
3570 for (ii=0; ii < hd->ioc->req_depth; ii++)
3571 hd->ScsiLookup[ii] = NULL;
3574 /* 2. Chain Buffer initialization
3576 mptscsih_initChainBuffers(hd, 0);
3584 /* 4. Renegotiate to all devices, if SCSI
3587 mptscsih_writeSDP1(hd, 0, 0, MPT_SCSICFG_ALL_IDS | MPT_SCSICFG_USE_NVRAM);
3589 /* 5. Enable new commands to be posted
3591 spin_lock_irqsave(&ioc->FreeQlock, flags);
3593 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
3594 hd->resetPending = 0;
3595 hd->numTMrequests = 0;
3596 hd->tmState = TM_STATE_NONE;
3598 /* 6. If there was an internal command,
3599 * wake this process up.
3603 * Wake up the original calling thread
3605 hd->pLocal = &hd->localReply;
3606 hd->pLocal->completion = MPT_SCANDV_DID_RESET;
3607 scandv_wait_done = 1;
3608 wake_up(&scandv_waitq);
3616 /* 8. Set flag to force DV and re-read IOC Page 3
3619 ioc->spi_data.forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
3620 ddvtprintk(("Set reload IOC Pg3 Flag\n"));
3623 dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name));
3627 return 1; /* currently means nothing really */
3630 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3632 mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
3635 u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
3637 dprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
3641 case MPI_EVENT_UNIT_ATTENTION: /* 03 */
3644 case MPI_EVENT_IOC_BUS_RESET: /* 04 */
3645 case MPI_EVENT_EXT_BUS_RESET: /* 05 */
3648 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
3649 if (hd && (hd->is_spi) && (hd->soft_resets < -1))
3653 case MPI_EVENT_LOGOUT: /* 09 */
3658 * CHECKME! Don't think we need to do
3659 * anything for these, but...
3661 case MPI_EVENT_RESCAN: /* 06 */
3662 case MPI_EVENT_LINK_STATUS_CHANGE: /* 07 */
3663 case MPI_EVENT_LOOP_STATE_CHANGE: /* 08 */
3665 * CHECKME! Falling thru...
3669 case MPI_EVENT_INTEGRATED_RAID: /* 0B */
3670 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
3671 /* negoNvram set to 0 if DV enabled and to USE_NVRAM if
3672 * if DV disabled. Need to check for target mode.
3676 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
3678 if (hd && (hd->is_spi) && (hd->negoNvram == 0)) {
3680 Ioc3PhysDisk_t *pPDisk;
3685 reason = (le32_to_cpu(pEvReply->Data[0]) & 0x00FF0000) >> 16;
3686 if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
3687 /* New or replaced disk.
3688 * Set DV flag and schedule DV.
3690 pSpi = &ioc->spi_data;
3691 physDiskNum = (le32_to_cpu(pEvReply->Data[0]) & 0xFF000000) >> 24;
3692 ddvtprintk(("DV requested for phys disk id %d\n", physDiskNum));
3693 if (pSpi->pIocPg3) {
3694 pPDisk = pSpi->pIocPg3->PhysDisk;
3695 numPDisk =pSpi->pIocPg3->NumPhysDisks;
3698 if (physDiskNum == pPDisk->PhysDiskNum) {
3699 pSpi->dvStatus[pPDisk->PhysDiskID] = (MPT_SCSICFG_NEED_DV | MPT_SCSICFG_DV_NOT_DONE);
3700 pSpi->forceDv = MPT_SCSICFG_NEED_DV;
3701 ddvtprintk(("NEED_DV set for phys disk id %d\n", pPDisk->PhysDiskID));
3708 if (numPDisk == 0) {
3709 /* The physical disk that needs DV was not found
3710 * in the stored IOC Page 3. The driver must reload
3711 * this page. DV routine will set the NEED_DV flag for
3712 * all phys disks that have DV_NOT_DONE set.
3714 pSpi->forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
3715 ddvtprintk(("phys disk %d not found. Setting reload IOC Pg3 Flag\n", physDiskNum));
3722 #if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY)
3723 printk("Raid Event RF: ");
3725 u32 *m = (u32 *)pEvReply;
3727 int n = (int)pEvReply->MsgLength;
3728 for (ii=6; ii < n; ii++)
3729 printk(" %08x", le32_to_cpu(m[ii]));
3735 case MPI_EVENT_NONE: /* 00 */
3736 case MPI_EVENT_LOG_DATA: /* 01 */
3737 case MPI_EVENT_STATE_CHANGE: /* 02 */
3738 case MPI_EVENT_EVENT_CHANGE: /* 0A */
3740 dprintk((KERN_INFO " Ignoring event (=%02Xh)\n", event));
3744 return 1; /* currently means nothing really */
3747 static struct scsi_host_template driver_template = {
3748 .proc_name = "mptscsih",
3749 .proc_info = mptscsih_proc_info,
3750 .name = "MPT SCSI Host",
3751 .info = mptscsih_info,
3752 .queuecommand = mptscsih_qcmd,
3753 .slave_alloc = mptscsih_slave_alloc,
3754 .slave_configure = mptscsih_slave_configure,
3755 .slave_destroy = mptscsih_slave_destroy,
3756 .eh_abort_handler = mptscsih_abort,
3757 .eh_device_reset_handler = mptscsih_dev_reset,
3758 .eh_bus_reset_handler = mptscsih_bus_reset,
3759 .eh_host_reset_handler = mptscsih_host_reset,
3760 .bios_param = mptscsih_bios_param,
3761 .can_queue = MPT_SCSI_CAN_QUEUE,
3763 .sg_tablesize = MPT_SCSI_SG_DEPTH,
3764 .max_sectors = 8192,
3766 .use_clustering = ENABLE_CLUSTERING,
3770 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3774 static ASCQ_Table_t *mptscsih_ASCQ_TablePtr;
3776 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3777 /* old symsense.c stuff... */
3778 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3781 * To protect ourselves against those that would pass us bogus pointers
3783 static u8 dummyInqData[SCSI_STD_INQUIRY_BYTES]
3784 = { 0x1F, 0x00, 0x00, 0x00,
3785 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3786 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3787 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3788 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
3789 static u8 dummySenseData[SCSI_STD_SENSE_BYTES]
3790 = { 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A,
3791 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3793 static u8 dummyCDB[16]
3794 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3795 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
3796 static u8 dummyScsiData[16]
3797 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3798 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
3800 static char *ScsiStatusString[] = {
3803 "CHECK CONDITION", /* 02h */
3805 "CONDITION MET", /* 04h */
3817 "INTERMEDIATE", /* 10h */
3821 "INTERMEDIATE-CONDITION MET", /* 14h */
3825 "RESERVATION CONFLICT", /* 18h */
3835 "COMMAND TERMINATED", /* 22h */
3841 "TASK SET FULL", /* 28h */
3849 "ACA ACTIVE", /* 30h */
3853 static const char *ScsiCommonOpString[] = {
3854 "TEST UNIT READY", /* 00h */
3855 "REZERO UNIT (REWIND)", /* 01h */
3857 "REQUEST_SENSE", /* 03h */
3858 "FORMAT UNIT (MEDIUM)", /* 04h */
3859 "READ BLOCK LIMITS", /* 05h */
3861 "REASSIGN BLOCKS", /* 07h */
3862 "READ(6)", /* 08h */
3864 "WRITE(6)", /* 0Ah */
3865 "SEEK(6)", /* 0Bh */
3869 "READ REVERSE", /* 0Fh */
3870 "WRITE_FILEMARKS", /* 10h */
3871 "SPACE(6)", /* 11h */
3872 "INQUIRY", /* 12h */
3876 static const char *SenseKeyString[] = {
3877 "NO SENSE", /* 0h */
3878 "RECOVERED ERROR", /* 1h */
3879 "NOT READY", /* 2h */
3880 "MEDIUM ERROR", /* 3h */
3881 "HARDWARE ERROR", /* 4h */
3882 "ILLEGAL REQUEST", /* 5h */
3883 "UNIT ATTENTION", /* 6h */
3884 "DATA PROTECT", /* 7h */
3885 "BLANK CHECK", /* 8h */
3886 "VENDOR-SPECIFIC", /* 9h */
3887 "ABORTED COPY", /* Ah */
3888 "ABORTED COMMAND", /* Bh */
3889 "EQUAL (obsolete)", /* Ch */
3890 "VOLUME OVERFLOW", /* Dh */
3891 "MISCOMPARE", /* Eh */
3892 "RESERVED", /* Fh */
3896 #define SPECIAL_ASCQ(c,q) \
3897 (((c) == 0x40 && (q) != 0x00) || ((c) == 0x4D) || ((c) == 0x70))
3899 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3900 static int dump_cdb(char *foo, unsigned char *cdb)
3902 int i, grpCode, cdbLen;
3905 grpCode = cdb[0] >> 5;
3908 else if (grpCode < 3)
3910 else if (grpCode == 5)
3915 for (i=0; i < cdbLen; i++)
3916 l += sprintf(foo+l, " %02X", cdb[i]);
3921 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3922 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3923 /* Do ASC/ASCQ lookup/grindage to English readable string(s) */
3924 static const char * ascq_set_strings_4max(
3926 const char **s1, const char **s2, const char **s3, const char **s4)
3928 static const char *asc_04_part1_string = "LOGICAL UNIT ";
3929 static const char *asc_04_part2a_string = "NOT READY, ";
3930 static const char *asc_04_part2b_string = "IS ";
3931 static const char *asc_04_ascq_NN_part3_strings[] = { /* ASC ASCQ (hex) */
3932 "CAUSE NOT REPORTABLE", /* 04 00 */
3933 "IN PROCESS OF BECOMING READY", /* 04 01 */
3934 "INITIALIZING CMD. REQUIRED", /* 04 02 */
3935 "MANUAL INTERVENTION REQUIRED", /* 04 03 */
3936 /* Add " IN PROGRESS" to all the following... */
3937 "FORMAT", /* 04 04 */
3938 "REBUILD", /* 04 05 */
3939 "RECALCULATION", /* 04 06 */
3940 "OPERATION", /* 04 07 */
3941 "LONG WRITE", /* 04 08 */
3942 "SELF-TEST", /* 04 09 */
3945 static char *asc_04_part4_string = " IN PROGRESS";
3947 static char *asc_29_ascq_NN_strings[] = { /* ASC ASCQ (hex) */
3948 "POWER ON, RESET, OR BUS DEVICE RESET OCCURRED", /* 29 00 */
3949 "POWER ON OCCURRED", /* 29 01 */
3950 "SCSI BUS RESET OCCURRED", /* 29 02 */
3951 "BUS DEVICE RESET FUNCTION OCCURRED", /* 29 03 */
3952 "DEVICE INTERNAL RESET", /* 29 04 */
3953 "TRANSCEIVER MODE CHANGED TO SINGLE-ENDED", /* 29 05 */
3954 "TRANSCEIVER MODE CHANGED TO LVD", /* 29 06 */
3957 static char *ascq_vendor_uniq = "(Vendor Unique)";
3958 static char *ascq_noone = "(no matching ASC/ASCQ description found)";
3961 *s1 = *s2 = *s3 = *s4 = ""; /* set'em all to the empty "" string */
3963 /* CHECKME! Need lock/sem?
3964 * Update and examine for isense module presense.
3966 mptscsih_ASCQ_TablePtr = (ASCQ_Table_t *)mpt_v_ASCQ_TablePtr;
3968 if (mptscsih_ASCQ_TablePtr == NULL) {
3969 /* 2nd chances... */
3970 if (ASC == 0x04 && (ASCQ < sizeof(asc_04_ascq_NN_part3_strings)/sizeof(char*)-1)) {
3971 *s1 = asc_04_part1_string;
3972 *s2 = (ASCQ == 0x01) ? asc_04_part2b_string : asc_04_part2a_string;
3973 *s3 = asc_04_ascq_NN_part3_strings[ASCQ];
3974 /* check for " IN PROGRESS" ones */
3976 *s4 = asc_04_part4_string;
3977 } else if (ASC == 0x29 && (ASCQ < sizeof(asc_29_ascq_NN_strings)/sizeof(char*)-1))
3978 *s1 = asc_29_ascq_NN_strings[ASCQ];
3980 * Else { leave all *s[1-4] values pointing to the empty "" string }
3986 * Need to check ASC here; if it is "special," then
3987 * the ASCQ is variable, and indicates failed component number.
3988 * We must treat the ASCQ as a "don't care" while searching the
3989 * mptscsih_ASCQ_Table[] by masking it off, and then restoring it later
3990 * on when we actually need to identify the failed component.
3992 if (SPECIAL_ASCQ(ASC,ASCQ))
3995 /* OK, now search mptscsih_ASCQ_Table[] for a matching entry */
3996 for (idx = 0; mptscsih_ASCQ_TablePtr && idx < mpt_ASCQ_TableSz; idx++)
3997 if ((ASC == mptscsih_ASCQ_TablePtr[idx].ASC) && (ASCQ == mptscsih_ASCQ_TablePtr[idx].ASCQ)) {
3998 *s1 = mptscsih_ASCQ_TablePtr[idx].Description;
4002 if ((ASC >= 0x80) || (ASCQ >= 0x80))
4003 *s1 = ascq_vendor_uniq;
4010 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4012 * SCSI Information Report; desired output format...
4014 SCSI Error: (iocnum:target_id:LUN) Status=02h (CHECK CONDITION)
4015 Key=6h (UNIT ATTENTION); FRU=03h
4016 ASC/ASCQ=29h/00h, "POWER ON, RESET, OR BUS DEVICE RESET OCCURRED"
4017 CDB: 00 00 00 00 00 00 - TestUnitReady
4021 * SCSI Error Report; desired output format...
4023 SCSI Error Report =-=-=-=-=-=-=-=-=-=-=-=-=-= (ioc0,scsi0:0)
4024 SCSI_Status=02h (CHECK CONDITION)
4025 Original_CDB[]: 00 00 00 00 00 00 - TestUnitReady
4026 SenseData[12h]: 70 00 06 00 00 00 00 0A 00 00 00 00 29 00 03 00 00 00
4027 SenseKey=6h (UNIT ATTENTION); FRU=03h
4028 ASC/ASCQ=29h/00h, "POWER ON, RESET, OR BUS DEVICE RESET OCCURRED"
4032 int mpt_ScsiHost_ErrorReport(IO_Info_t *ioop)
4038 int sk = SD_Sense_Key(ioop->sensePtr);
4039 const char *skstr = SenseKeyString[sk];
4040 unsigned char asc = SD_ASC(ioop->sensePtr);
4041 unsigned char ascq = SD_ASCQ(ioop->sensePtr);
4044 /* Change the error logging to only report errors on
4045 * read and write commands. Ignore errors on other commands.
4046 * Should this be configurable via proc?
4048 switch (ioop->cdbPtr[0]) {
4064 * Filter out common, repetitive, warning-type errors... like:
4065 * POWER ON (06,29/00 or 06,29/01),
4066 * SPINNING UP (02,04/01),
4067 * LOGICAL UNIT NOT SUPPORTED (05,25/00), etc.
4069 if (sk == SK_NO_SENSE) {
4073 if ( (sk==SK_UNIT_ATTENTION && asc==0x29 && (ascq==0x00 || ascq==0x01))
4074 || (sk==SK_NOT_READY && asc==0x04 && (ascq==0x01 || ascq==0x02))
4075 || (sk==SK_ILLEGAL_REQUEST && asc==0x25 && ascq==0x00)
4082 /* Prevent the system from continually writing to the log
4083 * if a medium is not found: 02 3A 00
4084 * Changer issues: TUR, Read Capacity, Table of Contents continually
4086 if (sk==SK_NOT_READY && asc==0x3A) {
4087 if (ioop->cdbPtr == NULL) {
4089 } else if ((ioop->cdbPtr[0] == CMD_TestUnitReady) ||
4090 (ioop->cdbPtr[0] == CMD_ReadCapacity) ||
4091 (ioop->cdbPtr[0] == 0x43)) {
4095 if (sk==SK_UNIT_ATTENTION) {
4096 if (ioop->cdbPtr == NULL)
4098 else if (ioop->cdbPtr[0] == CMD_TestUnitReady)
4103 * Protect ourselves...
4105 if (ioop->cdbPtr == NULL)
4106 ioop->cdbPtr = dummyCDB;
4107 if (ioop->sensePtr == NULL)
4108 ioop->sensePtr = dummySenseData;
4109 if (ioop->inqPtr == NULL)
4110 ioop->inqPtr = dummyInqData;
4111 if (ioop->dataPtr == NULL)
4112 ioop->dataPtr = dummyScsiData;
4115 if ((ioop->SCSIStatus >= sizeof(ScsiStatusString)/sizeof(char*)-1) ||
4116 ((statstr = (char*)ScsiStatusString[ioop->SCSIStatus]) == NULL)) {
4117 (void) sprintf(buf2, "Bad-Reserved-%02Xh", ioop->SCSIStatus);
4122 if (1+ioop->cdbPtr[0] <= sizeof(ScsiCommonOpString)/sizeof(char*))
4123 opstr = ScsiCommonOpString[ioop->cdbPtr[0]];
4124 else if (mpt_ScsiOpcodesPtr)
4125 opstr = mpt_ScsiOpcodesPtr[ioop->cdbPtr[0]];
4127 l = sprintf(foo, "SCSI Error: (%s) Status=%02Xh (%s)\n",
4131 l += sprintf(foo+l, " Key=%Xh (%s); FRU=%02Xh\n ASC/ASCQ=%02Xh/%02Xh",
4132 sk, skstr, SD_FRU(ioop->sensePtr), asc, ascq );
4134 const char *x1, *x2, *x3, *x4;
4135 x1 = x2 = x3 = x4 = "";
4136 x1 = ascq_set_strings_4max(asc, ascq, &x1, &x2, &x3, &x4);
4139 l += sprintf(foo+l, " \"%s%s%s%s\"", x1,x2,x3,x4);
4141 l += sprintf(foo+l, " %s%s%s%s", x1,x2,x3,x4);
4144 l += sprintf(foo+l, "\n CDB:");
4145 l += dump_cdb(foo+l, ioop->cdbPtr);
4147 l += sprintf(foo+l, " - \"%s\"", opstr);
4148 l += sprintf(foo+l, "\n");
4150 PrintF(("%s\n", foo));
4155 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4157 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4159 * mptscsih_initTarget - Target, LUN alloc/free functionality.
4160 * @hd: Pointer to MPT_SCSI_HOST structure
4161 * @bus_id: Bus number (?)
4162 * @target_id: SCSI target id
4164 * @data: Pointer to data
4165 * @dlen: Number of INQUIRY bytes
4167 * NOTE: It's only SAFE to call this routine if data points to
4168 * sane & valid STANDARD INQUIRY data!
4170 * Allocate and initialize memory for this target.
4171 * Save inquiry data.
4175 mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *data, int dlen)
4177 int indexed_lun, lun_index;
4181 dprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n",
4182 hd->ioc->name, bus_id, target_id, lun, hd));
4184 /* Is LUN supported? If so, upper 3 bits will be 0
4185 * in first byte of inquiry data.
4190 vdev = hd->Targets[target_id];
4192 lun_index = (lun >> 5); /* 32 luns per lun_index */
4193 indexed_lun = (lun % 32);
4194 vdev->luns[lun_index] |= (1 << indexed_lun);
4196 vdev->raidVolume = 0;
4198 if (hd->ioc->spi_data.isRaid & (1 << target_id)) {
4199 vdev->raidVolume = 1;
4200 ddvtprintk((KERN_INFO "RAID Volume @ id %d\n", target_id));
4204 if (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY)) {
4206 memcpy (vdev->inq_data, data, 8);
4208 memcpy (vdev->inq_data, data, dlen);
4210 vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
4212 /* If LUN 0, tape and have not done DV, set the DV flag.
4214 if (hd->is_spi && (lun == 0) && (data[0] == SCSI_TYPE_TAPE)) {
4215 ScsiCfgData *pSpi = &hd->ioc->spi_data;
4216 if (pSpi->dvStatus[target_id] & MPT_SCSICFG_DV_NOT_DONE)
4217 pSpi->dvStatus[target_id] |= MPT_SCSICFG_NEED_DV;
4220 if ( (data[0] == SCSI_TYPE_PROC) &&
4221 !(vdev->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) {
4223 vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
4224 if ( data[44] == 'S' &&
4230 vdev->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
4231 mptscsih_writeIOCPage4(hd, target_id, bus_id);
4234 /* Treat all Processors as SAF-TE if
4235 * command line option is set */
4236 if ( hd->ioc->spi_data.Saf_Te ) {
4237 vdev->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
4238 mptscsih_writeIOCPage4(hd, target_id, bus_id);
4243 data_56 = 0x0F; /* Default to full capabilities if Inq data length is < 57 */
4245 if ( (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_56))) {
4246 /* Update the target capabilities
4249 vdev->tflags |= MPT_TARGET_FLAGS_VALID_56;
4252 mptscsih_setTargetNegoParms(hd, vdev, data_56);
4255 dprintk((KERN_INFO " target = %p\n", vdev));
4259 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4261 * Update the target negotiation parameters based on the
4262 * the Inquiry data, adapter capabilities, and NVRAM settings.
4265 void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56)
4267 ScsiCfgData *pspi_data = &hd->ioc->spi_data;
4268 int id = (int) target->target_id;
4273 u8 width = MPT_NARROW;
4274 u8 factor = MPT_ASYNC;
4276 u8 version, nfactor;
4280 if (target->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) {
4281 if (target->inq_data[7] & 0x02)
4282 target->tflags |= MPT_TARGET_FLAGS_Q_YES;
4287 target->negoFlags = pspi_data->noQas;
4289 /* noQas == 0 => device supports QAS. Need byte 56 of Inq to determine
4290 * support. If available, default QAS to off and allow enabling.
4291 * If not available, default QAS to on, turn off for non-disks.
4294 /* Set flags based on Inquiry data
4296 if (target->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) {
4297 version = target->inq_data[2] & 0x07;
4300 factor = MPT_ULTRA2;
4301 offset = pspi_data->maxSyncOffset;
4303 if (target->inq_data[7] & 0x20) {
4307 if (target->inq_data[7] & 0x10) {
4308 /* bits 2 & 3 show Clocking support
4310 if ((byte56 & 0x0C) == 0)
4311 factor = MPT_ULTRA2;
4313 if ((byte56 & 0x03) == 0)
4314 factor = MPT_ULTRA160;
4316 factor = MPT_ULTRA320;
4318 offset = pspi_data->maxSyncOffset;
4320 /* If RAID, never disable QAS
4321 * else if non RAID, do not disable
4322 * QAS if bit 1 is set
4323 * bit 1 QAS support, non-raid only
4326 if ((target->raidVolume == 1) || (byte56 & 0x02)) {
4335 if (target->inq_data[7] & 0x02) {
4339 /* Update tflags based on NVRAM settings. (SCSI only)
4341 if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
4342 nvram = pspi_data->nvram[id];
4343 nfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
4346 width = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
4349 /* Ensure factor is set to the
4350 * maximum of: adapter, nvram, inquiry
4353 if (nfactor < pspi_data->minSyncFactor )
4354 nfactor = pspi_data->minSyncFactor;
4356 factor = max(factor, nfactor);
4357 if (factor == MPT_ASYNC)
4368 /* Make sure data is consistent
4370 if ((!width) && (factor < MPT_ULTRA2)) {
4371 factor = MPT_ULTRA2;
4374 /* Save the data to the target structure.
4376 target->minSyncFactor = factor;
4377 target->maxOffset = offset;
4378 target->maxWidth = width;
4380 target->tflags |= MPT_TARGET_FLAGS_Q_YES;
4383 target->tflags |= MPT_TARGET_FLAGS_VALID_NEGO;
4385 /* Disable unused features.
4388 target->negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
4391 target->negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
4393 /* GEM, processor WORKAROUND
4395 if (((target->inq_data[0] & 0x1F) == 0x03)
4396 || ((target->inq_data[0] & 0x1F) > 0x08)) {
4397 target->negoFlags |= (MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC);
4398 pspi_data->dvStatus[id] |= MPT_SCSICFG_BLK_NEGO;
4400 if (noQas && (pspi_data->noQas == 0)) {
4401 pspi_data->noQas |= MPT_TARGET_NO_NEGO_QAS;
4402 target->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
4404 /* Disable QAS in a mixed configuration case
4407 ddvtprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id));
4408 for (ii = 0; ii < id; ii++) {
4409 if ( (vdev = hd->Targets[ii]) ) {
4410 vdev->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
4416 /* Write SDP1 on this I/O to this target */
4417 if (pspi_data->dvStatus[id] & MPT_SCSICFG_NEGOTIATE) {
4418 mptscsih_writeSDP1(hd, 0, id, hd->negoNvram);
4419 pspi_data->dvStatus[id] &= ~MPT_SCSICFG_NEGOTIATE;
4420 } else if (pspi_data->dvStatus[id] & MPT_SCSICFG_BLK_NEGO) {
4421 mptscsih_writeSDP1(hd, 0, id, MPT_SCSICFG_BLK_NEGO);
4422 pspi_data->dvStatus[id] &= ~MPT_SCSICFG_BLK_NEGO;
4429 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4430 /* If DV disabled (negoNvram set to USE_NVARM) or if not LUN 0, return.
4431 * Else set the NEED_DV flag after Read Capacity Issued (disks)
4432 * or Mode Sense (cdroms).
4434 * Tapes, initTarget will set this flag on completion of Inquiry command.
4435 * Called only if DV_NOT_DONE flag is set
4437 static void mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq)
4441 if ((pReq->LUN[1] != 0) || (hd->negoNvram != 0))
4446 if ((cmd == READ_CAPACITY) || (cmd == MODE_SENSE)) {
4447 ScsiCfgData *pSpi = &hd->ioc->spi_data;
4448 if ((pSpi->isRaid & (1 << pReq->TargetID)) && pSpi->pIocPg3) {
4449 /* Set NEED_DV for all hidden disks
4451 Ioc3PhysDisk_t *pPDisk = pSpi->pIocPg3->PhysDisk;
4452 int numPDisk = pSpi->pIocPg3->NumPhysDisks;
4455 pSpi->dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV;
4456 ddvtprintk(("NEED_DV set for phys disk id %d\n", pPDisk->PhysDiskID));
4461 pSpi->dvStatus[pReq->TargetID] |= MPT_SCSICFG_NEED_DV;
4462 ddvtprintk(("NEED_DV set for visible disk id %d\n", pReq->TargetID));
4466 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4468 * If no Target, bus reset on 1st I/O. Set the flag to
4469 * prevent any future negotiations to this device.
4471 static void mptscsih_no_negotiate(MPT_SCSI_HOST *hd, int target_id)
4474 if ((hd->Targets) && (hd->Targets[target_id] == NULL))
4475 hd->ioc->spi_data.dvStatus[target_id] |= MPT_SCSICFG_BLK_NEGO;
4480 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4482 * SCSI Config Page functionality ...
4484 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4485 /* mptscsih_setDevicePage1Flags - add Requested and Configuration fields flags
4486 * based on width, factor and offset parameters.
4488 * @factor: sync factor
4489 * @offset: sync offset
4490 * @requestedPtr: pointer to requested values (updated)
4491 * @configurationPtr: pointer to configuration values (updated)
4492 * @flags: flags to block WDTR or SDTR negotiation
4496 * Remark: Called by writeSDP1 and _dv_params
4499 mptscsih_setDevicePage1Flags (u8 width, u8 factor, u8 offset, int *requestedPtr, int *configurationPtr, u8 flags)
4501 u8 nowide = flags & MPT_TARGET_NO_NEGO_WIDE;
4502 u8 nosync = flags & MPT_TARGET_NO_NEGO_SYNC;
4504 *configurationPtr = 0;
4505 *requestedPtr = width ? MPI_SCSIDEVPAGE1_RP_WIDE : 0;
4506 *requestedPtr |= (offset << 16) | (factor << 8);
4508 if (width && offset && !nowide && !nosync) {
4509 if (factor < MPT_ULTRA160) {
4510 *requestedPtr |= (MPI_SCSIDEVPAGE1_RP_IU + MPI_SCSIDEVPAGE1_RP_DT);
4511 if ((flags & MPT_TARGET_NO_NEGO_QAS) == 0)
4512 *requestedPtr |= MPI_SCSIDEVPAGE1_RP_QAS;
4513 } else if (factor < MPT_ULTRA2) {
4514 *requestedPtr |= MPI_SCSIDEVPAGE1_RP_DT;
4519 *configurationPtr |= MPI_SCSIDEVPAGE1_CONF_WDTR_DISALLOWED;
4522 *configurationPtr |= MPI_SCSIDEVPAGE1_CONF_SDTR_DISALLOWED;
4527 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4528 /* mptscsih_writeSDP1 - write SCSI Device Page 1
4529 * @hd: Pointer to a SCSI Host Strucutre
4530 * @portnum: IOC port number
4531 * @target_id: writeSDP1 for single ID
4532 * @flags: MPT_SCSICFG_ALL_IDS, MPT_SCSICFG_USE_NVRAM, MPT_SCSICFG_BLK_NEGO
4534 * Return: -EFAULT if read of config page header fails
4537 * Remark: If a target has been found, the settings from the
4538 * target structure are used, else the device is set
4541 * Remark: Called during init and after a FW reload.
4542 * Remark: We do not wait for a return, write pages sequentially.
4545 mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
4547 MPT_ADAPTER *ioc = hd->ioc;
4549 SCSIDevicePage1_t *pData;
4550 VirtDevice *pTarget;
4555 u32 requested, configuration, flagsLength;
4557 int id = 0, maxid = 0;
4563 u8 maxwidth, maxoffset, maxfactor;
4565 if (ioc->spi_data.sdp1length == 0)
4568 if (flags & MPT_SCSICFG_ALL_IDS) {
4570 maxid = ioc->sh->max_id - 1;
4571 } else if (ioc->sh) {
4573 maxid = min_t(int, id, ioc->sh->max_id - 1);
4576 for (; id <= maxid; id++) {
4578 if (id == ioc->pfacts[portnum].PortSCSIID)
4581 /* Use NVRAM to get adapter and target maximums
4582 * Data over-riden by target structure information, if present
4584 maxwidth = ioc->spi_data.maxBusWidth;
4585 maxoffset = ioc->spi_data.maxSyncOffset;
4586 maxfactor = ioc->spi_data.minSyncFactor;
4587 if (ioc->spi_data.nvram && (ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
4588 nvram = ioc->spi_data.nvram[id];
4591 maxwidth = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
4593 if (maxoffset > 0) {
4594 maxfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
4595 if (maxfactor == 0) {
4597 maxfactor = MPT_ASYNC;
4599 } else if (maxfactor < ioc->spi_data.minSyncFactor) {
4600 maxfactor = ioc->spi_data.minSyncFactor;
4603 maxfactor = MPT_ASYNC;
4606 /* Set the negotiation flags.
4608 negoFlags = ioc->spi_data.noQas;
4610 negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
4613 negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
4615 if (flags & MPT_SCSICFG_USE_NVRAM) {
4624 //negoFlags = MPT_TARGET_NO_NEGO_SYNC;
4627 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
4628 /* Force to async and narrow if DV has not been executed
4631 if ((hd->ioc->spi_data.dvStatus[id] & MPT_SCSICFG_DV_NOT_DONE) != 0) {
4638 /* If id is not a raid volume, get the updated
4639 * transmission settings from the target structure.
4641 if (hd->Targets && (pTarget = hd->Targets[id]) && !pTarget->raidVolume) {
4642 width = pTarget->maxWidth;
4643 factor = pTarget->minSyncFactor;
4644 offset = pTarget->maxOffset;
4645 negoFlags = pTarget->negoFlags;
4648 if (flags & MPT_SCSICFG_BLK_NEGO)
4649 negoFlags = MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC;
4651 mptscsih_setDevicePage1Flags(width, factor, offset,
4652 &requested, &configuration, negoFlags);
4654 /* Get a MF for this command.
4656 if ((mf = mpt_get_msg_frame(ScsiDoneCtx, ioc)) == NULL) {
4657 dprintk((MYIOC_s_WARN_FMT "write SDP1: no msg frames!\n",
4662 ddvprintk((MYIOC_s_INFO_FMT "WriteSDP1 (mf=%p, id=%d, req=0x%x, cfg=0x%x)\n",
4663 hd->ioc->name, mf, id, requested, configuration));
4666 /* Set the request and the data pointers.
4667 * Request takes: 36 bytes (32 bit SGE)
4668 * SCSI Device Page 1 requires 16 bytes
4669 * 40 + 16 <= size of SCSI IO Request = 56 bytes
4670 * and MF size >= 64 bytes.
4671 * Place data at end of MF.
4673 pReq = (Config_t *)mf;
4675 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
4676 frameOffset = ioc->req_sz - sizeof(SCSIDevicePage1_t);
4678 pData = (SCSIDevicePage1_t *)((u8 *) mf + frameOffset);
4679 dataDma = ioc->req_frames_dma + (req_idx * ioc->req_sz) + frameOffset;
4681 /* Complete the request frame (same for all requests).
4683 pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4685 pReq->ChainOffset = 0;
4686 pReq->Function = MPI_FUNCTION_CONFIG;
4687 pReq->ExtPageLength = 0;
4688 pReq->ExtPageType = 0;
4690 for (ii=0; ii < 8; ii++) {
4691 pReq->Reserved2[ii] = 0;
4693 pReq->Header.PageVersion = ioc->spi_data.sdp1version;
4694 pReq->Header.PageLength = ioc->spi_data.sdp1length;
4695 pReq->Header.PageNumber = 1;
4696 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4697 pReq->PageAddress = cpu_to_le32(id | (bus << 8 ));
4699 /* Add a SGE to the config request.
4701 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE | ioc->spi_data.sdp1length * 4;
4703 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma);
4705 /* Set up the common data portion
4707 pData->Header.PageVersion = pReq->Header.PageVersion;
4708 pData->Header.PageLength = pReq->Header.PageLength;
4709 pData->Header.PageNumber = pReq->Header.PageNumber;
4710 pData->Header.PageType = pReq->Header.PageType;
4711 pData->RequestedParameters = cpu_to_le32(requested);
4712 pData->Reserved = 0;
4713 pData->Configuration = cpu_to_le32(configuration);
4715 dprintk((MYIOC_s_INFO_FMT
4716 "write SDP1: id %d pgaddr 0x%x req 0x%x config 0x%x\n",
4717 ioc->name, id, (id | (bus<<8)),
4718 requested, configuration));
4720 mpt_put_msg_frame(ScsiDoneCtx, ioc, mf);
4726 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4727 /* mptscsih_writeIOCPage4 - write IOC Page 4
4728 * @hd: Pointer to a SCSI Host Structure
4729 * @target_id: write IOC Page4 for this ID & Bus
4731 * Return: -EAGAIN if unable to obtain a Message Frame
4734 * Remark: We do not wait for a return, write pages sequentially.
4737 mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus)
4739 MPT_ADAPTER *ioc = hd->ioc;
4741 IOCPage4_t *IOCPage4Ptr;
4749 /* Get a MF for this command.
4751 if ((mf = mpt_get_msg_frame(ScsiDoneCtx, ioc)) == NULL) {
4752 dprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n",
4757 ddvprintk((MYIOC_s_INFO_FMT "writeIOCPage4 (mf=%p, id=%d)\n",
4758 ioc->name, mf, target_id));
4760 /* Set the request and the data pointers.
4761 * Place data at end of MF.
4763 pReq = (Config_t *)mf;
4765 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
4766 frameOffset = ioc->req_sz - sizeof(IOCPage4_t);
4768 /* Complete the request frame (same for all requests).
4770 pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4772 pReq->ChainOffset = 0;
4773 pReq->Function = MPI_FUNCTION_CONFIG;
4774 pReq->ExtPageLength = 0;
4775 pReq->ExtPageType = 0;
4777 for (ii=0; ii < 8; ii++) {
4778 pReq->Reserved2[ii] = 0;
4781 IOCPage4Ptr = ioc->spi_data.pIocPg4;
4782 dataDma = ioc->spi_data.IocPg4_dma;
4783 ii = IOCPage4Ptr->ActiveSEP++;
4784 IOCPage4Ptr->SEP[ii].SEPTargetID = target_id;
4785 IOCPage4Ptr->SEP[ii].SEPBus = bus;
4786 pReq->Header = IOCPage4Ptr->Header;
4787 pReq->PageAddress = cpu_to_le32(target_id | (bus << 8 ));
4789 /* Add a SGE to the config request.
4791 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE |
4792 (IOCPage4Ptr->Header.PageLength + ii) * 4;
4794 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma);
4796 dsprintk((MYIOC_s_INFO_FMT
4797 "writeIOCPage4: pgaddr 0x%x\n",
4798 ioc->name, (target_id | (bus<<8))));
4800 mpt_put_msg_frame(ScsiDoneCtx, ioc, mf);
4805 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4806 /* mptscsih_taskmgmt_timeout - Call back for timeout on a
4807 * task management request.
4808 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
4811 static void mptscsih_taskmgmt_timeout(unsigned long data)
4813 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) data;
4815 dtmprintk((KERN_WARNING MYNAM ": %s: mptscsih_taskmgmt_timeout: "
4816 "TM request timed out!\n", hd->ioc->name));
4818 /* Delete the timer that triggered this callback.
4819 * Remark: del_timer checks to make sure timer is active
4822 del_timer(&hd->TMtimer);
4824 /* Call the reset handler. Already had a TM request
4825 * timeout - so issue a diagnostic reset
4827 INIT_WORK(&mptscsih_rstTask, mptscsih_schedule_reset, (void *)hd);
4828 schedule_work(&mptscsih_rstTask);
4832 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4833 /* mptscsih_schedule_reset - Call back for timeout on a
4834 * task management request.
4835 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
4839 mptscsih_schedule_reset(void *arg)
4842 hd = (MPT_SCSI_HOST *) arg;
4844 if (mpt_HardResetHandler(hd->ioc, CAN_SLEEP) < 0) {
4845 printk((KERN_WARNING " Firmware Reload FAILED!!\n"));
4847 /* Because we have reset the IOC, no TM requests can be
4848 * pending. So let's make sure the tmPending flag is reset.
4850 dtmprintk((KERN_WARNING MYNAM
4851 ": %s: mptscsih_taskmgmt_timeout\n",
4859 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4861 * Bus Scan and Domain Validation functionality ...
4864 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4866 * mptscsih_scandv_complete - Scan and DV callback routine registered
4867 * to Fustion MPT (base) driver.
4869 * @ioc: Pointer to MPT_ADAPTER structure
4870 * @mf: Pointer to original MPT request frame
4871 * @mr: Pointer to MPT reply frame (NULL if TurboReply)
4873 * This routine is called from mpt.c::mpt_interrupt() at the completion
4874 * of any SCSI IO request.
4875 * This routine is registered with the Fusion MPT (base) driver at driver
4876 * load/init time via the mpt_register() API call.
4878 * Returns 1 indicating alloc'd request frame ptr should be freed.
4880 * Remark: Sets a completion code and (possibly) saves sense data
4881 * in the IOC member localReply structure.
4882 * Used ONLY for DV and other internal commands.
4885 mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
4888 SCSIIORequest_t *pReq;
4893 (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) {
4894 printk(MYIOC_s_ERR_FMT
4895 "ScanDvComplete, %s req frame ptr! (=%p)\n",
4896 ioc->name, mf?"BAD":"NULL", (void *) mf);
4900 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
4901 del_timer(&hd->timer);
4902 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
4903 hd->ScsiLookup[req_idx] = NULL;
4904 pReq = (SCSIIORequest_t *) mf;
4906 if (mf != hd->cmdPtr) {
4907 printk(MYIOC_s_WARN_FMT "ScanDvComplete (mf=%p, cmdPtr=%p, idx=%d)\n",
4908 hd->ioc->name, (void *)mf, (void *) hd->cmdPtr, req_idx);
4912 ddvprintk((MYIOC_s_INFO_FMT "ScanDvComplete (mf=%p,mr=%p,idx=%d)\n",
4913 hd->ioc->name, mf, mr, req_idx));
4915 hd->pLocal = &hd->localReply;
4916 hd->pLocal->scsiStatus = 0;
4918 /* If target struct exists, clear sense valid flag.
4921 completionCode = MPT_SCANDV_GOOD;
4923 SCSIIOReply_t *pReply;
4926 pReply = (SCSIIOReply_t *) mr;
4928 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
4930 ddvtprintk((KERN_NOTICE " IOCStatus=%04xh, SCSIState=%02xh, SCSIStatus=%02xh, IOCLogInfo=%08xh\n",
4931 status, pReply->SCSIState, pReply->SCSIStatus,
4932 le32_to_cpu(pReply->IOCLogInfo)));
4936 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
4937 completionCode = MPT_SCANDV_SELECTION_TIMEOUT;
4940 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
4941 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
4942 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
4943 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
4944 completionCode = MPT_SCANDV_DID_RESET;
4947 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
4948 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
4949 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
4950 if (pReply->Function == MPI_FUNCTION_CONFIG) {
4951 ConfigReply_t *pr = (ConfigReply_t *)mr;
4952 completionCode = MPT_SCANDV_GOOD;
4953 hd->pLocal->header.PageVersion = pr->Header.PageVersion;
4954 hd->pLocal->header.PageLength = pr->Header.PageLength;
4955 hd->pLocal->header.PageNumber = pr->Header.PageNumber;
4956 hd->pLocal->header.PageType = pr->Header.PageType;
4958 } else if (pReply->Function == MPI_FUNCTION_RAID_ACTION) {
4959 /* If the RAID Volume request is successful,
4960 * return GOOD, else indicate that
4961 * some type of error occurred.
4963 MpiRaidActionReply_t *pr = (MpiRaidActionReply_t *)mr;
4964 if (pr->ActionStatus == MPI_RAID_ACTION_ASTATUS_SUCCESS)
4965 completionCode = MPT_SCANDV_GOOD;
4967 completionCode = MPT_SCANDV_SOME_ERROR;
4969 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID) {
4973 /* save sense data in global structure
4975 completionCode = MPT_SCANDV_SENSE;
4976 hd->pLocal->scsiStatus = pReply->SCSIStatus;
4977 sense_data = ((u8 *)hd->ioc->sense_buf_pool +
4978 (req_idx * MPT_SENSE_BUFFER_ALLOC));
4980 sz = min_t(int, pReq->SenseBufferLength,
4981 SCSI_STD_SENSE_BYTES);
4982 memcpy(hd->pLocal->sense, sense_data, sz);
4984 ddvprintk((KERN_NOTICE " Check Condition, sense ptr %p\n",
4986 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_FAILED) {
4987 if (pReq->CDB[0] == CMD_Inquiry)
4988 completionCode = MPT_SCANDV_ISSUE_SENSE;
4990 completionCode = MPT_SCANDV_DID_RESET;
4992 else if (pReply->SCSIState & MPI_SCSI_STATE_NO_SCSI_STATUS)
4993 completionCode = MPT_SCANDV_DID_RESET;
4994 else if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
4995 completionCode = MPT_SCANDV_DID_RESET;
4997 /* If no error, this will be equivalent
4998 * to MPT_SCANDV_GOOD
5000 completionCode = MPT_SCANDV_GOOD;
5001 hd->pLocal->scsiStatus = pReply->SCSIStatus;
5005 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
5006 if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
5007 completionCode = MPT_SCANDV_DID_RESET;
5009 completionCode = MPT_SCANDV_SOME_ERROR;
5013 completionCode = MPT_SCANDV_SOME_ERROR;
5016 } /* switch(status) */
5018 ddvtprintk((KERN_NOTICE " completionCode set to %08xh\n",
5020 } /* end of address reply case */
5022 hd->pLocal->completion = completionCode;
5024 /* MF and RF are freed in mpt_interrupt
5027 /* Free Chain buffers (will never chain) in scan or dv */
5028 //mptscsih_freeChainBuffers(hd, req_idx);
5031 * Wake up the original calling thread
5033 scandv_wait_done = 1;
5034 wake_up(&scandv_waitq);
5039 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5040 /* mptscsih_timer_expired - Call back for timer process.
5041 * Used only for dv functionality.
5042 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
5045 static void mptscsih_timer_expired(unsigned long data)
5047 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) data;
5049 ddvprintk((MYIOC_s_WARN_FMT "Timer Expired! Cmd %p\n", hd->ioc->name, hd->cmdPtr));
5052 MPIHeader_t *cmd = (MPIHeader_t *)hd->cmdPtr;
5054 if (cmd->Function == MPI_FUNCTION_SCSI_IO_REQUEST) {
5055 /* Desire to issue a task management request here.
5056 * TM requests MUST be single threaded.
5057 * If old eh code and no TM current, issue request.
5058 * If new eh code, do nothing. Wait for OS cmd timeout
5061 ddvtprintk((MYIOC_s_NOTE_FMT "DV Cmd Timeout: NoOp\n", hd->ioc->name));
5063 /* Perform a FW reload */
5064 if (mpt_HardResetHandler(hd->ioc, NO_SLEEP) < 0) {
5065 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", hd->ioc->name);
5069 /* This should NEVER happen */
5070 printk(MYIOC_s_WARN_FMT "Null cmdPtr!!!!\n", hd->ioc->name);
5073 /* No more processing.
5074 * TM call will generate an interrupt for SCSI TM Management.
5075 * The FW will reply to all outstanding commands, callback will finish cleanup.
5076 * Hard reset clean-up will free all resources.
5078 ddvprintk((MYIOC_s_WARN_FMT "Timer Expired Complete!\n", hd->ioc->name));
5083 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
5084 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5085 /* mptscsih_do_raid - Format and Issue a RAID volume request message.
5086 * @hd: Pointer to scsi host structure
5087 * @action: What do be done.
5088 * @id: Logical target id.
5089 * @bus: Target locations bus.
5091 * Returns: < 0 on a fatal error
5094 * Remark: Wait to return until reply processed by the ISR.
5097 mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io)
5099 MpiRaidActionRequest_t *pReq;
5103 in_isr = in_interrupt();
5105 dprintk((MYIOC_s_WARN_FMT "Internal raid request not allowed in ISR context!\n",
5110 /* Get and Populate a free Frame
5112 if ((mf = mpt_get_msg_frame(ScsiScanDvCtx, hd->ioc)) == NULL) {
5113 ddvprintk((MYIOC_s_WARN_FMT "_do_raid: no msg frames!\n",
5117 pReq = (MpiRaidActionRequest_t *)mf;
5118 pReq->Action = action;
5119 pReq->Reserved1 = 0;
5120 pReq->ChainOffset = 0;
5121 pReq->Function = MPI_FUNCTION_RAID_ACTION;
5122 pReq->VolumeID = io->id;
5123 pReq->VolumeBus = io->bus;
5124 pReq->PhysDiskNum = io->physDiskNum;
5126 pReq->Reserved2 = 0;
5127 pReq->ActionDataWord = 0; /* Reserved for this action */
5128 //pReq->ActionDataSGE = 0;
5130 mpt_add_sge((char *)&pReq->ActionDataSGE,
5131 MPT_SGE_FLAGS_SSIMPLE_READ | 0, (dma_addr_t) -1);
5133 ddvprintk((MYIOC_s_INFO_FMT "RAID Volume action %x id %d\n",
5134 hd->ioc->name, action, io->id));
5137 hd->timer.expires = jiffies + HZ*10; /* 10 second timeout */
5138 scandv_wait_done = 0;
5140 /* Save cmd pointer, for resource free if timeout or
5145 add_timer(&hd->timer);
5146 mpt_put_msg_frame(ScsiScanDvCtx, hd->ioc, mf);
5147 wait_event(scandv_waitq, scandv_wait_done);
5149 if ((hd->pLocal == NULL) || (hd->pLocal->completion != MPT_SCANDV_GOOD))
5154 #endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */
5156 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5158 * mptscsih_do_cmd - Do internal command.
5159 * @hd: MPT_SCSI_HOST pointer
5160 * @io: INTERNAL_CMD pointer.
5162 * Issue the specified internally generated command and do command
5163 * specific cleanup. For bus scan / DV only.
5164 * NOTES: If command is Inquiry and status is good,
5165 * initialize a target structure, save the data
5167 * Remark: Single threaded access only.
5170 * < 0 if an illegal command or no resources
5174 * > 0 if command complete but some type of completion error.
5177 mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
5180 SCSIIORequest_t *pScsiReq;
5181 SCSIIORequest_t ReqCopy;
5182 int my_idx, ii, dir;
5186 char CDB[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
5189 in_isr = in_interrupt();
5191 dprintk((MYIOC_s_WARN_FMT "Internal SCSI IO request not allowed in ISR context!\n",
5197 /* Set command specific information
5202 dir = MPI_SCSIIO_CONTROL_READ;
5208 case CMD_TestUnitReady:
5210 dir = MPI_SCSIIO_CONTROL_READ;
5214 case CMD_StartStopUnit:
5216 dir = MPI_SCSIIO_CONTROL_READ;
5218 CDB[4] = 1; /*Spin up the disk */
5222 case CMD_RequestSense:
5226 dir = MPI_SCSIIO_CONTROL_READ;
5230 case CMD_ReadBuffer:
5232 dir = MPI_SCSIIO_CONTROL_READ;
5234 if (io->flags & MPT_ICFLAG_ECHO) {
5240 if (io->flags & MPT_ICFLAG_BUF_CAP) {
5243 CDB[6] = (io->size >> 16) & 0xFF;
5244 CDB[7] = (io->size >> 8) & 0xFF;
5245 CDB[8] = io->size & 0xFF;
5249 case CMD_WriteBuffer:
5251 dir = MPI_SCSIIO_CONTROL_WRITE;
5253 if (io->flags & MPT_ICFLAG_ECHO) {
5258 CDB[6] = (io->size >> 16) & 0xFF;
5259 CDB[7] = (io->size >> 8) & 0xFF;
5260 CDB[8] = io->size & 0xFF;
5266 dir = MPI_SCSIIO_CONTROL_READ;
5273 dir = MPI_SCSIIO_CONTROL_READ;
5278 case CMD_SynchronizeCache:
5280 dir = MPI_SCSIIO_CONTROL_READ;
5282 // CDB[1] = 0x02; /* set immediate bit */
5291 /* Get and Populate a free Frame
5293 if ((mf = mpt_get_msg_frame(ScsiScanDvCtx, hd->ioc)) == NULL) {
5294 ddvprintk((MYIOC_s_WARN_FMT "No msg frames!\n",
5299 pScsiReq = (SCSIIORequest_t *) mf;
5301 /* Get the request index */
5302 my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
5303 ADD_INDEX_LOG(my_idx); /* for debug */
5305 if (io->flags & MPT_ICFLAG_PHYS_DISK) {
5306 pScsiReq->TargetID = io->physDiskNum;
5308 pScsiReq->ChainOffset = 0;
5309 pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
5311 pScsiReq->TargetID = io->id;
5312 pScsiReq->Bus = io->bus;
5313 pScsiReq->ChainOffset = 0;
5314 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
5317 pScsiReq->CDBLength = cmdLen;
5318 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
5320 pScsiReq->Reserved = 0;
5322 pScsiReq->MsgFlags = mpt_msg_flags();
5323 /* MsgContext set in mpt_get_msg_fram call */
5325 for (ii=0; ii < 8; ii++)
5326 pScsiReq->LUN[ii] = 0;
5327 pScsiReq->LUN[1] = io->lun;
5329 if (io->flags & MPT_ICFLAG_TAGGED_CMD)
5330 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ);
5332 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
5334 if (cmd == CMD_RequestSense) {
5335 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
5336 ddvprintk((MYIOC_s_INFO_FMT "Untagged! 0x%2x\n",
5337 hd->ioc->name, cmd));
5340 for (ii=0; ii < 16; ii++)
5341 pScsiReq->CDB[ii] = CDB[ii];
5343 pScsiReq->DataLength = cpu_to_le32(io->size);
5344 pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
5345 + (my_idx * MPT_SENSE_BUFFER_ALLOC));
5347 ddvprintk((MYIOC_s_INFO_FMT "Sending Command 0x%x for (%d:%d:%d)\n",
5348 hd->ioc->name, cmd, io->bus, io->id, io->lun));
5350 if (dir == MPI_SCSIIO_CONTROL_READ) {
5351 mpt_add_sge((char *) &pScsiReq->SGL,
5352 MPT_SGE_FLAGS_SSIMPLE_READ | io->size,
5355 mpt_add_sge((char *) &pScsiReq->SGL,
5356 MPT_SGE_FLAGS_SSIMPLE_WRITE | io->size,
5360 /* The ISR will free the request frame, but we need
5361 * the information to initialize the target. Duplicate.
5363 memcpy(&ReqCopy, pScsiReq, sizeof(SCSIIORequest_t));
5365 /* Issue this command after:
5368 * Wait until the reply has been received
5369 * ScsiScanDvCtx callback function will
5371 * set scandv_wait_done and call wake_up
5374 hd->timer.expires = jiffies + HZ*cmdTimeout;
5375 scandv_wait_done = 0;
5377 /* Save cmd pointer, for resource free if timeout or
5382 add_timer(&hd->timer);
5383 mpt_put_msg_frame(ScsiScanDvCtx, hd->ioc, mf);
5384 wait_event(scandv_waitq, scandv_wait_done);
5387 rc = hd->pLocal->completion;
5388 hd->pLocal->skip = 0;
5390 /* Always set fatal error codes in some cases.
5392 if (rc == MPT_SCANDV_SELECTION_TIMEOUT)
5394 else if (rc == MPT_SCANDV_SOME_ERROR)
5398 /* This should never happen. */
5399 ddvprintk((MYIOC_s_INFO_FMT "_do_cmd: Null pLocal!!!\n",
5406 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5408 * mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
5409 * @hd: Pointer to MPT_SCSI_HOST structure
5410 * @portnum: IOC port number
5412 * Uses the ISR, but with special processing.
5413 * MUST be single-threaded.
5415 * Return: 0 on completion
5418 mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum)
5420 MPT_ADAPTER *ioc= hd->ioc;
5421 VirtDevice *pTarget;
5422 SCSIDevicePage1_t *pcfg1Data = NULL;
5425 dma_addr_t cfg1_dma_addr = -1;
5426 ConfigPageHeader_t header1;
5430 int indexed_lun, lun_index;
5431 int hostId = ioc->pfacts[portnum].PortSCSIID;
5433 int requested, configuration, data;
5437 max_id = ioc->sh->max_id - 1;
5439 /* Following parameters will not change
5442 iocmd.cmd = CMD_SynchronizeCache;
5444 iocmd.physDiskNum = -1;
5446 iocmd.data_dma = -1;
5448 iocmd.rsvd = iocmd.rsvd2 = 0;
5452 if (hd->Targets == NULL)
5460 /* Write SDP1 for all SCSI devices
5461 * Alloc memory and set up config buffer
5464 if (ioc->spi_data.sdp1length > 0) {
5465 pcfg1Data = (SCSIDevicePage1_t *)pci_alloc_consistent(ioc->pcidev,
5466 ioc->spi_data.sdp1length * 4, &cfg1_dma_addr);
5468 if (pcfg1Data != NULL) {
5470 header1.PageVersion = ioc->spi_data.sdp1version;
5471 header1.PageLength = ioc->spi_data.sdp1length;
5472 header1.PageNumber = 1;
5473 header1.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5475 cfg.physAddr = cfg1_dma_addr;
5476 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5483 /* loop through all devices on this port
5485 while (bus < MPT_MAX_BUS) {
5488 pTarget = hd->Targets[(int)id];
5492 /* Set the negotiation flags */
5493 if (pTarget && (pTarget = hd->Targets[id]) && !pTarget->raidVolume) {
5494 flags = pTarget->negoFlags;
5496 flags = hd->ioc->spi_data.noQas;
5497 if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
5498 data = hd->ioc->spi_data.nvram[id];
5500 if (data & MPT_NVRAM_WIDE_DISABLE)
5501 flags |= MPT_TARGET_NO_NEGO_WIDE;
5503 factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT;
5504 if ((factor == 0) || (factor == MPT_ASYNC))
5505 flags |= MPT_TARGET_NO_NEGO_SYNC;
5509 /* Force to async, narrow */
5510 mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested,
5511 &configuration, flags);
5512 pcfg1Data->RequestedParameters = le32_to_cpu(requested);
5513 pcfg1Data->Reserved = 0;
5514 pcfg1Data->Configuration = le32_to_cpu(configuration);
5515 cfg.pageAddr = (bus<<8) | id;
5516 mpt_config(hd->ioc, &cfg);
5519 /* If target Ptr NULL or if this target is NOT a disk, skip.
5521 if ((pTarget) && (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)){
5522 for (lun=0; lun <= MPT_LAST_LUN; lun++) {
5523 /* If LUN present, issue the command
5525 lun_index = (lun >> 5); /* 32 luns per lun_index */
5526 indexed_lun = (lun % 32);
5527 if (pTarget->luns[lun_index] & (1<<indexed_lun)) {
5529 (void) mptscsih_do_cmd(hd, &iocmd);
5534 /* get next relevant device */
5547 pci_free_consistent(ioc->pcidev, header1.PageLength * 4, pcfg1Data, cfg1_dma_addr);
5553 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
5554 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5556 * mptscsih_domainValidation - Top level handler for domain validation.
5557 * @hd: Pointer to MPT_SCSI_HOST structure.
5559 * Uses the ISR, but with special processing.
5560 * Called from schedule, should not be in interrupt mode.
5561 * While thread alive, do dv for all devices needing dv
5566 mptscsih_domainValidation(void *arg)
5570 unsigned long flags;
5571 int id, maxid, dvStatus, did;
5574 spin_lock_irqsave(&dvtaskQ_lock, flags);
5576 if (dvtaskQ_release) {
5578 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
5581 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
5583 /* For this ioc, loop through all devices and do dv to each device.
5584 * When complete with this ioc, search through the ioc list, and
5585 * for each scsi ioc found, do dv for all devices. Exit when no
5591 list_for_each_entry(ioc, &ioc_list, list) {
5592 spin_lock_irqsave(&dvtaskQ_lock, flags);
5593 if (dvtaskQ_release) {
5595 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
5598 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
5600 set_current_state(TASK_INTERRUPTIBLE);
5601 schedule_timeout(HZ/4);
5603 /* DV only to SCSI adapters */
5604 if ((int)ioc->chip_type <= (int)FC929)
5607 /* Make sure everything looks ok */
5608 if (ioc->sh == NULL)
5611 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
5615 if ((ioc->spi_data.forceDv & MPT_SCSICFG_RELOAD_IOC_PG3) != 0) {
5616 mpt_read_ioc_pg_3(ioc);
5617 if (ioc->spi_data.pIocPg3) {
5618 Ioc3PhysDisk_t *pPDisk = ioc->spi_data.pIocPg3->PhysDisk;
5619 int numPDisk = ioc->spi_data.pIocPg3->NumPhysDisks;
5622 if (ioc->spi_data.dvStatus[pPDisk->PhysDiskID] & MPT_SCSICFG_DV_NOT_DONE)
5623 ioc->spi_data.dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV;
5629 ioc->spi_data.forceDv &= ~MPT_SCSICFG_RELOAD_IOC_PG3;
5632 maxid = min_t(int, ioc->sh->max_id, MPT_MAX_SCSI_DEVICES);
5634 for (id = 0; id < maxid; id++) {
5635 spin_lock_irqsave(&dvtaskQ_lock, flags);
5636 if (dvtaskQ_release) {
5638 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
5641 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
5642 dvStatus = hd->ioc->spi_data.dvStatus[id];
5644 if (dvStatus & MPT_SCSICFG_NEED_DV) {
5646 hd->ioc->spi_data.dvStatus[id] |= MPT_SCSICFG_DV_PENDING;
5647 hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_NEED_DV;
5649 set_current_state(TASK_INTERRUPTIBLE);
5650 schedule_timeout(HZ/4);
5652 /* If hidden phys disk, block IO's to all
5654 * else, process normally
5656 isPhysDisk = mptscsih_is_phys_disk(ioc, id);
5658 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5659 if (hd->ioc->spi_data.isRaid & (1 << ii)) {
5660 hd->ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_DV_PENDING;
5665 if (mptscsih_doDv(hd, 0, id) == 1) {
5666 /* Untagged device was busy, try again
5668 hd->ioc->spi_data.dvStatus[id] |= MPT_SCSICFG_NEED_DV;
5669 hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_PENDING;
5671 /* DV is complete. Clear flags.
5673 hd->ioc->spi_data.dvStatus[id] &= ~(MPT_SCSICFG_DV_NOT_DONE | MPT_SCSICFG_DV_PENDING);
5677 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5678 if (hd->ioc->spi_data.isRaid & (1 << ii)) {
5679 hd->ioc->spi_data.dvStatus[ii] &= ~MPT_SCSICFG_DV_PENDING;
5684 /* Post OS IOs that were pended while
5687 post_pendingQ_commands(hd);
5689 if (hd->ioc->spi_data.noQas)
5690 mptscsih_qas_check(hd, id);
5696 spin_lock_irqsave(&dvtaskQ_lock, flags);
5698 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
5703 /* Search IOC page 3 to determine if this is hidden physical disk
5705 static int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id)
5707 if (ioc->spi_data.pIocPg3) {
5708 Ioc3PhysDisk_t *pPDisk = ioc->spi_data.pIocPg3->PhysDisk;
5709 int numPDisk = ioc->spi_data.pIocPg3->NumPhysDisks;
5712 if (pPDisk->PhysDiskID == id) {
5722 /* Write SDP1 if no QAS has been enabled
5724 static void mptscsih_qas_check(MPT_SCSI_HOST *hd, int id)
5726 VirtDevice *pTarget;
5729 if (hd->Targets == NULL)
5732 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5736 if ((hd->ioc->spi_data.dvStatus[ii] & MPT_SCSICFG_DV_NOT_DONE) != 0)
5739 pTarget = hd->Targets[ii];
5741 if ((pTarget != NULL) && (!pTarget->raidVolume)) {
5742 if ((pTarget->negoFlags & hd->ioc->spi_data.noQas) == 0) {
5743 pTarget->negoFlags |= hd->ioc->spi_data.noQas;
5744 mptscsih_writeSDP1(hd, 0, ii, 0);
5747 if (mptscsih_is_phys_disk(hd->ioc, ii) == 1)
5748 mptscsih_writeSDP1(hd, 0, ii, MPT_SCSICFG_USE_NVRAM);
5756 #define MPT_GET_NVRAM_VALS 0x01
5757 #define MPT_UPDATE_MAX 0x02
5758 #define MPT_SET_MAX 0x04
5759 #define MPT_SET_MIN 0x08
5760 #define MPT_FALLBACK 0x10
5761 #define MPT_SAVE 0x20
5763 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5765 * mptscsih_doDv - Perform domain validation to a target.
5766 * @hd: Pointer to MPT_SCSI_HOST structure.
5767 * @portnum: IOC port number.
5768 * @target: Physical ID of this target
5770 * Uses the ISR, but with special processing.
5771 * MUST be single-threaded.
5772 * Test will exit if target is at async & narrow.
5777 mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
5779 MPT_ADAPTER *ioc = hd->ioc;
5780 VirtDevice *pTarget;
5781 SCSIDevicePage1_t *pcfg1Data;
5782 SCSIDevicePage0_t *pcfg0Data;
5786 dma_addr_t dvbuf_dma = -1;
5787 dma_addr_t buf1_dma = -1;
5788 dma_addr_t buf2_dma = -1;
5789 dma_addr_t cfg1_dma_addr = -1;
5790 dma_addr_t cfg0_dma_addr = -1;
5791 ConfigPageHeader_t header1;
5792 ConfigPageHeader_t header0;
5799 int dataBufSize = 0;
5800 int echoBufSize = 0;
5805 int nfactor = MPT_ULTRA320;
5807 char doFallback = 0;
5812 if (ioc->spi_data.sdp1length == 0)
5815 if (ioc->spi_data.sdp0length == 0)
5818 /* If multiple buses are used, require that the initiator
5819 * id be the same on all buses.
5821 if (id == ioc->pfacts[0].PortSCSIID)
5825 bus = (u8) bus_number;
5826 ddvtprintk((MYIOC_s_NOTE_FMT
5827 "DV started: bus=%d, id %d dv @ %p\n",
5828 ioc->name, bus, id, &dv));
5830 /* Prep DV structure
5832 memset (&dv, 0, sizeof(DVPARAMETERS));
5835 /* Populate tmax with the current maximum
5836 * transfer parameters for this target.
5837 * Exit if narrow and async.
5839 dv.cmd = MPT_GET_NVRAM_VALS;
5840 mptscsih_dv_parms(hd, &dv, NULL);
5841 if ((!dv.max.width) && (!dv.max.offset))
5844 /* Prep SCSI IO structure
5850 iocmd.physDiskNum = -1;
5851 iocmd.rsvd = iocmd.rsvd2 = 0;
5853 pTarget = hd->Targets[id];
5854 if (pTarget && (pTarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY)) {
5855 /* Another GEM workaround. Check peripheral device type,
5856 * if PROCESSOR, quit DV.
5858 if (((pTarget->inq_data[0] & 0x1F) == 0x03) || ((pTarget->inq_data[0] & 0x1F) > 0x08)) {
5859 pTarget->negoFlags |= (MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC);
5864 /* Use tagged commands if possible.
5867 if (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)
5868 iocmd.flags |= MPT_ICFLAG_TAGGED_CMD;
5870 if (hd->ioc->facts.FWVersion.Word < 0x01000600)
5873 if ((hd->ioc->facts.FWVersion.Word >= 0x01010000) &&
5874 (hd->ioc->facts.FWVersion.Word < 0x01010B00))
5879 /* Prep cfg structure
5881 cfg.pageAddr = (bus<<8) | id;
5886 header0.PageVersion = ioc->spi_data.sdp0version;
5887 header0.PageLength = ioc->spi_data.sdp0length;
5888 header0.PageNumber = 0;
5889 header0.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5893 header1.PageVersion = ioc->spi_data.sdp1version;
5894 header1.PageLength = ioc->spi_data.sdp1length;
5895 header1.PageNumber = 1;
5896 header1.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5898 if (header0.PageLength & 1)
5899 dv_alloc = (header0.PageLength * 4) + 4;
5901 dv_alloc += (2048 + (header1.PageLength * 4));
5903 pDvBuf = pci_alloc_consistent(ioc->pcidev, dv_alloc, &dvbuf_dma);
5908 pbuf1 = (u8 *)pDvBuf;
5909 buf1_dma = dvbuf_dma;
5912 pbuf2 = (u8 *) (pDvBuf + sz);
5913 buf2_dma = dvbuf_dma + sz;
5916 pcfg0Data = (SCSIDevicePage0_t *) (pDvBuf + sz);
5917 cfg0_dma_addr = dvbuf_dma + sz;
5918 sz += header0.PageLength * 4;
5922 if (header0.PageLength & 1)
5925 pcfg1Data = (SCSIDevicePage1_t *) (pDvBuf + sz);
5926 cfg1_dma_addr = dvbuf_dma + sz;
5928 /* Skip this ID? Set cfg.hdr to force config page write
5931 ScsiCfgData *pspi_data = &hd->ioc->spi_data;
5932 if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
5933 /* Set the factor from nvram */
5934 nfactor = (pspi_data->nvram[id] & MPT_NVRAM_SYNC_MASK) >> 8;
5935 if (nfactor < pspi_data->minSyncFactor )
5936 nfactor = pspi_data->minSyncFactor;
5938 if (!(pspi_data->nvram[id] & MPT_NVRAM_ID_SCAN_ENABLE) ||
5939 (pspi_data->PortFlags == MPI_SCSIPORTPAGE2_PORT_FLAGS_OFF_DV) ) {
5941 ddvprintk((MYIOC_s_NOTE_FMT "DV Skipped: bus, id, lun (%d, %d, %d)\n",
5942 ioc->name, bus, id, lun));
5944 dv.cmd = MPT_SET_MAX;
5945 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5948 /* Save the final negotiated settings to
5949 * SCSI device page 1.
5951 cfg.physAddr = cfg1_dma_addr;
5952 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5954 mpt_config(hd->ioc, &cfg);
5960 /* Finish iocmd inititialization - hidden or visible disk? */
5961 if (ioc->spi_data.pIocPg3) {
5962 /* Searc IOC page 3 for matching id
5964 Ioc3PhysDisk_t *pPDisk = ioc->spi_data.pIocPg3->PhysDisk;
5965 int numPDisk = ioc->spi_data.pIocPg3->NumPhysDisks;
5968 if (pPDisk->PhysDiskID == id) {
5970 iocmd.flags |= MPT_ICFLAG_PHYS_DISK;
5971 iocmd.physDiskNum = pPDisk->PhysDiskNum;
5975 if (mptscsih_do_raid(hd, MPI_RAID_ACTION_QUIESCE_PHYS_IO, &iocmd) < 0) {
5976 ddvprintk((MYIOC_s_ERR_FMT "RAID Queisce FAILED!\n", ioc->name));
5986 /* RAID Volume ID's may double for a physical device. If RAID but
5987 * not a physical ID as well, skip DV.
5989 if ((hd->ioc->spi_data.isRaid & (1 << id)) && !(iocmd.flags & MPT_ICFLAG_PHYS_DISK))
5994 * Async & Narrow - Inquiry
5995 * Async & Narrow - Inquiry
5996 * Maximum transfer rate - Inquiry
5998 * If compare, test complete.
5999 * If miscompare and first pass, repeat
6000 * If miscompare and not first pass, fall back and repeat
6004 sz = SCSI_STD_INQUIRY_BYTES;
6005 rc = MPT_SCANDV_GOOD;
6007 ddvprintk((MYIOC_s_NOTE_FMT "DV: Start Basic test on id=%d\n", ioc->name, id));
6009 dv.cmd = MPT_SET_MIN;
6010 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
6013 cfg.physAddr = cfg1_dma_addr;
6014 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
6016 if (mpt_config(hd->ioc, &cfg) != 0)
6019 /* Wide - narrow - wide workaround case
6021 if ((rc == MPT_SCANDV_ISSUE_SENSE) && dv.max.width) {
6022 /* Send an untagged command to reset disk Qs corrupted
6023 * when a parity error occurs on a Request Sense.
6025 if ((hd->ioc->facts.FWVersion.Word >= 0x01000600) ||
6026 ((hd->ioc->facts.FWVersion.Word >= 0x01010000) &&
6027 (hd->ioc->facts.FWVersion.Word < 0x01010B00)) ) {
6029 iocmd.cmd = CMD_RequestSense;
6030 iocmd.data_dma = buf1_dma;
6033 if (mptscsih_do_cmd(hd, &iocmd) < 0)
6036 if (hd->pLocal == NULL)
6038 rc = hd->pLocal->completion;
6039 if ((rc == MPT_SCANDV_GOOD) || (rc == MPT_SCANDV_SENSE)) {
6049 iocmd.cmd = CMD_Inquiry;
6050 iocmd.data_dma = buf1_dma;
6053 if (mptscsih_do_cmd(hd, &iocmd) < 0)
6056 if (hd->pLocal == NULL)
6058 rc = hd->pLocal->completion;
6059 if (rc == MPT_SCANDV_GOOD) {
6060 if (hd->pLocal->scsiStatus == STS_BUSY) {
6061 if ((iocmd.flags & MPT_ICFLAG_TAGGED_CMD) == 0)
6068 } else if (rc == MPT_SCANDV_SENSE) {
6071 /* If first command doesn't complete
6072 * with a good status or with a check condition,
6079 /* Reset the size for disks
6081 inq0 = (*pbuf1) & 0x1F;
6082 if ((inq0 == 0) && pTarget && !pTarget->raidVolume) {
6087 /* Another GEM workaround. Check peripheral device type,
6088 * if PROCESSOR, quit DV.
6090 if (((pbuf1[0] & 0x1F) == 0x03) || ((pbuf1[0] & 0x1F) > 0x08))
6093 if (mptscsih_do_cmd(hd, &iocmd) < 0)
6097 if ((pTarget->maxWidth == 1) && (pTarget->maxOffset) && (nfactor < 0x0A)
6098 && (pTarget->minSyncFactor > 0x09)) {
6099 if ((pbuf1[56] & 0x04) == 0)
6101 else if ((pbuf1[56] & 0x01) == 1) {
6102 pTarget->minSyncFactor =
6103 nfactor > MPT_ULTRA320 ? nfactor : MPT_ULTRA320;
6105 pTarget->minSyncFactor =
6106 nfactor > MPT_ULTRA160 ? nfactor : MPT_ULTRA160;
6109 dv.max.factor = pTarget->minSyncFactor;
6111 if ((pbuf1[56] & 0x02) == 0) {
6112 pTarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
6113 hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS;
6119 dv.cmd = MPT_FALLBACK;
6121 dv.cmd = MPT_SET_MAX;
6123 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
6124 if (mpt_config(hd->ioc, &cfg) != 0)
6127 if ((!dv.now.width) && (!dv.now.offset))
6130 iocmd.cmd = CMD_Inquiry;
6131 iocmd.data_dma = buf2_dma;
6134 if (mptscsih_do_cmd(hd, &iocmd) < 0)
6136 else if (hd->pLocal == NULL)
6139 /* Save the return code.
6140 * If this is the first pass,
6141 * read SCSI Device Page 0
6142 * and update the target max parameters.
6144 rc = hd->pLocal->completion;
6146 if (rc == MPT_SCANDV_GOOD) {
6152 cfg.physAddr = cfg0_dma_addr;
6153 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
6156 if (mpt_config(hd->ioc, &cfg) != 0)
6159 sdp0_info = le32_to_cpu(pcfg0Data->Information) & 0x0E;
6160 sdp0_nego = (le32_to_cpu(pcfg0Data->NegotiatedParameters) & 0xFF00 ) >> 8;
6162 /* Quantum and Fujitsu workarounds.
6163 * Quantum: PPR U320 -> PPR reply with Ultra2 and wide
6164 * Fujitsu: PPR U320 -> Msg Reject and Ultra2 and wide
6165 * Resetart with a request for U160.
6167 if ((dv.now.factor == MPT_ULTRA320) && (sdp0_nego == MPT_ULTRA2)) {
6170 dv.cmd = MPT_UPDATE_MAX;
6171 mptscsih_dv_parms(hd, &dv, (void *)pcfg0Data);
6172 /* Update the SCSI device page 1 area
6174 pcfg1Data->RequestedParameters = pcfg0Data->NegotiatedParameters;
6179 /* Quantum workaround. Restart this test will the fallback
6182 if (doFallback == 0) {
6183 if (memcmp(pbuf1, pbuf2, sz) != 0) {
6187 break; /* test complete */
6191 } else if (rc == MPT_SCANDV_ISSUE_SENSE)
6192 doFallback = 1; /* set fallback flag */
6193 else if ((rc == MPT_SCANDV_DID_RESET) || (rc == MPT_SCANDV_SENSE))
6194 doFallback = 1; /* set fallback flag */
6201 ddvprintk((MYIOC_s_NOTE_FMT "DV: Basic test on id=%d completed OK.\n", ioc->name, id));
6202 inq0 = (*pbuf1) & 0x1F;
6204 /* Continue only for disks
6209 if ( ioc->spi_data.PortFlags == MPI_SCSIPORTPAGE2_PORT_FLAGS_BASIC_DV_ONLY )
6212 /* Start the Enhanced Test.
6213 * 0) issue TUR to clear out check conditions
6214 * 1) read capacity of echo (regular) buffer
6216 * 3) do write-read-compare data pattern test
6218 * 5) update nego parms to target struct
6221 cfg.physAddr = cfg1_dma_addr;
6222 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
6225 iocmd.cmd = CMD_TestUnitReady;
6226 iocmd.data_dma = -1;
6231 if (mptscsih_do_cmd(hd, &iocmd) < 0)
6234 if (hd->pLocal == NULL)
6237 rc = hd->pLocal->completion;
6238 if (rc == MPT_SCANDV_GOOD)
6240 else if (rc == MPT_SCANDV_SENSE) {
6241 u8 skey = hd->pLocal->sense[2] & 0x0F;
6242 u8 asc = hd->pLocal->sense[12];
6243 u8 ascq = hd->pLocal->sense[13];
6244 ddvprintk((MYIOC_s_INFO_FMT
6245 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
6246 ioc->name, skey, asc, ascq));
6248 if (skey == SK_UNIT_ATTENTION)
6249 notDone++; /* repeat */
6250 else if ((skey == SK_NOT_READY) &&
6251 (asc == 0x04)&&(ascq == 0x01)) {
6252 /* wait then repeat */
6255 } else if ((skey == SK_NOT_READY) && (asc == 0x3A)) {
6256 /* no medium, try read test anyway */
6259 /* All other errors are fatal.
6261 ddvprintk((MYIOC_s_INFO_FMT "DV: fatal error.",
6269 iocmd.cmd = CMD_ReadBuffer;
6270 iocmd.data_dma = buf1_dma;
6273 iocmd.flags |= MPT_ICFLAG_BUF_CAP;
6277 for (patt = 0; patt < 2; patt++) {
6279 iocmd.flags |= MPT_ICFLAG_ECHO;
6281 iocmd.flags &= ~MPT_ICFLAG_ECHO;
6287 /* If not ready after 8 trials,
6288 * give up on this device.
6293 if (mptscsih_do_cmd(hd, &iocmd) < 0)
6295 else if (hd->pLocal == NULL)
6298 rc = hd->pLocal->completion;
6299 ddvprintk(("ReadBuffer Comp Code %d", rc));
6300 ddvprintk((" buff: %0x %0x %0x %0x\n",
6301 pbuf1[0], pbuf1[1], pbuf1[2], pbuf1[3]));
6303 if (rc == MPT_SCANDV_GOOD) {
6305 if (iocmd.flags & MPT_ICFLAG_ECHO) {
6306 bufsize = ((pbuf1[2] & 0x1F) <<8) | pbuf1[3];
6308 bufsize = pbuf1[1]<<16 | pbuf1[2]<<8 | pbuf1[3];
6310 } else if (rc == MPT_SCANDV_SENSE) {
6311 u8 skey = hd->pLocal->sense[2] & 0x0F;
6312 u8 asc = hd->pLocal->sense[12];
6313 u8 ascq = hd->pLocal->sense[13];
6314 ddvprintk((MYIOC_s_INFO_FMT
6315 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
6316 ioc->name, skey, asc, ascq));
6317 if (skey == SK_ILLEGAL_REQUEST) {
6319 } else if (skey == SK_UNIT_ATTENTION) {
6320 notDone++; /* repeat */
6321 } else if ((skey == SK_NOT_READY) &&
6322 (asc == 0x04)&&(ascq == 0x01)) {
6323 /* wait then repeat */
6327 /* All other errors are fatal.
6329 ddvprintk((MYIOC_s_INFO_FMT "DV: fatal error.",
6334 /* All other errors are fatal
6341 if (iocmd.flags & MPT_ICFLAG_ECHO)
6342 echoBufSize = bufsize;
6344 dataBufSize = bufsize;
6347 iocmd.flags &= ~MPT_ICFLAG_BUF_CAP;
6349 /* Use echo buffers if possible,
6350 * Exit if both buffers are 0.
6352 if (echoBufSize > 0) {
6353 iocmd.flags |= MPT_ICFLAG_ECHO;
6354 if (dataBufSize > 0)
6355 bufsize = min(echoBufSize, dataBufSize);
6357 bufsize = echoBufSize;
6358 } else if (dataBufSize == 0)
6361 ddvprintk((MYIOC_s_INFO_FMT "%s Buffer Capacity %d\n", ioc->name,
6362 (iocmd.flags & MPT_ICFLAG_ECHO) ? "Echo" : " ", bufsize));
6364 /* Data buffers for write-read-compare test max 1K.
6366 sz = min(bufsize, 1024);
6369 * On first pass, always issue a reserve.
6370 * On additional loops, only if a reset has occurred.
6371 * iocmd.flags indicates if echo or regular buffer
6373 for (patt = 0; patt < 4; patt++) {
6374 ddvprintk(("Pattern %d\n", patt));
6375 if ((iocmd.flags & MPT_ICFLAG_RESERVED) && (iocmd.flags & MPT_ICFLAG_DID_RESET)) {
6376 iocmd.cmd = CMD_TestUnitReady;
6377 iocmd.data_dma = -1;
6380 if (mptscsih_do_cmd(hd, &iocmd) < 0)
6383 iocmd.cmd = CMD_Release6;
6384 iocmd.data_dma = -1;
6387 if (mptscsih_do_cmd(hd, &iocmd) < 0)
6389 else if (hd->pLocal == NULL)
6392 rc = hd->pLocal->completion;
6393 ddvprintk(("Release rc %d\n", rc));
6394 if (rc == MPT_SCANDV_GOOD)
6395 iocmd.flags &= ~MPT_ICFLAG_RESERVED;
6399 iocmd.flags &= ~MPT_ICFLAG_RESERVED;
6401 iocmd.flags &= ~MPT_ICFLAG_DID_RESET;
6404 while (repeat && (!(iocmd.flags & MPT_ICFLAG_RESERVED))) {
6405 iocmd.cmd = CMD_Reserve6;
6406 iocmd.data_dma = -1;
6409 if (mptscsih_do_cmd(hd, &iocmd) < 0)
6411 else if (hd->pLocal == NULL)
6414 rc = hd->pLocal->completion;
6415 if (rc == MPT_SCANDV_GOOD) {
6416 iocmd.flags |= MPT_ICFLAG_RESERVED;
6417 } else if (rc == MPT_SCANDV_SENSE) {
6418 /* Wait if coming ready
6420 u8 skey = hd->pLocal->sense[2] & 0x0F;
6421 u8 asc = hd->pLocal->sense[12];
6422 u8 ascq = hd->pLocal->sense[13];
6423 ddvprintk((MYIOC_s_INFO_FMT
6424 "DV: Reserve Failed: ", ioc->name));
6425 ddvprintk(("SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
6428 if ((skey == SK_NOT_READY) && (asc == 0x04)&&
6430 /* wait then repeat */
6434 ddvprintk((MYIOC_s_INFO_FMT
6435 "DV: Reserved Failed.", ioc->name));
6439 ddvprintk((MYIOC_s_INFO_FMT "DV: Reserved Failed.",
6446 mptscsih_fillbuf(pbuf1, sz, patt, 1);
6447 iocmd.cmd = CMD_WriteBuffer;
6448 iocmd.data_dma = buf1_dma;
6451 if (mptscsih_do_cmd(hd, &iocmd) < 0)
6453 else if (hd->pLocal == NULL)
6456 rc = hd->pLocal->completion;
6457 if (rc == MPT_SCANDV_GOOD)
6458 ; /* Issue read buffer */
6459 else if (rc == MPT_SCANDV_DID_RESET) {
6460 /* If using echo buffers, reset to data buffers.
6461 * Else do Fallback and restart
6462 * this test (re-issue reserve
6463 * because of bus reset).
6465 if ((iocmd.flags & MPT_ICFLAG_ECHO) && (dataBufSize >= bufsize)) {
6466 iocmd.flags &= ~MPT_ICFLAG_ECHO;
6468 dv.cmd = MPT_FALLBACK;
6469 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
6471 if (mpt_config(hd->ioc, &cfg) != 0)
6474 if ((!dv.now.width) && (!dv.now.offset))
6478 iocmd.flags |= MPT_ICFLAG_DID_RESET;
6481 } else if (rc == MPT_SCANDV_SENSE) {
6482 /* Restart data test if UA, else quit.
6484 u8 skey = hd->pLocal->sense[2] & 0x0F;
6485 ddvprintk((MYIOC_s_INFO_FMT
6486 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n", ioc->name, skey,
6487 hd->pLocal->sense[12], hd->pLocal->sense[13]));
6488 if (skey == SK_UNIT_ATTENTION) {
6491 } else if (skey == SK_ILLEGAL_REQUEST) {
6492 if (iocmd.flags & MPT_ICFLAG_ECHO) {
6493 if (dataBufSize >= bufsize) {
6494 iocmd.flags &= ~MPT_ICFLAG_ECHO;
6509 iocmd.cmd = CMD_ReadBuffer;
6510 iocmd.data_dma = buf2_dma;
6513 if (mptscsih_do_cmd(hd, &iocmd) < 0)
6515 else if (hd->pLocal == NULL)
6518 rc = hd->pLocal->completion;
6519 if (rc == MPT_SCANDV_GOOD) {
6520 /* If buffers compare,
6521 * go to next pattern,
6522 * else, do a fallback and restart
6523 * data transfer test.
6525 if (memcmp (pbuf1, pbuf2, sz) == 0) {
6526 ; /* goto next pattern */
6528 /* Miscompare with Echo buffer, go to data buffer,
6529 * if that buffer exists.
6530 * Miscompare with Data buffer, check first 4 bytes,
6531 * some devices return capacity. Exit in this case.
6533 if (iocmd.flags & MPT_ICFLAG_ECHO) {
6534 if (dataBufSize >= bufsize)
6535 iocmd.flags &= ~MPT_ICFLAG_ECHO;
6539 if (dataBufSize == (pbuf2[1]<<16 | pbuf2[2]<<8 | pbuf2[3])) {
6540 /* Argh. Device returning wrong data.
6541 * Quit DV for this device.
6546 /* Had an actual miscompare. Slow down.*/
6547 dv.cmd = MPT_FALLBACK;
6548 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
6550 if (mpt_config(hd->ioc, &cfg) != 0)
6553 if ((!dv.now.width) && (!dv.now.offset))
6560 } else if (rc == MPT_SCANDV_DID_RESET) {
6561 /* Do Fallback and restart
6562 * this test (re-issue reserve
6563 * because of bus reset).
6565 dv.cmd = MPT_FALLBACK;
6566 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
6568 if (mpt_config(hd->ioc, &cfg) != 0)
6571 if ((!dv.now.width) && (!dv.now.offset))
6574 iocmd.flags |= MPT_ICFLAG_DID_RESET;
6577 } else if (rc == MPT_SCANDV_SENSE) {
6578 /* Restart data test if UA, else quit.
6580 u8 skey = hd->pLocal->sense[2] & 0x0F;
6581 ddvprintk((MYIOC_s_INFO_FMT
6582 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n", ioc->name, skey,
6583 hd->pLocal->sense[12], hd->pLocal->sense[13]));
6584 if (skey == SK_UNIT_ATTENTION) {
6596 } /* --- end of patt loop ---- */
6599 if (iocmd.flags & MPT_ICFLAG_RESERVED) {
6600 iocmd.cmd = CMD_Release6;
6601 iocmd.data_dma = -1;
6604 if (mptscsih_do_cmd(hd, &iocmd) < 0)
6605 printk(MYIOC_s_INFO_FMT "DV: Release failed. id %d",
6607 else if (hd->pLocal) {
6608 if (hd->pLocal->completion == MPT_SCANDV_GOOD)
6609 iocmd.flags &= ~MPT_ICFLAG_RESERVED;
6611 printk(MYIOC_s_INFO_FMT "DV: Release failed. id %d",
6617 /* Set if cfg1_dma_addr contents is valid
6619 if ((cfg.hdr != NULL) && (retcode == 0)){
6620 /* If disk, not U320, disable QAS
6622 if ((inq0 == 0) && (dv.now.factor > MPT_ULTRA320))
6623 hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS;
6626 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
6628 /* Double writes to SDP1 can cause problems,
6629 * skip save of the final negotiated settings to
6630 * SCSI device page 1.
6633 cfg.physAddr = cfg1_dma_addr;
6634 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
6636 mpt_config(hd->ioc, &cfg);
6640 /* If this is a RAID Passthrough, enable internal IOs
6642 if (iocmd.flags & MPT_ICFLAG_PHYS_DISK) {
6643 if (mptscsih_do_raid(hd, MPI_RAID_ACTION_ENABLE_PHYS_IO, &iocmd) < 0)
6644 ddvprintk((MYIOC_s_ERR_FMT "RAID Enable FAILED!\n", ioc->name));
6647 /* Done with the DV scan of the current target
6650 pci_free_consistent(ioc->pcidev, dv_alloc, pDvBuf, dvbuf_dma);
6652 ddvtprintk((MYIOC_s_INFO_FMT "DV Done.\n",
6658 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6659 /* mptscsih_dv_parms - perform a variety of operations on the
6660 * parameters used for negotiation.
6661 * @hd: Pointer to a SCSI host.
6662 * @dv: Pointer to a structure that contains the maximum and current
6663 * negotiated parameters.
6666 mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
6668 VirtDevice *pTarget;
6669 SCSIDevicePage0_t *pPage0;
6670 SCSIDevicePage1_t *pPage1;
6671 int val = 0, data, configuration;
6680 case MPT_GET_NVRAM_VALS:
6681 ddvprintk((MYIOC_s_NOTE_FMT "Getting NVRAM: ",
6683 /* Get the NVRAM values and save in tmax
6684 * If not an LVD bus, the adapter minSyncFactor has been
6685 * already throttled back.
6687 if ((hd->Targets)&&((pTarget = hd->Targets[(int)id]) != NULL) && !pTarget->raidVolume) {
6688 width = pTarget->maxWidth;
6689 offset = pTarget->maxOffset;
6690 factor = pTarget->minSyncFactor;
6691 negoFlags = pTarget->negoFlags;
6693 if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
6694 data = hd->ioc->spi_data.nvram[id];
6695 width = data & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
6696 if ((offset = hd->ioc->spi_data.maxSyncOffset) == 0)
6699 factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT;
6700 if ((factor == 0) || (factor == MPT_ASYNC)){
6711 /* Set the negotiation flags */
6712 negoFlags = hd->ioc->spi_data.noQas;
6714 negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
6717 negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
6720 /* limit by adapter capabilities */
6721 width = min(width, hd->ioc->spi_data.maxBusWidth);
6722 offset = min(offset, hd->ioc->spi_data.maxSyncOffset);
6723 factor = max(factor, hd->ioc->spi_data.minSyncFactor);
6725 /* Check Consistency */
6726 if (offset && (factor < MPT_ULTRA2) && !width)
6727 factor = MPT_ULTRA2;
6729 dv->max.width = width;
6730 dv->max.offset = offset;
6731 dv->max.factor = factor;
6732 dv->max.flags = negoFlags;
6733 ddvprintk((" width %d, factor %x, offset %x flags %x\n",
6734 width, factor, offset, negoFlags));
6737 case MPT_UPDATE_MAX:
6738 ddvprintk((MYIOC_s_NOTE_FMT
6739 "Updating with SDP0 Data: ", hd->ioc->name));
6740 /* Update tmax values with those from Device Page 0.*/
6741 pPage0 = (SCSIDevicePage0_t *) pPage;
6743 val = cpu_to_le32(pPage0->NegotiatedParameters);
6744 dv->max.width = val & MPI_SCSIDEVPAGE0_NP_WIDE ? 1 : 0;
6745 dv->max.offset = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK) >> 16;
6746 dv->max.factor = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK) >> 8;
6749 dv->now.width = dv->max.width;
6750 dv->now.offset = dv->max.offset;
6751 dv->now.factor = dv->max.factor;
6752 ddvprintk(("width %d, factor %x, offset %x, flags %x\n",
6753 dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags));
6757 ddvprintk((MYIOC_s_NOTE_FMT "Setting Max: ",
6759 /* Set current to the max values. Update the config page.*/
6760 dv->now.width = dv->max.width;
6761 dv->now.offset = dv->max.offset;
6762 dv->now.factor = dv->max.factor;
6763 dv->now.flags = dv->max.flags;
6765 pPage1 = (SCSIDevicePage1_t *)pPage;
6767 mptscsih_setDevicePage1Flags (dv->now.width, dv->now.factor,
6768 dv->now.offset, &val, &configuration, dv->now.flags);
6769 pPage1->RequestedParameters = le32_to_cpu(val);
6770 pPage1->Reserved = 0;
6771 pPage1->Configuration = le32_to_cpu(configuration);
6775 ddvprintk(("width %d, factor %x, offset %x request %x, config %x\n",
6776 dv->now.width, dv->now.factor, dv->now.offset, val, configuration));
6780 ddvprintk((MYIOC_s_NOTE_FMT "Setting Min: ",
6782 /* Set page to asynchronous and narrow
6783 * Do not update now, breaks fallback routine. */
6787 negoFlags = dv->max.flags;
6789 pPage1 = (SCSIDevicePage1_t *)pPage;
6791 mptscsih_setDevicePage1Flags (width, factor,
6792 offset, &val, &configuration, negoFlags);
6793 pPage1->RequestedParameters = le32_to_cpu(val);
6794 pPage1->Reserved = 0;
6795 pPage1->Configuration = le32_to_cpu(configuration);
6797 ddvprintk(("width %d, factor %x, offset %x request %x config %x\n",
6798 width, factor, offset, val, configuration));
6802 ddvprintk((MYIOC_s_NOTE_FMT
6803 "Fallback: Start: offset %d, factor %x, width %d \n",
6804 hd->ioc->name, dv->now.offset,
6805 dv->now.factor, dv->now.width));
6806 width = dv->now.width;
6807 offset = dv->now.offset;
6808 factor = dv->now.factor;
6809 if ((offset) && (dv->max.width)) {
6810 if (factor < MPT_ULTRA160)
6811 factor = MPT_ULTRA160;
6812 else if (factor < MPT_ULTRA2) {
6813 factor = MPT_ULTRA2;
6815 } else if ((factor == MPT_ULTRA2) && width) {
6816 factor = MPT_ULTRA2;
6818 } else if (factor < MPT_ULTRA) {
6821 } else if ((factor == MPT_ULTRA) && width) {
6823 } else if (factor < MPT_FAST) {
6826 } else if ((factor == MPT_FAST) && width) {
6829 } else if (factor < MPT_SCSI) {
6832 } else if ((factor == MPT_SCSI) && width) {
6840 } else if (offset) {
6842 if (factor < MPT_ULTRA)
6844 else if (factor < MPT_FAST)
6846 else if (factor < MPT_SCSI)
6857 dv->max.flags |= MPT_TARGET_NO_NEGO_QAS;
6859 dv->now.width = width;
6860 dv->now.offset = offset;
6861 dv->now.factor = factor;
6862 dv->now.flags = dv->max.flags;
6864 pPage1 = (SCSIDevicePage1_t *)pPage;
6866 mptscsih_setDevicePage1Flags (width, factor, offset, &val,
6867 &configuration, dv->now.flags);
6869 pPage1->RequestedParameters = le32_to_cpu(val);
6870 pPage1->Reserved = 0;
6871 pPage1->Configuration = le32_to_cpu(configuration);
6874 ddvprintk(("Finish: offset %d, factor %x, width %d, request %x config %x\n",
6875 dv->now.offset, dv->now.factor, dv->now.width, val, configuration));
6879 ddvprintk((MYIOC_s_NOTE_FMT
6880 "Saving to Target structure: ", hd->ioc->name));
6881 ddvprintk(("offset %d, factor %x, width %d \n",
6882 dv->now.offset, dv->now.factor, dv->now.width));
6884 /* Save these values to target structures
6885 * or overwrite nvram (phys disks only).
6888 if ((hd->Targets)&&((pTarget = hd->Targets[(int)id]) != NULL) && !pTarget->raidVolume ) {
6889 pTarget->maxWidth = dv->now.width;
6890 pTarget->maxOffset = dv->now.offset;
6891 pTarget->minSyncFactor = dv->now.factor;
6892 pTarget->negoFlags = dv->now.flags;
6894 /* Preserv all flags, use
6895 * read-modify-write algorithm
6897 if (hd->ioc->spi_data.nvram) {
6898 data = hd->ioc->spi_data.nvram[id];
6901 data &= ~MPT_NVRAM_WIDE_DISABLE;
6903 data |= MPT_NVRAM_WIDE_DISABLE;
6905 if (!dv->now.offset)
6908 data &= ~MPT_NVRAM_SYNC_MASK;
6909 data |= (dv->now.factor << MPT_NVRAM_SYNC_SHIFT) & MPT_NVRAM_SYNC_MASK;
6911 hd->ioc->spi_data.nvram[id] = data;
6918 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6919 /* mptscsih_fillbuf - fill a buffer with a special data pattern
6920 * cleanup. For bus scan only.
6922 * @buffer: Pointer to data buffer to be filled.
6923 * @size: Number of bytes to fill
6924 * @index: Pattern index
6925 * @width: bus width, 0 (8 bits) or 1 (16 bits)
6928 mptscsih_fillbuf(char *buffer, int size, int index, int width)
6939 /* Pattern: 0000 FFFF 0000 FFFF
6941 for (ii=0; ii < size; ii++, ptr++) {
6948 /* Pattern: 00 FF 00 FF
6950 for (ii=0; ii < size; ii++, ptr++) {
6961 /* Pattern: 5555 AAAA 5555 AAAA 5555
6963 for (ii=0; ii < size; ii++, ptr++) {
6970 /* Pattern: 55 AA 55 AA 55
6972 for (ii=0; ii < size; ii++, ptr++) {
6982 /* Pattern: 00 01 02 03 04 05
6985 for (ii=0; ii < size; ii++, ptr++)
6991 /* Wide Pattern: FFFE 0001 FFFD 0002
6992 * ... 4000 DFFF 8000 EFFF
6995 for (ii=0; ii < size/2; ii++) {
6996 /* Create the base pattern
6999 /* every 64 (0x40) bytes flip the pattern
7000 * since we fill 2 bytes / iteration,
7001 * test for ii = 0x20
7007 *ptr = (char)( (val & 0xFF00) >> 8);
7009 *ptr = (char)(val & 0xFF);
7014 *ptr = (char)( (val & 0xFF00) >> 8);
7016 *ptr = (char)(val & 0xFF);
7022 /* Narrow Pattern: FE 01 FD 02 FB 04
7023 * .. 7F 80 01 FE 02 FD ... 80 7F
7026 for (ii=0; ii < size; ii++, ptr++) {
7027 /* Base pattern - first 32 bytes
7034 *ptr = (char) (~(1 << byte));
7037 /* Flip the pattern every 32 bytes
7046 #endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */
7048 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7049 /* Commandline Parsing routines and defines.
7052 * insmod mptscsih mptscsih="width:1 dv:n factor:0x09 saf-te:1"
7054 * mptscsih=width:1,dv:n,factor:0x8,saf-te:1
7064 static char setup_token[] __initdata =
7069 ; /* DO NOT REMOVE THIS ';' */
7073 #define OPT_MAX_WIDTH 2
7074 #define OPT_MIN_SYNC_FACTOR 3
7075 #define OPT_SAF_TE 4
7077 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7080 get_setup_token(char *p)
7082 char *cur = setup_token;
7086 while (cur != NULL && (pc = strchr(cur, ':')) != NULL) {
7089 if (!strncmp(p, cur, pc - cur))
7096 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7098 mptscsih_setup(char *str)
7105 while (cur != NULL && (pc = strchr(cur, ':')) != NULL) {
7117 val = (int) simple_strtoul(pv, &pe, 0);
7119 printk("Found Token: %s, value %x\n", cur, (int)val);
7120 switch (get_setup_token(cur)) {
7122 driver_setup.dv = val;
7126 driver_setup.max_width = val;
7129 case OPT_MIN_SYNC_FACTOR:
7130 driver_setup.min_sync_fac = val;
7134 driver_setup.saf_te = val;
7138 printk("mptscsih_setup: unexpected boot option '%.*s' ignored\n", (int)(pc-cur+1), cur);
7142 if ((cur = strchr(cur, ARG_SEP)) != NULL)
7148 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7151 module_init(mptscsih_init);
7152 module_exit(mptscsih_exit);