[PATCH] aic7xxx_osm build fix
[cris-mirror.git] / drivers / message / fusion / mptscsih.c
blob3a3ef127df040c6ac6f7cb593223e515d1a2fa3c
1 /*
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.
8 * Credits:
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!
22 * (see mptbase.c)
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.
42 NO WARRANTY
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>
87 #include "mptbase.h"
88 #include "mptscsih.h"
90 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
91 #define my_NAME "Fusion MPT SCSI Host driver"
92 #define my_VERSION MPT_LINUX_VERSION_COMMON
93 #define MYNAM "mptscsih"
95 MODULE_AUTHOR(MODULEAUTHOR);
96 MODULE_DESCRIPTION(my_NAME);
97 MODULE_LICENSE("GPL");
99 /* Command line args */
100 static int mpt_dv = MPTSCSIH_DOMAIN_VALIDATION;
101 MODULE_PARM(mpt_dv, "i");
102 MODULE_PARM_DESC(mpt_dv, " DV Algorithm: enhanced=1, basic=0 (default=MPTSCSIH_DOMAIN_VALIDATION=1)");
104 static int mpt_width = MPTSCSIH_MAX_WIDTH;
105 MODULE_PARM(mpt_width, "i");
106 MODULE_PARM_DESC(mpt_width, " Max Bus Width: wide=1, narrow=0 (default=MPTSCSIH_MAX_WIDTH=1)");
108 static int mpt_factor = MPTSCSIH_MIN_SYNC;
109 MODULE_PARM(mpt_factor, "h");
110 MODULE_PARM_DESC(mpt_factor, " Min Sync Factor (default=MPTSCSIH_MIN_SYNC=0x08)");
112 static int mpt_saf_te = MPTSCSIH_SAF_TE;
113 MODULE_PARM(mpt_saf_te, "i");
114 MODULE_PARM_DESC(mpt_saf_te, " Force enabling SEP Processor: enable=1 (default=MPTSCSIH_SAF_TE=0)");
116 static int mpt_pq_filter = 0;
117 MODULE_PARM(mpt_pq_filter, "i");
118 MODULE_PARM_DESC(mpt_pq_filter, " Enable peripheral qualifier filter: enable=1 (default=0)");
120 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
122 typedef struct _BIG_SENSE_BUF {
123 u8 data[MPT_SENSE_BUFFER_ALLOC];
124 } BIG_SENSE_BUF;
126 #define MPT_SCANDV_GOOD (0x00000000) /* must be 0 */
127 #define MPT_SCANDV_DID_RESET (0x00000001)
128 #define MPT_SCANDV_SENSE (0x00000002)
129 #define MPT_SCANDV_SOME_ERROR (0x00000004)
130 #define MPT_SCANDV_SELECTION_TIMEOUT (0x00000008)
131 #define MPT_SCANDV_ISSUE_SENSE (0x00000010)
132 #define MPT_SCANDV_FALLBACK (0x00000020)
134 #define MPT_SCANDV_MAX_RETRIES (10)
136 #define MPT_ICFLAG_BUF_CAP 0x01 /* ReadBuffer Read Capacity format */
137 #define MPT_ICFLAG_ECHO 0x02 /* ReadBuffer Echo buffer format */
138 #define MPT_ICFLAG_PHYS_DISK 0x04 /* Any SCSI IO but do Phys Disk Format */
139 #define MPT_ICFLAG_TAGGED_CMD 0x08 /* Do tagged IO */
140 #define MPT_ICFLAG_DID_RESET 0x20 /* Bus Reset occurred with this command */
141 #define MPT_ICFLAG_RESERVED 0x40 /* Reserved has been issued */
143 typedef struct _internal_cmd {
144 char *data; /* data pointer */
145 dma_addr_t data_dma; /* data dma address */
146 int size; /* transfer size */
147 u8 cmd; /* SCSI Op Code */
148 u8 bus; /* bus number */
149 u8 id; /* SCSI ID (virtual) */
150 u8 lun;
151 u8 flags; /* Bit Field - See above */
152 u8 physDiskNum; /* Phys disk number, -1 else */
153 u8 rsvd2;
154 u8 rsvd;
155 } INTERNAL_CMD;
157 typedef struct _negoparms {
158 u8 width;
159 u8 offset;
160 u8 factor;
161 u8 flags;
162 } NEGOPARMS;
164 typedef struct _dv_parameters {
165 NEGOPARMS max;
166 NEGOPARMS now;
167 u8 cmd;
168 u8 id;
169 u16 pad1;
170 } DVPARAMETERS;
174 * Other private/forward protos...
176 static int mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
177 static void mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq);
178 static int mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
180 static int mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
181 SCSIIORequest_t *pReq, int req_idx);
182 static void mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx);
183 static void copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply);
184 static int mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd);
185 static int mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout );
186 static u32 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc);
188 static int mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout);
189 static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout);
191 static int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
192 static int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
194 static void mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *data, int dlen);
195 static void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56);
196 static void mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq);
197 static void mptscsih_setDevicePage1Flags (u8 width, u8 factor, u8 offset, int *requestedPtr, int *configurationPtr, u8 flags);
198 static void mptscsih_no_negotiate(MPT_SCSI_HOST *hd, int target_id);
199 static int mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target, int flags);
200 static int mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus);
201 static int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
202 static void mptscsih_timer_expired(unsigned long data);
203 static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
204 static int mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum);
206 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
207 static int mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io);
208 static void mptscsih_domainValidation(void *hd);
209 static int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id);
210 static void mptscsih_qas_check(MPT_SCSI_HOST *hd, int id);
211 static int mptscsih_doDv(MPT_SCSI_HOST *hd, int channel, int target);
212 static void mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage);
213 static void mptscsih_fillbuf(char *buffer, int size, int index, int width);
214 #endif
215 /* module entry point */
216 static int __init mptscsih_init (void);
217 static void __exit mptscsih_exit (void);
219 static int mptscsih_probe (struct pci_dev *, const struct pci_device_id *);
220 static void mptscsih_remove(struct pci_dev *);
221 static void mptscsih_shutdown(struct device *);
222 #ifdef CONFIG_PM
223 static int mptscsih_suspend(struct pci_dev *pdev, pm_message_t state);
224 static int mptscsih_resume(struct pci_dev *pdev);
225 #endif
229 * Private data...
232 static int mpt_scsi_hosts = 0;
234 static int ScsiDoneCtx = -1;
235 static int ScsiTaskCtx = -1;
236 static int ScsiScanDvCtx = -1; /* Used only for bus scan and dv */
238 #define SNS_LEN(scp) sizeof((scp)->sense_buffer)
240 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
242 * Domain Validation task structure
244 static DEFINE_SPINLOCK(dvtaskQ_lock);
245 static int dvtaskQ_active = 0;
246 static int dvtaskQ_release = 0;
247 static struct work_struct mptscsih_dvTask;
248 #endif
251 * Wait Queue setup
253 static DECLARE_WAIT_QUEUE_HEAD (scandv_waitq);
254 static int scandv_wait_done = 1;
257 /* Driver command line structure
259 static struct scsi_host_template driver_template;
261 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
263 * mptscsih_add_sge - Place a simple SGE at address pAddr.
264 * @pAddr: virtual address for SGE
265 * @flagslength: SGE flags and data transfer length
266 * @dma_addr: Physical address
268 * This routine places a MPT request frame back on the MPT adapter's
269 * FreeQ.
271 static inline void
272 mptscsih_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
274 if (sizeof(dma_addr_t) == sizeof(u64)) {
275 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
276 u32 tmp = dma_addr & 0xFFFFFFFF;
278 pSge->FlagsLength = cpu_to_le32(flagslength);
279 pSge->Address.Low = cpu_to_le32(tmp);
280 tmp = (u32) ((u64)dma_addr >> 32);
281 pSge->Address.High = cpu_to_le32(tmp);
283 } else {
284 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
285 pSge->FlagsLength = cpu_to_le32(flagslength);
286 pSge->Address = cpu_to_le32(dma_addr);
288 } /* mptscsih_add_sge() */
290 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
292 * mptscsih_add_chain - Place a chain SGE at address pAddr.
293 * @pAddr: virtual address for SGE
294 * @next: nextChainOffset value (u32's)
295 * @length: length of next SGL segment
296 * @dma_addr: Physical address
298 * This routine places a MPT request frame back on the MPT adapter's
299 * FreeQ.
301 static inline void
302 mptscsih_add_chain(char *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
304 if (sizeof(dma_addr_t) == sizeof(u64)) {
305 SGEChain64_t *pChain = (SGEChain64_t *) pAddr;
306 u32 tmp = dma_addr & 0xFFFFFFFF;
308 pChain->Length = cpu_to_le16(length);
309 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size();
311 pChain->NextChainOffset = next;
313 pChain->Address.Low = cpu_to_le32(tmp);
314 tmp = (u32) ((u64)dma_addr >> 32);
315 pChain->Address.High = cpu_to_le32(tmp);
316 } else {
317 SGEChain32_t *pChain = (SGEChain32_t *) pAddr;
318 pChain->Length = cpu_to_le16(length);
319 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size();
320 pChain->NextChainOffset = next;
321 pChain->Address = cpu_to_le32(dma_addr);
323 } /* mptscsih_add_chain() */
325 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
327 * mptscsih_getFreeChainBuffer - Function to get a free chain
328 * from the MPT_SCSI_HOST FreeChainQ.
329 * @ioc: Pointer to MPT_ADAPTER structure
330 * @req_idx: Index of the SCSI IO request frame. (output)
332 * return SUCCESS or FAILED
334 static inline int
335 mptscsih_getFreeChainBuffer(MPT_ADAPTER *ioc, int *retIndex)
337 MPT_FRAME_HDR *chainBuf;
338 unsigned long flags;
339 int rc;
340 int chain_idx;
342 dsgprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer called\n",
343 ioc->name));
344 spin_lock_irqsave(&ioc->FreeQlock, flags);
345 if (!list_empty(&ioc->FreeChainQ)) {
346 int offset;
348 chainBuf = list_entry(ioc->FreeChainQ.next, MPT_FRAME_HDR,
349 u.frame.linkage.list);
350 list_del(&chainBuf->u.frame.linkage.list);
351 offset = (u8 *)chainBuf - (u8 *)ioc->ChainBuffer;
352 chain_idx = offset / ioc->req_sz;
353 rc = SUCCESS;
354 dsgprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer (index %d), got buf=%p\n",
355 ioc->name, *retIndex, chainBuf));
356 } else {
357 rc = FAILED;
358 chain_idx = MPT_HOST_NO_CHAIN;
359 dfailprintk((MYIOC_s_ERR_FMT "getFreeChainBuffer failed\n",
360 ioc->name));
362 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
364 *retIndex = chain_idx;
365 return rc;
366 } /* mptscsih_getFreeChainBuffer() */
368 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
370 * mptscsih_AddSGE - Add a SGE (plus chain buffers) to the
371 * SCSIIORequest_t Message Frame.
372 * @ioc: Pointer to MPT_ADAPTER structure
373 * @SCpnt: Pointer to scsi_cmnd structure
374 * @pReq: Pointer to SCSIIORequest_t structure
376 * Returns ...
378 static int
379 mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
380 SCSIIORequest_t *pReq, int req_idx)
382 char *psge;
383 char *chainSge;
384 struct scatterlist *sg;
385 int frm_sz;
386 int sges_left, sg_done;
387 int chain_idx = MPT_HOST_NO_CHAIN;
388 int sgeOffset;
389 int numSgeSlots, numSgeThisFrame;
390 u32 sgflags, sgdir, thisxfer = 0;
391 int chain_dma_off = 0;
392 int newIndex;
393 int ii;
394 dma_addr_t v2;
395 u32 RequestNB;
397 sgdir = le32_to_cpu(pReq->Control) & MPI_SCSIIO_CONTROL_DATADIRECTION_MASK;
398 if (sgdir == MPI_SCSIIO_CONTROL_WRITE) {
399 sgdir = MPT_TRANSFER_HOST_TO_IOC;
400 } else {
401 sgdir = MPT_TRANSFER_IOC_TO_HOST;
404 psge = (char *) &pReq->SGL;
405 frm_sz = ioc->req_sz;
407 /* Map the data portion, if any.
408 * sges_left = 0 if no data transfer.
410 if ( (sges_left = SCpnt->use_sg) ) {
411 sges_left = pci_map_sg(ioc->pcidev,
412 (struct scatterlist *) SCpnt->request_buffer,
413 SCpnt->use_sg,
414 SCpnt->sc_data_direction);
415 if (sges_left == 0)
416 return FAILED;
417 } else if (SCpnt->request_bufflen) {
418 SCpnt->SCp.dma_handle = pci_map_single(ioc->pcidev,
419 SCpnt->request_buffer,
420 SCpnt->request_bufflen,
421 SCpnt->sc_data_direction);
422 dsgprintk((MYIOC_s_INFO_FMT "SG: non-SG for %p, len=%d\n",
423 ioc->name, SCpnt, SCpnt->request_bufflen));
424 mptscsih_add_sge((char *) &pReq->SGL,
425 0xD1000000|MPT_SGE_FLAGS_ADDRESSING|sgdir|SCpnt->request_bufflen,
426 SCpnt->SCp.dma_handle);
428 return SUCCESS;
431 /* Handle the SG case.
433 sg = (struct scatterlist *) SCpnt->request_buffer;
434 sg_done = 0;
435 sgeOffset = sizeof(SCSIIORequest_t) - sizeof(SGE_IO_UNION);
436 chainSge = NULL;
438 /* Prior to entering this loop - the following must be set
439 * current MF: sgeOffset (bytes)
440 * chainSge (Null if original MF is not a chain buffer)
441 * sg_done (num SGE done for this MF)
444 nextSGEset:
445 numSgeSlots = ((frm_sz - sgeOffset) / (sizeof(u32) + sizeof(dma_addr_t)) );
446 numSgeThisFrame = (sges_left < numSgeSlots) ? sges_left : numSgeSlots;
448 sgflags = MPT_SGE_FLAGS_SIMPLE_ELEMENT | MPT_SGE_FLAGS_ADDRESSING | sgdir;
450 /* Get first (num - 1) SG elements
451 * Skip any SG entries with a length of 0
452 * NOTE: at finish, sg and psge pointed to NEXT data/location positions
454 for (ii=0; ii < (numSgeThisFrame-1); ii++) {
455 thisxfer = sg_dma_len(sg);
456 if (thisxfer == 0) {
457 sg ++; /* Get next SG element from the OS */
458 sg_done++;
459 continue;
462 v2 = sg_dma_address(sg);
463 mptscsih_add_sge(psge, sgflags | thisxfer, v2);
465 sg++; /* Get next SG element from the OS */
466 psge += (sizeof(u32) + sizeof(dma_addr_t));
467 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
468 sg_done++;
471 if (numSgeThisFrame == sges_left) {
472 /* Add last element, end of buffer and end of list flags.
474 sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT |
475 MPT_SGE_FLAGS_END_OF_BUFFER |
476 MPT_SGE_FLAGS_END_OF_LIST;
478 /* Add last SGE and set termination flags.
479 * Note: Last SGE may have a length of 0 - which should be ok.
481 thisxfer = sg_dma_len(sg);
483 v2 = sg_dma_address(sg);
484 mptscsih_add_sge(psge, sgflags | thisxfer, v2);
486 sg++;
487 psge += (sizeof(u32) + sizeof(dma_addr_t));
489 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
490 sg_done++;
492 if (chainSge) {
493 /* The current buffer is a chain buffer,
494 * but there is not another one.
495 * Update the chain element
496 * Offset and Length fields.
498 mptscsih_add_chain((char *)chainSge, 0, sgeOffset, ioc->ChainBufferDMA + chain_dma_off);
499 } else {
500 /* The current buffer is the original MF
501 * and there is no Chain buffer.
503 pReq->ChainOffset = 0;
504 RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor) + 1) & 0x03;
505 dsgprintk((MYIOC_s_ERR_FMT
506 "Single Buffer RequestNB=%x, sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
507 ioc->RequestNB[req_idx] = RequestNB;
509 } else {
510 /* At least one chain buffer is needed.
511 * Complete the first MF
512 * - last SGE element, set the LastElement bit
513 * - set ChainOffset (words) for orig MF
514 * (OR finish previous MF chain buffer)
515 * - update MFStructPtr ChainIndex
516 * - Populate chain element
517 * Also
518 * Loop until done.
521 dsgprintk((MYIOC_s_INFO_FMT "SG: Chain Required! sg done %d\n",
522 ioc->name, sg_done));
524 /* Set LAST_ELEMENT flag for last non-chain element
525 * in the buffer. Since psge points at the NEXT
526 * SGE element, go back one SGE element, update the flags
527 * and reset the pointer. (Note: sgflags & thisxfer are already
528 * set properly).
530 if (sg_done) {
531 u32 *ptmp = (u32 *) (psge - (sizeof(u32) + sizeof(dma_addr_t)));
532 sgflags = le32_to_cpu(*ptmp);
533 sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT;
534 *ptmp = cpu_to_le32(sgflags);
537 if (chainSge) {
538 /* The current buffer is a chain buffer.
539 * chainSge points to the previous Chain Element.
540 * Update its chain element Offset and Length (must
541 * include chain element size) fields.
542 * Old chain element is now complete.
544 u8 nextChain = (u8) (sgeOffset >> 2);
545 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
546 mptscsih_add_chain((char *)chainSge, nextChain, sgeOffset, ioc->ChainBufferDMA + chain_dma_off);
547 } else {
548 /* The original MF buffer requires a chain buffer -
549 * set the offset.
550 * Last element in this MF is a chain element.
552 pReq->ChainOffset = (u8) (sgeOffset >> 2);
553 RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor) + 1) & 0x03;
554 dsgprintk((MYIOC_s_ERR_FMT "Chain Buffer Needed, RequestNB=%x sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
555 ioc->RequestNB[req_idx] = RequestNB;
558 sges_left -= sg_done;
561 /* NOTE: psge points to the beginning of the chain element
562 * in current buffer. Get a chain buffer.
564 dsgprintk((MYIOC_s_INFO_FMT
565 "calling getFreeChainBuffer SCSI cmd=%02x (%p)\n",
566 ioc->name, pReq->CDB[0], SCpnt));
567 if ((mptscsih_getFreeChainBuffer(ioc, &newIndex)) == FAILED)
568 return FAILED;
570 /* Update the tracking arrays.
571 * If chainSge == NULL, update ReqToChain, else ChainToChain
573 if (chainSge) {
574 ioc->ChainToChain[chain_idx] = newIndex;
575 } else {
576 ioc->ReqToChain[req_idx] = newIndex;
578 chain_idx = newIndex;
579 chain_dma_off = ioc->req_sz * chain_idx;
581 /* Populate the chainSGE for the current buffer.
582 * - Set chain buffer pointer to psge and fill
583 * out the Address and Flags fields.
585 chainSge = (char *) psge;
586 dsgprintk((KERN_INFO " Current buff @ %p (index 0x%x)",
587 psge, req_idx));
589 /* Start the SGE for the next buffer
591 psge = (char *) (ioc->ChainBuffer + chain_dma_off);
592 sgeOffset = 0;
593 sg_done = 0;
595 dsgprintk((KERN_INFO " Chain buff @ %p (index 0x%x)\n",
596 psge, chain_idx));
598 /* Start the SGE for the next buffer
601 goto nextSGEset;
604 return SUCCESS;
605 } /* mptscsih_AddSGE() */
607 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
609 * mptscsih_io_done - Main SCSI IO callback routine registered to
610 * Fusion MPT (base) driver
611 * @ioc: Pointer to MPT_ADAPTER structure
612 * @mf: Pointer to original MPT request frame
613 * @r: Pointer to MPT reply frame (NULL if TurboReply)
615 * This routine is called from mpt.c::mpt_interrupt() at the completion
616 * of any SCSI IO request.
617 * This routine is registered with the Fusion MPT (base) driver at driver
618 * load/init time via the mpt_register() API call.
620 * Returns 1 indicating alloc'd request frame ptr should be freed.
622 static int
623 mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
625 struct scsi_cmnd *sc;
626 MPT_SCSI_HOST *hd;
627 SCSIIORequest_t *pScsiReq;
628 SCSIIOReply_t *pScsiReply;
629 u16 req_idx;
631 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
633 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
634 sc = hd->ScsiLookup[req_idx];
635 if (sc == NULL) {
636 MPIHeader_t *hdr = (MPIHeader_t *)mf;
638 /* Remark: writeSDP1 will use the ScsiDoneCtx
639 * If a SCSI I/O cmd, device disabled by OS and
640 * completion done. Cannot touch sc struct. Just free mem.
642 if (hdr->Function == MPI_FUNCTION_SCSI_IO_REQUEST)
643 printk(MYIOC_s_ERR_FMT "NULL ScsiCmd ptr!\n",
644 ioc->name);
646 mptscsih_freeChainBuffers(ioc, req_idx);
647 return 1;
650 dmfprintk((MYIOC_s_INFO_FMT
651 "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n",
652 ioc->name, mf, mr, sc, req_idx));
654 sc->result = DID_OK << 16; /* Set default reply as OK */
655 pScsiReq = (SCSIIORequest_t *) mf;
656 pScsiReply = (SCSIIOReply_t *) mr;
658 if (pScsiReply == NULL) {
659 /* special context reply handling */
661 } else {
662 u32 xfer_cnt;
663 u16 status;
664 u8 scsi_state, scsi_status;
666 status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK;
667 scsi_state = pScsiReply->SCSIState;
668 scsi_status = pScsiReply->SCSIStatus;
669 xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
670 sc->resid = sc->request_bufflen - xfer_cnt;
672 dreplyprintk((KERN_NOTICE "Reply ha=%d id=%d lun=%d:\n"
673 "IOCStatus=%04xh SCSIState=%02xh SCSIStatus=%02xh\n"
674 "resid=%d bufflen=%d xfer_cnt=%d\n",
675 ioc->id, pScsiReq->TargetID, pScsiReq->LUN[1],
676 status, scsi_state, scsi_status, sc->resid,
677 sc->request_bufflen, xfer_cnt));
679 if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)
680 copy_sense_data(sc, hd, mf, pScsiReply);
683 * Look for + dump FCP ResponseInfo[]!
685 if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID) {
686 printk(KERN_NOTICE " FCP_ResponseInfo=%08xh\n",
687 le32_to_cpu(pScsiReply->ResponseInfo));
690 switch(status) {
691 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
692 /* CHECKME!
693 * Maybe: DRIVER_BUSY | SUGGEST_RETRY | DID_SOFT_ERROR (retry)
694 * But not: DID_BUS_BUSY lest one risk
695 * killing interrupt handler:-(
697 sc->result = SAM_STAT_BUSY;
698 break;
700 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
701 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
702 sc->result = DID_BAD_TARGET << 16;
703 break;
705 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
706 /* Spoof to SCSI Selection Timeout! */
707 sc->result = DID_NO_CONNECT << 16;
709 if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF)
710 hd->sel_timeout[pScsiReq->TargetID]++;
711 break;
713 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
714 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
715 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
716 /* Linux handles an unsolicited DID_RESET better
717 * than an unsolicited DID_ABORT.
719 sc->result = DID_RESET << 16;
721 /* GEM Workaround. */
722 if (ioc->bus_type == SCSI)
723 mptscsih_no_negotiate(hd, sc->device->id);
724 break;
726 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
727 if ( xfer_cnt >= sc->underflow ) {
728 /* Sufficient data transfer occurred */
729 sc->result = (DID_OK << 16) | scsi_status;
730 } else if ( xfer_cnt == 0 ) {
731 /* A CRC Error causes this condition; retry */
732 sc->result = (DRIVER_SENSE << 24) | (DID_OK << 16) |
733 (CHECK_CONDITION << 1);
734 sc->sense_buffer[0] = 0x70;
735 sc->sense_buffer[2] = NO_SENSE;
736 sc->sense_buffer[12] = 0;
737 sc->sense_buffer[13] = 0;
738 } else {
739 sc->result = DID_SOFT_ERROR << 16;
741 dreplyprintk((KERN_NOTICE "RESIDUAL_MISMATCH: result=%x on id=%d\n", sc->result, sc->target));
742 break;
744 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
746 * Do upfront check for valid SenseData and give it
747 * precedence!
749 sc->result = (DID_OK << 16) | scsi_status;
750 if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
751 /* Have already saved the status and sense data
754 } else {
755 if (xfer_cnt < sc->underflow) {
756 sc->result = DID_SOFT_ERROR << 16;
758 if (scsi_state & (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)) {
759 /* What to do?
761 sc->result = DID_SOFT_ERROR << 16;
763 else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
764 /* Not real sure here either... */
765 sc->result = DID_RESET << 16;
769 dreplyprintk((KERN_NOTICE " sc->underflow={report ERR if < %02xh bytes xfer'd}\n",
770 sc->underflow));
771 dreplyprintk((KERN_NOTICE " ActBytesXferd=%02xh\n", xfer_cnt));
772 /* Report Queue Full
774 if (scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)
775 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
777 break;
779 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
780 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
781 scsi_status = pScsiReply->SCSIStatus;
782 sc->result = (DID_OK << 16) | scsi_status;
783 if (scsi_state == 0) {
785 } else if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
787 * If running against circa 200003dd 909 MPT f/w,
788 * may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL
789 * (QUEUE_FULL) returned from device! --> get 0x0000?128
790 * and with SenseBytes set to 0.
792 if (pScsiReply->SCSIStatus == MPI_SCSI_STATUS_TASK_SET_FULL)
793 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
796 else if (scsi_state &
797 (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)
800 * What to do?
802 sc->result = DID_SOFT_ERROR << 16;
804 else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
805 /* Not real sure here either... */
806 sc->result = DID_RESET << 16;
808 else if (scsi_state & MPI_SCSI_STATE_QUEUE_TAG_REJECTED) {
809 /* Device Inq. data indicates that it supports
810 * QTags, but rejects QTag messages.
811 * This command completed OK.
813 * Not real sure here either so do nothing... */
816 if (sc->result == MPI_SCSI_STATUS_TASK_SET_FULL)
817 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
819 /* Add handling of:
820 * Reservation Conflict, Busy,
821 * Command Terminated, CHECK
823 break;
825 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
826 sc->result = DID_SOFT_ERROR << 16;
827 break;
829 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
830 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
831 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
832 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
833 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
834 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
835 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
836 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
837 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
838 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
839 default:
841 * What to do?
843 sc->result = DID_SOFT_ERROR << 16;
844 break;
846 } /* switch(status) */
848 dreplyprintk((KERN_NOTICE " sc->result is %08xh\n", sc->result));
849 } /* end of address reply case */
851 /* Unmap the DMA buffers, if any. */
852 if (sc->use_sg) {
853 pci_unmap_sg(ioc->pcidev, (struct scatterlist *) sc->request_buffer,
854 sc->use_sg, sc->sc_data_direction);
855 } else if (sc->request_bufflen) {
856 pci_unmap_single(ioc->pcidev, sc->SCp.dma_handle,
857 sc->request_bufflen, sc->sc_data_direction);
860 hd->ScsiLookup[req_idx] = NULL;
862 sc->scsi_done(sc); /* Issue the command callback */
864 /* Free Chain buffers */
865 mptscsih_freeChainBuffers(ioc, req_idx);
866 return 1;
871 * mptscsih_flush_running_cmds - For each command found, search
872 * Scsi_Host instance taskQ and reply to OS.
873 * Called only if recovering from a FW reload.
874 * @hd: Pointer to a SCSI HOST structure
876 * Returns: None.
878 * Must be called while new I/Os are being queued.
880 static void
881 mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
883 MPT_ADAPTER *ioc = hd->ioc;
884 struct scsi_cmnd *SCpnt;
885 MPT_FRAME_HDR *mf;
886 int ii;
887 int max = ioc->req_depth;
889 dprintk((KERN_INFO MYNAM ": flush_ScsiLookup called\n"));
890 for (ii= 0; ii < max; ii++) {
891 if ((SCpnt = hd->ScsiLookup[ii]) != NULL) {
893 /* Command found.
896 /* Null ScsiLookup index
898 hd->ScsiLookup[ii] = NULL;
900 mf = MPT_INDEX_2_MFPTR(ioc, ii);
901 dmfprintk(( "flush: ScsiDone (mf=%p,sc=%p)\n",
902 mf, SCpnt));
904 /* Set status, free OS resources (SG DMA buffers)
905 * Do OS callback
906 * Free driver resources (chain, msg buffers)
908 if (scsi_device_online(SCpnt->device)) {
909 if (SCpnt->use_sg) {
910 pci_unmap_sg(ioc->pcidev,
911 (struct scatterlist *) SCpnt->request_buffer,
912 SCpnt->use_sg,
913 SCpnt->sc_data_direction);
914 } else if (SCpnt->request_bufflen) {
915 pci_unmap_single(ioc->pcidev,
916 SCpnt->SCp.dma_handle,
917 SCpnt->request_bufflen,
918 SCpnt->sc_data_direction);
921 SCpnt->result = DID_RESET << 16;
922 SCpnt->host_scribble = NULL;
924 /* Free Chain buffers */
925 mptscsih_freeChainBuffers(ioc, ii);
927 /* Free Message frames */
928 mpt_free_msg_frame(ioc, mf);
930 SCpnt->scsi_done(SCpnt); /* Issue the command callback */
934 return;
938 * mptscsih_search_running_cmds - Delete any commands associated
939 * with the specified target and lun. Function called only
940 * when a lun is disable by mid-layer.
941 * Do NOT access the referenced scsi_cmnd structure or
942 * members. Will cause either a paging or NULL ptr error.
943 * @hd: Pointer to a SCSI HOST structure
944 * @target: target id
945 * @lun: lun
947 * Returns: None.
949 * Called from slave_destroy.
951 static void
952 mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, uint target, uint lun)
954 SCSIIORequest_t *mf = NULL;
955 int ii;
956 int max = hd->ioc->req_depth;
958 dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n",
959 target, lun, max));
961 for (ii=0; ii < max; ii++) {
962 if (hd->ScsiLookup[ii] != NULL) {
964 mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii);
966 dsprintk(( "search_running: found (sc=%p, mf = %p) target %d, lun %d \n",
967 hd->ScsiLookup[ii], mf, mf->TargetID, mf->LUN[1]));
969 if ((mf->TargetID != ((u8)target)) || (mf->LUN[1] != ((u8) lun)))
970 continue;
972 /* Cleanup
974 hd->ScsiLookup[ii] = NULL;
975 mptscsih_freeChainBuffers(hd->ioc, ii);
976 mpt_free_msg_frame(hd->ioc, (MPT_FRAME_HDR *)mf);
980 return;
983 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
985 * Hack! It might be nice to report if a device is returning QUEUE_FULL
986 * but maybe not each and every time...
988 static long last_queue_full = 0;
990 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
992 * mptscsih_report_queue_full - Report QUEUE_FULL status returned
993 * from a SCSI target device.
994 * @sc: Pointer to scsi_cmnd structure
995 * @pScsiReply: Pointer to SCSIIOReply_t
996 * @pScsiReq: Pointer to original SCSI request
998 * This routine periodically reports QUEUE_FULL status returned from a
999 * SCSI target device. It reports this to the console via kernel
1000 * printk() API call, not more than once every 10 seconds.
1002 static void
1003 mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq)
1005 long time = jiffies;
1007 if (time - last_queue_full > 10 * HZ) {
1008 char *ioc_str = "ioc?";
1010 if (sc->device && sc->device->host != NULL && sc->device->host->hostdata != NULL)
1011 ioc_str = ((MPT_SCSI_HOST *)sc->device->host->hostdata)->ioc->name;
1012 dprintk((MYIOC_s_WARN_FMT "Device (%d:%d:%d) reported QUEUE_FULL!\n",
1013 ioc_str, 0, sc->device->id, sc->device->lun));
1014 last_queue_full = time;
1018 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1019 static char *info_kbuf = NULL;
1021 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1022 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1024 * mptscsih_probe - Installs scsi devices per bus.
1025 * @pdev: Pointer to pci_dev structure
1027 * Returns 0 for success, non-zero for failure.
1031 static int
1032 mptscsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1034 struct Scsi_Host *sh;
1035 MPT_SCSI_HOST *hd;
1036 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1037 unsigned long flags;
1038 int sz, ii;
1039 int numSGE = 0;
1040 int scale;
1041 int ioc_cap;
1042 u8 *mem;
1043 int error=0;
1046 /* 20010202 -sralston
1047 * Added sanity check on readiness of the MPT adapter.
1049 if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
1050 printk(MYIOC_s_WARN_FMT
1051 "Skipping because it's not operational!\n",
1052 ioc->name);
1053 return -ENODEV;
1056 if (!ioc->active) {
1057 printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
1058 ioc->name);
1059 return -ENODEV;
1062 /* Sanity check - ensure at least 1 port is INITIATOR capable
1064 ioc_cap = 0;
1065 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
1066 if (ioc->pfacts[ii].ProtocolFlags &
1067 MPI_PORTFACTS_PROTOCOL_INITIATOR)
1068 ioc_cap ++;
1071 if (!ioc_cap) {
1072 printk(MYIOC_s_WARN_FMT
1073 "Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n",
1074 ioc->name, ioc);
1075 return -ENODEV;
1078 sh = scsi_host_alloc(&driver_template, sizeof(MPT_SCSI_HOST));
1080 if (!sh) {
1081 printk(MYIOC_s_WARN_FMT
1082 "Unable to register controller with SCSI subsystem\n",
1083 ioc->name);
1084 return -1;
1087 spin_lock_irqsave(&ioc->FreeQlock, flags);
1089 /* Attach the SCSI Host to the IOC structure
1091 ioc->sh = sh;
1093 sh->io_port = 0;
1094 sh->n_io_port = 0;
1095 sh->irq = 0;
1097 /* set 16 byte cdb's */
1098 sh->max_cmd_len = 16;
1100 /* Yikes! This is important!
1101 * Otherwise, by default, linux
1102 * only scans target IDs 0-7!
1103 * pfactsN->MaxDevices unreliable
1104 * (not supported in early
1105 * versions of the FW).
1106 * max_id = 1 + actual max id,
1107 * max_lun = 1 + actual last lun,
1108 * see hosts.h :o(
1110 if (ioc->bus_type == SCSI) {
1111 sh->max_id = MPT_MAX_SCSI_DEVICES;
1112 } else {
1113 /* For FC, increase the queue depth
1114 * from MPT_SCSI_CAN_QUEUE (31)
1115 * to MPT_FC_CAN_QUEUE (63).
1117 sh->can_queue = MPT_FC_CAN_QUEUE;
1118 sh->max_id =
1119 MPT_MAX_FC_DEVICES<256 ? MPT_MAX_FC_DEVICES : 255;
1122 sh->max_lun = MPT_LAST_LUN + 1;
1123 sh->max_channel = 0;
1124 sh->this_id = ioc->pfacts[0].PortSCSIID;
1126 /* Required entry.
1128 sh->unique_id = ioc->id;
1130 /* Verify that we won't exceed the maximum
1131 * number of chain buffers
1132 * We can optimize: ZZ = req_sz/sizeof(SGE)
1133 * For 32bit SGE's:
1134 * numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
1135 * + (req_sz - 64)/sizeof(SGE)
1136 * A slightly different algorithm is required for
1137 * 64bit SGEs.
1139 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
1140 if (sizeof(dma_addr_t) == sizeof(u64)) {
1141 numSGE = (scale - 1) *
1142 (ioc->facts.MaxChainDepth-1) + scale +
1143 (ioc->req_sz - 60) / (sizeof(dma_addr_t) +
1144 sizeof(u32));
1145 } else {
1146 numSGE = 1 + (scale - 1) *
1147 (ioc->facts.MaxChainDepth-1) + scale +
1148 (ioc->req_sz - 64) / (sizeof(dma_addr_t) +
1149 sizeof(u32));
1152 if (numSGE < sh->sg_tablesize) {
1153 /* Reset this value */
1154 dprintk((MYIOC_s_INFO_FMT
1155 "Resetting sg_tablesize to %d from %d\n",
1156 ioc->name, numSGE, sh->sg_tablesize));
1157 sh->sg_tablesize = numSGE;
1160 /* Set the pci device pointer in Scsi_Host structure.
1162 scsi_set_device(sh, &ioc->pcidev->dev);
1164 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1166 hd = (MPT_SCSI_HOST *) sh->hostdata;
1167 hd->ioc = ioc;
1169 /* SCSI needs scsi_cmnd lookup table!
1170 * (with size equal to req_depth*PtrSz!)
1172 sz = ioc->req_depth * sizeof(void *);
1173 mem = kmalloc(sz, GFP_ATOMIC);
1174 if (mem == NULL) {
1175 error = -ENOMEM;
1176 goto mptscsih_probe_failed;
1179 memset(mem, 0, sz);
1180 hd->ScsiLookup = (struct scsi_cmnd **) mem;
1182 dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n",
1183 ioc->name, hd->ScsiLookup, sz));
1185 /* Allocate memory for the device structures.
1186 * A non-Null pointer at an offset
1187 * indicates a device exists.
1188 * max_id = 1 + maximum id (hosts.h)
1190 sz = sh->max_id * sizeof(void *);
1191 mem = kmalloc(sz, GFP_ATOMIC);
1192 if (mem == NULL) {
1193 error = -ENOMEM;
1194 goto mptscsih_probe_failed;
1197 memset(mem, 0, sz);
1198 hd->Targets = (VirtDevice **) mem;
1200 dprintk((KERN_INFO
1201 " Targets @ %p, sz=%d\n", hd->Targets, sz));
1203 /* Clear the TM flags
1205 hd->tmPending = 0;
1206 hd->tmState = TM_STATE_NONE;
1207 hd->resetPending = 0;
1208 hd->abortSCpnt = NULL;
1210 /* Clear the pointer used to store
1211 * single-threaded commands, i.e., those
1212 * issued during a bus scan, dv and
1213 * configuration pages.
1215 hd->cmdPtr = NULL;
1217 /* Initialize this SCSI Hosts' timers
1218 * To use, set the timer expires field
1219 * and add_timer
1221 init_timer(&hd->timer);
1222 hd->timer.data = (unsigned long) hd;
1223 hd->timer.function = mptscsih_timer_expired;
1225 if (ioc->bus_type == SCSI) {
1226 /* Update with the driver setup
1227 * values.
1229 if (ioc->spi_data.maxBusWidth > mpt_width)
1230 ioc->spi_data.maxBusWidth = mpt_width;
1231 if (ioc->spi_data.minSyncFactor < mpt_factor)
1232 ioc->spi_data.minSyncFactor = mpt_factor;
1234 if (ioc->spi_data.minSyncFactor == MPT_ASYNC) {
1235 ioc->spi_data.maxSyncOffset = 0;
1238 ioc->spi_data.Saf_Te = mpt_saf_te;
1240 hd->negoNvram = 0;
1241 #ifndef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1242 hd->negoNvram = MPT_SCSICFG_USE_NVRAM;
1243 #endif
1244 ioc->spi_data.forceDv = 0;
1245 ioc->spi_data.noQas = 0;
1246 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
1247 ioc->spi_data.dvStatus[ii] =
1248 MPT_SCSICFG_NEGOTIATE;
1251 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++)
1252 ioc->spi_data.dvStatus[ii] |=
1253 MPT_SCSICFG_DV_NOT_DONE;
1255 dinitprintk((MYIOC_s_INFO_FMT
1256 "dv %x width %x factor %x saf_te %x\n",
1257 ioc->name, mpt_dv,
1258 mpt_width,
1259 mpt_factor,
1260 mpt_saf_te));
1263 mpt_scsi_hosts++;
1265 error = scsi_add_host (sh, &ioc->pcidev->dev);
1266 if(error) {
1267 dprintk((KERN_ERR MYNAM
1268 "scsi_add_host failed\n"));
1269 goto mptscsih_probe_failed;
1272 scsi_scan_host(sh);
1273 return 0;
1275 mptscsih_probe_failed:
1277 mptscsih_remove(pdev);
1278 return error;
1282 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1284 * mptscsih_remove - Removed scsi devices
1285 * @pdev: Pointer to pci_dev structure
1289 static void
1290 mptscsih_remove(struct pci_dev *pdev)
1292 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1293 struct Scsi_Host *host = ioc->sh;
1294 MPT_SCSI_HOST *hd;
1295 int count;
1296 unsigned long flags;
1298 if(!host)
1299 return;
1301 scsi_remove_host(host);
1303 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1304 /* Check DV thread active */
1305 count = 10 * HZ;
1306 spin_lock_irqsave(&dvtaskQ_lock, flags);
1307 if (dvtaskQ_active) {
1308 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
1309 while(dvtaskQ_active && --count) {
1310 set_current_state(TASK_INTERRUPTIBLE);
1311 schedule_timeout(1);
1313 } else {
1314 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
1316 if (!count)
1317 printk(KERN_ERR MYNAM ": ERROR - DV thread still active!\n");
1318 #if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY)
1319 else
1320 printk(KERN_ERR MYNAM ": DV thread orig %d, count %d\n", 10 * HZ, count);
1321 #endif
1322 #endif
1324 hd = (MPT_SCSI_HOST *)host->hostdata;
1325 if (hd != NULL) {
1326 int sz1;
1328 mptscsih_shutdown(&pdev->dev);
1330 sz1=0;
1332 if (hd->ScsiLookup != NULL) {
1333 sz1 = hd->ioc->req_depth * sizeof(void *);
1334 kfree(hd->ScsiLookup);
1335 hd->ScsiLookup = NULL;
1338 if (hd->Targets != NULL) {
1340 * Free pointer array.
1342 kfree(hd->Targets);
1343 hd->Targets = NULL;
1346 dprintk((MYIOC_s_INFO_FMT
1347 "Free'd ScsiLookup (%d) memory\n",
1348 hd->ioc->name, sz1));
1350 /* NULL the Scsi_Host pointer
1352 hd->ioc->sh = NULL;
1355 scsi_host_put(host);
1356 mpt_scsi_hosts--;
1360 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1362 * mptscsih_shutdown - reboot notifier
1365 static void
1366 mptscsih_shutdown(struct device * dev)
1368 MPT_ADAPTER *ioc = pci_get_drvdata(to_pci_dev(dev));
1369 struct Scsi_Host *host = ioc->sh;
1370 MPT_SCSI_HOST *hd;
1372 if(!host)
1373 return;
1375 hd = (MPT_SCSI_HOST *)host->hostdata;
1377 /* Flush the cache of this adapter
1379 if(hd != NULL)
1380 mptscsih_synchronize_cache(hd, 0);
1384 #ifdef CONFIG_PM
1385 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1387 * mptscsih_suspend - Fusion MPT scsie driver suspend routine.
1391 static int
1392 mptscsih_suspend(struct pci_dev *pdev, pm_message_t state)
1394 mptscsih_shutdown(&pdev->dev);
1395 return 0;
1398 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1400 * mptscsih_resume - Fusion MPT scsi driver resume routine.
1404 static int
1405 mptscsih_resume(struct pci_dev *pdev)
1407 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1408 struct Scsi_Host *host = ioc->sh;
1409 MPT_SCSI_HOST *hd;
1411 if(!host)
1412 return 0;
1414 hd = (MPT_SCSI_HOST *)host->hostdata;
1415 if(!hd)
1416 return 0;
1418 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1420 unsigned long lflags;
1421 spin_lock_irqsave(&dvtaskQ_lock, lflags);
1422 if (!dvtaskQ_active) {
1423 dvtaskQ_active = 1;
1424 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1425 INIT_WORK(&mptscsih_dvTask,
1426 mptscsih_domainValidation, (void *) hd);
1427 schedule_work(&mptscsih_dvTask);
1428 } else {
1429 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1432 #endif
1433 return 0;
1436 #endif
1438 static struct mpt_pci_driver mptscsih_driver = {
1439 .probe = mptscsih_probe,
1440 .remove = mptscsih_remove,
1441 .shutdown = mptscsih_shutdown,
1442 #ifdef CONFIG_PM
1443 .suspend = mptscsih_suspend,
1444 .resume = mptscsih_resume,
1445 #endif
1448 /* SCSI host fops start here... */
1449 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1451 * mptscsih_init - Register MPT adapter(s) as SCSI host(s) with
1452 * linux scsi mid-layer.
1454 * Returns 0 for success, non-zero for failure.
1456 static int __init
1457 mptscsih_init(void)
1460 show_mptmod_ver(my_NAME, my_VERSION);
1462 ScsiDoneCtx = mpt_register(mptscsih_io_done, MPTSCSIH_DRIVER);
1463 ScsiTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSCSIH_DRIVER);
1464 ScsiScanDvCtx = mpt_register(mptscsih_scandv_complete, MPTSCSIH_DRIVER);
1466 if (mpt_event_register(ScsiDoneCtx, mptscsih_event_process) == 0) {
1467 devtprintk((KERN_INFO MYNAM
1468 ": Registered for IOC event notifications\n"));
1471 if (mpt_reset_register(ScsiDoneCtx, mptscsih_ioc_reset) == 0) {
1472 dprintk((KERN_INFO MYNAM
1473 ": Registered for IOC reset notifications\n"));
1476 if(mpt_device_driver_register(&mptscsih_driver,
1477 MPTSCSIH_DRIVER) != 0 ) {
1478 dprintk((KERN_INFO MYNAM
1479 ": failed to register dd callbacks\n"));
1482 return 0;
1486 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1487 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1489 * mptscsih_exit - Unregisters MPT adapter(s)
1492 static void __exit
1493 mptscsih_exit(void)
1495 mpt_device_driver_deregister(MPTSCSIH_DRIVER);
1497 mpt_reset_deregister(ScsiDoneCtx);
1498 dprintk((KERN_INFO MYNAM
1499 ": Deregistered for IOC reset notifications\n"));
1501 mpt_event_deregister(ScsiDoneCtx);
1502 dprintk((KERN_INFO MYNAM
1503 ": Deregistered for IOC event notifications\n"));
1505 mpt_deregister(ScsiScanDvCtx);
1506 mpt_deregister(ScsiTaskCtx);
1507 mpt_deregister(ScsiDoneCtx);
1509 if (info_kbuf != NULL)
1510 kfree(info_kbuf);
1514 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1516 * mptscsih_info - Return information about MPT adapter
1517 * @SChost: Pointer to Scsi_Host structure
1519 * (linux scsi_host_template.info routine)
1521 * Returns pointer to buffer where information was written.
1523 static const char *
1524 mptscsih_info(struct Scsi_Host *SChost)
1526 MPT_SCSI_HOST *h;
1527 int size = 0;
1529 if (info_kbuf == NULL)
1530 if ((info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)
1531 return info_kbuf;
1533 h = (MPT_SCSI_HOST *)SChost->hostdata;
1534 info_kbuf[0] = '\0';
1535 if (h) {
1536 mpt_print_ioc_summary(h->ioc, info_kbuf, &size, 0, 0);
1537 info_kbuf[size-1] = '\0';
1540 return info_kbuf;
1543 struct info_str {
1544 char *buffer;
1545 int length;
1546 int offset;
1547 int pos;
1550 static void copy_mem_info(struct info_str *info, char *data, int len)
1552 if (info->pos + len > info->length)
1553 len = info->length - info->pos;
1555 if (info->pos + len < info->offset) {
1556 info->pos += len;
1557 return;
1560 if (info->pos < info->offset) {
1561 data += (info->offset - info->pos);
1562 len -= (info->offset - info->pos);
1565 if (len > 0) {
1566 memcpy(info->buffer + info->pos, data, len);
1567 info->pos += len;
1571 static int copy_info(struct info_str *info, char *fmt, ...)
1573 va_list args;
1574 char buf[81];
1575 int len;
1577 va_start(args, fmt);
1578 len = vsprintf(buf, fmt, args);
1579 va_end(args);
1581 copy_mem_info(info, buf, len);
1582 return len;
1585 static int mptscsih_host_info(MPT_ADAPTER *ioc, char *pbuf, off_t offset, int len)
1587 struct info_str info;
1589 info.buffer = pbuf;
1590 info.length = len;
1591 info.offset = offset;
1592 info.pos = 0;
1594 copy_info(&info, "%s: %s, ", ioc->name, ioc->prod_name);
1595 copy_info(&info, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING, ioc->facts.FWVersion.Word);
1596 copy_info(&info, "Ports=%d, ", ioc->facts.NumberOfPorts);
1597 copy_info(&info, "MaxQ=%d\n", ioc->req_depth);
1599 return ((info.pos > info.offset) ? info.pos - info.offset : 0);
1602 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1604 * mptscsih_proc_info - Return information about MPT adapter
1606 * (linux scsi_host_template.info routine)
1608 * buffer: if write, user data; if read, buffer for user
1609 * length: if write, return length;
1610 * offset: if write, 0; if read, the current offset into the buffer from
1611 * the previous read.
1612 * hostno: scsi host number
1613 * func: if write = 1; if read = 0
1615 static int
1616 mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
1617 int length, int func)
1619 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
1620 MPT_ADAPTER *ioc = hd->ioc;
1621 int size = 0;
1623 if (func) {
1625 * write is not supported
1627 } else {
1628 if (start)
1629 *start = buffer;
1631 size = mptscsih_host_info(ioc, buffer, offset, length);
1634 return size;
1637 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1638 #define ADD_INDEX_LOG(req_ent) do { } while(0)
1640 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1642 * mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine.
1643 * @SCpnt: Pointer to scsi_cmnd structure
1644 * @done: Pointer SCSI mid-layer IO completion function
1646 * (linux scsi_host_template.queuecommand routine)
1647 * This is the primary SCSI IO start routine. Create a MPI SCSIIORequest
1648 * from a linux scsi_cmnd request and send it to the IOC.
1650 * Returns 0. (rtn value discarded by linux scsi mid-layer)
1652 static int
1653 mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1655 MPT_SCSI_HOST *hd;
1656 MPT_FRAME_HDR *mf;
1657 SCSIIORequest_t *pScsiReq;
1658 VirtDevice *pTarget;
1659 int target;
1660 int lun;
1661 u32 datalen;
1662 u32 scsictl;
1663 u32 scsidir;
1664 u32 cmd_len;
1665 int my_idx;
1666 int ii;
1668 hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata;
1669 target = SCpnt->device->id;
1670 lun = SCpnt->device->lun;
1671 SCpnt->scsi_done = done;
1673 pTarget = hd->Targets[target];
1675 dmfprintk((MYIOC_s_INFO_FMT "qcmd: SCpnt=%p, done()=%p\n",
1676 (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt, done));
1678 if (hd->resetPending) {
1679 dtmprintk((MYIOC_s_WARN_FMT "qcmd: SCpnt=%p timeout + 60HZ\n",
1680 (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt));
1681 return SCSI_MLQUEUE_HOST_BUSY;
1685 * Put together a MPT SCSI request...
1687 if ((mf = mpt_get_msg_frame(ScsiDoneCtx, hd->ioc)) == NULL) {
1688 dprintk((MYIOC_s_WARN_FMT "QueueCmd, no msg frames!!\n",
1689 hd->ioc->name));
1690 return SCSI_MLQUEUE_HOST_BUSY;
1693 pScsiReq = (SCSIIORequest_t *) mf;
1695 my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
1697 ADD_INDEX_LOG(my_idx);
1699 /* BUG FIX! 19991030 -sralston
1700 * TUR's being issued with scsictl=0x02000000 (DATA_IN)!
1701 * Seems we may receive a buffer (datalen>0) even when there
1702 * will be no data transfer! GRRRRR...
1704 if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
1705 datalen = SCpnt->request_bufflen;
1706 scsidir = MPI_SCSIIO_CONTROL_READ; /* DATA IN (host<--ioc<--dev) */
1707 } else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
1708 datalen = SCpnt->request_bufflen;
1709 scsidir = MPI_SCSIIO_CONTROL_WRITE; /* DATA OUT (host-->ioc-->dev) */
1710 } else {
1711 datalen = 0;
1712 scsidir = MPI_SCSIIO_CONTROL_NODATATRANSFER;
1715 /* Default to untagged. Once a target structure has been allocated,
1716 * use the Inquiry data to determine if device supports tagged.
1718 if ( pTarget
1719 && (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)
1720 && (SCpnt->device->tagged_supported)) {
1721 scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
1722 } else {
1723 scsictl = scsidir | MPI_SCSIIO_CONTROL_UNTAGGED;
1726 /* Use the above information to set up the message frame
1728 pScsiReq->TargetID = (u8) target;
1729 pScsiReq->Bus = (u8) SCpnt->device->channel;
1730 pScsiReq->ChainOffset = 0;
1731 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
1732 pScsiReq->CDBLength = SCpnt->cmd_len;
1733 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
1734 pScsiReq->Reserved = 0;
1735 pScsiReq->MsgFlags = mpt_msg_flags();
1736 pScsiReq->LUN[0] = 0;
1737 pScsiReq->LUN[1] = lun;
1738 pScsiReq->LUN[2] = 0;
1739 pScsiReq->LUN[3] = 0;
1740 pScsiReq->LUN[4] = 0;
1741 pScsiReq->LUN[5] = 0;
1742 pScsiReq->LUN[6] = 0;
1743 pScsiReq->LUN[7] = 0;
1744 pScsiReq->Control = cpu_to_le32(scsictl);
1747 * Write SCSI CDB into the message
1749 cmd_len = SCpnt->cmd_len;
1750 for (ii=0; ii < cmd_len; ii++)
1751 pScsiReq->CDB[ii] = SCpnt->cmnd[ii];
1753 for (ii=cmd_len; ii < 16; ii++)
1754 pScsiReq->CDB[ii] = 0;
1756 /* DataLength */
1757 pScsiReq->DataLength = cpu_to_le32(datalen);
1759 /* SenseBuffer low address */
1760 pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
1761 + (my_idx * MPT_SENSE_BUFFER_ALLOC));
1763 /* Now add the SG list
1764 * Always have a SGE even if null length.
1766 if (datalen == 0) {
1767 /* Add a NULL SGE */
1768 mptscsih_add_sge((char *)&pScsiReq->SGL, MPT_SGE_FLAGS_SSIMPLE_READ | 0,
1769 (dma_addr_t) -1);
1770 } else {
1771 /* Add a 32 or 64 bit SGE */
1772 if (mptscsih_AddSGE(hd->ioc, SCpnt, pScsiReq, my_idx) != SUCCESS)
1773 goto fail;
1776 hd->ScsiLookup[my_idx] = SCpnt;
1777 SCpnt->host_scribble = NULL;
1779 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1780 if (hd->ioc->bus_type == SCSI) {
1781 int dvStatus = hd->ioc->spi_data.dvStatus[target];
1782 int issueCmd = 1;
1784 if (dvStatus || hd->ioc->spi_data.forceDv) {
1786 if ((dvStatus & MPT_SCSICFG_NEED_DV) ||
1787 (hd->ioc->spi_data.forceDv & MPT_SCSICFG_NEED_DV)) {
1788 unsigned long lflags;
1789 /* Schedule DV if necessary */
1790 spin_lock_irqsave(&dvtaskQ_lock, lflags);
1791 if (!dvtaskQ_active) {
1792 dvtaskQ_active = 1;
1793 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1794 INIT_WORK(&mptscsih_dvTask, mptscsih_domainValidation, (void *) hd);
1796 schedule_work(&mptscsih_dvTask);
1797 } else {
1798 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1800 hd->ioc->spi_data.forceDv &= ~MPT_SCSICFG_NEED_DV;
1803 /* Trying to do DV to this target, extend timeout.
1804 * Wait to issue until flag is clear
1806 if (dvStatus & MPT_SCSICFG_DV_PENDING) {
1807 mod_timer(&SCpnt->eh_timeout, jiffies + 40 * HZ);
1808 issueCmd = 0;
1811 /* Set the DV flags.
1813 if (dvStatus & MPT_SCSICFG_DV_NOT_DONE)
1814 mptscsih_set_dvflags(hd, pScsiReq);
1816 if (!issueCmd)
1817 goto fail;
1820 #endif
1822 mpt_put_msg_frame(ScsiDoneCtx, hd->ioc, mf);
1823 dmfprintk((MYIOC_s_INFO_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n",
1824 hd->ioc->name, SCpnt, mf, my_idx));
1825 DBG_DUMP_REQUEST_FRAME(mf)
1826 return 0;
1828 fail:
1829 mptscsih_freeChainBuffers(hd->ioc, my_idx);
1830 mpt_free_msg_frame(hd->ioc, mf);
1831 return SCSI_MLQUEUE_HOST_BUSY;
1834 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1836 * mptscsih_freeChainBuffers - Function to free chain buffers associated
1837 * with a SCSI IO request
1838 * @hd: Pointer to the MPT_SCSI_HOST instance
1839 * @req_idx: Index of the SCSI IO request frame.
1841 * Called if SG chain buffer allocation fails and mptscsih callbacks.
1842 * No return.
1844 static void
1845 mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
1847 MPT_FRAME_HDR *chain;
1848 unsigned long flags;
1849 int chain_idx;
1850 int next;
1852 /* Get the first chain index and reset
1853 * tracker state.
1855 chain_idx = ioc->ReqToChain[req_idx];
1856 ioc->ReqToChain[req_idx] = MPT_HOST_NO_CHAIN;
1858 while (chain_idx != MPT_HOST_NO_CHAIN) {
1860 /* Save the next chain buffer index */
1861 next = ioc->ChainToChain[chain_idx];
1863 /* Free this chain buffer and reset
1864 * tracker
1866 ioc->ChainToChain[chain_idx] = MPT_HOST_NO_CHAIN;
1868 chain = (MPT_FRAME_HDR *) (ioc->ChainBuffer
1869 + (chain_idx * ioc->req_sz));
1871 spin_lock_irqsave(&ioc->FreeQlock, flags);
1872 list_add_tail(&chain->u.frame.linkage.list, &ioc->FreeChainQ);
1873 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1875 dmfprintk((MYIOC_s_INFO_FMT "FreeChainBuffers (index %d)\n",
1876 ioc->name, chain_idx));
1878 /* handle next */
1879 chain_idx = next;
1881 return;
1884 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1886 * Reset Handling
1889 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1891 * mptscsih_TMHandler - Generic handler for SCSI Task Management.
1892 * Fall through to mpt_HardResetHandler if: not operational, too many
1893 * failed TM requests or handshake failure.
1895 * @ioc: Pointer to MPT_ADAPTER structure
1896 * @type: Task Management type
1897 * @target: Logical Target ID for reset (if appropriate)
1898 * @lun: Logical Unit for reset (if appropriate)
1899 * @ctx2abort: Context for the task to be aborted (if appropriate)
1901 * Remark: Currently invoked from a non-interrupt thread (_bh).
1903 * Remark: With old EH code, at most 1 SCSI TaskMgmt function per IOC
1904 * will be active.
1906 * Returns 0 for SUCCESS or -1 if FAILED.
1908 static int
1909 mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout)
1911 MPT_ADAPTER *ioc;
1912 int rc = -1;
1913 int doTask = 1;
1914 u32 ioc_raw_state;
1915 unsigned long flags;
1917 /* If FW is being reloaded currently, return success to
1918 * the calling function.
1920 if (hd == NULL)
1921 return 0;
1923 ioc = hd->ioc;
1924 if (ioc == NULL) {
1925 printk(KERN_ERR MYNAM " TMHandler" " NULL ioc!\n");
1926 return FAILED;
1928 dtmprintk((MYIOC_s_INFO_FMT "TMHandler Entered!\n", ioc->name));
1930 // SJR - CHECKME - Can we avoid this here?
1931 // (mpt_HardResetHandler has this check...)
1932 spin_lock_irqsave(&ioc->diagLock, flags);
1933 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)) {
1934 spin_unlock_irqrestore(&ioc->diagLock, flags);
1935 return FAILED;
1937 spin_unlock_irqrestore(&ioc->diagLock, flags);
1939 /* Wait a fixed amount of time for the TM pending flag to be cleared.
1940 * If we time out and not bus reset, then we return a FAILED status to the caller.
1941 * The call to mptscsih_tm_pending_wait() will set the pending flag if we are
1942 * successful. Otherwise, reload the FW.
1944 if (mptscsih_tm_pending_wait(hd) == FAILED) {
1945 if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
1946 dtmprintk((KERN_WARNING MYNAM ": %s: TMHandler abort: "
1947 "Timed out waiting for last TM (%d) to complete! \n",
1948 hd->ioc->name, hd->tmPending));
1949 return FAILED;
1950 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) {
1951 dtmprintk((KERN_WARNING MYNAM ": %s: TMHandler target reset: "
1952 "Timed out waiting for last TM (%d) to complete! \n",
1953 hd->ioc->name, hd->tmPending));
1954 return FAILED;
1955 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
1956 dtmprintk((KERN_WARNING MYNAM ": %s: TMHandler bus reset: "
1957 "Timed out waiting for last TM (%d) to complete! \n",
1958 hd->ioc->name, hd->tmPending));
1959 if (hd->tmPending & (1 << MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS))
1960 return FAILED;
1962 doTask = 0;
1964 } else {
1965 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
1966 hd->tmPending |= (1 << type);
1967 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1970 /* Is operational?
1972 ioc_raw_state = mpt_GetIocState(hd->ioc, 0);
1974 #ifdef MPT_DEBUG_RESET
1975 if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) {
1976 printk(MYIOC_s_WARN_FMT
1977 "TM Handler: IOC Not operational(0x%x)!\n",
1978 hd->ioc->name, ioc_raw_state);
1980 #endif
1982 if (doTask && ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL)
1983 && !(ioc_raw_state & MPI_DOORBELL_ACTIVE)) {
1985 /* Isse the Task Mgmt request.
1987 if (hd->hard_resets < -1)
1988 hd->hard_resets++;
1989 rc = mptscsih_IssueTaskMgmt(hd, type, channel, target, lun, ctx2abort, timeout);
1990 if (rc) {
1991 printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n", hd->ioc->name);
1992 } else {
1993 dtmprintk((MYIOC_s_INFO_FMT "Issue of TaskMgmt Successful!\n", hd->ioc->name));
1997 /* Only fall through to the HRH if this is a bus reset
1999 if ((type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) && (rc ||
2000 ioc->reload_fw || (ioc->alt_ioc && ioc->alt_ioc->reload_fw))) {
2001 dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
2002 hd->ioc->name));
2003 rc = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
2006 dtmprintk((MYIOC_s_INFO_FMT "TMHandler rc = %d!\n", hd->ioc->name, rc));
2008 return rc;
2012 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2014 * mptscsih_IssueTaskMgmt - Generic send Task Management function.
2015 * @hd: Pointer to MPT_SCSI_HOST structure
2016 * @type: Task Management type
2017 * @target: Logical Target ID for reset (if appropriate)
2018 * @lun: Logical Unit for reset (if appropriate)
2019 * @ctx2abort: Context for the task to be aborted (if appropriate)
2021 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
2022 * or a non-interrupt thread. In the former, must not call schedule().
2024 * Not all fields are meaningfull for all task types.
2026 * Returns 0 for SUCCESS, -999 for "no msg frames",
2027 * else other non-zero value returned.
2029 static int
2030 mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout)
2032 MPT_FRAME_HDR *mf;
2033 SCSITaskMgmt_t *pScsiTm;
2034 int ii;
2035 int retval;
2037 /* Return Fail to calling function if no message frames available.
2039 if ((mf = mpt_get_msg_frame(ScsiTaskCtx, hd->ioc)) == NULL) {
2040 dfailprintk((MYIOC_s_ERR_FMT "IssueTaskMgmt, no msg frames!!\n",
2041 hd->ioc->name));
2042 //return FAILED;
2043 return -999;
2045 dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt request @ %p\n",
2046 hd->ioc->name, mf));
2048 /* Format the Request
2050 pScsiTm = (SCSITaskMgmt_t *) mf;
2051 pScsiTm->TargetID = target;
2052 pScsiTm->Bus = channel;
2053 pScsiTm->ChainOffset = 0;
2054 pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
2056 pScsiTm->Reserved = 0;
2057 pScsiTm->TaskType = type;
2058 pScsiTm->Reserved1 = 0;
2059 pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)
2060 ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0;
2062 for (ii= 0; ii < 8; ii++) {
2063 pScsiTm->LUN[ii] = 0;
2065 pScsiTm->LUN[1] = lun;
2067 for (ii=0; ii < 7; ii++)
2068 pScsiTm->Reserved2[ii] = 0;
2070 pScsiTm->TaskMsgContext = ctx2abort;
2072 dtmprintk((MYIOC_s_INFO_FMT
2073 "IssueTaskMgmt: ctx2abort (0x%08x) type=%d\n",
2074 hd->ioc->name, ctx2abort, type));
2076 DBG_DUMP_TM_REQUEST_FRAME((u32 *)pScsiTm);
2078 if ((retval = mpt_send_handshake_request(ScsiTaskCtx, hd->ioc,
2079 sizeof(SCSITaskMgmt_t), (u32*)pScsiTm,
2080 CAN_SLEEP)) != 0) {
2081 dfailprintk((MYIOC_s_ERR_FMT "_send_handshake FAILED!"
2082 " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
2083 hd->ioc, mf));
2084 mpt_free_msg_frame(hd->ioc, mf);
2085 return retval;
2088 if(mptscsih_tm_wait_for_completion(hd, timeout) == FAILED) {
2089 dfailprintk((MYIOC_s_ERR_FMT "_wait_for_completion FAILED!"
2090 " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
2091 hd->ioc, mf));
2092 mpt_free_msg_frame(hd->ioc, mf);
2093 dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
2094 hd->ioc->name));
2095 retval = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
2098 return retval;
2101 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2103 * mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant
2104 * @SCpnt: Pointer to scsi_cmnd structure, IO to be aborted
2106 * (linux scsi_host_template.eh_abort_handler routine)
2108 * Returns SUCCESS or FAILED.
2110 static int
2111 mptscsih_abort(struct scsi_cmnd * SCpnt)
2113 MPT_SCSI_HOST *hd;
2114 MPT_ADAPTER *ioc;
2115 MPT_FRAME_HDR *mf;
2116 u32 ctx2abort;
2117 int scpnt_idx;
2118 spinlock_t *host_lock = SCpnt->device->host->host_lock;
2120 /* If we can't locate our host adapter structure, return FAILED status.
2122 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL) {
2123 SCpnt->result = DID_RESET << 16;
2124 SCpnt->scsi_done(SCpnt);
2125 dfailprintk((KERN_WARNING MYNAM ": mptscsih_abort: "
2126 "Can't locate host! (sc=%p)\n",
2127 SCpnt));
2128 return FAILED;
2131 ioc = hd->ioc;
2132 if (hd->resetPending)
2133 return FAILED;
2135 printk(KERN_WARNING MYNAM ": %s: >> Attempting task abort! (sc=%p)\n",
2136 hd->ioc->name, SCpnt);
2138 if (hd->timeouts < -1)
2139 hd->timeouts++;
2141 /* Find this command
2143 if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) {
2144 /* Cmd not found in ScsiLookup.
2145 * Do OS callback.
2147 SCpnt->result = DID_RESET << 16;
2148 dtmprintk((KERN_WARNING MYNAM ": %s: mptscsih_abort: "
2149 "Command not in the active list! (sc=%p)\n",
2150 hd->ioc->name, SCpnt));
2151 return SUCCESS;
2154 /* Most important! Set TaskMsgContext to SCpnt's MsgContext!
2155 * (the IO to be ABORT'd)
2157 * NOTE: Since we do not byteswap MsgContext, we do not
2158 * swap it here either. It is an opaque cookie to
2159 * the controller, so it does not matter. -DaveM
2161 mf = MPT_INDEX_2_MFPTR(hd->ioc, scpnt_idx);
2162 ctx2abort = mf->u.frame.hwhdr.msgctxu.MsgContext;
2164 hd->abortSCpnt = SCpnt;
2166 spin_unlock_irq(host_lock);
2167 if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
2168 SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun,
2169 ctx2abort, 2 /* 2 second timeout */)
2170 < 0) {
2172 /* The TM request failed and the subsequent FW-reload failed!
2173 * Fatal error case.
2175 printk(MYIOC_s_WARN_FMT "Error issuing abort task! (sc=%p)\n",
2176 hd->ioc->name, SCpnt);
2178 /* We must clear our pending flag before clearing our state.
2180 hd->tmPending = 0;
2181 hd->tmState = TM_STATE_NONE;
2183 spin_lock_irq(host_lock);
2185 /* Unmap the DMA buffers, if any. */
2186 if (SCpnt->use_sg) {
2187 pci_unmap_sg(ioc->pcidev, (struct scatterlist *) SCpnt->request_buffer,
2188 SCpnt->use_sg, SCpnt->sc_data_direction);
2189 } else if (SCpnt->request_bufflen) {
2190 pci_unmap_single(ioc->pcidev, SCpnt->SCp.dma_handle,
2191 SCpnt->request_bufflen, SCpnt->sc_data_direction);
2193 hd->ScsiLookup[scpnt_idx] = NULL;
2194 SCpnt->result = DID_RESET << 16;
2195 SCpnt->scsi_done(SCpnt); /* Issue the command callback */
2196 mptscsih_freeChainBuffers(ioc, scpnt_idx);
2197 mpt_free_msg_frame(ioc, mf);
2198 return FAILED;
2200 spin_lock_irq(host_lock);
2201 return SUCCESS;
2204 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2206 * mptscsih_dev_reset - Perform a SCSI TARGET_RESET! new_eh variant
2207 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
2209 * (linux scsi_host_template.eh_dev_reset_handler routine)
2211 * Returns SUCCESS or FAILED.
2213 static int
2214 mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
2216 MPT_SCSI_HOST *hd;
2217 spinlock_t *host_lock = SCpnt->device->host->host_lock;
2219 /* If we can't locate our host adapter structure, return FAILED status.
2221 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
2222 dtmprintk((KERN_WARNING MYNAM ": mptscsih_dev_reset: "
2223 "Can't locate host! (sc=%p)\n",
2224 SCpnt));
2225 return FAILED;
2228 if (hd->resetPending)
2229 return FAILED;
2231 printk(KERN_WARNING MYNAM ": %s: >> Attempting target reset! (sc=%p)\n",
2232 hd->ioc->name, SCpnt);
2234 spin_unlock_irq(host_lock);
2235 if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
2236 SCpnt->device->channel, SCpnt->device->id,
2237 0, 0, 5 /* 5 second timeout */)
2238 < 0){
2239 /* The TM request failed and the subsequent FW-reload failed!
2240 * Fatal error case.
2242 printk(MYIOC_s_WARN_FMT "Error processing TaskMgmt request (sc=%p)\n",
2243 hd->ioc->name, SCpnt);
2244 hd->tmPending = 0;
2245 hd->tmState = TM_STATE_NONE;
2246 spin_lock_irq(host_lock);
2247 return FAILED;
2249 spin_lock_irq(host_lock);
2250 return SUCCESS;
2254 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2256 * mptscsih_bus_reset - Perform a SCSI BUS_RESET! new_eh variant
2257 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
2259 * (linux scsi_host_template.eh_bus_reset_handler routine)
2261 * Returns SUCCESS or FAILED.
2263 static int
2264 mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
2266 MPT_SCSI_HOST *hd;
2267 spinlock_t *host_lock = SCpnt->device->host->host_lock;
2269 /* If we can't locate our host adapter structure, return FAILED status.
2271 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
2272 dtmprintk((KERN_WARNING MYNAM ": mptscsih_bus_reset: "
2273 "Can't locate host! (sc=%p)\n",
2274 SCpnt ) );
2275 return FAILED;
2278 printk(KERN_WARNING MYNAM ": %s: >> Attempting bus reset! (sc=%p)\n",
2279 hd->ioc->name, SCpnt);
2281 if (hd->timeouts < -1)
2282 hd->timeouts++;
2284 /* We are now ready to execute the task management request. */
2285 spin_unlock_irq(host_lock);
2286 if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
2287 SCpnt->device->channel, 0, 0, 0, 5 /* 5 second timeout */)
2288 < 0){
2290 /* The TM request failed and the subsequent FW-reload failed!
2291 * Fatal error case.
2293 printk(MYIOC_s_WARN_FMT
2294 "Error processing TaskMgmt request (sc=%p)\n",
2295 hd->ioc->name, SCpnt);
2296 hd->tmPending = 0;
2297 hd->tmState = TM_STATE_NONE;
2298 spin_lock_irq(host_lock);
2299 return FAILED;
2301 spin_lock_irq(host_lock);
2302 return SUCCESS;
2305 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2307 * mptscsih_host_reset - Perform a SCSI host adapter RESET!
2308 * new_eh variant
2309 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
2311 * (linux scsi_host_template.eh_host_reset_handler routine)
2313 * Returns SUCCESS or FAILED.
2315 static int
2316 mptscsih_host_reset(struct scsi_cmnd *SCpnt)
2318 MPT_SCSI_HOST * hd;
2319 int status = SUCCESS;
2320 spinlock_t *host_lock = SCpnt->device->host->host_lock;
2322 /* If we can't locate the host to reset, then we failed. */
2323 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
2324 dtmprintk( ( KERN_WARNING MYNAM ": mptscsih_host_reset: "
2325 "Can't locate host! (sc=%p)\n",
2326 SCpnt ) );
2327 return FAILED;
2330 printk(KERN_WARNING MYNAM ": %s: >> Attempting host reset! (sc=%p)\n",
2331 hd->ioc->name, SCpnt);
2333 /* If our attempts to reset the host failed, then return a failed
2334 * status. The host will be taken off line by the SCSI mid-layer.
2336 spin_unlock_irq(host_lock);
2337 if (mpt_HardResetHandler(hd->ioc, CAN_SLEEP) < 0){
2338 status = FAILED;
2339 } else {
2340 /* Make sure TM pending is cleared and TM state is set to
2341 * NONE.
2343 hd->tmPending = 0;
2344 hd->tmState = TM_STATE_NONE;
2346 spin_lock_irq(host_lock);
2349 dtmprintk( ( KERN_WARNING MYNAM ": mptscsih_host_reset: "
2350 "Status = %s\n",
2351 (status == SUCCESS) ? "SUCCESS" : "FAILED" ) );
2353 return status;
2356 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2358 * mptscsih_tm_pending_wait - wait for pending task management request to
2359 * complete.
2360 * @hd: Pointer to MPT host structure.
2362 * Returns {SUCCESS,FAILED}.
2364 static int
2365 mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd)
2367 unsigned long flags;
2368 int loop_count = 4 * 10; /* Wait 10 seconds */
2369 int status = FAILED;
2371 do {
2372 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
2373 if (hd->tmState == TM_STATE_NONE) {
2374 hd->tmState = TM_STATE_IN_PROGRESS;
2375 hd->tmPending = 1;
2376 status = SUCCESS;
2377 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2378 break;
2380 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2381 msleep(250);
2382 } while (--loop_count);
2384 return status;
2387 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2389 * mptscsih_tm_wait_for_completion - wait for completion of TM task
2390 * @hd: Pointer to MPT host structure.
2392 * Returns {SUCCESS,FAILED}.
2394 static int
2395 mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout )
2397 unsigned long flags;
2398 int loop_count = 4 * timeout;
2399 int status = FAILED;
2401 do {
2402 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
2403 if(hd->tmPending == 0) {
2404 status = SUCCESS;
2405 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2406 break;
2408 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2409 msleep_interruptible(250);
2410 } while (--loop_count);
2412 return status;
2415 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2417 * mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
2418 * @ioc: Pointer to MPT_ADAPTER structure
2419 * @mf: Pointer to SCSI task mgmt request frame
2420 * @mr: Pointer to SCSI task mgmt reply frame
2422 * This routine is called from mptbase.c::mpt_interrupt() at the completion
2423 * of any SCSI task management request.
2424 * This routine is registered with the MPT (base) driver at driver
2425 * load/init time via the mpt_register() API call.
2427 * Returns 1 indicating alloc'd request frame ptr should be freed.
2429 static int
2430 mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
2432 SCSITaskMgmtReply_t *pScsiTmReply;
2433 SCSITaskMgmt_t *pScsiTmReq;
2434 MPT_SCSI_HOST *hd;
2435 unsigned long flags;
2436 u16 iocstatus;
2437 u8 tmType;
2439 dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt completed (mf=%p,mr=%p)\n",
2440 ioc->name, mf, mr));
2441 if (ioc->sh) {
2442 /* Depending on the thread, a timer is activated for
2443 * the TM request. Delete this timer on completion of TM.
2444 * Decrement count of outstanding TM requests.
2446 hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
2447 } else {
2448 dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt Complete: NULL Scsi Host Ptr\n",
2449 ioc->name));
2450 return 1;
2453 if (mr == NULL) {
2454 dtmprintk((MYIOC_s_WARN_FMT "ERROR! TaskMgmt Reply: NULL Request %p\n",
2455 ioc->name, mf));
2456 return 1;
2457 } else {
2458 pScsiTmReply = (SCSITaskMgmtReply_t*)mr;
2459 pScsiTmReq = (SCSITaskMgmt_t*)mf;
2461 /* Figure out if this was ABORT_TASK, TARGET_RESET, or BUS_RESET! */
2462 tmType = pScsiTmReq->TaskType;
2464 dtmprintk((MYIOC_s_WARN_FMT " TaskType = %d, TerminationCount=%d\n",
2465 ioc->name, tmType, le32_to_cpu(pScsiTmReply->TerminationCount)));
2466 DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply);
2468 iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2469 dtmprintk((MYIOC_s_WARN_FMT " SCSI TaskMgmt (%d) IOCStatus=%04x IOCLogInfo=%08x\n",
2470 ioc->name, tmType, iocstatus, le32_to_cpu(pScsiTmReply->IOCLogInfo)));
2471 /* Error? (anything non-zero?) */
2472 if (iocstatus) {
2474 /* clear flags and continue.
2476 if (tmType == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK)
2477 hd->abortSCpnt = NULL;
2479 /* If an internal command is present
2480 * or the TM failed - reload the FW.
2481 * FC FW may respond FAILED to an ABORT
2483 if (tmType == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
2484 if ((hd->cmdPtr) ||
2485 (iocstatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED)) {
2486 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0) {
2487 printk((KERN_WARNING
2488 " Firmware Reload FAILED!!\n"));
2492 } else {
2493 dtmprintk((MYIOC_s_WARN_FMT " TaskMgmt SUCCESS\n", ioc->name));
2495 hd->abortSCpnt = NULL;
2500 spin_lock_irqsave(&ioc->FreeQlock, flags);
2501 hd->tmPending = 0;
2502 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2503 hd->tmState = TM_STATE_NONE;
2505 return 1;
2508 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2510 * This is anyones guess quite frankly.
2512 static int
2513 mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
2514 sector_t capacity, int geom[])
2516 int heads;
2517 int sectors;
2518 sector_t cylinders;
2519 ulong dummy;
2521 heads = 64;
2522 sectors = 32;
2524 dummy = heads * sectors;
2525 cylinders = capacity;
2526 sector_div(cylinders,dummy);
2529 * Handle extended translation size for logical drives
2530 * > 1Gb
2532 if ((ulong)capacity >= 0x200000) {
2533 heads = 255;
2534 sectors = 63;
2535 dummy = heads * sectors;
2536 cylinders = capacity;
2537 sector_div(cylinders,dummy);
2540 /* return result */
2541 geom[0] = heads;
2542 geom[1] = sectors;
2543 geom[2] = cylinders;
2545 dprintk((KERN_NOTICE
2546 ": bios_param: Id=%i Lun=%i Channel=%i CHS=%i/%i/%i\n",
2547 sdev->id, sdev->lun,sdev->channel,(int)cylinders,heads,sectors));
2549 return 0;
2552 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2554 * OS entry point to allow host driver to alloc memory
2555 * for each scsi device. Called once per device the bus scan.
2556 * Return non-zero if allocation fails.
2557 * Init memory once per id (not LUN).
2559 static int
2560 mptscsih_slave_alloc(struct scsi_device *device)
2562 struct Scsi_Host *host = device->host;
2563 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
2564 VirtDevice *vdev;
2565 uint target = device->id;
2567 if (hd == NULL)
2568 return -ENODEV;
2570 if ((vdev = hd->Targets[target]) != NULL)
2571 goto out;
2573 vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL);
2574 if (!vdev) {
2575 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
2576 hd->ioc->name, sizeof(VirtDevice));
2577 return -ENOMEM;
2580 memset(vdev, 0, sizeof(VirtDevice));
2581 vdev->tflags = MPT_TARGET_FLAGS_Q_YES;
2582 vdev->ioc_id = hd->ioc->id;
2583 vdev->target_id = device->id;
2584 vdev->bus_id = device->channel;
2585 vdev->raidVolume = 0;
2586 hd->Targets[device->id] = vdev;
2587 if (hd->ioc->bus_type == SCSI) {
2588 if (hd->ioc->spi_data.isRaid & (1 << device->id)) {
2589 vdev->raidVolume = 1;
2590 ddvtprintk((KERN_INFO
2591 "RAID Volume @ id %d\n", device->id));
2593 } else {
2594 vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
2597 out:
2598 vdev->num_luns++;
2599 return 0;
2602 static int mptscsih_is_raid_volume(MPT_SCSI_HOST *hd, uint id)
2604 int i;
2606 if (!hd->ioc->spi_data.isRaid || !hd->ioc->spi_data.pIocPg3)
2607 return 0;
2609 for (i = 0; i < hd->ioc->spi_data.pIocPg3->NumPhysDisks; i++) {
2610 if (id == hd->ioc->spi_data.pIocPg3->PhysDisk[i].PhysDiskID)
2611 return 1;
2614 return 0;
2618 * OS entry point to allow for host driver to free allocated memory
2619 * Called if no device present or device being unloaded
2621 static void
2622 mptscsih_slave_destroy(struct scsi_device *device)
2624 struct Scsi_Host *host = device->host;
2625 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
2626 VirtDevice *vdev;
2627 uint target = device->id;
2628 uint lun = device->lun;
2630 if (hd == NULL)
2631 return;
2633 mptscsih_search_running_cmds(hd, target, lun);
2635 vdev = hd->Targets[target];
2636 vdev->luns[0] &= ~(1 << lun);
2637 if (--vdev->num_luns)
2638 return;
2640 kfree(hd->Targets[target]);
2641 hd->Targets[target] = NULL;
2643 if (hd->ioc->bus_type == SCSI) {
2644 if (mptscsih_is_raid_volume(hd, target)) {
2645 hd->ioc->spi_data.forceDv |= MPT_SCSICFG_RELOAD_IOC_PG3;
2646 } else {
2647 hd->ioc->spi_data.dvStatus[target] =
2648 MPT_SCSICFG_NEGOTIATE;
2650 if (!hd->negoNvram) {
2651 hd->ioc->spi_data.dvStatus[target] |=
2652 MPT_SCSICFG_DV_NOT_DONE;
2658 static void
2659 mptscsih_set_queue_depth(struct scsi_device *device, MPT_SCSI_HOST *hd,
2660 VirtDevice *pTarget, int qdepth)
2662 int max_depth;
2663 int tagged;
2665 if (hd->ioc->bus_type == SCSI) {
2666 if (pTarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) {
2667 if (!(pTarget->tflags & MPT_TARGET_FLAGS_Q_YES))
2668 max_depth = 1;
2669 else if (((pTarget->inq_data[0] & 0x1f) == 0x00) &&
2670 (pTarget->minSyncFactor <= MPT_ULTRA160 ))
2671 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2672 else
2673 max_depth = MPT_SCSI_CMD_PER_DEV_LOW;
2674 } else {
2675 /* error case - No Inq. Data */
2676 max_depth = 1;
2678 } else
2679 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2681 if (qdepth > max_depth)
2682 qdepth = max_depth;
2683 if (qdepth == 1)
2684 tagged = 0;
2685 else
2686 tagged = MSG_SIMPLE_TAG;
2688 scsi_adjust_queue_depth(device, tagged, qdepth);
2693 * OS entry point to adjust the queue_depths on a per-device basis.
2694 * Called once per device the bus scan. Use it to force the queue_depth
2695 * member to 1 if a device does not support Q tags.
2696 * Return non-zero if fails.
2698 static int
2699 mptscsih_slave_configure(struct scsi_device *device)
2701 struct Scsi_Host *sh = device->host;
2702 VirtDevice *pTarget;
2703 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sh->hostdata;
2705 if ((hd == NULL) || (hd->Targets == NULL)) {
2706 return 0;
2709 dsprintk((MYIOC_s_INFO_FMT
2710 "device @ %p, id=%d, LUN=%d, channel=%d\n",
2711 hd->ioc->name, device, device->id, device->lun, device->channel));
2712 dsprintk((MYIOC_s_INFO_FMT
2713 "sdtr %d wdtr %d ppr %d inq length=%d\n",
2714 hd->ioc->name, device->sdtr, device->wdtr,
2715 device->ppr, device->inquiry_len));
2717 if (device->id > sh->max_id) {
2718 /* error case, should never happen */
2719 scsi_adjust_queue_depth(device, 0, 1);
2720 goto slave_configure_exit;
2723 pTarget = hd->Targets[device->id];
2725 if (pTarget == NULL) {
2726 /* Driver doesn't know about this device.
2727 * Kernel may generate a "Dummy Lun 0" which
2728 * may become a real Lun if a
2729 * "scsi add-single-device" command is executed
2730 * while the driver is active (hot-plug a
2731 * device). LSI Raid controllers need
2732 * queue_depth set to DEV_HIGH for this reason.
2734 scsi_adjust_queue_depth(device, MSG_SIMPLE_TAG,
2735 MPT_SCSI_CMD_PER_DEV_HIGH);
2736 goto slave_configure_exit;
2739 mptscsih_initTarget(hd, device->channel, device->id, device->lun,
2740 device->inquiry, device->inquiry_len );
2741 mptscsih_set_queue_depth(device, hd, pTarget, MPT_SCSI_CMD_PER_DEV_HIGH);
2743 dsprintk((MYIOC_s_INFO_FMT
2744 "Queue depth=%d, tflags=%x\n",
2745 hd->ioc->name, device->queue_depth, pTarget->tflags));
2747 dsprintk((MYIOC_s_INFO_FMT
2748 "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
2749 hd->ioc->name, pTarget->negoFlags, pTarget->maxOffset, pTarget->minSyncFactor));
2751 slave_configure_exit:
2753 dsprintk((MYIOC_s_INFO_FMT
2754 "tagged %d, simple %d, ordered %d\n",
2755 hd->ioc->name,device->tagged_supported, device->simple_tags,
2756 device->ordered_tags));
2758 return 0;
2761 static ssize_t
2762 mptscsih_store_queue_depth(struct device *dev, const char *buf, size_t count)
2764 int depth;
2765 struct scsi_device *sdev = to_scsi_device(dev);
2766 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) sdev->host->hostdata;
2767 VirtDevice *pTarget;
2769 depth = simple_strtoul(buf, NULL, 0);
2770 if (depth == 0)
2771 return -EINVAL;
2772 pTarget = hd->Targets[sdev->id];
2773 if (pTarget == NULL)
2774 return -EINVAL;
2775 mptscsih_set_queue_depth(sdev, (MPT_SCSI_HOST *) sdev->host->hostdata,
2776 pTarget, depth);
2777 return count;
2780 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2782 * Private routines...
2785 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2786 /* Utility function to copy sense data from the scsi_cmnd buffer
2787 * to the FC and SCSI target structures.
2790 static void
2791 copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
2793 VirtDevice *target;
2794 SCSIIORequest_t *pReq;
2795 u32 sense_count = le32_to_cpu(pScsiReply->SenseCount);
2796 int index;
2798 /* Get target structure
2800 pReq = (SCSIIORequest_t *) mf;
2801 index = (int) pReq->TargetID;
2802 target = hd->Targets[index];
2804 if (sense_count) {
2805 u8 *sense_data;
2806 int req_index;
2808 /* Copy the sense received into the scsi command block. */
2809 req_index = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2810 sense_data = ((u8 *)hd->ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC));
2811 memcpy(sc->sense_buffer, sense_data, SNS_LEN(sc));
2813 /* Log SMART data (asc = 0x5D, non-IM case only) if required.
2815 if ((hd->ioc->events) && (hd->ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) {
2816 if ((sense_data[12] == 0x5D) && (target->raidVolume == 0)) {
2817 int idx;
2818 MPT_ADAPTER *ioc = hd->ioc;
2820 idx = ioc->eventContext % ioc->eventLogSize;
2821 ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
2822 ioc->events[idx].eventContext = ioc->eventContext;
2824 ioc->events[idx].data[0] = (pReq->LUN[1] << 24) ||
2825 (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) ||
2826 (pReq->Bus << 8) || pReq->TargetID;
2828 ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12];
2830 ioc->eventContext++;
2833 } else {
2834 dprintk((MYIOC_s_INFO_FMT "Hmmm... SenseData len=0! (?)\n",
2835 hd->ioc->name));
2839 static u32
2840 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc)
2842 MPT_SCSI_HOST *hd;
2843 int i;
2845 hd = (MPT_SCSI_HOST *) sc->device->host->hostdata;
2847 for (i = 0; i < hd->ioc->req_depth; i++) {
2848 if (hd->ScsiLookup[i] == sc) {
2849 return i;
2853 return -1;
2856 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2857 static int
2858 mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2860 MPT_SCSI_HOST *hd;
2861 unsigned long flags;
2863 dtmprintk((KERN_WARNING MYNAM
2864 ": IOC %s_reset routed to SCSI host driver!\n",
2865 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
2866 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
2868 /* If a FW reload request arrives after base installed but
2869 * before all scsi hosts have been attached, then an alt_ioc
2870 * may have a NULL sh pointer.
2872 if ((ioc->sh == NULL) || (ioc->sh->hostdata == NULL))
2873 return 0;
2874 else
2875 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2877 if (reset_phase == MPT_IOC_SETUP_RESET) {
2878 dtmprintk((MYIOC_s_WARN_FMT "Setup-Diag Reset\n", ioc->name));
2880 /* Clean Up:
2881 * 1. Set Hard Reset Pending Flag
2882 * All new commands go to doneQ
2884 hd->resetPending = 1;
2886 } else if (reset_phase == MPT_IOC_PRE_RESET) {
2887 dtmprintk((MYIOC_s_WARN_FMT "Pre-Diag Reset\n", ioc->name));
2889 /* 2. Flush running commands
2890 * Clean ScsiLookup (and associated memory)
2891 * AND clean mytaskQ
2894 /* 2b. Reply to OS all known outstanding I/O commands.
2896 mptscsih_flush_running_cmds(hd);
2898 /* 2c. If there was an internal command that
2899 * has not completed, configuration or io request,
2900 * free these resources.
2902 if (hd->cmdPtr) {
2903 del_timer(&hd->timer);
2904 mpt_free_msg_frame(ioc, hd->cmdPtr);
2907 dtmprintk((MYIOC_s_WARN_FMT "Pre-Reset complete.\n", ioc->name));
2909 } else {
2910 dtmprintk((MYIOC_s_WARN_FMT "Post-Diag Reset\n", ioc->name));
2912 /* Once a FW reload begins, all new OS commands are
2913 * redirected to the doneQ w/ a reset status.
2914 * Init all control structures.
2917 /* ScsiLookup initialization
2920 int ii;
2921 for (ii=0; ii < hd->ioc->req_depth; ii++)
2922 hd->ScsiLookup[ii] = NULL;
2925 /* 2. Chain Buffer initialization
2928 /* 4. Renegotiate to all devices, if SCSI
2930 if (ioc->bus_type == SCSI) {
2931 dnegoprintk(("writeSDP1: ALL_IDS USE_NVRAM\n"));
2932 mptscsih_writeSDP1(hd, 0, 0, MPT_SCSICFG_ALL_IDS | MPT_SCSICFG_USE_NVRAM);
2935 /* 5. Enable new commands to be posted
2937 spin_lock_irqsave(&ioc->FreeQlock, flags);
2938 hd->tmPending = 0;
2939 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2940 hd->resetPending = 0;
2941 hd->tmState = TM_STATE_NONE;
2943 /* 6. If there was an internal command,
2944 * wake this process up.
2946 if (hd->cmdPtr) {
2948 * Wake up the original calling thread
2950 hd->pLocal = &hd->localReply;
2951 hd->pLocal->completion = MPT_SCANDV_DID_RESET;
2952 scandv_wait_done = 1;
2953 wake_up(&scandv_waitq);
2954 hd->cmdPtr = NULL;
2957 /* 7. Set flag to force DV and re-read IOC Page 3
2959 if (ioc->bus_type == SCSI) {
2960 ioc->spi_data.forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
2961 ddvtprintk(("Set reload IOC Pg3 Flag\n"));
2964 dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name));
2968 return 1; /* currently means nothing really */
2971 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2972 static int
2973 mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2975 MPT_SCSI_HOST *hd;
2976 u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
2978 devtprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
2979 ioc->name, event));
2981 switch (event) {
2982 case MPI_EVENT_UNIT_ATTENTION: /* 03 */
2983 /* FIXME! */
2984 break;
2985 case MPI_EVENT_IOC_BUS_RESET: /* 04 */
2986 case MPI_EVENT_EXT_BUS_RESET: /* 05 */
2987 hd = NULL;
2988 if (ioc->sh) {
2989 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2990 if (hd && (ioc->bus_type == SCSI) && (hd->soft_resets < -1))
2991 hd->soft_resets++;
2993 break;
2994 case MPI_EVENT_LOGOUT: /* 09 */
2995 /* FIXME! */
2996 break;
2999 * CHECKME! Don't think we need to do
3000 * anything for these, but...
3002 case MPI_EVENT_RESCAN: /* 06 */
3003 case MPI_EVENT_LINK_STATUS_CHANGE: /* 07 */
3004 case MPI_EVENT_LOOP_STATE_CHANGE: /* 08 */
3006 * CHECKME! Falling thru...
3008 break;
3010 case MPI_EVENT_INTEGRATED_RAID: /* 0B */
3011 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
3012 /* negoNvram set to 0 if DV enabled and to USE_NVRAM if
3013 * if DV disabled. Need to check for target mode.
3015 hd = NULL;
3016 if (ioc->sh)
3017 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
3019 if (hd && (ioc->bus_type == SCSI) && (hd->negoNvram == 0)) {
3020 ScsiCfgData *pSpi;
3021 Ioc3PhysDisk_t *pPDisk;
3022 int numPDisk;
3023 u8 reason;
3024 u8 physDiskNum;
3026 reason = (le32_to_cpu(pEvReply->Data[0]) & 0x00FF0000) >> 16;
3027 if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
3028 /* New or replaced disk.
3029 * Set DV flag and schedule DV.
3031 pSpi = &ioc->spi_data;
3032 physDiskNum = (le32_to_cpu(pEvReply->Data[0]) & 0xFF000000) >> 24;
3033 ddvtprintk(("DV requested for phys disk id %d\n", physDiskNum));
3034 if (pSpi->pIocPg3) {
3035 pPDisk = pSpi->pIocPg3->PhysDisk;
3036 numPDisk =pSpi->pIocPg3->NumPhysDisks;
3038 while (numPDisk) {
3039 if (physDiskNum == pPDisk->PhysDiskNum) {
3040 pSpi->dvStatus[pPDisk->PhysDiskID] = (MPT_SCSICFG_NEED_DV | MPT_SCSICFG_DV_NOT_DONE);
3041 pSpi->forceDv = MPT_SCSICFG_NEED_DV;
3042 ddvtprintk(("NEED_DV set for phys disk id %d\n", pPDisk->PhysDiskID));
3043 break;
3045 pPDisk++;
3046 numPDisk--;
3049 if (numPDisk == 0) {
3050 /* The physical disk that needs DV was not found
3051 * in the stored IOC Page 3. The driver must reload
3052 * this page. DV routine will set the NEED_DV flag for
3053 * all phys disks that have DV_NOT_DONE set.
3055 pSpi->forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
3056 ddvtprintk(("phys disk %d not found. Setting reload IOC Pg3 Flag\n", physDiskNum));
3061 #endif
3063 #if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY)
3064 printk("Raid Event RF: ");
3066 u32 *m = (u32 *)pEvReply;
3067 int ii;
3068 int n = (int)pEvReply->MsgLength;
3069 for (ii=6; ii < n; ii++)
3070 printk(" %08x", le32_to_cpu(m[ii]));
3071 printk("\n");
3073 #endif
3074 break;
3076 case MPI_EVENT_NONE: /* 00 */
3077 case MPI_EVENT_LOG_DATA: /* 01 */
3078 case MPI_EVENT_STATE_CHANGE: /* 02 */
3079 case MPI_EVENT_EVENT_CHANGE: /* 0A */
3080 default:
3081 dprintk((KERN_INFO " Ignoring event (=%02Xh)\n", event));
3082 break;
3085 return 1; /* currently means nothing really */
3088 static struct device_attribute mptscsih_queue_depth_attr = {
3089 .attr = {
3090 .name = "queue_depth",
3091 .mode = S_IWUSR,
3093 .store = mptscsih_store_queue_depth,
3096 static struct device_attribute *mptscsih_dev_attrs[] = {
3097 &mptscsih_queue_depth_attr,
3098 NULL,
3101 static struct scsi_host_template driver_template = {
3102 .proc_name = "mptscsih",
3103 .proc_info = mptscsih_proc_info,
3104 .name = "MPT SCSI Host",
3105 .info = mptscsih_info,
3106 .queuecommand = mptscsih_qcmd,
3107 .slave_alloc = mptscsih_slave_alloc,
3108 .slave_configure = mptscsih_slave_configure,
3109 .slave_destroy = mptscsih_slave_destroy,
3110 .eh_abort_handler = mptscsih_abort,
3111 .eh_device_reset_handler = mptscsih_dev_reset,
3112 .eh_bus_reset_handler = mptscsih_bus_reset,
3113 .eh_host_reset_handler = mptscsih_host_reset,
3114 .bios_param = mptscsih_bios_param,
3115 .can_queue = MPT_SCSI_CAN_QUEUE,
3116 .this_id = -1,
3117 .sg_tablesize = MPT_SCSI_SG_DEPTH,
3118 .max_sectors = 8192,
3119 .cmd_per_lun = 7,
3120 .use_clustering = ENABLE_CLUSTERING,
3121 .sdev_attrs = mptscsih_dev_attrs,
3124 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3126 * mptscsih_initTarget - Target, LUN alloc/free functionality.
3127 * @hd: Pointer to MPT_SCSI_HOST structure
3128 * @bus_id: Bus number (?)
3129 * @target_id: SCSI target id
3130 * @lun: SCSI LUN id
3131 * @data: Pointer to data
3132 * @dlen: Number of INQUIRY bytes
3134 * NOTE: It's only SAFE to call this routine if data points to
3135 * sane & valid STANDARD INQUIRY data!
3137 * Allocate and initialize memory for this target.
3138 * Save inquiry data.
3141 static void
3142 mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *data, int dlen)
3144 int indexed_lun, lun_index;
3145 VirtDevice *vdev;
3146 ScsiCfgData *pSpi;
3147 char data_56;
3149 dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n",
3150 hd->ioc->name, bus_id, target_id, lun, hd));
3153 * If the peripheral qualifier filter is enabled then if the target reports a 0x1
3154 * (i.e. The targer is capable of supporting the specified peripheral device type
3155 * on this logical unit; however, the physical device is not currently connected
3156 * to this logical unit) it will be converted to a 0x3 (i.e. The target is not
3157 * capable of supporting a physical device on this logical unit). This is to work
3158 * around a bug in th emid-layer in some distributions in which the mid-layer will
3159 * continue to try to communicate to the LUN and evntually create a dummy LUN.
3161 if (mpt_pq_filter && dlen && (data[0] & 0xE0))
3162 data[0] |= 0x40;
3164 /* Is LUN supported? If so, upper 2 bits will be 0
3165 * in first byte of inquiry data.
3167 if (data[0] & 0xe0)
3168 return;
3170 if ((vdev = hd->Targets[target_id]) == NULL) {
3171 return;
3174 lun_index = (lun >> 5); /* 32 luns per lun_index */
3175 indexed_lun = (lun % 32);
3176 vdev->luns[lun_index] |= (1 << indexed_lun);
3178 if (hd->ioc->bus_type == SCSI) {
3179 if ((data[0] == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) {
3180 /* Treat all Processors as SAF-TE if
3181 * command line option is set */
3182 vdev->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
3183 mptscsih_writeIOCPage4(hd, target_id, bus_id);
3184 }else if ((data[0] == TYPE_PROCESSOR) &&
3185 !(vdev->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) {
3186 if ( dlen > 49 ) {
3187 vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
3188 if ( data[44] == 'S' &&
3189 data[45] == 'A' &&
3190 data[46] == 'F' &&
3191 data[47] == '-' &&
3192 data[48] == 'T' &&
3193 data[49] == 'E' ) {
3194 vdev->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
3195 mptscsih_writeIOCPage4(hd, target_id, bus_id);
3199 if (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY)) {
3200 if ( dlen > 8 ) {
3201 memcpy (vdev->inq_data, data, 8);
3202 } else {
3203 memcpy (vdev->inq_data, data, dlen);
3206 /* If have not done DV, set the DV flag.
3208 pSpi = &hd->ioc->spi_data;
3209 if ((data[0] == TYPE_TAPE) || (data[0] == TYPE_PROCESSOR)) {
3210 if (pSpi->dvStatus[target_id] & MPT_SCSICFG_DV_NOT_DONE)
3211 pSpi->dvStatus[target_id] |= MPT_SCSICFG_NEED_DV;
3214 vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
3217 data_56 = 0x0F; /* Default to full capabilities if Inq data length is < 57 */
3218 if (dlen > 56) {
3219 if ( (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_56))) {
3220 /* Update the target capabilities
3222 data_56 = data[56];
3223 vdev->tflags |= MPT_TARGET_FLAGS_VALID_56;
3226 mptscsih_setTargetNegoParms(hd, vdev, data_56);
3227 } else {
3228 /* Initial Inquiry may not request enough data bytes to
3229 * obtain byte 57. DV will; if target doesn't return
3230 * at least 57 bytes, data[56] will be zero. */
3231 if (dlen > 56) {
3232 if ( (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_56))) {
3233 /* Update the target capabilities
3235 data_56 = data[56];
3236 vdev->tflags |= MPT_TARGET_FLAGS_VALID_56;
3237 mptscsih_setTargetNegoParms(hd, vdev, data_56);
3244 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3246 * Update the target negotiation parameters based on the
3247 * the Inquiry data, adapter capabilities, and NVRAM settings.
3250 static void
3251 mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56)
3253 ScsiCfgData *pspi_data = &hd->ioc->spi_data;
3254 int id = (int) target->target_id;
3255 int nvram;
3256 VirtDevice *vdev;
3257 int ii;
3258 u8 width = MPT_NARROW;
3259 u8 factor = MPT_ASYNC;
3260 u8 offset = 0;
3261 u8 version, nfactor;
3262 u8 noQas = 1;
3264 target->negoFlags = pspi_data->noQas;
3266 /* noQas == 0 => device supports QAS. Need byte 56 of Inq to determine
3267 * support. If available, default QAS to off and allow enabling.
3268 * If not available, default QAS to on, turn off for non-disks.
3271 /* Set flags based on Inquiry data
3273 version = target->inq_data[2] & 0x07;
3274 if (version < 2) {
3275 width = 0;
3276 factor = MPT_ULTRA2;
3277 offset = pspi_data->maxSyncOffset;
3278 target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
3279 } else {
3280 if (target->inq_data[7] & 0x20) {
3281 width = 1;
3284 if (target->inq_data[7] & 0x10) {
3285 factor = pspi_data->minSyncFactor;
3286 if (target->tflags & MPT_TARGET_FLAGS_VALID_56) {
3287 /* bits 2 & 3 show Clocking support */
3288 if ((byte56 & 0x0C) == 0)
3289 factor = MPT_ULTRA2;
3290 else {
3291 if ((byte56 & 0x03) == 0)
3292 factor = MPT_ULTRA160;
3293 else {
3294 factor = MPT_ULTRA320;
3295 if (byte56 & 0x02)
3297 ddvtprintk((KERN_INFO "Enabling QAS due to byte56=%02x on id=%d!\n", byte56, id));
3298 noQas = 0;
3300 if (target->inq_data[0] == TYPE_TAPE) {
3301 if (byte56 & 0x01)
3302 target->negoFlags |= MPT_TAPE_NEGO_IDP;
3306 } else {
3307 ddvtprintk((KERN_INFO "Enabling QAS on id=%d due to ~TARGET_FLAGS_VALID_56!\n", id));
3308 noQas = 0;
3311 offset = pspi_data->maxSyncOffset;
3313 /* If RAID, never disable QAS
3314 * else if non RAID, do not disable
3315 * QAS if bit 1 is set
3316 * bit 1 QAS support, non-raid only
3317 * bit 0 IU support
3319 if (target->raidVolume == 1) {
3320 noQas = 0;
3322 } else {
3323 factor = MPT_ASYNC;
3324 offset = 0;
3328 if ( (target->inq_data[7] & 0x02) == 0) {
3329 target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
3332 /* Update tflags based on NVRAM settings. (SCSI only)
3334 if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
3335 nvram = pspi_data->nvram[id];
3336 nfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
3338 if (width)
3339 width = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
3341 if (offset > 0) {
3342 /* Ensure factor is set to the
3343 * maximum of: adapter, nvram, inquiry
3345 if (nfactor) {
3346 if (nfactor < pspi_data->minSyncFactor )
3347 nfactor = pspi_data->minSyncFactor;
3349 factor = max(factor, nfactor);
3350 if (factor == MPT_ASYNC)
3351 offset = 0;
3352 } else {
3353 offset = 0;
3354 factor = MPT_ASYNC;
3356 } else {
3357 factor = MPT_ASYNC;
3361 /* Make sure data is consistent
3363 if ((!width) && (factor < MPT_ULTRA2)) {
3364 factor = MPT_ULTRA2;
3367 /* Save the data to the target structure.
3369 target->minSyncFactor = factor;
3370 target->maxOffset = offset;
3371 target->maxWidth = width;
3373 target->tflags |= MPT_TARGET_FLAGS_VALID_NEGO;
3375 /* Disable unused features.
3377 if (!width)
3378 target->negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
3380 if (!offset)
3381 target->negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
3383 if ( factor > MPT_ULTRA320 )
3384 noQas = 0;
3386 /* GEM, processor WORKAROUND
3388 if ((target->inq_data[0] == TYPE_PROCESSOR) || (target->inq_data[0] > 0x08)) {
3389 target->negoFlags |= (MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC);
3390 pspi_data->dvStatus[id] |= MPT_SCSICFG_BLK_NEGO;
3391 } else {
3392 if (noQas && (pspi_data->noQas == 0)) {
3393 pspi_data->noQas |= MPT_TARGET_NO_NEGO_QAS;
3394 target->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
3396 /* Disable QAS in a mixed configuration case
3399 ddvtprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id));
3400 for (ii = 0; ii < id; ii++) {
3401 if ( (vdev = hd->Targets[ii]) ) {
3402 vdev->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
3403 mptscsih_writeSDP1(hd, 0, ii, vdev->negoFlags);
3409 /* Write SDP1 on this I/O to this target */
3410 if (pspi_data->dvStatus[id] & MPT_SCSICFG_NEGOTIATE) {
3411 ddvtprintk((KERN_INFO "MPT_SCSICFG_NEGOTIATE on id=%d!\n", id));
3412 mptscsih_writeSDP1(hd, 0, id, hd->negoNvram);
3413 pspi_data->dvStatus[id] &= ~MPT_SCSICFG_NEGOTIATE;
3414 } else if (pspi_data->dvStatus[id] & MPT_SCSICFG_BLK_NEGO) {
3415 ddvtprintk((KERN_INFO "MPT_SCSICFG_BLK_NEGO on id=%d!\n", id));
3416 mptscsih_writeSDP1(hd, 0, id, MPT_SCSICFG_BLK_NEGO);
3417 pspi_data->dvStatus[id] &= ~MPT_SCSICFG_BLK_NEGO;
3421 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3422 /* If DV disabled (negoNvram set to USE_NVARM) or if not LUN 0, return.
3423 * Else set the NEED_DV flag after Read Capacity Issued (disks)
3424 * or Mode Sense (cdroms).
3426 * Tapes, initTarget will set this flag on completion of Inquiry command.
3427 * Called only if DV_NOT_DONE flag is set
3429 static void mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq)
3431 u8 cmd;
3432 ScsiCfgData *pSpi;
3434 ddvtprintk((" set_dvflags: id=%d lun=%d negoNvram=%x cmd=%x\n",
3435 pReq->TargetID, pReq->LUN[1], hd->negoNvram, pReq->CDB[0]));
3437 if ((pReq->LUN[1] != 0) || (hd->negoNvram != 0))
3438 return;
3440 cmd = pReq->CDB[0];
3442 if ((cmd == READ_CAPACITY) || (cmd == MODE_SENSE)) {
3443 pSpi = &hd->ioc->spi_data;
3444 if ((pSpi->isRaid & (1 << pReq->TargetID)) && pSpi->pIocPg3) {
3445 /* Set NEED_DV for all hidden disks
3447 Ioc3PhysDisk_t *pPDisk = pSpi->pIocPg3->PhysDisk;
3448 int numPDisk = pSpi->pIocPg3->NumPhysDisks;
3450 while (numPDisk) {
3451 pSpi->dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV;
3452 ddvtprintk(("NEED_DV set for phys disk id %d\n", pPDisk->PhysDiskID));
3453 pPDisk++;
3454 numPDisk--;
3457 pSpi->dvStatus[pReq->TargetID] |= MPT_SCSICFG_NEED_DV;
3458 ddvtprintk(("NEED_DV set for visible disk id %d\n", pReq->TargetID));
3462 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3464 * If no Target, bus reset on 1st I/O. Set the flag to
3465 * prevent any future negotiations to this device.
3467 static void mptscsih_no_negotiate(MPT_SCSI_HOST *hd, int target_id)
3470 if ((hd->Targets) && (hd->Targets[target_id] == NULL))
3471 hd->ioc->spi_data.dvStatus[target_id] |= MPT_SCSICFG_BLK_NEGO;
3473 return;
3476 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3478 * SCSI Config Page functionality ...
3480 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3481 /* mptscsih_setDevicePage1Flags - add Requested and Configuration fields flags
3482 * based on width, factor and offset parameters.
3483 * @width: bus width
3484 * @factor: sync factor
3485 * @offset: sync offset
3486 * @requestedPtr: pointer to requested values (updated)
3487 * @configurationPtr: pointer to configuration values (updated)
3488 * @flags: flags to block WDTR or SDTR negotiation
3490 * Return: None.
3492 * Remark: Called by writeSDP1 and _dv_params
3494 static void
3495 mptscsih_setDevicePage1Flags (u8 width, u8 factor, u8 offset, int *requestedPtr, int *configurationPtr, u8 flags)
3497 u8 nowide = flags & MPT_TARGET_NO_NEGO_WIDE;
3498 u8 nosync = flags & MPT_TARGET_NO_NEGO_SYNC;
3500 *configurationPtr = 0;
3501 *requestedPtr = width ? MPI_SCSIDEVPAGE1_RP_WIDE : 0;
3502 *requestedPtr |= (offset << 16) | (factor << 8);
3504 if (width && offset && !nowide && !nosync) {
3505 if (factor < MPT_ULTRA160) {
3506 *requestedPtr |= (MPI_SCSIDEVPAGE1_RP_IU + MPI_SCSIDEVPAGE1_RP_DT);
3507 if ((flags & MPT_TARGET_NO_NEGO_QAS) == 0)
3508 *requestedPtr |= MPI_SCSIDEVPAGE1_RP_QAS;
3509 if (flags & MPT_TAPE_NEGO_IDP)
3510 *requestedPtr |= 0x08000000;
3511 } else if (factor < MPT_ULTRA2) {
3512 *requestedPtr |= MPI_SCSIDEVPAGE1_RP_DT;
3516 if (nowide)
3517 *configurationPtr |= MPI_SCSIDEVPAGE1_CONF_WDTR_DISALLOWED;
3519 if (nosync)
3520 *configurationPtr |= MPI_SCSIDEVPAGE1_CONF_SDTR_DISALLOWED;
3522 return;
3525 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3526 /* mptscsih_writeSDP1 - write SCSI Device Page 1
3527 * @hd: Pointer to a SCSI Host Strucutre
3528 * @portnum: IOC port number
3529 * @target_id: writeSDP1 for single ID
3530 * @flags: MPT_SCSICFG_ALL_IDS, MPT_SCSICFG_USE_NVRAM, MPT_SCSICFG_BLK_NEGO
3532 * Return: -EFAULT if read of config page header fails
3533 * or 0 if success.
3535 * Remark: If a target has been found, the settings from the
3536 * target structure are used, else the device is set
3537 * to async/narrow.
3539 * Remark: Called during init and after a FW reload.
3540 * Remark: We do not wait for a return, write pages sequentially.
3542 static int
3543 mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
3545 MPT_ADAPTER *ioc = hd->ioc;
3546 Config_t *pReq;
3547 SCSIDevicePage1_t *pData;
3548 VirtDevice *pTarget;
3549 MPT_FRAME_HDR *mf;
3550 dma_addr_t dataDma;
3551 u16 req_idx;
3552 u32 frameOffset;
3553 u32 requested, configuration, flagsLength;
3554 int ii, nvram;
3555 int id = 0, maxid = 0;
3556 u8 width;
3557 u8 factor;
3558 u8 offset;
3559 u8 bus = 0;
3560 u8 negoFlags;
3561 u8 maxwidth, maxoffset, maxfactor;
3563 if (ioc->spi_data.sdp1length == 0)
3564 return 0;
3566 if (flags & MPT_SCSICFG_ALL_IDS) {
3567 id = 0;
3568 maxid = ioc->sh->max_id - 1;
3569 } else if (ioc->sh) {
3570 id = target_id;
3571 maxid = min_t(int, id, ioc->sh->max_id - 1);
3574 for (; id <= maxid; id++) {
3576 if (id == ioc->pfacts[portnum].PortSCSIID)
3577 continue;
3579 /* Use NVRAM to get adapter and target maximums
3580 * Data over-riden by target structure information, if present
3582 maxwidth = ioc->spi_data.maxBusWidth;
3583 maxoffset = ioc->spi_data.maxSyncOffset;
3584 maxfactor = ioc->spi_data.minSyncFactor;
3585 if (ioc->spi_data.nvram && (ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
3586 nvram = ioc->spi_data.nvram[id];
3588 if (maxwidth)
3589 maxwidth = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
3591 if (maxoffset > 0) {
3592 maxfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
3593 if (maxfactor == 0) {
3594 /* Key for async */
3595 maxfactor = MPT_ASYNC;
3596 maxoffset = 0;
3597 } else if (maxfactor < ioc->spi_data.minSyncFactor) {
3598 maxfactor = ioc->spi_data.minSyncFactor;
3600 } else
3601 maxfactor = MPT_ASYNC;
3604 /* Set the negotiation flags.
3606 negoFlags = ioc->spi_data.noQas;
3607 if (!maxwidth)
3608 negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
3610 if (!maxoffset)
3611 negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
3613 if (flags & MPT_SCSICFG_USE_NVRAM) {
3614 width = maxwidth;
3615 factor = maxfactor;
3616 offset = maxoffset;
3617 } else {
3618 width = 0;
3619 factor = MPT_ASYNC;
3620 offset = 0;
3621 //negoFlags = 0;
3622 //negoFlags = MPT_TARGET_NO_NEGO_SYNC;
3625 /* If id is not a raid volume, get the updated
3626 * transmission settings from the target structure.
3628 if (hd->Targets && (pTarget = hd->Targets[id]) && !pTarget->raidVolume) {
3629 width = pTarget->maxWidth;
3630 factor = pTarget->minSyncFactor;
3631 offset = pTarget->maxOffset;
3632 negoFlags = pTarget->negoFlags;
3635 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
3636 /* Force to async and narrow if DV has not been executed
3637 * for this ID
3639 if ((hd->ioc->spi_data.dvStatus[id] & MPT_SCSICFG_DV_NOT_DONE) != 0) {
3640 width = 0;
3641 factor = MPT_ASYNC;
3642 offset = 0;
3644 #endif
3646 if (flags & MPT_SCSICFG_BLK_NEGO)
3647 negoFlags = MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC;
3649 mptscsih_setDevicePage1Flags(width, factor, offset,
3650 &requested, &configuration, negoFlags);
3651 dnegoprintk(("writeSDP1: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
3652 target_id, width, factor, offset, negoFlags, requested, configuration));
3654 /* Get a MF for this command.
3656 if ((mf = mpt_get_msg_frame(ScsiDoneCtx, ioc)) == NULL) {
3657 dprintk((MYIOC_s_WARN_FMT "write SDP1: no msg frames!\n",
3658 ioc->name));
3659 return -EAGAIN;
3662 ddvprintk((MYIOC_s_INFO_FMT "WriteSDP1 (mf=%p, id=%d, req=0x%x, cfg=0x%x)\n",
3663 hd->ioc->name, mf, id, requested, configuration));
3666 /* Set the request and the data pointers.
3667 * Request takes: 36 bytes (32 bit SGE)
3668 * SCSI Device Page 1 requires 16 bytes
3669 * 40 + 16 <= size of SCSI IO Request = 56 bytes
3670 * and MF size >= 64 bytes.
3671 * Place data at end of MF.
3673 pReq = (Config_t *)mf;
3675 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3676 frameOffset = ioc->req_sz - sizeof(SCSIDevicePage1_t);
3678 pData = (SCSIDevicePage1_t *)((u8 *) mf + frameOffset);
3679 dataDma = ioc->req_frames_dma + (req_idx * ioc->req_sz) + frameOffset;
3681 /* Complete the request frame (same for all requests).
3683 pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
3684 pReq->Reserved = 0;
3685 pReq->ChainOffset = 0;
3686 pReq->Function = MPI_FUNCTION_CONFIG;
3687 pReq->ExtPageLength = 0;
3688 pReq->ExtPageType = 0;
3689 pReq->MsgFlags = 0;
3690 for (ii=0; ii < 8; ii++) {
3691 pReq->Reserved2[ii] = 0;
3693 pReq->Header.PageVersion = ioc->spi_data.sdp1version;
3694 pReq->Header.PageLength = ioc->spi_data.sdp1length;
3695 pReq->Header.PageNumber = 1;
3696 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
3697 pReq->PageAddress = cpu_to_le32(id | (bus << 8 ));
3699 /* Add a SGE to the config request.
3701 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE | ioc->spi_data.sdp1length * 4;
3703 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma);
3705 /* Set up the common data portion
3707 pData->Header.PageVersion = pReq->Header.PageVersion;
3708 pData->Header.PageLength = pReq->Header.PageLength;
3709 pData->Header.PageNumber = pReq->Header.PageNumber;
3710 pData->Header.PageType = pReq->Header.PageType;
3711 pData->RequestedParameters = cpu_to_le32(requested);
3712 pData->Reserved = 0;
3713 pData->Configuration = cpu_to_le32(configuration);
3715 dprintk((MYIOC_s_INFO_FMT
3716 "write SDP1: id %d pgaddr 0x%x req 0x%x config 0x%x\n",
3717 ioc->name, id, (id | (bus<<8)),
3718 requested, configuration));
3720 mpt_put_msg_frame(ScsiDoneCtx, ioc, mf);
3723 return 0;
3726 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3727 /* mptscsih_writeIOCPage4 - write IOC Page 4
3728 * @hd: Pointer to a SCSI Host Structure
3729 * @target_id: write IOC Page4 for this ID & Bus
3731 * Return: -EAGAIN if unable to obtain a Message Frame
3732 * or 0 if success.
3734 * Remark: We do not wait for a return, write pages sequentially.
3736 static int
3737 mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus)
3739 MPT_ADAPTER *ioc = hd->ioc;
3740 Config_t *pReq;
3741 IOCPage4_t *IOCPage4Ptr;
3742 MPT_FRAME_HDR *mf;
3743 dma_addr_t dataDma;
3744 u16 req_idx;
3745 u32 frameOffset;
3746 u32 flagsLength;
3747 int ii;
3749 /* Get a MF for this command.
3751 if ((mf = mpt_get_msg_frame(ScsiDoneCtx, ioc)) == NULL) {
3752 dprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n",
3753 ioc->name));
3754 return -EAGAIN;
3757 /* Set the request and the data pointers.
3758 * Place data at end of MF.
3760 pReq = (Config_t *)mf;
3762 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3763 frameOffset = ioc->req_sz - sizeof(IOCPage4_t);
3765 /* Complete the request frame (same for all requests).
3767 pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
3768 pReq->Reserved = 0;
3769 pReq->ChainOffset = 0;
3770 pReq->Function = MPI_FUNCTION_CONFIG;
3771 pReq->ExtPageLength = 0;
3772 pReq->ExtPageType = 0;
3773 pReq->MsgFlags = 0;
3774 for (ii=0; ii < 8; ii++) {
3775 pReq->Reserved2[ii] = 0;
3778 IOCPage4Ptr = ioc->spi_data.pIocPg4;
3779 dataDma = ioc->spi_data.IocPg4_dma;
3780 ii = IOCPage4Ptr->ActiveSEP++;
3781 IOCPage4Ptr->SEP[ii].SEPTargetID = target_id;
3782 IOCPage4Ptr->SEP[ii].SEPBus = bus;
3783 pReq->Header = IOCPage4Ptr->Header;
3784 pReq->PageAddress = cpu_to_le32(target_id | (bus << 8 ));
3786 /* Add a SGE to the config request.
3788 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE |
3789 (IOCPage4Ptr->Header.PageLength + ii) * 4;
3791 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma);
3793 dinitprintk((MYIOC_s_INFO_FMT
3794 "writeIOCPage4: MaxSEP=%d ActiveSEP=%d id=%d bus=%d\n",
3795 ioc->name, IOCPage4Ptr->MaxSEP, IOCPage4Ptr->ActiveSEP, target_id, bus));
3797 mpt_put_msg_frame(ScsiDoneCtx, ioc, mf);
3799 return 0;
3802 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3804 * Bus Scan and Domain Validation functionality ...
3807 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3809 * mptscsih_scandv_complete - Scan and DV callback routine registered
3810 * to Fustion MPT (base) driver.
3812 * @ioc: Pointer to MPT_ADAPTER structure
3813 * @mf: Pointer to original MPT request frame
3814 * @mr: Pointer to MPT reply frame (NULL if TurboReply)
3816 * This routine is called from mpt.c::mpt_interrupt() at the completion
3817 * of any SCSI IO request.
3818 * This routine is registered with the Fusion MPT (base) driver at driver
3819 * load/init time via the mpt_register() API call.
3821 * Returns 1 indicating alloc'd request frame ptr should be freed.
3823 * Remark: Sets a completion code and (possibly) saves sense data
3824 * in the IOC member localReply structure.
3825 * Used ONLY for DV and other internal commands.
3827 static int
3828 mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
3830 MPT_SCSI_HOST *hd;
3831 SCSIIORequest_t *pReq;
3832 int completionCode;
3833 u16 req_idx;
3835 if ((mf == NULL) ||
3836 (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) {
3837 printk(MYIOC_s_ERR_FMT
3838 "ScanDvComplete, %s req frame ptr! (=%p)\n",
3839 ioc->name, mf?"BAD":"NULL", (void *) mf);
3840 goto wakeup;
3843 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
3844 del_timer(&hd->timer);
3845 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3846 hd->ScsiLookup[req_idx] = NULL;
3847 pReq = (SCSIIORequest_t *) mf;
3849 if (mf != hd->cmdPtr) {
3850 printk(MYIOC_s_WARN_FMT "ScanDvComplete (mf=%p, cmdPtr=%p, idx=%d)\n",
3851 hd->ioc->name, (void *)mf, (void *) hd->cmdPtr, req_idx);
3853 hd->cmdPtr = NULL;
3855 ddvprintk((MYIOC_s_INFO_FMT "ScanDvComplete (mf=%p,mr=%p,idx=%d)\n",
3856 hd->ioc->name, mf, mr, req_idx));
3858 hd->pLocal = &hd->localReply;
3859 hd->pLocal->scsiStatus = 0;
3861 /* If target struct exists, clear sense valid flag.
3863 if (mr == NULL) {
3864 completionCode = MPT_SCANDV_GOOD;
3865 } else {
3866 SCSIIOReply_t *pReply;
3867 u16 status;
3868 u8 scsi_status;
3870 pReply = (SCSIIOReply_t *) mr;
3872 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
3873 scsi_status = pReply->SCSIStatus;
3875 ddvtprintk((KERN_NOTICE " IOCStatus=%04xh, SCSIState=%02xh, SCSIStatus=%02xh, IOCLogInfo=%08xh\n",
3876 status, pReply->SCSIState, scsi_status,
3877 le32_to_cpu(pReply->IOCLogInfo)));
3879 switch(status) {
3881 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
3882 completionCode = MPT_SCANDV_SELECTION_TIMEOUT;
3883 break;
3885 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
3886 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
3887 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
3888 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
3889 completionCode = MPT_SCANDV_DID_RESET;
3890 break;
3892 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
3893 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
3894 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
3895 if (pReply->Function == MPI_FUNCTION_CONFIG) {
3896 ConfigReply_t *pr = (ConfigReply_t *)mr;
3897 completionCode = MPT_SCANDV_GOOD;
3898 hd->pLocal->header.PageVersion = pr->Header.PageVersion;
3899 hd->pLocal->header.PageLength = pr->Header.PageLength;
3900 hd->pLocal->header.PageNumber = pr->Header.PageNumber;
3901 hd->pLocal->header.PageType = pr->Header.PageType;
3903 } else if (pReply->Function == MPI_FUNCTION_RAID_ACTION) {
3904 /* If the RAID Volume request is successful,
3905 * return GOOD, else indicate that
3906 * some type of error occurred.
3908 MpiRaidActionReply_t *pr = (MpiRaidActionReply_t *)mr;
3909 if (pr->ActionStatus == MPI_RAID_ACTION_ASTATUS_SUCCESS)
3910 completionCode = MPT_SCANDV_GOOD;
3911 else
3912 completionCode = MPT_SCANDV_SOME_ERROR;
3914 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID) {
3915 u8 *sense_data;
3916 int sz;
3918 /* save sense data in global structure
3920 completionCode = MPT_SCANDV_SENSE;
3921 hd->pLocal->scsiStatus = scsi_status;
3922 sense_data = ((u8 *)hd->ioc->sense_buf_pool +
3923 (req_idx * MPT_SENSE_BUFFER_ALLOC));
3925 sz = min_t(int, pReq->SenseBufferLength,
3926 SCSI_STD_SENSE_BYTES);
3927 memcpy(hd->pLocal->sense, sense_data, sz);
3929 ddvprintk((KERN_NOTICE " Check Condition, sense ptr %p\n",
3930 sense_data));
3931 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_FAILED) {
3932 if (pReq->CDB[0] == INQUIRY)
3933 completionCode = MPT_SCANDV_ISSUE_SENSE;
3934 else
3935 completionCode = MPT_SCANDV_DID_RESET;
3937 else if (pReply->SCSIState & MPI_SCSI_STATE_NO_SCSI_STATUS)
3938 completionCode = MPT_SCANDV_DID_RESET;
3939 else if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
3940 completionCode = MPT_SCANDV_DID_RESET;
3941 else {
3942 completionCode = MPT_SCANDV_GOOD;
3943 hd->pLocal->scsiStatus = scsi_status;
3945 break;
3947 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
3948 if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
3949 completionCode = MPT_SCANDV_DID_RESET;
3950 else
3951 completionCode = MPT_SCANDV_SOME_ERROR;
3952 break;
3954 default:
3955 completionCode = MPT_SCANDV_SOME_ERROR;
3956 break;
3958 } /* switch(status) */
3960 ddvtprintk((KERN_NOTICE " completionCode set to %08xh\n",
3961 completionCode));
3962 } /* end of address reply case */
3964 hd->pLocal->completion = completionCode;
3966 /* MF and RF are freed in mpt_interrupt
3968 wakeup:
3969 /* Free Chain buffers (will never chain) in scan or dv */
3970 //mptscsih_freeChainBuffers(ioc, req_idx);
3973 * Wake up the original calling thread
3975 scandv_wait_done = 1;
3976 wake_up(&scandv_waitq);
3978 return 1;
3981 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3982 /* mptscsih_timer_expired - Call back for timer process.
3983 * Used only for dv functionality.
3984 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
3987 static void mptscsih_timer_expired(unsigned long data)
3989 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) data;
3991 ddvprintk((MYIOC_s_WARN_FMT "Timer Expired! Cmd %p\n", hd->ioc->name, hd->cmdPtr));
3993 if (hd->cmdPtr) {
3994 MPIHeader_t *cmd = (MPIHeader_t *)hd->cmdPtr;
3996 if (cmd->Function == MPI_FUNCTION_SCSI_IO_REQUEST) {
3997 /* Desire to issue a task management request here.
3998 * TM requests MUST be single threaded.
3999 * If old eh code and no TM current, issue request.
4000 * If new eh code, do nothing. Wait for OS cmd timeout
4001 * for bus reset.
4003 ddvtprintk((MYIOC_s_NOTE_FMT "DV Cmd Timeout: NoOp\n", hd->ioc->name));
4004 } else {
4005 /* Perform a FW reload */
4006 if (mpt_HardResetHandler(hd->ioc, NO_SLEEP) < 0) {
4007 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", hd->ioc->name);
4010 } else {
4011 /* This should NEVER happen */
4012 printk(MYIOC_s_WARN_FMT "Null cmdPtr!!!!\n", hd->ioc->name);
4015 /* No more processing.
4016 * TM call will generate an interrupt for SCSI TM Management.
4017 * The FW will reply to all outstanding commands, callback will finish cleanup.
4018 * Hard reset clean-up will free all resources.
4020 ddvprintk((MYIOC_s_WARN_FMT "Timer Expired Complete!\n", hd->ioc->name));
4022 return;
4025 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
4026 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4027 /* mptscsih_do_raid - Format and Issue a RAID volume request message.
4028 * @hd: Pointer to scsi host structure
4029 * @action: What do be done.
4030 * @id: Logical target id.
4031 * @bus: Target locations bus.
4033 * Returns: < 0 on a fatal error
4034 * 0 on success
4036 * Remark: Wait to return until reply processed by the ISR.
4038 static int
4039 mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io)
4041 MpiRaidActionRequest_t *pReq;
4042 MPT_FRAME_HDR *mf;
4043 int in_isr;
4045 in_isr = in_interrupt();
4046 if (in_isr) {
4047 dprintk((MYIOC_s_WARN_FMT "Internal raid request not allowed in ISR context!\n",
4048 hd->ioc->name));
4049 return -EPERM;
4052 /* Get and Populate a free Frame
4054 if ((mf = mpt_get_msg_frame(ScsiScanDvCtx, hd->ioc)) == NULL) {
4055 ddvprintk((MYIOC_s_WARN_FMT "_do_raid: no msg frames!\n",
4056 hd->ioc->name));
4057 return -EAGAIN;
4059 pReq = (MpiRaidActionRequest_t *)mf;
4060 pReq->Action = action;
4061 pReq->Reserved1 = 0;
4062 pReq->ChainOffset = 0;
4063 pReq->Function = MPI_FUNCTION_RAID_ACTION;
4064 pReq->VolumeID = io->id;
4065 pReq->VolumeBus = io->bus;
4066 pReq->PhysDiskNum = io->physDiskNum;
4067 pReq->MsgFlags = 0;
4068 pReq->Reserved2 = 0;
4069 pReq->ActionDataWord = 0; /* Reserved for this action */
4070 //pReq->ActionDataSGE = 0;
4072 mpt_add_sge((char *)&pReq->ActionDataSGE,
4073 MPT_SGE_FLAGS_SSIMPLE_READ | 0, (dma_addr_t) -1);
4075 ddvprintk((MYIOC_s_INFO_FMT "RAID Volume action %x id %d\n",
4076 hd->ioc->name, action, io->id));
4078 hd->pLocal = NULL;
4079 hd->timer.expires = jiffies + HZ*10; /* 10 second timeout */
4080 scandv_wait_done = 0;
4082 /* Save cmd pointer, for resource free if timeout or
4083 * FW reload occurs
4085 hd->cmdPtr = mf;
4087 add_timer(&hd->timer);
4088 mpt_put_msg_frame(ScsiScanDvCtx, hd->ioc, mf);
4089 wait_event(scandv_waitq, scandv_wait_done);
4091 if ((hd->pLocal == NULL) || (hd->pLocal->completion != MPT_SCANDV_GOOD))
4092 return -1;
4094 return 0;
4096 #endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */
4098 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4100 * mptscsih_do_cmd - Do internal command.
4101 * @hd: MPT_SCSI_HOST pointer
4102 * @io: INTERNAL_CMD pointer.
4104 * Issue the specified internally generated command and do command
4105 * specific cleanup. For bus scan / DV only.
4106 * NOTES: If command is Inquiry and status is good,
4107 * initialize a target structure, save the data
4109 * Remark: Single threaded access only.
4111 * Return:
4112 * < 0 if an illegal command or no resources
4114 * 0 if good
4116 * > 0 if command complete but some type of completion error.
4118 static int
4119 mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
4121 MPT_FRAME_HDR *mf;
4122 SCSIIORequest_t *pScsiReq;
4123 SCSIIORequest_t ReqCopy;
4124 int my_idx, ii, dir;
4125 int rc, cmdTimeout;
4126 int in_isr;
4127 char cmdLen;
4128 char CDB[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
4129 char cmd = io->cmd;
4131 in_isr = in_interrupt();
4132 if (in_isr) {
4133 dprintk((MYIOC_s_WARN_FMT "Internal SCSI IO request not allowed in ISR context!\n",
4134 hd->ioc->name));
4135 return -EPERM;
4139 /* Set command specific information
4141 switch (cmd) {
4142 case INQUIRY:
4143 cmdLen = 6;
4144 dir = MPI_SCSIIO_CONTROL_READ;
4145 CDB[0] = cmd;
4146 CDB[4] = io->size;
4147 cmdTimeout = 10;
4148 break;
4150 case TEST_UNIT_READY:
4151 cmdLen = 6;
4152 dir = MPI_SCSIIO_CONTROL_READ;
4153 cmdTimeout = 10;
4154 break;
4156 case START_STOP:
4157 cmdLen = 6;
4158 dir = MPI_SCSIIO_CONTROL_READ;
4159 CDB[0] = cmd;
4160 CDB[4] = 1; /*Spin up the disk */
4161 cmdTimeout = 15;
4162 break;
4164 case REQUEST_SENSE:
4165 cmdLen = 6;
4166 CDB[0] = cmd;
4167 CDB[4] = io->size;
4168 dir = MPI_SCSIIO_CONTROL_READ;
4169 cmdTimeout = 10;
4170 break;
4172 case READ_BUFFER:
4173 cmdLen = 10;
4174 dir = MPI_SCSIIO_CONTROL_READ;
4175 CDB[0] = cmd;
4176 if (io->flags & MPT_ICFLAG_ECHO) {
4177 CDB[1] = 0x0A;
4178 } else {
4179 CDB[1] = 0x02;
4182 if (io->flags & MPT_ICFLAG_BUF_CAP) {
4183 CDB[1] |= 0x01;
4185 CDB[6] = (io->size >> 16) & 0xFF;
4186 CDB[7] = (io->size >> 8) & 0xFF;
4187 CDB[8] = io->size & 0xFF;
4188 cmdTimeout = 10;
4189 break;
4191 case WRITE_BUFFER:
4192 cmdLen = 10;
4193 dir = MPI_SCSIIO_CONTROL_WRITE;
4194 CDB[0] = cmd;
4195 if (io->flags & MPT_ICFLAG_ECHO) {
4196 CDB[1] = 0x0A;
4197 } else {
4198 CDB[1] = 0x02;
4200 CDB[6] = (io->size >> 16) & 0xFF;
4201 CDB[7] = (io->size >> 8) & 0xFF;
4202 CDB[8] = io->size & 0xFF;
4203 cmdTimeout = 10;
4204 break;
4206 case RESERVE:
4207 cmdLen = 6;
4208 dir = MPI_SCSIIO_CONTROL_READ;
4209 CDB[0] = cmd;
4210 cmdTimeout = 10;
4211 break;
4213 case RELEASE:
4214 cmdLen = 6;
4215 dir = MPI_SCSIIO_CONTROL_READ;
4216 CDB[0] = cmd;
4217 cmdTimeout = 10;
4218 break;
4220 case SYNCHRONIZE_CACHE:
4221 cmdLen = 10;
4222 dir = MPI_SCSIIO_CONTROL_READ;
4223 CDB[0] = cmd;
4224 // CDB[1] = 0x02; /* set immediate bit */
4225 cmdTimeout = 10;
4226 break;
4228 default:
4229 /* Error Case */
4230 return -EFAULT;
4233 /* Get and Populate a free Frame
4235 if ((mf = mpt_get_msg_frame(ScsiScanDvCtx, hd->ioc)) == NULL) {
4236 ddvprintk((MYIOC_s_WARN_FMT "No msg frames!\n",
4237 hd->ioc->name));
4238 return -EBUSY;
4241 pScsiReq = (SCSIIORequest_t *) mf;
4243 /* Get the request index */
4244 my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
4245 ADD_INDEX_LOG(my_idx); /* for debug */
4247 if (io->flags & MPT_ICFLAG_PHYS_DISK) {
4248 pScsiReq->TargetID = io->physDiskNum;
4249 pScsiReq->Bus = 0;
4250 pScsiReq->ChainOffset = 0;
4251 pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
4252 } else {
4253 pScsiReq->TargetID = io->id;
4254 pScsiReq->Bus = io->bus;
4255 pScsiReq->ChainOffset = 0;
4256 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
4259 pScsiReq->CDBLength = cmdLen;
4260 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
4262 pScsiReq->Reserved = 0;
4264 pScsiReq->MsgFlags = mpt_msg_flags();
4265 /* MsgContext set in mpt_get_msg_fram call */
4267 for (ii=0; ii < 8; ii++)
4268 pScsiReq->LUN[ii] = 0;
4269 pScsiReq->LUN[1] = io->lun;
4271 if (io->flags & MPT_ICFLAG_TAGGED_CMD)
4272 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ);
4273 else
4274 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
4276 if (cmd == REQUEST_SENSE) {
4277 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
4278 ddvprintk((MYIOC_s_INFO_FMT "Untagged! 0x%2x\n",
4279 hd->ioc->name, cmd));
4282 for (ii=0; ii < 16; ii++)
4283 pScsiReq->CDB[ii] = CDB[ii];
4285 pScsiReq->DataLength = cpu_to_le32(io->size);
4286 pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
4287 + (my_idx * MPT_SENSE_BUFFER_ALLOC));
4289 ddvprintk((MYIOC_s_INFO_FMT "Sending Command 0x%x for (%d:%d:%d)\n",
4290 hd->ioc->name, cmd, io->bus, io->id, io->lun));
4292 if (dir == MPI_SCSIIO_CONTROL_READ) {
4293 mpt_add_sge((char *) &pScsiReq->SGL,
4294 MPT_SGE_FLAGS_SSIMPLE_READ | io->size,
4295 io->data_dma);
4296 } else {
4297 mpt_add_sge((char *) &pScsiReq->SGL,
4298 MPT_SGE_FLAGS_SSIMPLE_WRITE | io->size,
4299 io->data_dma);
4302 /* The ISR will free the request frame, but we need
4303 * the information to initialize the target. Duplicate.
4305 memcpy(&ReqCopy, pScsiReq, sizeof(SCSIIORequest_t));
4307 /* Issue this command after:
4308 * finish init
4309 * add timer
4310 * Wait until the reply has been received
4311 * ScsiScanDvCtx callback function will
4312 * set hd->pLocal;
4313 * set scandv_wait_done and call wake_up
4315 hd->pLocal = NULL;
4316 hd->timer.expires = jiffies + HZ*cmdTimeout;
4317 scandv_wait_done = 0;
4319 /* Save cmd pointer, for resource free if timeout or
4320 * FW reload occurs
4322 hd->cmdPtr = mf;
4324 add_timer(&hd->timer);
4325 mpt_put_msg_frame(ScsiScanDvCtx, hd->ioc, mf);
4326 wait_event(scandv_waitq, scandv_wait_done);
4328 if (hd->pLocal) {
4329 rc = hd->pLocal->completion;
4330 hd->pLocal->skip = 0;
4332 /* Always set fatal error codes in some cases.
4334 if (rc == MPT_SCANDV_SELECTION_TIMEOUT)
4335 rc = -ENXIO;
4336 else if (rc == MPT_SCANDV_SOME_ERROR)
4337 rc = -rc;
4338 } else {
4339 rc = -EFAULT;
4340 /* This should never happen. */
4341 ddvprintk((MYIOC_s_INFO_FMT "_do_cmd: Null pLocal!!!\n",
4342 hd->ioc->name));
4345 return rc;
4348 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4350 * mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
4351 * @hd: Pointer to MPT_SCSI_HOST structure
4352 * @portnum: IOC port number
4354 * Uses the ISR, but with special processing.
4355 * MUST be single-threaded.
4357 * Return: 0 on completion
4359 static int
4360 mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum)
4362 MPT_ADAPTER *ioc= hd->ioc;
4363 VirtDevice *pTarget;
4364 SCSIDevicePage1_t *pcfg1Data = NULL;
4365 INTERNAL_CMD iocmd;
4366 CONFIGPARMS cfg;
4367 dma_addr_t cfg1_dma_addr = -1;
4368 ConfigPageHeader_t header1;
4369 int bus = 0;
4370 int id = 0;
4371 int lun;
4372 int indexed_lun, lun_index;
4373 int hostId = ioc->pfacts[portnum].PortSCSIID;
4374 int max_id;
4375 int requested, configuration, data;
4376 int doConfig = 0;
4377 u8 flags, factor;
4379 max_id = ioc->sh->max_id - 1;
4381 /* Following parameters will not change
4382 * in this routine.
4384 iocmd.cmd = SYNCHRONIZE_CACHE;
4385 iocmd.flags = 0;
4386 iocmd.physDiskNum = -1;
4387 iocmd.data = NULL;
4388 iocmd.data_dma = -1;
4389 iocmd.size = 0;
4390 iocmd.rsvd = iocmd.rsvd2 = 0;
4392 /* No SCSI hosts
4394 if (hd->Targets == NULL)
4395 return 0;
4397 /* Skip the host
4399 if (id == hostId)
4400 id++;
4402 /* Write SDP1 for all SCSI devices
4403 * Alloc memory and set up config buffer
4405 if (ioc->bus_type == SCSI) {
4406 if (ioc->spi_data.sdp1length > 0) {
4407 pcfg1Data = (SCSIDevicePage1_t *)pci_alloc_consistent(ioc->pcidev,
4408 ioc->spi_data.sdp1length * 4, &cfg1_dma_addr);
4410 if (pcfg1Data != NULL) {
4411 doConfig = 1;
4412 header1.PageVersion = ioc->spi_data.sdp1version;
4413 header1.PageLength = ioc->spi_data.sdp1length;
4414 header1.PageNumber = 1;
4415 header1.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4416 cfg.hdr = &header1;
4417 cfg.physAddr = cfg1_dma_addr;
4418 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4419 cfg.dir = 1;
4420 cfg.timeout = 0;
4425 /* loop through all devices on this port
4427 while (bus < MPT_MAX_BUS) {
4428 iocmd.bus = bus;
4429 iocmd.id = id;
4430 pTarget = hd->Targets[(int)id];
4432 if (doConfig) {
4434 /* Set the negotiation flags */
4435 if (pTarget && (pTarget = hd->Targets[id]) && !pTarget->raidVolume) {
4436 flags = pTarget->negoFlags;
4437 } else {
4438 flags = hd->ioc->spi_data.noQas;
4439 if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
4440 data = hd->ioc->spi_data.nvram[id];
4442 if (data & MPT_NVRAM_WIDE_DISABLE)
4443 flags |= MPT_TARGET_NO_NEGO_WIDE;
4445 factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT;
4446 if ((factor == 0) || (factor == MPT_ASYNC))
4447 flags |= MPT_TARGET_NO_NEGO_SYNC;
4451 /* Force to async, narrow */
4452 mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested,
4453 &configuration, flags);
4454 dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC "
4455 "offset=0 negoFlags=%x request=%x config=%x\n",
4456 id, flags, requested, configuration));
4457 pcfg1Data->RequestedParameters = le32_to_cpu(requested);
4458 pcfg1Data->Reserved = 0;
4459 pcfg1Data->Configuration = le32_to_cpu(configuration);
4460 cfg.pageAddr = (bus<<8) | id;
4461 mpt_config(hd->ioc, &cfg);
4464 /* If target Ptr NULL or if this target is NOT a disk, skip.
4466 if ((pTarget) && (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)){
4467 for (lun=0; lun <= MPT_LAST_LUN; lun++) {
4468 /* If LUN present, issue the command
4470 lun_index = (lun >> 5); /* 32 luns per lun_index */
4471 indexed_lun = (lun % 32);
4472 if (pTarget->luns[lun_index] & (1<<indexed_lun)) {
4473 iocmd.lun = lun;
4474 (void) mptscsih_do_cmd(hd, &iocmd);
4479 /* get next relevant device */
4480 id++;
4482 if (id == hostId)
4483 id++;
4485 if (id > max_id) {
4486 id = 0;
4487 bus++;
4491 if (pcfg1Data) {
4492 pci_free_consistent(ioc->pcidev, header1.PageLength * 4, pcfg1Data, cfg1_dma_addr);
4495 return 0;
4498 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
4499 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4501 * mptscsih_domainValidation - Top level handler for domain validation.
4502 * @hd: Pointer to MPT_SCSI_HOST structure.
4504 * Uses the ISR, but with special processing.
4505 * Called from schedule, should not be in interrupt mode.
4506 * While thread alive, do dv for all devices needing dv
4508 * Return: None.
4510 static void
4511 mptscsih_domainValidation(void *arg)
4513 MPT_SCSI_HOST *hd;
4514 MPT_ADAPTER *ioc;
4515 unsigned long flags;
4516 int id, maxid, dvStatus, did;
4517 int ii, isPhysDisk;
4519 spin_lock_irqsave(&dvtaskQ_lock, flags);
4520 dvtaskQ_active = 1;
4521 if (dvtaskQ_release) {
4522 dvtaskQ_active = 0;
4523 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4524 return;
4526 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4528 /* For this ioc, loop through all devices and do dv to each device.
4529 * When complete with this ioc, search through the ioc list, and
4530 * for each scsi ioc found, do dv for all devices. Exit when no
4531 * device needs dv.
4533 did = 1;
4534 while (did) {
4535 did = 0;
4536 list_for_each_entry(ioc, &ioc_list, list) {
4537 spin_lock_irqsave(&dvtaskQ_lock, flags);
4538 if (dvtaskQ_release) {
4539 dvtaskQ_active = 0;
4540 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4541 return;
4543 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4545 msleep(250);
4547 /* DV only to SCSI adapters */
4548 if (ioc->bus_type != SCSI)
4549 continue;
4551 /* Make sure everything looks ok */
4552 if (ioc->sh == NULL)
4553 continue;
4555 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
4556 if (hd == NULL)
4557 continue;
4559 if ((ioc->spi_data.forceDv & MPT_SCSICFG_RELOAD_IOC_PG3) != 0) {
4560 mpt_read_ioc_pg_3(ioc);
4561 if (ioc->spi_data.pIocPg3) {
4562 Ioc3PhysDisk_t *pPDisk = ioc->spi_data.pIocPg3->PhysDisk;
4563 int numPDisk = ioc->spi_data.pIocPg3->NumPhysDisks;
4565 while (numPDisk) {
4566 if (ioc->spi_data.dvStatus[pPDisk->PhysDiskID] & MPT_SCSICFG_DV_NOT_DONE)
4567 ioc->spi_data.dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV;
4569 pPDisk++;
4570 numPDisk--;
4573 ioc->spi_data.forceDv &= ~MPT_SCSICFG_RELOAD_IOC_PG3;
4576 maxid = min_t(int, ioc->sh->max_id, MPT_MAX_SCSI_DEVICES);
4578 for (id = 0; id < maxid; id++) {
4579 spin_lock_irqsave(&dvtaskQ_lock, flags);
4580 if (dvtaskQ_release) {
4581 dvtaskQ_active = 0;
4582 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4583 return;
4585 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4586 dvStatus = hd->ioc->spi_data.dvStatus[id];
4588 if (dvStatus & MPT_SCSICFG_NEED_DV) {
4589 did++;
4590 hd->ioc->spi_data.dvStatus[id] |= MPT_SCSICFG_DV_PENDING;
4591 hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_NEED_DV;
4593 msleep(250);
4595 /* If hidden phys disk, block IO's to all
4596 * raid volumes
4597 * else, process normally
4599 isPhysDisk = mptscsih_is_phys_disk(ioc, id);
4600 if (isPhysDisk) {
4601 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4602 if (hd->ioc->spi_data.isRaid & (1 << ii)) {
4603 hd->ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_DV_PENDING;
4608 if (mptscsih_doDv(hd, 0, id) == 1) {
4609 /* Untagged device was busy, try again
4611 hd->ioc->spi_data.dvStatus[id] |= MPT_SCSICFG_NEED_DV;
4612 hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_PENDING;
4613 } else {
4614 /* DV is complete. Clear flags.
4616 hd->ioc->spi_data.dvStatus[id] &= ~(MPT_SCSICFG_DV_NOT_DONE | MPT_SCSICFG_DV_PENDING);
4619 if (isPhysDisk) {
4620 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4621 if (hd->ioc->spi_data.isRaid & (1 << ii)) {
4622 hd->ioc->spi_data.dvStatus[ii] &= ~MPT_SCSICFG_DV_PENDING;
4627 if (hd->ioc->spi_data.noQas)
4628 mptscsih_qas_check(hd, id);
4634 spin_lock_irqsave(&dvtaskQ_lock, flags);
4635 dvtaskQ_active = 0;
4636 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4638 return;
4641 /* Search IOC page 3 to determine if this is hidden physical disk
4643 static int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id)
4645 if (ioc->spi_data.pIocPg3) {
4646 Ioc3PhysDisk_t *pPDisk = ioc->spi_data.pIocPg3->PhysDisk;
4647 int numPDisk = ioc->spi_data.pIocPg3->NumPhysDisks;
4649 while (numPDisk) {
4650 if (pPDisk->PhysDiskID == id) {
4651 return 1;
4653 pPDisk++;
4654 numPDisk--;
4657 return 0;
4660 /* Write SDP1 if no QAS has been enabled
4662 static void mptscsih_qas_check(MPT_SCSI_HOST *hd, int id)
4664 VirtDevice *pTarget;
4665 int ii;
4667 if (hd->Targets == NULL)
4668 return;
4670 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4671 if (ii == id)
4672 continue;
4674 if ((hd->ioc->spi_data.dvStatus[ii] & MPT_SCSICFG_DV_NOT_DONE) != 0)
4675 continue;
4677 pTarget = hd->Targets[ii];
4679 if ((pTarget != NULL) && (!pTarget->raidVolume)) {
4680 if ((pTarget->negoFlags & hd->ioc->spi_data.noQas) == 0) {
4681 pTarget->negoFlags |= hd->ioc->spi_data.noQas;
4682 dnegoprintk(("writeSDP1: id=%d flags=0\n", id));
4683 mptscsih_writeSDP1(hd, 0, ii, 0);
4685 } else {
4686 if (mptscsih_is_phys_disk(hd->ioc, ii) == 1) {
4687 dnegoprintk(("writeSDP1: id=%d SCSICFG_USE_NVRAM\n", id));
4688 mptscsih_writeSDP1(hd, 0, ii, MPT_SCSICFG_USE_NVRAM);
4692 return;
4697 #define MPT_GET_NVRAM_VALS 0x01
4698 #define MPT_UPDATE_MAX 0x02
4699 #define MPT_SET_MAX 0x04
4700 #define MPT_SET_MIN 0x08
4701 #define MPT_FALLBACK 0x10
4702 #define MPT_SAVE 0x20
4704 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4706 * mptscsih_doDv - Perform domain validation to a target.
4707 * @hd: Pointer to MPT_SCSI_HOST structure.
4708 * @portnum: IOC port number.
4709 * @target: Physical ID of this target
4711 * Uses the ISR, but with special processing.
4712 * MUST be single-threaded.
4713 * Test will exit if target is at async & narrow.
4715 * Return: None.
4717 static int
4718 mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
4720 MPT_ADAPTER *ioc = hd->ioc;
4721 VirtDevice *pTarget;
4722 SCSIDevicePage1_t *pcfg1Data;
4723 SCSIDevicePage0_t *pcfg0Data;
4724 u8 *pbuf1;
4725 u8 *pbuf2;
4726 u8 *pDvBuf;
4727 dma_addr_t dvbuf_dma = -1;
4728 dma_addr_t buf1_dma = -1;
4729 dma_addr_t buf2_dma = -1;
4730 dma_addr_t cfg1_dma_addr = -1;
4731 dma_addr_t cfg0_dma_addr = -1;
4732 ConfigPageHeader_t header1;
4733 ConfigPageHeader_t header0;
4734 DVPARAMETERS dv;
4735 INTERNAL_CMD iocmd;
4736 CONFIGPARMS cfg;
4737 int dv_alloc = 0;
4738 int rc, sz = 0;
4739 int bufsize = 0;
4740 int dataBufSize = 0;
4741 int echoBufSize = 0;
4742 int notDone;
4743 int patt;
4744 int repeat;
4745 int retcode = 0;
4746 int nfactor = MPT_ULTRA320;
4747 char firstPass = 1;
4748 char doFallback = 0;
4749 char readPage0;
4750 char bus, lun;
4751 char inq0 = 0;
4753 if (ioc->spi_data.sdp1length == 0)
4754 return 0;
4756 if (ioc->spi_data.sdp0length == 0)
4757 return 0;
4759 /* If multiple buses are used, require that the initiator
4760 * id be the same on all buses.
4762 if (id == ioc->pfacts[0].PortSCSIID)
4763 return 0;
4765 lun = 0;
4766 bus = (u8) bus_number;
4767 ddvtprintk((MYIOC_s_NOTE_FMT
4768 "DV started: bus=%d, id=%d dv @ %p\n",
4769 ioc->name, bus, id, &dv));
4771 /* Prep DV structure
4773 memset (&dv, 0, sizeof(DVPARAMETERS));
4774 dv.id = id;
4776 /* Populate tmax with the current maximum
4777 * transfer parameters for this target.
4778 * Exit if narrow and async.
4780 dv.cmd = MPT_GET_NVRAM_VALS;
4781 mptscsih_dv_parms(hd, &dv, NULL);
4783 /* Prep SCSI IO structure
4785 iocmd.id = id;
4786 iocmd.bus = bus;
4787 iocmd.lun = lun;
4788 iocmd.flags = 0;
4789 iocmd.physDiskNum = -1;
4790 iocmd.rsvd = iocmd.rsvd2 = 0;
4792 pTarget = hd->Targets[id];
4794 /* Use tagged commands if possible.
4796 if (pTarget) {
4797 if (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)
4798 iocmd.flags |= MPT_ICFLAG_TAGGED_CMD;
4799 else {
4800 if (hd->ioc->facts.FWVersion.Word < 0x01000600)
4801 return 0;
4803 if ((hd->ioc->facts.FWVersion.Word >= 0x01010000) &&
4804 (hd->ioc->facts.FWVersion.Word < 0x01010B00))
4805 return 0;
4809 /* Prep cfg structure
4811 cfg.pageAddr = (bus<<8) | id;
4812 cfg.hdr = NULL;
4814 /* Prep SDP0 header
4816 header0.PageVersion = ioc->spi_data.sdp0version;
4817 header0.PageLength = ioc->spi_data.sdp0length;
4818 header0.PageNumber = 0;
4819 header0.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4821 /* Prep SDP1 header
4823 header1.PageVersion = ioc->spi_data.sdp1version;
4824 header1.PageLength = ioc->spi_data.sdp1length;
4825 header1.PageNumber = 1;
4826 header1.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4828 if (header0.PageLength & 1)
4829 dv_alloc = (header0.PageLength * 4) + 4;
4831 dv_alloc += (2048 + (header1.PageLength * 4));
4833 pDvBuf = pci_alloc_consistent(ioc->pcidev, dv_alloc, &dvbuf_dma);
4834 if (pDvBuf == NULL)
4835 return 0;
4837 sz = 0;
4838 pbuf1 = (u8 *)pDvBuf;
4839 buf1_dma = dvbuf_dma;
4840 sz +=1024;
4842 pbuf2 = (u8 *) (pDvBuf + sz);
4843 buf2_dma = dvbuf_dma + sz;
4844 sz +=1024;
4846 pcfg0Data = (SCSIDevicePage0_t *) (pDvBuf + sz);
4847 cfg0_dma_addr = dvbuf_dma + sz;
4848 sz += header0.PageLength * 4;
4850 /* 8-byte alignment
4852 if (header0.PageLength & 1)
4853 sz += 4;
4855 pcfg1Data = (SCSIDevicePage1_t *) (pDvBuf + sz);
4856 cfg1_dma_addr = dvbuf_dma + sz;
4858 /* Skip this ID? Set cfg.hdr to force config page write
4861 ScsiCfgData *pspi_data = &hd->ioc->spi_data;
4862 if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
4863 /* Set the factor from nvram */
4864 nfactor = (pspi_data->nvram[id] & MPT_NVRAM_SYNC_MASK) >> 8;
4865 if (nfactor < pspi_data->minSyncFactor )
4866 nfactor = pspi_data->minSyncFactor;
4868 if (!(pspi_data->nvram[id] & MPT_NVRAM_ID_SCAN_ENABLE) ||
4869 (pspi_data->PortFlags == MPI_SCSIPORTPAGE2_PORT_FLAGS_OFF_DV) ) {
4871 ddvprintk((MYIOC_s_NOTE_FMT "DV Skipped: bus, id, lun (%d, %d, %d)\n",
4872 ioc->name, bus, id, lun));
4874 dv.cmd = MPT_SET_MAX;
4875 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
4876 cfg.hdr = &header1;
4878 /* Save the final negotiated settings to
4879 * SCSI device page 1.
4881 cfg.physAddr = cfg1_dma_addr;
4882 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4883 cfg.dir = 1;
4884 mpt_config(hd->ioc, &cfg);
4885 goto target_done;
4890 /* Finish iocmd inititialization - hidden or visible disk? */
4891 if (ioc->spi_data.pIocPg3) {
4892 /* Search IOC page 3 for matching id
4894 Ioc3PhysDisk_t *pPDisk = ioc->spi_data.pIocPg3->PhysDisk;
4895 int numPDisk = ioc->spi_data.pIocPg3->NumPhysDisks;
4897 while (numPDisk) {
4898 if (pPDisk->PhysDiskID == id) {
4899 /* match */
4900 iocmd.flags |= MPT_ICFLAG_PHYS_DISK;
4901 iocmd.physDiskNum = pPDisk->PhysDiskNum;
4903 /* Quiesce the IM
4905 if (mptscsih_do_raid(hd, MPI_RAID_ACTION_QUIESCE_PHYS_IO, &iocmd) < 0) {
4906 ddvprintk((MYIOC_s_ERR_FMT "RAID Queisce FAILED!\n", ioc->name));
4907 goto target_done;
4909 break;
4911 pPDisk++;
4912 numPDisk--;
4916 /* RAID Volume ID's may double for a physical device. If RAID but
4917 * not a physical ID as well, skip DV.
4919 if ((hd->ioc->spi_data.isRaid & (1 << id)) && !(iocmd.flags & MPT_ICFLAG_PHYS_DISK))
4920 goto target_done;
4923 /* Basic Test.
4924 * Async & Narrow - Inquiry
4925 * Async & Narrow - Inquiry
4926 * Maximum transfer rate - Inquiry
4927 * Compare buffers:
4928 * If compare, test complete.
4929 * If miscompare and first pass, repeat
4930 * If miscompare and not first pass, fall back and repeat
4932 hd->pLocal = NULL;
4933 readPage0 = 0;
4934 sz = SCSI_MAX_INQUIRY_BYTES;
4935 rc = MPT_SCANDV_GOOD;
4936 while (1) {
4937 ddvprintk((MYIOC_s_NOTE_FMT "DV: Start Basic test on id=%d\n", ioc->name, id));
4938 retcode = 0;
4939 dv.cmd = MPT_SET_MIN;
4940 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
4942 cfg.hdr = &header1;
4943 cfg.physAddr = cfg1_dma_addr;
4944 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4945 cfg.dir = 1;
4946 if (mpt_config(hd->ioc, &cfg) != 0)
4947 goto target_done;
4949 /* Wide - narrow - wide workaround case
4951 if ((rc == MPT_SCANDV_ISSUE_SENSE) && dv.max.width) {
4952 /* Send an untagged command to reset disk Qs corrupted
4953 * when a parity error occurs on a Request Sense.
4955 if ((hd->ioc->facts.FWVersion.Word >= 0x01000600) ||
4956 ((hd->ioc->facts.FWVersion.Word >= 0x01010000) &&
4957 (hd->ioc->facts.FWVersion.Word < 0x01010B00)) ) {
4959 iocmd.cmd = REQUEST_SENSE;
4960 iocmd.data_dma = buf1_dma;
4961 iocmd.data = pbuf1;
4962 iocmd.size = 0x12;
4963 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4964 goto target_done;
4965 else {
4966 if (hd->pLocal == NULL)
4967 goto target_done;
4968 rc = hd->pLocal->completion;
4969 if ((rc == MPT_SCANDV_GOOD) || (rc == MPT_SCANDV_SENSE)) {
4970 dv.max.width = 0;
4971 doFallback = 0;
4972 } else
4973 goto target_done;
4975 } else
4976 goto target_done;
4979 iocmd.cmd = INQUIRY;
4980 iocmd.data_dma = buf1_dma;
4981 iocmd.data = pbuf1;
4982 iocmd.size = sz;
4983 memset(pbuf1, 0x00, sz);
4984 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4985 goto target_done;
4986 else {
4987 if (hd->pLocal == NULL)
4988 goto target_done;
4989 rc = hd->pLocal->completion;
4990 if (rc == MPT_SCANDV_GOOD) {
4991 if (hd->pLocal->scsiStatus == SAM_STAT_BUSY) {
4992 if ((iocmd.flags & MPT_ICFLAG_TAGGED_CMD) == 0)
4993 retcode = 1;
4994 else
4995 retcode = 0;
4997 goto target_done;
4999 } else if (rc == MPT_SCANDV_SENSE) {
5001 } else {
5002 /* If first command doesn't complete
5003 * with a good status or with a check condition,
5004 * exit.
5006 goto target_done;
5010 /* Reset the size for disks
5012 inq0 = (*pbuf1) & 0x1F;
5013 if ((inq0 == 0) && pTarget && !pTarget->raidVolume) {
5014 sz = 0x40;
5015 iocmd.size = sz;
5018 /* Another GEM workaround. Check peripheral device type,
5019 * if PROCESSOR, quit DV.
5021 if (inq0 == TYPE_PROCESSOR) {
5022 mptscsih_initTarget(hd,
5023 bus,
5025 lun,
5026 pbuf1,
5027 sz);
5028 goto target_done;
5031 if (inq0 > 0x08)
5032 goto target_done;
5034 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5035 goto target_done;
5037 if (sz == 0x40) {
5038 if ((pTarget->maxWidth == 1) && (pTarget->maxOffset) && (nfactor < 0x0A)
5039 && (pTarget->minSyncFactor > 0x09)) {
5040 if ((pbuf1[56] & 0x04) == 0)
5042 else if ((pbuf1[56] & 0x01) == 1) {
5043 pTarget->minSyncFactor =
5044 nfactor > MPT_ULTRA320 ? nfactor : MPT_ULTRA320;
5045 } else {
5046 pTarget->minSyncFactor =
5047 nfactor > MPT_ULTRA160 ? nfactor : MPT_ULTRA160;
5050 dv.max.factor = pTarget->minSyncFactor;
5052 if ((pbuf1[56] & 0x02) == 0) {
5053 pTarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
5054 hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS;
5055 ddvprintk((MYIOC_s_NOTE_FMT
5056 "DV: Start Basic noQas on id=%d due to pbuf1[56]=%x\n",
5057 ioc->name, id, pbuf1[56]));
5062 if (doFallback)
5063 dv.cmd = MPT_FALLBACK;
5064 else
5065 dv.cmd = MPT_SET_MAX;
5067 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5068 if (mpt_config(hd->ioc, &cfg) != 0)
5069 goto target_done;
5071 if ((!dv.now.width) && (!dv.now.offset))
5072 goto target_done;
5074 iocmd.cmd = INQUIRY;
5075 iocmd.data_dma = buf2_dma;
5076 iocmd.data = pbuf2;
5077 iocmd.size = sz;
5078 memset(pbuf2, 0x00, sz);
5079 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5080 goto target_done;
5081 else if (hd->pLocal == NULL)
5082 goto target_done;
5083 else {
5084 /* Save the return code.
5085 * If this is the first pass,
5086 * read SCSI Device Page 0
5087 * and update the target max parameters.
5089 rc = hd->pLocal->completion;
5090 doFallback = 0;
5091 if (rc == MPT_SCANDV_GOOD) {
5092 if (!readPage0) {
5093 u32 sdp0_info;
5094 u32 sdp0_nego;
5096 cfg.hdr = &header0;
5097 cfg.physAddr = cfg0_dma_addr;
5098 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5099 cfg.dir = 0;
5101 if (mpt_config(hd->ioc, &cfg) != 0)
5102 goto target_done;
5104 sdp0_info = le32_to_cpu(pcfg0Data->Information) & 0x0E;
5105 sdp0_nego = (le32_to_cpu(pcfg0Data->NegotiatedParameters) & 0xFF00 ) >> 8;
5107 /* Quantum and Fujitsu workarounds.
5108 * Quantum: PPR U320 -> PPR reply with Ultra2 and wide
5109 * Fujitsu: PPR U320 -> Msg Reject and Ultra2 and wide
5110 * Resetart with a request for U160.
5112 if ((dv.now.factor == MPT_ULTRA320) && (sdp0_nego == MPT_ULTRA2)) {
5113 doFallback = 1;
5114 } else {
5115 dv.cmd = MPT_UPDATE_MAX;
5116 mptscsih_dv_parms(hd, &dv, (void *)pcfg0Data);
5117 /* Update the SCSI device page 1 area
5119 pcfg1Data->RequestedParameters = pcfg0Data->NegotiatedParameters;
5120 readPage0 = 1;
5124 /* Quantum workaround. Restart this test will the fallback
5125 * flag set.
5127 if (doFallback == 0) {
5128 if (memcmp(pbuf1, pbuf2, sz) != 0) {
5129 if (!firstPass)
5130 doFallback = 1;
5131 } else {
5132 ddvprintk((MYIOC_s_NOTE_FMT
5133 "DV:Inquiry compared id=%d, calling initTarget\n", ioc->name, id));
5134 hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_NOT_DONE;
5135 mptscsih_initTarget(hd,
5136 bus,
5138 lun,
5139 pbuf1,
5140 sz);
5141 break; /* test complete */
5146 } else if (rc == MPT_SCANDV_ISSUE_SENSE)
5147 doFallback = 1; /* set fallback flag */
5148 else if ((rc == MPT_SCANDV_DID_RESET) ||
5149 (rc == MPT_SCANDV_SENSE) ||
5150 (rc == MPT_SCANDV_FALLBACK))
5151 doFallback = 1; /* set fallback flag */
5152 else
5153 goto target_done;
5155 firstPass = 0;
5158 ddvprintk((MYIOC_s_NOTE_FMT "DV: Basic test on id=%d completed OK.\n", ioc->name, id));
5160 if (mpt_dv == 0)
5161 goto target_done;
5163 inq0 = (*pbuf1) & 0x1F;
5165 /* Continue only for disks
5167 if (inq0 != 0)
5168 goto target_done;
5170 if ( ioc->spi_data.PortFlags == MPI_SCSIPORTPAGE2_PORT_FLAGS_BASIC_DV_ONLY )
5171 goto target_done;
5173 /* Start the Enhanced Test.
5174 * 0) issue TUR to clear out check conditions
5175 * 1) read capacity of echo (regular) buffer
5176 * 2) reserve device
5177 * 3) do write-read-compare data pattern test
5178 * 4) release
5179 * 5) update nego parms to target struct
5181 cfg.hdr = &header1;
5182 cfg.physAddr = cfg1_dma_addr;
5183 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5184 cfg.dir = 1;
5186 iocmd.cmd = TEST_UNIT_READY;
5187 iocmd.data_dma = -1;
5188 iocmd.data = NULL;
5189 iocmd.size = 0;
5190 notDone = 1;
5191 while (notDone) {
5192 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5193 goto target_done;
5195 if (hd->pLocal == NULL)
5196 goto target_done;
5198 rc = hd->pLocal->completion;
5199 if (rc == MPT_SCANDV_GOOD)
5200 notDone = 0;
5201 else if (rc == MPT_SCANDV_SENSE) {
5202 u8 skey = hd->pLocal->sense[2] & 0x0F;
5203 u8 asc = hd->pLocal->sense[12];
5204 u8 ascq = hd->pLocal->sense[13];
5205 ddvprintk((MYIOC_s_INFO_FMT
5206 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
5207 ioc->name, skey, asc, ascq));
5209 if (skey == UNIT_ATTENTION)
5210 notDone++; /* repeat */
5211 else if ((skey == NOT_READY) &&
5212 (asc == 0x04)&&(ascq == 0x01)) {
5213 /* wait then repeat */
5214 mdelay (2000);
5215 notDone++;
5216 } else if ((skey == NOT_READY) && (asc == 0x3A)) {
5217 /* no medium, try read test anyway */
5218 notDone = 0;
5219 } else {
5220 /* All other errors are fatal.
5222 ddvprintk((MYIOC_s_INFO_FMT "DV: fatal error.",
5223 ioc->name));
5224 goto target_done;
5226 } else
5227 goto target_done;
5230 iocmd.cmd = READ_BUFFER;
5231 iocmd.data_dma = buf1_dma;
5232 iocmd.data = pbuf1;
5233 iocmd.size = 4;
5234 iocmd.flags |= MPT_ICFLAG_BUF_CAP;
5236 dataBufSize = 0;
5237 echoBufSize = 0;
5238 for (patt = 0; patt < 2; patt++) {
5239 if (patt == 0)
5240 iocmd.flags |= MPT_ICFLAG_ECHO;
5241 else
5242 iocmd.flags &= ~MPT_ICFLAG_ECHO;
5244 notDone = 1;
5245 while (notDone) {
5246 bufsize = 0;
5248 /* If not ready after 8 trials,
5249 * give up on this device.
5251 if (notDone > 8)
5252 goto target_done;
5254 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5255 goto target_done;
5256 else if (hd->pLocal == NULL)
5257 goto target_done;
5258 else {
5259 rc = hd->pLocal->completion;
5260 ddvprintk(("ReadBuffer Comp Code %d", rc));
5261 ddvprintk((" buff: %0x %0x %0x %0x\n",
5262 pbuf1[0], pbuf1[1], pbuf1[2], pbuf1[3]));
5264 if (rc == MPT_SCANDV_GOOD) {
5265 notDone = 0;
5266 if (iocmd.flags & MPT_ICFLAG_ECHO) {
5267 bufsize = ((pbuf1[2] & 0x1F) <<8) | pbuf1[3];
5268 } else {
5269 bufsize = pbuf1[1]<<16 | pbuf1[2]<<8 | pbuf1[3];
5271 } else if (rc == MPT_SCANDV_SENSE) {
5272 u8 skey = hd->pLocal->sense[2] & 0x0F;
5273 u8 asc = hd->pLocal->sense[12];
5274 u8 ascq = hd->pLocal->sense[13];
5275 ddvprintk((MYIOC_s_INFO_FMT
5276 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
5277 ioc->name, skey, asc, ascq));
5278 if (skey == ILLEGAL_REQUEST) {
5279 notDone = 0;
5280 } else if (skey == UNIT_ATTENTION) {
5281 notDone++; /* repeat */
5282 } else if ((skey == NOT_READY) &&
5283 (asc == 0x04)&&(ascq == 0x01)) {
5284 /* wait then repeat */
5285 mdelay (2000);
5286 notDone++;
5287 } else {
5288 /* All other errors are fatal.
5290 ddvprintk((MYIOC_s_INFO_FMT "DV: fatal error.",
5291 ioc->name));
5292 goto target_done;
5294 } else {
5295 /* All other errors are fatal
5297 goto target_done;
5302 if (iocmd.flags & MPT_ICFLAG_ECHO)
5303 echoBufSize = bufsize;
5304 else
5305 dataBufSize = bufsize;
5307 sz = 0;
5308 iocmd.flags &= ~MPT_ICFLAG_BUF_CAP;
5310 /* Use echo buffers if possible,
5311 * Exit if both buffers are 0.
5313 if (echoBufSize > 0) {
5314 iocmd.flags |= MPT_ICFLAG_ECHO;
5315 if (dataBufSize > 0)
5316 bufsize = min(echoBufSize, dataBufSize);
5317 else
5318 bufsize = echoBufSize;
5319 } else if (dataBufSize == 0)
5320 goto target_done;
5322 ddvprintk((MYIOC_s_INFO_FMT "%s Buffer Capacity %d\n", ioc->name,
5323 (iocmd.flags & MPT_ICFLAG_ECHO) ? "Echo" : " ", bufsize));
5325 /* Data buffers for write-read-compare test max 1K.
5327 sz = min(bufsize, 1024);
5329 /* --- loop ----
5330 * On first pass, always issue a reserve.
5331 * On additional loops, only if a reset has occurred.
5332 * iocmd.flags indicates if echo or regular buffer
5334 for (patt = 0; patt < 4; patt++) {
5335 ddvprintk(("Pattern %d\n", patt));
5336 if ((iocmd.flags & MPT_ICFLAG_RESERVED) && (iocmd.flags & MPT_ICFLAG_DID_RESET)) {
5337 iocmd.cmd = TEST_UNIT_READY;
5338 iocmd.data_dma = -1;
5339 iocmd.data = NULL;
5340 iocmd.size = 0;
5341 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5342 goto target_done;
5344 iocmd.cmd = RELEASE;
5345 iocmd.data_dma = -1;
5346 iocmd.data = NULL;
5347 iocmd.size = 0;
5348 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5349 goto target_done;
5350 else if (hd->pLocal == NULL)
5351 goto target_done;
5352 else {
5353 rc = hd->pLocal->completion;
5354 ddvprintk(("Release rc %d\n", rc));
5355 if (rc == MPT_SCANDV_GOOD)
5356 iocmd.flags &= ~MPT_ICFLAG_RESERVED;
5357 else
5358 goto target_done;
5360 iocmd.flags &= ~MPT_ICFLAG_RESERVED;
5362 iocmd.flags &= ~MPT_ICFLAG_DID_RESET;
5364 repeat = 5;
5365 while (repeat && (!(iocmd.flags & MPT_ICFLAG_RESERVED))) {
5366 iocmd.cmd = RESERVE;
5367 iocmd.data_dma = -1;
5368 iocmd.data = NULL;
5369 iocmd.size = 0;
5370 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5371 goto target_done;
5372 else if (hd->pLocal == NULL)
5373 goto target_done;
5374 else {
5375 rc = hd->pLocal->completion;
5376 if (rc == MPT_SCANDV_GOOD) {
5377 iocmd.flags |= MPT_ICFLAG_RESERVED;
5378 } else if (rc == MPT_SCANDV_SENSE) {
5379 /* Wait if coming ready
5381 u8 skey = hd->pLocal->sense[2] & 0x0F;
5382 u8 asc = hd->pLocal->sense[12];
5383 u8 ascq = hd->pLocal->sense[13];
5384 ddvprintk((MYIOC_s_INFO_FMT
5385 "DV: Reserve Failed: ", ioc->name));
5386 ddvprintk(("SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
5387 skey, asc, ascq));
5389 if ((skey == NOT_READY) && (asc == 0x04)&&
5390 (ascq == 0x01)) {
5391 /* wait then repeat */
5392 mdelay (2000);
5393 notDone++;
5394 } else {
5395 ddvprintk((MYIOC_s_INFO_FMT
5396 "DV: Reserved Failed.", ioc->name));
5397 goto target_done;
5399 } else {
5400 ddvprintk((MYIOC_s_INFO_FMT "DV: Reserved Failed.",
5401 ioc->name));
5402 goto target_done;
5407 mptscsih_fillbuf(pbuf1, sz, patt, 1);
5408 iocmd.cmd = WRITE_BUFFER;
5409 iocmd.data_dma = buf1_dma;
5410 iocmd.data = pbuf1;
5411 iocmd.size = sz;
5412 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5413 goto target_done;
5414 else if (hd->pLocal == NULL)
5415 goto target_done;
5416 else {
5417 rc = hd->pLocal->completion;
5418 if (rc == MPT_SCANDV_GOOD)
5419 ; /* Issue read buffer */
5420 else if (rc == MPT_SCANDV_DID_RESET) {
5421 /* If using echo buffers, reset to data buffers.
5422 * Else do Fallback and restart
5423 * this test (re-issue reserve
5424 * because of bus reset).
5426 if ((iocmd.flags & MPT_ICFLAG_ECHO) && (dataBufSize >= bufsize)) {
5427 iocmd.flags &= ~MPT_ICFLAG_ECHO;
5428 } else {
5429 dv.cmd = MPT_FALLBACK;
5430 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5432 if (mpt_config(hd->ioc, &cfg) != 0)
5433 goto target_done;
5435 if ((!dv.now.width) && (!dv.now.offset))
5436 goto target_done;
5439 iocmd.flags |= MPT_ICFLAG_DID_RESET;
5440 patt = -1;
5441 continue;
5442 } else if (rc == MPT_SCANDV_SENSE) {
5443 /* Restart data test if UA, else quit.
5445 u8 skey = hd->pLocal->sense[2] & 0x0F;
5446 ddvprintk((MYIOC_s_INFO_FMT
5447 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n", ioc->name, skey,
5448 hd->pLocal->sense[12], hd->pLocal->sense[13]));
5449 if (skey == UNIT_ATTENTION) {
5450 patt = -1;
5451 continue;
5452 } else if (skey == ILLEGAL_REQUEST) {
5453 if (iocmd.flags & MPT_ICFLAG_ECHO) {
5454 if (dataBufSize >= bufsize) {
5455 iocmd.flags &= ~MPT_ICFLAG_ECHO;
5456 patt = -1;
5457 continue;
5460 goto target_done;
5462 else
5463 goto target_done;
5464 } else {
5465 /* fatal error */
5466 goto target_done;
5470 iocmd.cmd = READ_BUFFER;
5471 iocmd.data_dma = buf2_dma;
5472 iocmd.data = pbuf2;
5473 iocmd.size = sz;
5474 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5475 goto target_done;
5476 else if (hd->pLocal == NULL)
5477 goto target_done;
5478 else {
5479 rc = hd->pLocal->completion;
5480 if (rc == MPT_SCANDV_GOOD) {
5481 /* If buffers compare,
5482 * go to next pattern,
5483 * else, do a fallback and restart
5484 * data transfer test.
5486 if (memcmp (pbuf1, pbuf2, sz) == 0) {
5487 ; /* goto next pattern */
5488 } else {
5489 /* Miscompare with Echo buffer, go to data buffer,
5490 * if that buffer exists.
5491 * Miscompare with Data buffer, check first 4 bytes,
5492 * some devices return capacity. Exit in this case.
5494 if (iocmd.flags & MPT_ICFLAG_ECHO) {
5495 if (dataBufSize >= bufsize)
5496 iocmd.flags &= ~MPT_ICFLAG_ECHO;
5497 else
5498 goto target_done;
5499 } else {
5500 if (dataBufSize == (pbuf2[1]<<16 | pbuf2[2]<<8 | pbuf2[3])) {
5501 /* Argh. Device returning wrong data.
5502 * Quit DV for this device.
5504 goto target_done;
5507 /* Had an actual miscompare. Slow down.*/
5508 dv.cmd = MPT_FALLBACK;
5509 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5511 if (mpt_config(hd->ioc, &cfg) != 0)
5512 goto target_done;
5514 if ((!dv.now.width) && (!dv.now.offset))
5515 goto target_done;
5518 patt = -1;
5519 continue;
5521 } else if (rc == MPT_SCANDV_DID_RESET) {
5522 /* Do Fallback and restart
5523 * this test (re-issue reserve
5524 * because of bus reset).
5526 dv.cmd = MPT_FALLBACK;
5527 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5529 if (mpt_config(hd->ioc, &cfg) != 0)
5530 goto target_done;
5532 if ((!dv.now.width) && (!dv.now.offset))
5533 goto target_done;
5535 iocmd.flags |= MPT_ICFLAG_DID_RESET;
5536 patt = -1;
5537 continue;
5538 } else if (rc == MPT_SCANDV_SENSE) {
5539 /* Restart data test if UA, else quit.
5541 u8 skey = hd->pLocal->sense[2] & 0x0F;
5542 ddvprintk((MYIOC_s_INFO_FMT
5543 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n", ioc->name, skey,
5544 hd->pLocal->sense[12], hd->pLocal->sense[13]));
5545 if (skey == UNIT_ATTENTION) {
5546 patt = -1;
5547 continue;
5549 else
5550 goto target_done;
5551 } else {
5552 /* fatal error */
5553 goto target_done;
5557 } /* --- end of patt loop ---- */
5559 target_done:
5560 if (iocmd.flags & MPT_ICFLAG_RESERVED) {
5561 iocmd.cmd = RELEASE;
5562 iocmd.data_dma = -1;
5563 iocmd.data = NULL;
5564 iocmd.size = 0;
5565 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5566 printk(MYIOC_s_INFO_FMT "DV: Release failed. id %d",
5567 ioc->name, id);
5568 else if (hd->pLocal) {
5569 if (hd->pLocal->completion == MPT_SCANDV_GOOD)
5570 iocmd.flags &= ~MPT_ICFLAG_RESERVED;
5571 } else {
5572 printk(MYIOC_s_INFO_FMT "DV: Release failed. id %d",
5573 ioc->name, id);
5578 /* Set if cfg1_dma_addr contents is valid
5580 if ((cfg.hdr != NULL) && (retcode == 0)){
5581 /* If disk, not U320, disable QAS
5583 if ((inq0 == 0) && (dv.now.factor > MPT_ULTRA320)) {
5584 hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS;
5585 ddvprintk((MYIOC_s_NOTE_FMT
5586 "noQas set due to id=%d has factor=%x\n", ioc->name, id, dv.now.factor));
5589 dv.cmd = MPT_SAVE;
5590 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5592 /* Double writes to SDP1 can cause problems,
5593 * skip save of the final negotiated settings to
5594 * SCSI device page 1.
5596 cfg.hdr = &header1;
5597 cfg.physAddr = cfg1_dma_addr;
5598 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5599 cfg.dir = 1;
5600 mpt_config(hd->ioc, &cfg);
5604 /* If this is a RAID Passthrough, enable internal IOs
5606 if (iocmd.flags & MPT_ICFLAG_PHYS_DISK) {
5607 if (mptscsih_do_raid(hd, MPI_RAID_ACTION_ENABLE_PHYS_IO, &iocmd) < 0)
5608 ddvprintk((MYIOC_s_ERR_FMT "RAID Enable FAILED!\n", ioc->name));
5611 /* Done with the DV scan of the current target
5613 if (pDvBuf)
5614 pci_free_consistent(ioc->pcidev, dv_alloc, pDvBuf, dvbuf_dma);
5616 ddvtprintk((MYIOC_s_INFO_FMT "DV Done id=%d\n",
5617 ioc->name, id));
5619 return retcode;
5622 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5623 /* mptscsih_dv_parms - perform a variety of operations on the
5624 * parameters used for negotiation.
5625 * @hd: Pointer to a SCSI host.
5626 * @dv: Pointer to a structure that contains the maximum and current
5627 * negotiated parameters.
5629 static void
5630 mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
5632 VirtDevice *pTarget;
5633 SCSIDevicePage0_t *pPage0;
5634 SCSIDevicePage1_t *pPage1;
5635 int val = 0, data, configuration;
5636 u8 width = 0;
5637 u8 offset = 0;
5638 u8 factor = 0;
5639 u8 negoFlags = 0;
5640 u8 cmd = dv->cmd;
5641 u8 id = dv->id;
5643 switch (cmd) {
5644 case MPT_GET_NVRAM_VALS:
5645 ddvprintk((MYIOC_s_NOTE_FMT "Getting NVRAM: ",
5646 hd->ioc->name));
5647 /* Get the NVRAM values and save in tmax
5648 * If not an LVD bus, the adapter minSyncFactor has been
5649 * already throttled back.
5651 if ((hd->Targets)&&((pTarget = hd->Targets[(int)id]) != NULL) && !pTarget->raidVolume) {
5652 width = pTarget->maxWidth;
5653 offset = pTarget->maxOffset;
5654 factor = pTarget->minSyncFactor;
5655 negoFlags = pTarget->negoFlags;
5656 } else {
5657 if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
5658 data = hd->ioc->spi_data.nvram[id];
5659 width = data & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
5660 if ((offset = hd->ioc->spi_data.maxSyncOffset) == 0)
5661 factor = MPT_ASYNC;
5662 else {
5663 factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT;
5664 if ((factor == 0) || (factor == MPT_ASYNC)){
5665 factor = MPT_ASYNC;
5666 offset = 0;
5669 } else {
5670 width = MPT_NARROW;
5671 offset = 0;
5672 factor = MPT_ASYNC;
5675 /* Set the negotiation flags */
5676 negoFlags = hd->ioc->spi_data.noQas;
5677 if (!width)
5678 negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
5680 if (!offset)
5681 negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
5684 /* limit by adapter capabilities */
5685 width = min(width, hd->ioc->spi_data.maxBusWidth);
5686 offset = min(offset, hd->ioc->spi_data.maxSyncOffset);
5687 factor = max(factor, hd->ioc->spi_data.minSyncFactor);
5689 /* Check Consistency */
5690 if (offset && (factor < MPT_ULTRA2) && !width)
5691 factor = MPT_ULTRA2;
5693 dv->max.width = width;
5694 dv->max.offset = offset;
5695 dv->max.factor = factor;
5696 dv->max.flags = negoFlags;
5697 ddvprintk((" id=%d width=%d factor=%x offset=%x flags=%x\n",
5698 id, width, factor, offset, negoFlags));
5699 break;
5701 case MPT_UPDATE_MAX:
5702 ddvprintk((MYIOC_s_NOTE_FMT
5703 "Updating with SDP0 Data: ", hd->ioc->name));
5704 /* Update tmax values with those from Device Page 0.*/
5705 pPage0 = (SCSIDevicePage0_t *) pPage;
5706 if (pPage0) {
5707 val = cpu_to_le32(pPage0->NegotiatedParameters);
5708 dv->max.width = val & MPI_SCSIDEVPAGE0_NP_WIDE ? 1 : 0;
5709 dv->max.offset = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK) >> 16;
5710 dv->max.factor = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK) >> 8;
5713 dv->now.width = dv->max.width;
5714 dv->now.offset = dv->max.offset;
5715 dv->now.factor = dv->max.factor;
5716 ddvprintk(("id=%d width=%d factor=%x offset=%x flags=%x\n",
5717 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags));
5718 break;
5720 case MPT_SET_MAX:
5721 ddvprintk((MYIOC_s_NOTE_FMT "Setting Max: ",
5722 hd->ioc->name));
5723 /* Set current to the max values. Update the config page.*/
5724 dv->now.width = dv->max.width;
5725 dv->now.offset = dv->max.offset;
5726 dv->now.factor = dv->max.factor;
5727 dv->now.flags = dv->max.flags;
5729 pPage1 = (SCSIDevicePage1_t *)pPage;
5730 if (pPage1) {
5731 mptscsih_setDevicePage1Flags (dv->now.width, dv->now.factor,
5732 dv->now.offset, &val, &configuration, dv->now.flags);
5733 dnegoprintk(("Setting Max: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
5734 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags, val, configuration));
5735 pPage1->RequestedParameters = le32_to_cpu(val);
5736 pPage1->Reserved = 0;
5737 pPage1->Configuration = le32_to_cpu(configuration);
5740 ddvprintk(("id=%d width=%d factor=%x offset=%x flags=%x request=%x configuration=%x\n",
5741 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags, val, configuration));
5742 break;
5744 case MPT_SET_MIN:
5745 ddvprintk((MYIOC_s_NOTE_FMT "Setting Min: ",
5746 hd->ioc->name));
5747 /* Set page to asynchronous and narrow
5748 * Do not update now, breaks fallback routine. */
5749 width = MPT_NARROW;
5750 offset = 0;
5751 factor = MPT_ASYNC;
5752 negoFlags = dv->max.flags;
5754 pPage1 = (SCSIDevicePage1_t *)pPage;
5755 if (pPage1) {
5756 mptscsih_setDevicePage1Flags (width, factor,
5757 offset, &val, &configuration, negoFlags);
5758 dnegoprintk(("Setting Min: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
5759 id, width, factor, offset, negoFlags, val, configuration));
5760 pPage1->RequestedParameters = le32_to_cpu(val);
5761 pPage1->Reserved = 0;
5762 pPage1->Configuration = le32_to_cpu(configuration);
5764 ddvprintk(("id=%d width=%d factor=%x offset=%x request=%x config=%x negoFlags=%x\n",
5765 id, width, factor, offset, val, configuration, negoFlags));
5766 break;
5768 case MPT_FALLBACK:
5769 ddvprintk((MYIOC_s_NOTE_FMT
5770 "Fallback: Start: offset %d, factor %x, width %d \n",
5771 hd->ioc->name, dv->now.offset,
5772 dv->now.factor, dv->now.width));
5773 width = dv->now.width;
5774 offset = dv->now.offset;
5775 factor = dv->now.factor;
5776 if ((offset) && (dv->max.width)) {
5777 if (factor < MPT_ULTRA160)
5778 factor = MPT_ULTRA160;
5779 else if (factor < MPT_ULTRA2) {
5780 factor = MPT_ULTRA2;
5781 width = MPT_WIDE;
5782 } else if ((factor == MPT_ULTRA2) && width) {
5783 factor = MPT_ULTRA2;
5784 width = MPT_NARROW;
5785 } else if (factor < MPT_ULTRA) {
5786 factor = MPT_ULTRA;
5787 width = MPT_WIDE;
5788 } else if ((factor == MPT_ULTRA) && width) {
5789 width = MPT_NARROW;
5790 } else if (factor < MPT_FAST) {
5791 factor = MPT_FAST;
5792 width = MPT_WIDE;
5793 } else if ((factor == MPT_FAST) && width) {
5794 factor = MPT_FAST;
5795 width = MPT_NARROW;
5796 } else if (factor < MPT_SCSI) {
5797 factor = MPT_SCSI;
5798 width = MPT_WIDE;
5799 } else if ((factor == MPT_SCSI) && width) {
5800 factor = MPT_SCSI;
5801 width = MPT_NARROW;
5802 } else {
5803 factor = MPT_ASYNC;
5804 offset = 0;
5807 } else if (offset) {
5808 width = MPT_NARROW;
5809 if (factor < MPT_ULTRA)
5810 factor = MPT_ULTRA;
5811 else if (factor < MPT_FAST)
5812 factor = MPT_FAST;
5813 else if (factor < MPT_SCSI)
5814 factor = MPT_SCSI;
5815 else {
5816 factor = MPT_ASYNC;
5817 offset = 0;
5820 } else {
5821 width = MPT_NARROW;
5822 factor = MPT_ASYNC;
5824 dv->max.flags |= MPT_TARGET_NO_NEGO_QAS;
5825 dv->max.flags &= ~MPT_TAPE_NEGO_IDP;
5827 dv->now.width = width;
5828 dv->now.offset = offset;
5829 dv->now.factor = factor;
5830 dv->now.flags = dv->max.flags;
5832 pPage1 = (SCSIDevicePage1_t *)pPage;
5833 if (pPage1) {
5834 mptscsih_setDevicePage1Flags (width, factor, offset, &val,
5835 &configuration, dv->now.flags);
5836 dnegoprintk(("Finish: id=%d width=%d offset=%d factor=%x flags=%x request=%x config=%x\n",
5837 id, width, offset, factor, dv->now.flags, val, configuration));
5839 pPage1->RequestedParameters = le32_to_cpu(val);
5840 pPage1->Reserved = 0;
5841 pPage1->Configuration = le32_to_cpu(configuration);
5844 ddvprintk(("Finish: id=%d offset=%d factor=%x width=%d request=%x config=%x\n",
5845 id, dv->now.offset, dv->now.factor, dv->now.width, val, configuration));
5846 break;
5848 case MPT_SAVE:
5849 ddvprintk((MYIOC_s_NOTE_FMT
5850 "Saving to Target structure: ", hd->ioc->name));
5851 ddvprintk(("id=%d width=%x factor=%x offset=%d flags=%x\n",
5852 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags));
5854 /* Save these values to target structures
5855 * or overwrite nvram (phys disks only).
5858 if ((hd->Targets)&&((pTarget = hd->Targets[(int)id]) != NULL) && !pTarget->raidVolume ) {
5859 pTarget->maxWidth = dv->now.width;
5860 pTarget->maxOffset = dv->now.offset;
5861 pTarget->minSyncFactor = dv->now.factor;
5862 pTarget->negoFlags = dv->now.flags;
5863 } else {
5864 /* Preserv all flags, use
5865 * read-modify-write algorithm
5867 if (hd->ioc->spi_data.nvram) {
5868 data = hd->ioc->spi_data.nvram[id];
5870 if (dv->now.width)
5871 data &= ~MPT_NVRAM_WIDE_DISABLE;
5872 else
5873 data |= MPT_NVRAM_WIDE_DISABLE;
5875 if (!dv->now.offset)
5876 factor = MPT_ASYNC;
5878 data &= ~MPT_NVRAM_SYNC_MASK;
5879 data |= (dv->now.factor << MPT_NVRAM_SYNC_SHIFT) & MPT_NVRAM_SYNC_MASK;
5881 hd->ioc->spi_data.nvram[id] = data;
5884 break;
5888 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5889 /* mptscsih_fillbuf - fill a buffer with a special data pattern
5890 * cleanup. For bus scan only.
5892 * @buffer: Pointer to data buffer to be filled.
5893 * @size: Number of bytes to fill
5894 * @index: Pattern index
5895 * @width: bus width, 0 (8 bits) or 1 (16 bits)
5897 static void
5898 mptscsih_fillbuf(char *buffer, int size, int index, int width)
5900 char *ptr = buffer;
5901 int ii;
5902 char byte;
5903 short val;
5905 switch (index) {
5906 case 0:
5908 if (width) {
5909 /* Pattern: 0000 FFFF 0000 FFFF
5911 for (ii=0; ii < size; ii++, ptr++) {
5912 if (ii & 0x02)
5913 *ptr = 0xFF;
5914 else
5915 *ptr = 0x00;
5917 } else {
5918 /* Pattern: 00 FF 00 FF
5920 for (ii=0; ii < size; ii++, ptr++) {
5921 if (ii & 0x01)
5922 *ptr = 0xFF;
5923 else
5924 *ptr = 0x00;
5927 break;
5929 case 1:
5930 if (width) {
5931 /* Pattern: 5555 AAAA 5555 AAAA 5555
5933 for (ii=0; ii < size; ii++, ptr++) {
5934 if (ii & 0x02)
5935 *ptr = 0xAA;
5936 else
5937 *ptr = 0x55;
5939 } else {
5940 /* Pattern: 55 AA 55 AA 55
5942 for (ii=0; ii < size; ii++, ptr++) {
5943 if (ii & 0x01)
5944 *ptr = 0xAA;
5945 else
5946 *ptr = 0x55;
5949 break;
5951 case 2:
5952 /* Pattern: 00 01 02 03 04 05
5953 * ... FE FF 00 01..
5955 for (ii=0; ii < size; ii++, ptr++)
5956 *ptr = (char) ii;
5957 break;
5959 case 3:
5960 if (width) {
5961 /* Wide Pattern: FFFE 0001 FFFD 0002
5962 * ... 4000 DFFF 8000 EFFF
5964 byte = 0;
5965 for (ii=0; ii < size/2; ii++) {
5966 /* Create the base pattern
5968 val = (1 << byte);
5969 /* every 64 (0x40) bytes flip the pattern
5970 * since we fill 2 bytes / iteration,
5971 * test for ii = 0x20
5973 if (ii & 0x20)
5974 val = ~(val);
5976 if (ii & 0x01) {
5977 *ptr = (char)( (val & 0xFF00) >> 8);
5978 ptr++;
5979 *ptr = (char)(val & 0xFF);
5980 byte++;
5981 byte &= 0x0F;
5982 } else {
5983 val = ~val;
5984 *ptr = (char)( (val & 0xFF00) >> 8);
5985 ptr++;
5986 *ptr = (char)(val & 0xFF);
5989 ptr++;
5991 } else {
5992 /* Narrow Pattern: FE 01 FD 02 FB 04
5993 * .. 7F 80 01 FE 02 FD ... 80 7F
5995 byte = 0;
5996 for (ii=0; ii < size; ii++, ptr++) {
5997 /* Base pattern - first 32 bytes
5999 if (ii & 0x01) {
6000 *ptr = (1 << byte);
6001 byte++;
6002 byte &= 0x07;
6003 } else {
6004 *ptr = (char) (~(1 << byte));
6007 /* Flip the pattern every 32 bytes
6009 if (ii & 0x20)
6010 *ptr = ~(*ptr);
6013 break;
6016 #endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */
6018 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6020 module_init(mptscsih_init);
6021 module_exit(mptscsih_exit);