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.
7 *
8 * Credits:
9 * This driver would not exist if not for Alan Cox's development
10 * of the linux i2o driver.
11 *
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.
17 *
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!
21 *
22 * (see mptbase.c)
23 *
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)
28 *
29 * $Id: mptscsih.c,v 1.104 2002/12/03 21:26:34 pdelaney Exp $
30 */
31 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
32 /*
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.
36
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.
41
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.
52
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
61
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
65 */
66 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
67
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>
80
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>
86
87 #include "mptbase.h"
88 #include "mptscsih.h"
89
90 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
91 #define my_NAME "Fusion MPT SCSI Host driver"
92 #define my_VERSION MPT_LINUX_VERSION_COMMON
93 #define MYNAM "mptscsih"
94
95 MODULE_AUTHOR(MODULEAUTHOR);
96 MODULE_DESCRIPTION(my_NAME);
97 MODULE_LICENSE("GPL");
98
99 #ifdef MODULE
100 static int dv = MPTSCSIH_DOMAIN_VALIDATION;
101 module_param(dv, int, 0);
102 MODULE_PARM_DESC(dv, "DV Algorithm: enhanced = 1, basic = 0 (default=MPTSCSIH_DOMAIN_VALIDATION=1)");
103
104 static int width = MPTSCSIH_MAX_WIDTH;
105 module_param(width, int, 0);
106 MODULE_PARM_DESC(width, "Max Bus Width: wide = 1, narrow = 0 (default=MPTSCSIH_MAX_WIDTH=1)");
107
108 static ushort factor = MPTSCSIH_MIN_SYNC;
109 module_param(factor, ushort, 0);
110 MODULE_PARM_DESC(factor, "Min Sync Factor: (default=MPTSCSIH_MIN_SYNC=0x08)");
111
112 static int saf_te = MPTSCSIH_SAF_TE;
113 module_param(saf_te, int, 0);
114 MODULE_PARM_DESC(saf_te, "Force enabling SEP Processor: (default=MPTSCSIH_SAF_TE=0)");
115 #endif
116
117 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
118
119 typedef struct _BIG_SENSE_BUF {
120 u8 data[MPT_SENSE_BUFFER_ALLOC];
121 } BIG_SENSE_BUF;
122
123 #define MPT_SCANDV_GOOD (0x00000000) /* must be 0 */
124 #define MPT_SCANDV_DID_RESET (0x00000001)
125 #define MPT_SCANDV_SENSE (0x00000002)
126 #define MPT_SCANDV_SOME_ERROR (0x00000004)
127 #define MPT_SCANDV_SELECTION_TIMEOUT (0x00000008)
128 #define MPT_SCANDV_ISSUE_SENSE (0x00000010)
129 #define MPT_SCANDV_FALLBACK (0x00000020)
130
131 #define MPT_SCANDV_MAX_RETRIES (10)
132
133 #define MPT_ICFLAG_BUF_CAP 0x01 /* ReadBuffer Read Capacity format */
134 #define MPT_ICFLAG_ECHO 0x02 /* ReadBuffer Echo buffer format */
135 #define MPT_ICFLAG_PHYS_DISK 0x04 /* Any SCSI IO but do Phys Disk Format */
136 #define MPT_ICFLAG_TAGGED_CMD 0x08 /* Do tagged IO */
137 #define MPT_ICFLAG_DID_RESET 0x20 /* Bus Reset occurred with this command */
138 #define MPT_ICFLAG_RESERVED 0x40 /* Reserved has been issued */
139
140 typedef struct _internal_cmd {
141 char *data; /* data pointer */
142 dma_addr_t data_dma; /* data dma address */
143 int size; /* transfer size */
144 u8 cmd; /* SCSI Op Code */
145 u8 bus; /* bus number */
146 u8 id; /* SCSI ID (virtual) */
147 u8 lun;
148 u8 flags; /* Bit Field - See above */
149 u8 physDiskNum; /* Phys disk number, -1 else */
150 u8 rsvd2;
151 u8 rsvd;
152 } INTERNAL_CMD;
153
154 typedef struct _negoparms {
155 u8 width;
156 u8 offset;
157 u8 factor;
158 u8 flags;
159 } NEGOPARMS;
160
161 typedef struct _dv_parameters {
162 NEGOPARMS max;
163 NEGOPARMS now;
164 u8 cmd;
165 u8 id;
166 u16 pad1;
167 } DVPARAMETERS;
168
169
170 /*
171 * Other private/forward protos...
172 */
173 static int mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
174 static void mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq);
175 static int mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
176
177 static int mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
178 SCSIIORequest_t *pReq, int req_idx);
179 static void mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx);
180 static void copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply);
181 static int mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd);
182 static u32 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc);
183
184 static int mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout, int sleepFlag);
185 static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout, int sleepFlag);
186
187 static int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
188 static int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
189
190 static void mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *data, int dlen);
191 static void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56);
192 static void mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq);
193 static void mptscsih_setDevicePage1Flags (u8 width, u8 factor, u8 offset, int *requestedPtr, int *configurationPtr, u8 flags);
194 static void mptscsih_no_negotiate(MPT_SCSI_HOST *hd, int target_id);
195 static int mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target, int flags);
196 static int mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus);
197 static int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
198 static void mptscsih_timer_expired(unsigned long data);
199 static void mptscsih_taskmgmt_timeout(unsigned long data);
200 static void mptscsih_schedule_reset(void *hd);
201 static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
202 static int mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum);
203
204 static struct work_struct mptscsih_rstTask;
205
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);
218
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, u32 state);
224 static int mptscsih_resume(struct pci_dev *pdev);
225 #endif
226
227
228 /*
229 * Private data...
230 */
231
232 static int mpt_scsi_hosts = 0;
233
234 static int ScsiDoneCtx = -1;
235 static int ScsiTaskCtx = -1;
236 static int ScsiScanDvCtx = -1; /* Used only for bus scan and dv */
237
238 #define SNS_LEN(scp) sizeof((scp)->sense_buffer)
239
240 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
241 /*
242 * Domain Validation task structure
243 */
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
249
250 /*
251 * Wait Queue setup
252 */
253 static DECLARE_WAIT_QUEUE_HEAD (scandv_waitq);
254 static int scandv_wait_done = 1;
255
256
257 /* Driver command line structure
258 */
259 static struct mptscsih_driver_setup driver_setup;
260 static struct scsi_host_template driver_template;
261
262 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
263 /**
264 * mptscsih_add_sge - Place a simple SGE at address pAddr.
265 * @pAddr: virtual address for SGE
266 * @flagslength: SGE flags and data transfer length
267 * @dma_addr: Physical address
268 *
269 * This routine places a MPT request frame back on the MPT adapter's
270 * FreeQ.
271 */
272 static inline void
273 mptscsih_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
274 {
275 if (sizeof(dma_addr_t) == sizeof(u64)) {
276 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
277 u32 tmp = dma_addr & 0xFFFFFFFF;
278
279 pSge->FlagsLength = cpu_to_le32(flagslength);
280 pSge->Address.Low = cpu_to_le32(tmp);
281 tmp = (u32) ((u64)dma_addr >> 32);
282 pSge->Address.High = cpu_to_le32(tmp);
283
284 } else {
285 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
286 pSge->FlagsLength = cpu_to_le32(flagslength);
287 pSge->Address = cpu_to_le32(dma_addr);
288 }
289 } /* mptscsih_add_sge() */
290
291 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
292 /**
293 * mptscsih_add_chain - Place a chain SGE at address pAddr.
294 * @pAddr: virtual address for SGE
295 * @next: nextChainOffset value (u32's)
296 * @length: length of next SGL segment
297 * @dma_addr: Physical address
298 *
299 * This routine places a MPT request frame back on the MPT adapter's
300 * FreeQ.
301 */
302 static inline void
303 mptscsih_add_chain(char *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
304 {
305 if (sizeof(dma_addr_t) == sizeof(u64)) {
306 SGEChain64_t *pChain = (SGEChain64_t *) pAddr;
307 u32 tmp = dma_addr & 0xFFFFFFFF;
308
309 pChain->Length = cpu_to_le16(length);
310 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size();
311
312 pChain->NextChainOffset = next;
313
314 pChain->Address.Low = cpu_to_le32(tmp);
315 tmp = (u32) ((u64)dma_addr >> 32);
316 pChain->Address.High = cpu_to_le32(tmp);
317 } else {
318 SGEChain32_t *pChain = (SGEChain32_t *) pAddr;
319 pChain->Length = cpu_to_le16(length);
320 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size();
321 pChain->NextChainOffset = next;
322 pChain->Address = cpu_to_le32(dma_addr);
323 }
324 } /* mptscsih_add_chain() */
325
326 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
327 /*
328 * mptscsih_getFreeChainBuffer - Function to get a free chain
329 * from the MPT_SCSI_HOST FreeChainQ.
330 * @ioc: Pointer to MPT_ADAPTER structure
331 * @req_idx: Index of the SCSI IO request frame. (output)
332 *
333 * return SUCCESS or FAILED
334 */
335 static inline int
336 mptscsih_getFreeChainBuffer(MPT_ADAPTER *ioc, int *retIndex)
337 {
338 MPT_FRAME_HDR *chainBuf;
339 unsigned long flags;
340 int rc;
341 int chain_idx;
342
343 dsgprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer called\n",
344 ioc->name));
345 spin_lock_irqsave(&ioc->FreeQlock, flags);
346 if (!list_empty(&ioc->FreeChainQ)) {
347 int offset;
348
349 chainBuf = list_entry(ioc->FreeChainQ.next, MPT_FRAME_HDR,
350 u.frame.linkage.list);
351 list_del(&chainBuf->u.frame.linkage.list);
352 offset = (u8 *)chainBuf - (u8 *)ioc->ChainBuffer;
353 chain_idx = offset / ioc->req_sz;
354 rc = SUCCESS;
355 dsgprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer (index %d), got buf=%p\n",
356 ioc->name, *retIndex, chainBuf));
357 } else {
358 rc = FAILED;
359 chain_idx = MPT_HOST_NO_CHAIN;
360 dfailprintk((MYIOC_s_ERR_FMT "getFreeChainBuffer failed\n",
361 ioc->name));
362 }
363 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
364
365 *retIndex = chain_idx;
366 return rc;
367 } /* mptscsih_getFreeChainBuffer() */
368
369 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
370 /*
371 * mptscsih_AddSGE - Add a SGE (plus chain buffers) to the
372 * SCSIIORequest_t Message Frame.
373 * @ioc: Pointer to MPT_ADAPTER structure
374 * @SCpnt: Pointer to scsi_cmnd structure
375 * @pReq: Pointer to SCSIIORequest_t structure
376 *
377 * Returns ...
378 */
379 static int
380 mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
381 SCSIIORequest_t *pReq, int req_idx)
382 {
383 char *psge;
384 char *chainSge;
385 struct scatterlist *sg;
386 int frm_sz;
387 int sges_left, sg_done;
388 int chain_idx = MPT_HOST_NO_CHAIN;
389 int sgeOffset;
390 int numSgeSlots, numSgeThisFrame;
391 u32 sgflags, sgdir, thisxfer = 0;
392 int chain_dma_off = 0;
393 int newIndex;
394 int ii;
395 dma_addr_t v2;
396 u32 RequestNB;
397
398 sgdir = le32_to_cpu(pReq->Control) & MPI_SCSIIO_CONTROL_DATADIRECTION_MASK;
399 if (sgdir == MPI_SCSIIO_CONTROL_WRITE) {
400 sgdir = MPT_TRANSFER_HOST_TO_IOC;
401 } else {
402 sgdir = MPT_TRANSFER_IOC_TO_HOST;
403 }
404
405 psge = (char *) &pReq->SGL;
406 frm_sz = ioc->req_sz;
407
408 /* Map the data portion, if any.
409 * sges_left = 0 if no data transfer.
410 */
411 if ( (sges_left = SCpnt->use_sg) ) {
412 sges_left = pci_map_sg(ioc->pcidev,
413 (struct scatterlist *) SCpnt->request_buffer,
414 SCpnt->use_sg,
415 SCpnt->sc_data_direction);
416 if (sges_left == 0)
417 return FAILED;
418 } else if (SCpnt->request_bufflen) {
419 SCpnt->SCp.dma_handle = pci_map_single(ioc->pcidev,
420 SCpnt->request_buffer,
421 SCpnt->request_bufflen,
422 SCpnt->sc_data_direction);
423 dsgprintk((MYIOC_s_INFO_FMT "SG: non-SG for %p, len=%d\n",
424 ioc->name, SCpnt, SCpnt->request_bufflen));
425 mptscsih_add_sge((char *) &pReq->SGL,
426 0xD1000000|MPT_SGE_FLAGS_ADDRESSING|sgdir|SCpnt->request_bufflen,
427 SCpnt->SCp.dma_handle);
428
429 return SUCCESS;
430 }
431
432 /* Handle the SG case.
433 */
434 sg = (struct scatterlist *) SCpnt->request_buffer;
435 sg_done = 0;
436 sgeOffset = sizeof(SCSIIORequest_t) - sizeof(SGE_IO_UNION);
437 chainSge = NULL;
438
439 /* Prior to entering this loop - the following must be set
440 * current MF: sgeOffset (bytes)
441 * chainSge (Null if original MF is not a chain buffer)
442 * sg_done (num SGE done for this MF)
443 */
444
445 nextSGEset:
446 numSgeSlots = ((frm_sz - sgeOffset) / (sizeof(u32) + sizeof(dma_addr_t)) );
447 numSgeThisFrame = (sges_left < numSgeSlots) ? sges_left : numSgeSlots;
448
449 sgflags = MPT_SGE_FLAGS_SIMPLE_ELEMENT | MPT_SGE_FLAGS_ADDRESSING | sgdir;
450
451 /* Get first (num - 1) SG elements
452 * Skip any SG entries with a length of 0
453 * NOTE: at finish, sg and psge pointed to NEXT data/location positions
454 */
455 for (ii=0; ii < (numSgeThisFrame-1); ii++) {
456 thisxfer = sg_dma_len(sg);
457 if (thisxfer == 0) {
458 sg ++; /* Get next SG element from the OS */
459 sg_done++;
460 continue;
461 }
462
463 v2 = sg_dma_address(sg);
464 mptscsih_add_sge(psge, sgflags | thisxfer, v2);
465
466 sg++; /* Get next SG element from the OS */
467 psge += (sizeof(u32) + sizeof(dma_addr_t));
468 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
469 sg_done++;
470 }
471
472 if (numSgeThisFrame == sges_left) {
473 /* Add last element, end of buffer and end of list flags.
474 */
475 sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT |
476 MPT_SGE_FLAGS_END_OF_BUFFER |
477 MPT_SGE_FLAGS_END_OF_LIST;
478
479 /* Add last SGE and set termination flags.
480 * Note: Last SGE may have a length of 0 - which should be ok.
481 */
482 thisxfer = sg_dma_len(sg);
483
484 v2 = sg_dma_address(sg);
485 mptscsih_add_sge(psge, sgflags | thisxfer, v2);
486 /*
487 sg++;
488 psge += (sizeof(u32) + sizeof(dma_addr_t));
489 */
490 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
491 sg_done++;
492
493 if (chainSge) {
494 /* The current buffer is a chain buffer,
495 * but there is not another one.
496 * Update the chain element
497 * Offset and Length fields.
498 */
499 mptscsih_add_chain((char *)chainSge, 0, sgeOffset, ioc->ChainBufferDMA + chain_dma_off);
500 } else {
501 /* The current buffer is the original MF
502 * and there is no Chain buffer.
503 */
504 pReq->ChainOffset = 0;
505 RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor) + 1) & 0x03;
506 dsgprintk((MYIOC_s_ERR_FMT
507 "Single Buffer RequestNB=%x, sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
508 ioc->RequestNB[req_idx] = RequestNB;
509 }
510 } else {
511 /* At least one chain buffer is needed.
512 * Complete the first MF
513 * - last SGE element, set the LastElement bit
514 * - set ChainOffset (words) for orig MF
515 * (OR finish previous MF chain buffer)
516 * - update MFStructPtr ChainIndex
517 * - Populate chain element
518 * Also
519 * Loop until done.
520 */
521
522 dsgprintk((MYIOC_s_INFO_FMT "SG: Chain Required! sg done %d\n",
523 ioc->name, sg_done));
524
525 /* Set LAST_ELEMENT flag for last non-chain element
526 * in the buffer. Since psge points at the NEXT
527 * SGE element, go back one SGE element, update the flags
528 * and reset the pointer. (Note: sgflags & thisxfer are already
529 * set properly).
530 */
531 if (sg_done) {
532 u32 *ptmp = (u32 *) (psge - (sizeof(u32) + sizeof(dma_addr_t)));
533 sgflags = le32_to_cpu(*ptmp);
534 sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT;
535 *ptmp = cpu_to_le32(sgflags);
536 }
537
538 if (chainSge) {
539 /* The current buffer is a chain buffer.
540 * chainSge points to the previous Chain Element.
541 * Update its chain element Offset and Length (must
542 * include chain element size) fields.
543 * Old chain element is now complete.
544 */
545 u8 nextChain = (u8) (sgeOffset >> 2);
546 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
547 mptscsih_add_chain((char *)chainSge, nextChain, sgeOffset, ioc->ChainBufferDMA + chain_dma_off);
548 } else {
549 /* The original MF buffer requires a chain buffer -
550 * set the offset.
551 * Last element in this MF is a chain element.
552 */
553 pReq->ChainOffset = (u8) (sgeOffset >> 2);
554 RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor) + 1) & 0x03;
555 dsgprintk((MYIOC_s_ERR_FMT "Chain Buffer Needed, RequestNB=%x sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
556 ioc->RequestNB[req_idx] = RequestNB;
557 }
558
559 sges_left -= sg_done;
560
561
562 /* NOTE: psge points to the beginning of the chain element
563 * in current buffer. Get a chain buffer.
564 */
565 dsgprintk((MYIOC_s_INFO_FMT
566 "calling getFreeChainBuffer SCSI cmd=%02x (%p)\n",
567 ioc->name, pReq->CDB[0], SCpnt));
568 if ((mptscsih_getFreeChainBuffer(ioc, &newIndex)) == FAILED)
569 return FAILED;
570
571 /* Update the tracking arrays.
572 * If chainSge == NULL, update ReqToChain, else ChainToChain
573 */
574 if (chainSge) {
575 ioc->ChainToChain[chain_idx] = newIndex;
576 } else {
577 ioc->ReqToChain[req_idx] = newIndex;
578 }
579 chain_idx = newIndex;
580 chain_dma_off = ioc->req_sz * chain_idx;
581
582 /* Populate the chainSGE for the current buffer.
583 * - Set chain buffer pointer to psge and fill
584 * out the Address and Flags fields.
585 */
586 chainSge = (char *) psge;
587 dsgprintk((KERN_INFO " Current buff @ %p (index 0x%x)",
588 psge, req_idx));
589
590 /* Start the SGE for the next buffer
591 */
592 psge = (char *) (ioc->ChainBuffer + chain_dma_off);
593 sgeOffset = 0;
594 sg_done = 0;
595
596 dsgprintk((KERN_INFO " Chain buff @ %p (index 0x%x)\n",
597 psge, chain_idx));
598
599 /* Start the SGE for the next buffer
600 */
601
602 goto nextSGEset;
603 }
604
605 return SUCCESS;
606 } /* mptscsih_AddSGE() */
607
608 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
609 /*
610 * mptscsih_io_done - Main SCSI IO callback routine registered to
611 * Fusion MPT (base) driver
612 * @ioc: Pointer to MPT_ADAPTER structure
613 * @mf: Pointer to original MPT request frame
614 * @r: Pointer to MPT reply frame (NULL if TurboReply)
615 *
616 * This routine is called from mpt.c::mpt_interrupt() at the completion
617 * of any SCSI IO request.
618 * This routine is registered with the Fusion MPT (base) driver at driver
619 * load/init time via the mpt_register() API call.
620 *
621 * Returns 1 indicating alloc'd request frame ptr should be freed.
622 */
623 static int
624 mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
625 {
626 struct scsi_cmnd *sc;
627 MPT_SCSI_HOST *hd;
628 SCSIIORequest_t *pScsiReq;
629 SCSIIOReply_t *pScsiReply;
630 u16 req_idx;
631
632 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
633
634 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
635 sc = hd->ScsiLookup[req_idx];
636 if (sc == NULL) {
637 MPIHeader_t *hdr = (MPIHeader_t *)mf;
638
639 /* Remark: writeSDP1 will use the ScsiDoneCtx
640 * If a SCSI I/O cmd, device disabled by OS and
641 * completion done. Cannot touch sc struct. Just free mem.
642 */
643 if (hdr->Function == MPI_FUNCTION_SCSI_IO_REQUEST)
644 printk(MYIOC_s_ERR_FMT "NULL ScsiCmd ptr!\n",
645 ioc->name);
646
647 mptscsih_freeChainBuffers(ioc, req_idx);
648 return 1;
649 }
650
651 dmfprintk((MYIOC_s_INFO_FMT
652 "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n",
653 ioc->name, mf, mr, sc, req_idx));
654
655 sc->result = DID_OK << 16; /* Set default reply as OK */
656 pScsiReq = (SCSIIORequest_t *) mf;
657 pScsiReply = (SCSIIOReply_t *) mr;
658
659 if (pScsiReply == NULL) {
660 /* special context reply handling */
661 ;
662 } else {
663 u32 xfer_cnt;
664 u16 status;
665 u8 scsi_state, scsi_status;
666
667 status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK;
668 scsi_state = pScsiReply->SCSIState;
669 scsi_status = pScsiReply->SCSIStatus;
670 xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
671 sc->resid = sc->request_bufflen - xfer_cnt;
672
673 dreplyprintk((KERN_NOTICE "Reply ha=%d id=%d lun=%d:\n"
674 "IOCStatus=%04xh SCSIState=%02xh SCSIStatus=%02xh\n"
675 "resid=%d bufflen=%d xfer_cnt=%d\n",
676 ioc->id, pScsiReq->TargetID, pScsiReq->LUN[1],
677 status, scsi_state, scsi_status, sc->resid,
678 sc->request_bufflen, xfer_cnt));
679
680 if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)
681 copy_sense_data(sc, hd, mf, pScsiReply);
682
683 /*
684 * Look for + dump FCP ResponseInfo[]!
685 */
686 if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID) {
687 printk(KERN_NOTICE " FCP_ResponseInfo=%08xh\n",
688 le32_to_cpu(pScsiReply->ResponseInfo));
689 }
690
691 switch(status) {
692 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
693 /* CHECKME!
694 * Maybe: DRIVER_BUSY | SUGGEST_RETRY | DID_SOFT_ERROR (retry)
695 * But not: DID_BUS_BUSY lest one risk
696 * killing interrupt handler:-(
697 */
698 sc->result = SAM_STAT_BUSY;
699 break;
700
701 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
702 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
703 sc->result = DID_BAD_TARGET << 16;
704 break;
705
706 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
707 /* Spoof to SCSI Selection Timeout! */
708 sc->result = DID_NO_CONNECT << 16;
709
710 if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF)
711 hd->sel_timeout[pScsiReq->TargetID]++;
712 break;
713
714 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
715 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
716 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
717 /* Linux handles an unsolicited DID_RESET better
718 * than an unsolicited DID_ABORT.
719 */
720 sc->result = DID_RESET << 16;
721
722 /* GEM Workaround. */
723 if (ioc->bus_type == SCSI)
724 mptscsih_no_negotiate(hd, sc->device->id);
725 break;
726
727 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
728 if ( xfer_cnt >= sc->underflow ) {
729 /* Sufficient data transfer occurred */
730 sc->result = (DID_OK << 16) | scsi_status;
731 } else if ( xfer_cnt == 0 ) {
732 /* A CRC Error causes this condition; retry */
733 sc->result = (DRIVER_SENSE << 24) | (DID_OK << 16) |
734 (CHECK_CONDITION << 1);
735 sc->sense_buffer[0] = 0x70;
736 sc->sense_buffer[2] = NO_SENSE;
737 sc->sense_buffer[12] = 0;
738 sc->sense_buffer[13] = 0;
739 } else {
740 sc->result = DID_SOFT_ERROR << 16;
741 }
742 dreplyprintk((KERN_NOTICE "RESIDUAL_MISMATCH: result=%x on id=%d\n", sc->result, sc->target));
743 break;
744
745 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
746 /*
747 * Do upfront check for valid SenseData and give it
748 * precedence!
749 */
750 sc->result = (DID_OK << 16) | scsi_status;
751 if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
752 /* Have already saved the status and sense data
753 */
754 ;
755 } else {
756 if (xfer_cnt < sc->underflow) {
757 sc->result = DID_SOFT_ERROR << 16;
758 }
759 if (scsi_state & (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)) {
760 /* What to do?
761 */
762 sc->result = DID_SOFT_ERROR << 16;
763 }
764 else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
765 /* Not real sure here either... */
766 sc->result = DID_RESET << 16;
767 }
768 }
769
770 dreplyprintk((KERN_NOTICE " sc->underflow={report ERR if < %02xh bytes xfer'd}\n",
771 sc->underflow));
772 dreplyprintk((KERN_NOTICE " ActBytesXferd=%02xh\n", xfer_cnt));
773 /* Report Queue Full
774 */
775 if (scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)
776 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
777
778 break;
779
780 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
781 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
782 scsi_status = pScsiReply->SCSIStatus;
783 sc->result = (DID_OK << 16) | scsi_status;
784 if (scsi_state == 0) {
785 ;
786 } else if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
787 /*
788 * If running against circa 200003dd 909 MPT f/w,
789 * may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL
790 * (QUEUE_FULL) returned from device! --> get 0x0000?128
791 * and with SenseBytes set to 0.
792 */
793 if (pScsiReply->SCSIStatus == MPI_SCSI_STATUS_TASK_SET_FULL)
794 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
795
796 }
797 else if (scsi_state &
798 (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)
799 ) {
800 /*
801 * What to do?
802 */
803 sc->result = DID_SOFT_ERROR << 16;
804 }
805 else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
806 /* Not real sure here either... */
807 sc->result = DID_RESET << 16;
808 }
809 else if (scsi_state & MPI_SCSI_STATE_QUEUE_TAG_REJECTED) {
810 /* Device Inq. data indicates that it supports
811 * QTags, but rejects QTag messages.
812 * This command completed OK.
813 *
814 * Not real sure here either so do nothing... */
815 }
816
817 if (sc->result == MPI_SCSI_STATUS_TASK_SET_FULL)
818 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
819
820 /* Add handling of:
821 * Reservation Conflict, Busy,
822 * Command Terminated, CHECK
823 */
824 break;
825
826 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
827 sc->result = DID_SOFT_ERROR << 16;
828 break;
829
830 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
831 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
832 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
833 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
834 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
835 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
836 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
837 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
838 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
839 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
840 default:
841 /*
842 * What to do?
843 */
844 sc->result = DID_SOFT_ERROR << 16;
845 break;
846
847 } /* switch(status) */
848
849 dreplyprintk((KERN_NOTICE " sc->result is %08xh\n", sc->result));
850 } /* end of address reply case */
851
852 /* Unmap the DMA buffers, if any. */
853 if (sc->use_sg) {
854 pci_unmap_sg(ioc->pcidev, (struct scatterlist *) sc->request_buffer,
855 sc->use_sg, sc->sc_data_direction);
856 } else if (sc->request_bufflen) {
857 pci_unmap_single(ioc->pcidev, sc->SCp.dma_handle,
858 sc->request_bufflen, sc->sc_data_direction);
859 }
860
861 hd->ScsiLookup[req_idx] = NULL;
862
863 sc->scsi_done(sc); /* Issue the command callback */
864
865 /* Free Chain buffers */
866 mptscsih_freeChainBuffers(ioc, req_idx);
867 return 1;
868 }
869
870
871 /*
872 * mptscsih_flush_running_cmds - For each command found, search
873 * Scsi_Host instance taskQ and reply to OS.
874 * Called only if recovering from a FW reload.
875 * @hd: Pointer to a SCSI HOST structure
876 *
877 * Returns: None.
878 *
879 * Must be called while new I/Os are being queued.
880 */
881 static void
882 mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
883 {
884 MPT_ADAPTER *ioc = hd->ioc;
885 struct scsi_cmnd *SCpnt;
886 MPT_FRAME_HDR *mf;
887 int ii;
888 int max = ioc->req_depth;
889
890 dprintk((KERN_INFO MYNAM ": flush_ScsiLookup called\n"));
891 for (ii= 0; ii < max; ii++) {
892 if ((SCpnt = hd->ScsiLookup[ii]) != NULL) {
893
894 /* Command found.
895 */
896
897 /* Null ScsiLookup index
898 */
899 hd->ScsiLookup[ii] = NULL;
900
901 mf = MPT_INDEX_2_MFPTR(ioc, ii);
902 dmfprintk(( "flush: ScsiDone (mf=%p,sc=%p)\n",
903 mf, SCpnt));
904
905 /* Set status, free OS resources (SG DMA buffers)
906 * Do OS callback
907 * Free driver resources (chain, msg buffers)
908 */
909 if (scsi_device_online(SCpnt->device)) {
910 if (SCpnt->use_sg) {
911 pci_unmap_sg(ioc->pcidev,
912 (struct scatterlist *) SCpnt->request_buffer,
913 SCpnt->use_sg,
914 SCpnt->sc_data_direction);
915 } else if (SCpnt->request_bufflen) {
916 pci_unmap_single(ioc->pcidev,
917 SCpnt->SCp.dma_handle,
918 SCpnt->request_bufflen,
919 SCpnt->sc_data_direction);
920 }
921 }
922 SCpnt->result = DID_RESET << 16;
923 SCpnt->host_scribble = NULL;
924
925 /* Free Chain buffers */
926 mptscsih_freeChainBuffers(ioc, ii);
927
928 /* Free Message frames */
929 mpt_free_msg_frame(ioc, mf);
930
931 SCpnt->scsi_done(SCpnt); /* Issue the command callback */
932 }
933 }
934
935 return;
936 }
937
938 /*
939 * mptscsih_search_running_cmds - Delete any commands associated
940 * with the specified target and lun. Function called only
941 * when a lun is disable by mid-layer.
942 * Do NOT access the referenced scsi_cmnd structure or
943 * members. Will cause either a paging or NULL ptr error.
944 * @hd: Pointer to a SCSI HOST structure
945 * @target: target id
946 * @lun: lun
947 *
948 * Returns: None.
949 *
950 * Called from slave_destroy.
951 */
952 static void
953 mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, uint target, uint lun)
954 {
955 SCSIIORequest_t *mf = NULL;
956 int ii;
957 int max = hd->ioc->req_depth;
958
959 dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n",
960 target, lun, max));
961
962 for (ii=0; ii < max; ii++) {
963 if (hd->ScsiLookup[ii] != NULL) {
964
965 mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii);
966
967 dsprintk(( "search_running: found (sc=%p, mf = %p) target %d, lun %d \n",
968 hd->ScsiLookup[ii], mf, mf->TargetID, mf->LUN[1]));
969
970 if ((mf->TargetID != ((u8)target)) || (mf->LUN[1] != ((u8) lun)))
971 continue;
972
973 /* Cleanup
974 */
975 hd->ScsiLookup[ii] = NULL;
976 mptscsih_freeChainBuffers(hd->ioc, ii);
977 mpt_free_msg_frame(hd->ioc, (MPT_FRAME_HDR *)mf);
978 }
979 }
980
981 return;
982 }
983
984 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
985 /*
986 * Hack! It might be nice to report if a device is returning QUEUE_FULL
987 * but maybe not each and every time...
988 */
989 static long last_queue_full = 0;
990
991 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
992 /*
993 * mptscsih_report_queue_full - Report QUEUE_FULL status returned
994 * from a SCSI target device.
995 * @sc: Pointer to scsi_cmnd structure
996 * @pScsiReply: Pointer to SCSIIOReply_t
997 * @pScsiReq: Pointer to original SCSI request
998 *
999 * This routine periodically reports QUEUE_FULL status returned from a
1000 * SCSI target device. It reports this to the console via kernel
1001 * printk() API call, not more than once every 10 seconds.
1002 */
1003 static void
1004 mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq)
1005 {
1006 long time = jiffies;
1007
1008 if (time - last_queue_full > 10 * HZ) {
1009 char *ioc_str = "ioc?";
1010
1011 if (sc->device && sc->device->host != NULL && sc->device->host->hostdata != NULL)
1012 ioc_str = ((MPT_SCSI_HOST *)sc->device->host->hostdata)->ioc->name;
1013 dprintk((MYIOC_s_WARN_FMT "Device (%d:%d:%d) reported QUEUE_FULL!\n",
1014 ioc_str, 0, sc->device->id, sc->device->lun));
1015 last_queue_full = time;
1016 }
1017 }
1018
1019 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1020 static char *info_kbuf = NULL;
1021
1022 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1023 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1024 /*
1025 * mptscsih_probe - Installs scsi devices per bus.
1026 * @pdev: Pointer to pci_dev structure
1027 *
1028 * Returns 0 for success, non-zero for failure.
1029 *
1030 */
1031
1032 static int
1033 mptscsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1034 {
1035 struct Scsi_Host *sh;
1036 MPT_SCSI_HOST *hd;
1037 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1038 unsigned long flags;
1039 int sz, ii;
1040 int numSGE = 0;
1041 int scale;
1042 int ioc_cap;
1043 u8 *mem;
1044 int error=0;
1045
1046
1047 /* 20010202 -sralston
1048 * Added sanity check on readiness of the MPT adapter.
1049 */
1050 if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
1051 printk(MYIOC_s_WARN_FMT
1052 "Skipping because it's not operational!\n",
1053 ioc->name);
1054 return -ENODEV;
1055 }
1056
1057 if (!ioc->active) {
1058 printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
1059 ioc->name);
1060 return -ENODEV;
1061 }
1062
1063 /* Sanity check - ensure at least 1 port is INITIATOR capable
1064 */
1065 ioc_cap = 0;
1066 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
1067 if (ioc->pfacts[ii].ProtocolFlags &
1068 MPI_PORTFACTS_PROTOCOL_INITIATOR)
1069 ioc_cap ++;
1070 }
1071
1072 if (!ioc_cap) {
1073 printk(MYIOC_s_WARN_FMT
1074 "Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n",
1075 ioc->name, ioc);
1076 return -ENODEV;
1077 }
1078
1079 sh = scsi_host_alloc(&driver_template, sizeof(MPT_SCSI_HOST));
1080
1081 if (!sh) {
1082 printk(MYIOC_s_WARN_FMT
1083 "Unable to register controller with SCSI subsystem\n",
1084 ioc->name);
1085 return -1;
1086 }
1087
1088 spin_lock_irqsave(&ioc->FreeQlock, flags);
1089
1090 /* Attach the SCSI Host to the IOC structure
1091 */
1092 ioc->sh = sh;
1093
1094 sh->io_port = 0;
1095 sh->n_io_port = 0;
1096 sh->irq = 0;
1097
1098 /* set 16 byte cdb's */
1099 sh->max_cmd_len = 16;
1100
1101 /* Yikes! This is important!
1102 * Otherwise, by default, linux
1103 * only scans target IDs 0-7!
1104 * pfactsN->MaxDevices unreliable
1105 * (not supported in early
1106 * versions of the FW).
1107 * max_id = 1 + actual max id,
1108 * max_lun = 1 + actual last lun,
1109 * see hosts.h :o(
1110 */
1111 if (ioc->bus_type == SCSI) {
1112 sh->max_id = MPT_MAX_SCSI_DEVICES;
1113 } else {
1114 /* For FC, increase the queue depth
1115 * from MPT_SCSI_CAN_QUEUE (31)
1116 * to MPT_FC_CAN_QUEUE (63).
1117 */
1118 sh->can_queue = MPT_FC_CAN_QUEUE;
1119 sh->max_id =
1120 MPT_MAX_FC_DEVICES<256 ? MPT_MAX_FC_DEVICES : 255;
1121 }
1122
1123 sh->max_lun = MPT_LAST_LUN + 1;
1124 sh->max_channel = 0;
1125 sh->this_id = ioc->pfacts[0].PortSCSIID;
1126
1127 /* Required entry.
1128 */
1129 sh->unique_id = ioc->id;
1130
1131 /* Verify that we won't exceed the maximum
1132 * number of chain buffers
1133 * We can optimize: ZZ = req_sz/sizeof(SGE)
1134 * For 32bit SGE's:
1135 * numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
1136 * + (req_sz - 64)/sizeof(SGE)
1137 * A slightly different algorithm is required for
1138 * 64bit SGEs.
1139 */
1140 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
1141 if (sizeof(dma_addr_t) == sizeof(u64)) {
1142 numSGE = (scale - 1) *
1143 (ioc->facts.MaxChainDepth-1) + scale +
1144 (ioc->req_sz - 60) / (sizeof(dma_addr_t) +
1145 sizeof(u32));
1146 } else {
1147 numSGE = 1 + (scale - 1) *
1148 (ioc->facts.MaxChainDepth-1) + scale +
1149 (ioc->req_sz - 64) / (sizeof(dma_addr_t) +
1150 sizeof(u32));
1151 }
1152
1153 if (numSGE < sh->sg_tablesize) {
1154 /* Reset this value */
1155 dprintk((MYIOC_s_INFO_FMT
1156 "Resetting sg_tablesize to %d from %d\n",
1157 ioc->name, numSGE, sh->sg_tablesize));
1158 sh->sg_tablesize = numSGE;
1159 }
1160
1161 /* Set the pci device pointer in Scsi_Host structure.
1162 */
1163 scsi_set_device(sh, &ioc->pcidev->dev);
1164
1165 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1166
1167 hd = (MPT_SCSI_HOST *) sh->hostdata;
1168 hd->ioc = ioc;
1169
1170 /* SCSI needs scsi_cmnd lookup table!
1171 * (with size equal to req_depth*PtrSz!)
1172 */
1173 sz = ioc->req_depth * sizeof(void *);
1174 mem = kmalloc(sz, GFP_ATOMIC);
1175 if (mem == NULL) {
1176 error = -ENOMEM;
1177 goto mptscsih_probe_failed;
1178 }
1179
1180 memset(mem, 0, sz);
1181 hd->ScsiLookup = (struct scsi_cmnd **) mem;
1182
1183 dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n",
1184 ioc->name, hd->ScsiLookup, sz));
1185
1186 /* Allocate memory for the device structures.
1187 * A non-Null pointer at an offset
1188 * indicates a device exists.
1189 * max_id = 1 + maximum id (hosts.h)
1190 */
1191 sz = sh->max_id * sizeof(void *);
1192 mem = kmalloc(sz, GFP_ATOMIC);
1193 if (mem == NULL) {
1194 error = -ENOMEM;
1195 goto mptscsih_probe_failed;
1196 }
1197
1198 memset(mem, 0, sz);
1199 hd->Targets = (VirtDevice **) mem;
1200
1201 dprintk((KERN_INFO
1202 " Targets @ %p, sz=%d\n", hd->Targets, sz));
1203
1204 /* Clear the TM flags
1205 */
1206 hd->tmPending = 0;
1207 hd->tmState = TM_STATE_NONE;
1208 hd->resetPending = 0;
1209 hd->abortSCpnt = NULL;
1210 hd->tmPtr = NULL;
1211
1212 /* Clear the pointer used to store
1213 * single-threaded commands, i.e., those
1214 * issued during a bus scan, dv and
1215 * configuration pages.
1216 */
1217 hd->cmdPtr = NULL;
1218
1219 /* Initialize this SCSI Hosts' timers
1220 * To use, set the timer expires field
1221 * and add_timer
1222 */
1223 init_timer(&hd->timer);
1224 hd->timer.data = (unsigned long) hd;
1225 hd->timer.function = mptscsih_timer_expired;
1226
1227 init_timer(&hd->TMtimer);
1228 hd->TMtimer.data = (unsigned long) hd;
1229 hd->TMtimer.function = mptscsih_taskmgmt_timeout;
1230 hd->qtag_tick = jiffies;
1231
1232 /* Moved Earlier Pam D */
1233 /* ioc->sh = sh; */
1234
1235 if (ioc->bus_type == SCSI) {
1236 /* Update with the driver setup
1237 * values.
1238 */
1239 if (ioc->spi_data.maxBusWidth >
1240 driver_setup.max_width) {
1241 ioc->spi_data.maxBusWidth =
1242 driver_setup.max_width;
1243 }
1244
1245 if (ioc->spi_data.minSyncFactor <
1246 driver_setup.min_sync_factor) {
1247 ioc->spi_data.minSyncFactor =
1248 driver_setup.min_sync_factor;
1249 }
1250
1251 if (ioc->spi_data.minSyncFactor == MPT_ASYNC) {
1252 ioc->spi_data.maxSyncOffset = 0;
1253 }
1254
1255 ioc->spi_data.Saf_Te = driver_setup.saf_te;
1256
1257 hd->negoNvram = 0;
1258 #ifndef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1259 hd->negoNvram = MPT_SCSICFG_USE_NVRAM;
1260 #endif
1261 ioc->spi_data.forceDv = 0;
1262 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
1263 ioc->spi_data.dvStatus[ii] =
1264 MPT_SCSICFG_NEGOTIATE;
1265 }
1266
1267 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++)
1268 ioc->spi_data.dvStatus[ii] |=
1269 MPT_SCSICFG_DV_NOT_DONE;
1270
1271 ddvprintk((MYIOC_s_INFO_FMT
1272 "dv %x width %x factor %x saf_te %x\n",
1273 ioc->name, driver_setup.dv,
1274 driver_setup.max_width,
1275 driver_setup.min_sync_factor,
1276 driver_setup.saf_te));
1277 }
1278
1279 mpt_scsi_hosts++;
1280
1281 error = scsi_add_host (sh, &ioc->pcidev->dev);
1282 if(error) {
1283 dprintk((KERN_ERR MYNAM
1284 "scsi_add_host failed\n"));
1285 goto mptscsih_probe_failed;
1286 }
1287
1288 scsi_scan_host(sh);
1289 return 0;
1290
1291 mptscsih_probe_failed:
1292
1293 mptscsih_remove(pdev);
1294 return error;
1295
1296 }
1297
1298 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1299 /*
1300 * mptscsih_remove - Removed scsi devices
1301 * @pdev: Pointer to pci_dev structure
1302 *
1303 *
1304 */
1305 static void
1306 mptscsih_remove(struct pci_dev *pdev)
1307 {
1308 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1309 struct Scsi_Host *host = ioc->sh;
1310 MPT_SCSI_HOST *hd;
1311 int count;
1312 unsigned long flags;
1313
1314 if(!host)
1315 return;
1316
1317 scsi_remove_host(host);
1318
1319 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1320 /* Check DV thread active */
1321 count = 10 * HZ;
1322 spin_lock_irqsave(&dvtaskQ_lock, flags);
1323 if (dvtaskQ_active) {
1324 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
1325 while(dvtaskQ_active && --count) {
1326 set_current_state(TASK_INTERRUPTIBLE);
1327 schedule_timeout(1);
1328 }
1329 } else {
1330 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
1331 }
1332 if (!count)
1333 printk(KERN_ERR MYNAM ": ERROR - DV thread still active!\n");
1334 #if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY)
1335 else
1336 printk(KERN_ERR MYNAM ": DV thread orig %d, count %d\n", 10 * HZ, count);
1337 #endif
1338 #endif
1339
1340 hd = (MPT_SCSI_HOST *)host->hostdata;
1341 if (hd != NULL) {
1342 int sz1;
1343
1344 mptscsih_shutdown(&pdev->dev);
1345
1346 sz1=0;
1347
1348 if (hd->ScsiLookup != NULL) {
1349 sz1 = hd->ioc->req_depth * sizeof(void *);
1350 kfree(hd->ScsiLookup);
1351 hd->ScsiLookup = NULL;
1352 }
1353
1354 if (hd->Targets != NULL) {
1355 /*
1356 * Free pointer array.
1357 */
1358 kfree(hd->Targets);
1359 hd->Targets = NULL;
1360 }
1361
1362 dprintk((MYIOC_s_INFO_FMT
1363 "Free'd ScsiLookup (%d) memory\n",
1364 hd->ioc->name, sz1));
1365
1366 /* NULL the Scsi_Host pointer
1367 */
1368 hd->ioc->sh = NULL;
1369 }
1370
1371 scsi_host_put(host);
1372 mpt_scsi_hosts--;
1373
1374 }
1375
1376 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1377 /*
1378 * mptscsih_shutdown - reboot notifier
1379 *
1380 */
1381 static void
1382 mptscsih_shutdown(struct device * dev)
1383 {
1384 MPT_ADAPTER *ioc = pci_get_drvdata(to_pci_dev(dev));
1385 struct Scsi_Host *host = ioc->sh;
1386 MPT_SCSI_HOST *hd;
1387
1388 if(!host)
1389 return;
1390
1391 hd = (MPT_SCSI_HOST *)host->hostdata;
1392
1393 /* Flush the cache of this adapter
1394 */
1395 if(hd != NULL)
1396 mptscsih_synchronize_cache(hd, 0);
1397
1398 }
1399
1400 #ifdef CONFIG_PM
1401 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1402 /*
1403 * mptscsih_suspend - Fusion MPT scsie driver suspend routine.
1404 *
1405 *
1406 */
1407 static int
1408 mptscsih_suspend(struct pci_dev *pdev, u32 state)
1409 {
1410 mptscsih_shutdown(&pdev->dev);
1411 return 0;
1412 }
1413
1414 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1415 /*
1416 * mptscsih_resume - Fusion MPT scsi driver resume routine.
1417 *
1418 *
1419 */
1420 static int
1421 mptscsih_resume(struct pci_dev *pdev)
1422 {
1423 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1424 struct Scsi_Host *host = ioc->sh;
1425 MPT_SCSI_HOST *hd;
1426
1427 if(!host)
1428 return 0;
1429
1430 hd = (MPT_SCSI_HOST *)host->hostdata;
1431 if(!hd)
1432 return 0;
1433
1434 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1435 {
1436 unsigned long lflags;
1437 spin_lock_irqsave(&dvtaskQ_lock, lflags);
1438 if (!dvtaskQ_active) {
1439 dvtaskQ_active = 1;
1440 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1441 INIT_WORK(&mptscsih_dvTask,
1442 mptscsih_domainValidation, (void *) hd);
1443 schedule_work(&mptscsih_dvTask);
1444 } else {
1445 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1446 }
1447 }
1448 #endif
1449 return 0;
1450 }
1451
1452 #endif
1453
1454 static struct mpt_pci_driver mptscsih_driver = {
1455 .probe = mptscsih_probe,
1456 .remove = mptscsih_remove,
1457 .shutdown = mptscsih_shutdown,
1458 #ifdef CONFIG_PM
1459 .suspend = mptscsih_suspend,
1460 .resume = mptscsih_resume,
1461 #endif
1462 };
1463
1464 /* SCSI host fops start here... */
1465 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1466 /**
1467 * mptscsih_init - Register MPT adapter(s) as SCSI host(s) with
1468 * linux scsi mid-layer.
1469 *
1470 * Returns 0 for success, non-zero for failure.
1471 */
1472 static int __init
1473 mptscsih_init(void)
1474 {
1475
1476 show_mptmod_ver(my_NAME, my_VERSION);
1477
1478 ScsiDoneCtx = mpt_register(mptscsih_io_done, MPTSCSIH_DRIVER);
1479 ScsiTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSCSIH_DRIVER);
1480 ScsiScanDvCtx = mpt_register(mptscsih_scandv_complete, MPTSCSIH_DRIVER);
1481
1482 if (mpt_event_register(ScsiDoneCtx, mptscsih_event_process) == 0) {
1483 devtprintk((KERN_INFO MYNAM
1484 ": Registered for IOC event notifications\n"));
1485 }
1486
1487 if (mpt_reset_register(ScsiDoneCtx, mptscsih_ioc_reset) == 0) {
1488 dprintk((KERN_INFO MYNAM
1489 ": Registered for IOC reset notifications\n"));
1490 }
1491
1492 #ifdef MODULE
1493 dinitprintk((KERN_INFO MYNAM
1494 ": Command Line Args: dv=%d max_width=%d "
1495 "factor=0x%x saf_te=%d\n",
1496 dv, width, factor, saf_te));
1497
1498 driver_setup.dv = (dv) ? 1 : 0;
1499 driver_setup.max_width = (width) ? 1 : 0;
1500 driver_setup.min_sync_factor = factor;
1501 driver_setup.saf_te = (saf_te) ? 1 : 0;;
1502 #endif
1503
1504 if(mpt_device_driver_register(&mptscsih_driver,
1505 MPTSCSIH_DRIVER) != 0 ) {
1506 dprintk((KERN_INFO MYNAM
1507 ": failed to register dd callbacks\n"));
1508 }
1509
1510 return 0;
1511
1512 }
1513
1514 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1515 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1516 /**
1517 * mptscsih_exit - Unregisters MPT adapter(s)
1518 *
1519 */
1520 static void __exit
1521 mptscsih_exit(void)
1522 {
1523 mpt_device_driver_deregister(MPTSCSIH_DRIVER);
1524
1525 mpt_reset_deregister(ScsiDoneCtx);
1526 dprintk((KERN_INFO MYNAM
1527 ": Deregistered for IOC reset notifications\n"));
1528
1529 mpt_event_deregister(ScsiDoneCtx);
1530 dprintk((KERN_INFO MYNAM
1531 ": Deregistered for IOC event notifications\n"));
1532
1533 mpt_deregister(ScsiScanDvCtx);
1534 mpt_deregister(ScsiTaskCtx);
1535 mpt_deregister(ScsiDoneCtx);
1536
1537 if (info_kbuf != NULL)
1538 kfree(info_kbuf);
1539
1540 }
1541
1542 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1543 /**
1544 * mptscsih_info - Return information about MPT adapter
1545 * @SChost: Pointer to Scsi_Host structure
1546 *
1547 * (linux scsi_host_template.info routine)
1548 *
1549 * Returns pointer to buffer where information was written.
1550 */
1551 static const char *
1552 mptscsih_info(struct Scsi_Host *SChost)
1553 {
1554 MPT_SCSI_HOST *h;
1555 int size = 0;
1556
1557 if (info_kbuf == NULL)
1558 if ((info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)
1559 return info_kbuf;
1560
1561 h = (MPT_SCSI_HOST *)SChost->hostdata;
1562 info_kbuf[0] = '\0';
1563 if (h) {
1564 mpt_print_ioc_summary(h->ioc, info_kbuf, &size, 0, 0);
1565 info_kbuf[size-1] = '\0';
1566 }
1567
1568 return info_kbuf;
1569 }
1570
1571 struct info_str {
1572 char *buffer;
1573 int length;
1574 int offset;
1575 int pos;
1576 };
1577
1578 static void copy_mem_info(struct info_str *info, char *data, int len)
1579 {
1580 if (info->pos + len > info->length)
1581 len = info->length - info->pos;
1582
1583 if (info->pos + len < info->offset) {
1584 info->pos += len;
1585 return;
1586 }
1587
1588 if (info->pos < info->offset) {
1589 data += (info->offset - info->pos);
1590 len -= (info->offset - info->pos);
1591 }
1592
1593 if (len > 0) {
1594 memcpy(info->buffer + info->pos, data, len);
1595 info->pos += len;
1596 }
1597 }
1598
1599 static int copy_info(struct info_str *info, char *fmt, ...)
1600 {
1601 va_list args;
1602 char buf[81];
1603 int len;
1604
1605 va_start(args, fmt);
1606 len = vsprintf(buf, fmt, args);
1607 va_end(args);
1608
1609 copy_mem_info(info, buf, len);
1610 return len;
1611 }
1612
1613 static int mptscsih_host_info(MPT_ADAPTER *ioc, char *pbuf, off_t offset, int len)
1614 {
1615 struct info_str info;
1616
1617 info.buffer = pbuf;
1618 info.length = len;
1619 info.offset = offset;
1620 info.pos = 0;
1621
1622 copy_info(&info, "%s: %s, ", ioc->name, ioc->prod_name);
1623 copy_info(&info, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING, ioc->facts.FWVersion.Word);
1624 copy_info(&info, "Ports=%d, ", ioc->facts.NumberOfPorts);
1625 copy_info(&info, "MaxQ=%d\n", ioc->req_depth);
1626
1627 return ((info.pos > info.offset) ? info.pos - info.offset : 0);
1628 }
1629
1630 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1631 /**
1632 * mptscsih_proc_info - Return information about MPT adapter
1633 *
1634 * (linux scsi_host_template.info routine)
1635 *
1636 * buffer: if write, user data; if read, buffer for user
1637 * length: if write, return length;
1638 * offset: if write, 0; if read, the current offset into the buffer from
1639 * the previous read.
1640 * hostno: scsi host number
1641 * func: if write = 1; if read = 0
1642 */
1643 static int
1644 mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
1645 int length, int func)
1646 {
1647 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
1648 MPT_ADAPTER *ioc = hd->ioc;
1649 int size = 0;
1650
1651 if (func) {
1652 /*
1653 * write is not supported
1654 */
1655 } else {
1656 if (start)
1657 *start = buffer;
1658
1659 size = mptscsih_host_info(ioc, buffer, offset, length);
1660 }
1661
1662 return size;
1663 }
1664
1665 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1666 #define ADD_INDEX_LOG(req_ent) do { } while(0)
1667
1668 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1669 /**
1670 * mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine.
1671 * @SCpnt: Pointer to scsi_cmnd structure
1672 * @done: Pointer SCSI mid-layer IO completion function
1673 *
1674 * (linux scsi_host_template.queuecommand routine)
1675 * This is the primary SCSI IO start routine. Create a MPI SCSIIORequest
1676 * from a linux scsi_cmnd request and send it to the IOC.
1677 *
1678 * Returns 0. (rtn value discarded by linux scsi mid-layer)
1679 */
1680 static int
1681 mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1682 {
1683 MPT_SCSI_HOST *hd;
1684 MPT_FRAME_HDR *mf;
1685 SCSIIORequest_t *pScsiReq;
1686 VirtDevice *pTarget;
1687 int target;
1688 int lun;
1689 u32 datalen;
1690 u32 scsictl;
1691 u32 scsidir;
1692 u32 cmd_len;
1693 int my_idx;
1694 int ii;
1695
1696 hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata;
1697 target = SCpnt->device->id;
1698 lun = SCpnt->device->lun;
1699 SCpnt->scsi_done = done;
1700
1701 pTarget = hd->Targets[target];
1702
1703 dmfprintk((MYIOC_s_INFO_FMT "qcmd: SCpnt=%p, done()=%p\n",
1704 (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt, done));
1705
1706 if (hd->resetPending) {
1707 dtmprintk((MYIOC_s_WARN_FMT "qcmd: SCpnt=%p timeout + 60HZ\n",
1708 (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt));
1709 return SCSI_MLQUEUE_HOST_BUSY;
1710 }
1711
1712 /*
1713 * Put together a MPT SCSI request...
1714 */
1715 if ((mf = mpt_get_msg_frame(ScsiDoneCtx, hd->ioc)) == NULL) {
1716 dprintk((MYIOC_s_WARN_FMT "QueueCmd, no msg frames!!\n",
1717 hd->ioc->name));
1718 return SCSI_MLQUEUE_HOST_BUSY;
1719 }
1720
1721 pScsiReq = (SCSIIORequest_t *) mf;
1722
1723 my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
1724
1725 ADD_INDEX_LOG(my_idx);
1726
1727 /* BUG FIX! 19991030 -sralston
1728 * TUR's being issued with scsictl=0x02000000 (DATA_IN)!
1729 * Seems we may receive a buffer (datalen>0) even when there
1730 * will be no data transfer! GRRRRR...
1731 */
1732 if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
1733 datalen = SCpnt->request_bufflen;
1734 scsidir = MPI_SCSIIO_CONTROL_READ; /* DATA IN (host<--ioc<--dev) */
1735 } else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
1736 datalen = SCpnt->request_bufflen;
1737 scsidir = MPI_SCSIIO_CONTROL_WRITE; /* DATA OUT (host-->ioc-->dev) */
1738 } else {
1739 datalen = 0;
1740 scsidir = MPI_SCSIIO_CONTROL_NODATATRANSFER;
1741 }
1742
1743 /* Default to untagged. Once a target structure has been allocated,
1744 * use the Inquiry data to determine if device supports tagged.
1745 */
1746 if ( pTarget
1747 && (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)
1748 && (SCpnt->device->tagged_supported)) {
1749 scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
1750 } else {
1751 scsictl = scsidir | MPI_SCSIIO_CONTROL_UNTAGGED;
1752 }
1753
1754 /* Use the above information to set up the message frame
1755 */
1756 pScsiReq->TargetID = (u8) target;
1757 pScsiReq->Bus = (u8) SCpnt->device->channel;
1758 pScsiReq->ChainOffset = 0;
1759 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
1760 pScsiReq->CDBLength = SCpnt->cmd_len;
1761 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
1762 pScsiReq->Reserved = 0;
1763 pScsiReq->MsgFlags = mpt_msg_flags();
1764 pScsiReq->LUN[0] = 0;
1765 pScsiReq->LUN[1] = lun;
1766 pScsiReq->LUN[2] = 0;
1767 pScsiReq->LUN[3] = 0;
1768 pScsiReq->LUN[4] = 0;
1769 pScsiReq->LUN[5] = 0;
1770 pScsiReq->LUN[6] = 0;
1771 pScsiReq->LUN[7] = 0;
1772 pScsiReq->Control = cpu_to_le32(scsictl);
1773
1774 /*
1775 * Write SCSI CDB into the message
1776 */
1777 cmd_len = SCpnt->cmd_len;
1778 for (ii=0; ii < cmd_len; ii++)
1779 pScsiReq->CDB[ii] = SCpnt->cmnd[ii];
1780
1781 for (ii=cmd_len; ii < 16; ii++)
1782 pScsiReq->CDB[ii] = 0;
1783
1784 /* DataLength */
1785 pScsiReq->DataLength = cpu_to_le32(datalen);
1786
1787 /* SenseBuffer low address */
1788 pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
1789 + (my_idx * MPT_SENSE_BUFFER_ALLOC));
1790
1791 /* Now add the SG list
1792 * Always have a SGE even if null length.
1793 */
1794 if (datalen == 0) {
1795 /* Add a NULL SGE */
1796 mptscsih_add_sge((char *)&pScsiReq->SGL, MPT_SGE_FLAGS_SSIMPLE_READ | 0,
1797 (dma_addr_t) -1);
1798 } else {
1799 /* Add a 32 or 64 bit SGE */
1800 if (mptscsih_AddSGE(hd->ioc, SCpnt, pScsiReq, my_idx) != SUCCESS)
1801 goto fail;
1802 }
1803
1804 hd->ScsiLookup[my_idx] = SCpnt;
1805 SCpnt->host_scribble = NULL;
1806
1807 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1808 if (hd->ioc->bus_type == SCSI) {
1809 int dvStatus = hd->ioc->spi_data.dvStatus[target];
1810 int issueCmd = 1;
1811
1812 if (dvStatus || hd->ioc->spi_data.forceDv) {
1813
1814 if ((dvStatus & MPT_SCSICFG_NEED_DV) ||
1815 (hd->ioc->spi_data.forceDv & MPT_SCSICFG_NEED_DV)) {
1816 unsigned long lflags;
1817 /* Schedule DV if necessary */
1818 spin_lock_irqsave(&dvtaskQ_lock, lflags);
1819 if (!dvtaskQ_active) {
1820 dvtaskQ_active = 1;
1821 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1822 INIT_WORK(&mptscsih_dvTask, mptscsih_domainValidation, (void *) hd);
1823
1824 schedule_work(&mptscsih_dvTask);
1825 } else {
1826 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1827 }
1828 hd->ioc->spi_data.forceDv &= ~MPT_SCSICFG_NEED_DV;
1829 }
1830
1831 /* Trying to do DV to this target, extend timeout.
1832 * Wait to issue until flag is clear
1833 */
1834 if (dvStatus & MPT_SCSICFG_DV_PENDING) {
1835 mod_timer(&SCpnt->eh_timeout, jiffies + 40 * HZ);
1836 issueCmd = 0;
1837 }
1838
1839 /* Set the DV flags.
1840 */
1841 if (dvStatus & MPT_SCSICFG_DV_NOT_DONE)
1842 mptscsih_set_dvflags(hd, pScsiReq);
1843
1844 if (!issueCmd)
1845 goto fail;
1846 }
1847 }
1848 #endif
1849
1850 mpt_put_msg_frame(ScsiDoneCtx, hd->ioc, mf);
1851 dmfprintk((MYIOC_s_INFO_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n",
1852 hd->ioc->name, SCpnt, mf, my_idx));
1853 DBG_DUMP_REQUEST_FRAME(mf)
1854 return 0;
1855
1856 fail:
1857 mptscsih_freeChainBuffers(hd->ioc, my_idx);
1858 mpt_free_msg_frame(hd->ioc, mf);
1859 return SCSI_MLQUEUE_HOST_BUSY;
1860 }
1861
1862 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1863 /*
1864 * mptscsih_freeChainBuffers - Function to free chain buffers associated
1865 * with a SCSI IO request
1866 * @hd: Pointer to the MPT_SCSI_HOST instance
1867 * @req_idx: Index of the SCSI IO request frame.
1868 *
1869 * Called if SG chain buffer allocation fails and mptscsih callbacks.
1870 * No return.
1871 */
1872 static void
1873 mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
1874 {
1875 MPT_FRAME_HDR *chain;
1876 unsigned long flags;
1877 int chain_idx;
1878 int next;
1879
1880 /* Get the first chain index and reset
1881 * tracker state.
1882 */
1883 chain_idx = ioc->ReqToChain[req_idx];
1884 ioc->ReqToChain[req_idx] = MPT_HOST_NO_CHAIN;
1885
1886 while (chain_idx != MPT_HOST_NO_CHAIN) {
1887
1888 /* Save the next chain buffer index */
1889 next = ioc->ChainToChain[chain_idx];
1890
1891 /* Free this chain buffer and reset
1892 * tracker
1893 */
1894 ioc->ChainToChain[chain_idx] = MPT_HOST_NO_CHAIN;
1895
1896 chain = (MPT_FRAME_HDR *) (ioc->ChainBuffer
1897 + (chain_idx * ioc->req_sz));
1898
1899 spin_lock_irqsave(&ioc->FreeQlock, flags);
1900 list_add_tail(&chain->u.frame.linkage.list, &ioc->FreeChainQ);
1901 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1902
1903 dmfprintk((MYIOC_s_INFO_FMT "FreeChainBuffers (index %d)\n",
1904 ioc->name, chain_idx));
1905
1906 /* handle next */
1907 chain_idx = next;
1908 }
1909 return;
1910 }
1911
1912 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1913 /*
1914 * Reset Handling
1915 */
1916
1917 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1918 /*
1919 * mptscsih_TMHandler - Generic handler for SCSI Task Management.
1920 * Fall through to mpt_HardResetHandler if: not operational, too many
1921 * failed TM requests or handshake failure.
1922 *
1923 * @ioc: Pointer to MPT_ADAPTER structure
1924 * @type: Task Management type
1925 * @target: Logical Target ID for reset (if appropriate)
1926 * @lun: Logical Unit for reset (if appropriate)
1927 * @ctx2abort: Context for the task to be aborted (if appropriate)
1928 * @sleepFlag: If set, use udelay instead of schedule in handshake code.
1929 *
1930 * Remark: Currently invoked from a non-interrupt thread (_bh).
1931 *
1932 * Remark: With old EH code, at most 1 SCSI TaskMgmt function per IOC
1933 * will be active.
1934 *
1935 * Returns 0 for SUCCESS or -1 if FAILED.
1936 */
1937 static int
1938 mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout, int sleepFlag)
1939 {
1940 MPT_ADAPTER *ioc;
1941 int rc = -1;
1942 int doTask = 1;
1943 u32 ioc_raw_state;
1944 unsigned long flags;
1945
1946 /* If FW is being reloaded currently, return success to
1947 * the calling function.
1948 */
1949 if (hd == NULL)
1950 return 0;
1951
1952 ioc = hd->ioc;
1953 if (ioc == NULL) {
1954 printk(KERN_ERR MYNAM " TMHandler" " NULL ioc!\n");
1955 return FAILED;
1956 }
1957 dtmprintk((MYIOC_s_INFO_FMT "TMHandler Entered!\n", ioc->name));
1958
1959 // SJR - CHECKME - Can we avoid this here?
1960 // (mpt_HardResetHandler has this check...)
1961 spin_lock_irqsave(&ioc->diagLock, flags);
1962 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)) {
1963 spin_unlock_irqrestore(&ioc->diagLock, flags);
1964 return FAILED;
1965 }
1966 spin_unlock_irqrestore(&ioc->diagLock, flags);
1967
1968 /* Wait a fixed amount of time for the TM pending flag to be cleared.
1969 * If we time out and not bus reset, then we return a FAILED status to the caller.
1970 * The call to mptscsih_tm_pending_wait() will set the pending flag if we are
1971 * successful. Otherwise, reload the FW.
1972 */
1973 if (mptscsih_tm_pending_wait(hd) == FAILED) {
1974 if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
1975 dtmprintk((KERN_WARNING MYNAM ": %s: TMHandler abort: "
1976 "Timed out waiting for last TM (%d) to complete! \n",
1977 hd->ioc->name, hd->tmPending));
1978 return FAILED;
1979 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) {
1980 dtmprintk((KERN_WARNING MYNAM ": %s: TMHandler target reset: "
1981 "Timed out waiting for last TM (%d) to complete! \n",
1982 hd->ioc->name, hd->tmPending));
1983 return FAILED;
1984 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
1985 dtmprintk((KERN_WARNING MYNAM ": %s: TMHandler bus reset: "
1986 "Timed out waiting for last TM (%d) to complete! \n",
1987 hd->ioc->name, hd->tmPending));
1988 if (hd->tmPending & (1 << MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS))
1989 return FAILED;
1990
1991 doTask = 0;
1992 }
1993 } else {
1994 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
1995 hd->tmPending |= (1 << type);
1996 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1997 }
1998
1999 /* Is operational?
2000 */
2001 ioc_raw_state = mpt_GetIocState(hd->ioc, 0);
2002
2003 #ifdef MPT_DEBUG_RESET
2004 if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) {
2005 printk(MYIOC_s_WARN_FMT
2006 "TM Handler: IOC Not operational(0x%x)!\n",
2007 hd->ioc->name, ioc_raw_state);
2008 }
2009 #endif
2010
2011 if (doTask && ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL)
2012 && !(ioc_raw_state & MPI_DOORBELL_ACTIVE)) {
2013
2014 /* Isse the Task Mgmt request.
2015 */
2016 if (hd->hard_resets < -1)
2017 hd->hard_resets++;
2018 rc = mptscsih_IssueTaskMgmt(hd, type, channel, target, lun, ctx2abort, timeout, sleepFlag);
2019 if (rc) {
2020 printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n", hd->ioc->name);
2021 } else {
2022 dtmprintk((MYIOC_s_INFO_FMT "Issue of TaskMgmt Successful!\n", hd->ioc->name));
2023 }
2024 }
2025
2026 /* Only fall through to the HRH if this is a bus reset
2027 */
2028 if ((type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) && (rc ||
2029 ioc->reload_fw || (ioc->alt_ioc && ioc->alt_ioc->reload_fw))) {
2030 dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
2031 hd->ioc->name));
2032 rc = mpt_HardResetHandler(hd->ioc, sleepFlag);
2033 }
2034
2035 dtmprintk((MYIOC_s_INFO_FMT "TMHandler rc = %d!\n", hd->ioc->name, rc));
2036
2037 return rc;
2038 }
2039
2040
2041 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2042 /*
2043 * mptscsih_IssueTaskMgmt - Generic send Task Management function.
2044 * @hd: Pointer to MPT_SCSI_HOST structure
2045 * @type: Task Management type
2046 * @target: Logical Target ID for reset (if appropriate)
2047 * @lun: Logical Unit for reset (if appropriate)
2048 * @ctx2abort: Context for the task to be aborted (if appropriate)
2049 * @sleepFlag: If set, use udelay instead of schedule in handshake code.
2050 *
2051 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
2052 * or a non-interrupt thread. In the former, must not call schedule().
2053 *
2054 * Not all fields are meaningfull for all task types.
2055 *
2056 * Returns 0 for SUCCESS, -999 for "no msg frames",
2057 * else other non-zero value returned.
2058 */
2059 static int
2060 mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout, int sleepFlag)
2061 {
2062 MPT_FRAME_HDR *mf;
2063 SCSITaskMgmt_t *pScsiTm;
2064 int ii;
2065 int retval;
2066
2067 /* Return Fail to calling function if no message frames available.
2068 */
2069 if ((mf = mpt_get_msg_frame(ScsiTaskCtx, hd->ioc)) == NULL) {
2070 dfailprintk((MYIOC_s_ERR_FMT "IssueTaskMgmt, no msg frames!!\n",
2071 hd->ioc->name));
2072 //return FAILED;
2073 return -999;
2074 }
2075 dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt request @ %p\n",
2076 hd->ioc->name, mf));
2077
2078 /* Format the Request
2079 */
2080 pScsiTm = (SCSITaskMgmt_t *) mf;
2081 pScsiTm->TargetID = target;
2082 pScsiTm->Bus = channel;
2083 pScsiTm->ChainOffset = 0;
2084 pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
2085
2086 pScsiTm->Reserved = 0;
2087 pScsiTm->TaskType = type;
2088 pScsiTm->Reserved1 = 0;
2089 pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)
2090 ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0;
2091
2092 for (ii= 0; ii < 8; ii++) {
2093 pScsiTm->LUN[ii] = 0;
2094 }
2095 pScsiTm->LUN[1] = lun;
2096
2097 for (ii=0; ii < 7; ii++)
2098 pScsiTm->Reserved2[ii] = 0;
2099
2100 pScsiTm->TaskMsgContext = ctx2abort;
2101
2102 /* MPI v0.10 requires SCSITaskMgmt requests be sent via Doorbell/handshake
2103 mpt_put_msg_frame(hd->ioc->id, mf);
2104 * Save the MF pointer in case the request times out.
2105 */
2106 hd->tmPtr = mf;
2107 hd->TMtimer.expires = jiffies + timeout;
2108 add_timer(&hd->TMtimer);
2109
2110 dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt: ctx2abort (0x%08x) type=%d\n",
2111 hd->ioc->name, ctx2abort, type));
2112
2113 DBG_DUMP_TM_REQUEST_FRAME((u32 *)pScsiTm);
2114
2115 if ((retval = mpt_send_handshake_request(ScsiTaskCtx, hd->ioc,
2116 sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, sleepFlag))
2117 != 0) {
2118 dfailprintk((MYIOC_s_ERR_FMT "_send_handshake FAILED!"
2119 " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd, hd->ioc, mf));
2120 hd->tmPtr = NULL;
2121 del_timer(&hd->TMtimer);
2122 mpt_free_msg_frame(hd->ioc, mf);
2123 }
2124
2125 return retval;
2126 }
2127
2128 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2129 /**
2130 * mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant
2131 * @SCpnt: Pointer to scsi_cmnd structure, IO to be aborted
2132 *
2133 * (linux scsi_host_template.eh_abort_handler routine)
2134 *
2135 * Returns SUCCESS or FAILED.
2136 */
2137 static int
2138 mptscsih_abort(struct scsi_cmnd * SCpnt)
2139 {
2140 MPT_SCSI_HOST *hd;
2141 MPT_ADAPTER *ioc;
2142 MPT_FRAME_HDR *mf;
2143 u32 ctx2abort;
2144 int scpnt_idx;
2145 spinlock_t *host_lock = SCpnt->device->host->host_lock;
2146
2147 /* If we can't locate our host adapter structure, return FAILED status.
2148 */
2149 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL) {
2150 SCpnt->result = DID_RESET << 16;
2151 SCpnt->scsi_done(SCpnt);
2152 dfailprintk((KERN_WARNING MYNAM ": mptscsih_abort: "
2153 "Can't locate host! (sc=%p)\n",
2154 SCpnt));
2155 return FAILED;
2156 }
2157
2158 ioc = hd->ioc;
2159 if (hd->resetPending)
2160 return FAILED;
2161
2162 printk(KERN_WARNING MYNAM ": %s: >> Attempting task abort! (sc=%p)\n",
2163 hd->ioc->name, SCpnt);
2164
2165 if (hd->timeouts < -1)
2166 hd->timeouts++;
2167
2168 /* Find this command
2169 */
2170 if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) {
2171 /* Cmd not found in ScsiLookup.
2172 * Do OS callback.
2173 */
2174 SCpnt->result = DID_RESET << 16;
2175 dtmprintk((KERN_WARNING MYNAM ": %s: mptscsih_abort: "
2176 "Command not in the active list! (sc=%p)\n",
2177 hd->ioc->name, SCpnt));
2178 return SUCCESS;
2179 }
2180
2181 /* Most important! Set TaskMsgContext to SCpnt's MsgContext!
2182 * (the IO to be ABORT'd)
2183 *
2184 * NOTE: Since we do not byteswap MsgContext, we do not
2185 * swap it here either. It is an opaque cookie to
2186 * the controller, so it does not matter. -DaveM
2187 */
2188 mf = MPT_INDEX_2_MFPTR(hd->ioc, scpnt_idx);
2189 ctx2abort = mf->u.frame.hwhdr.msgctxu.MsgContext;
2190
2191 hd->abortSCpnt = SCpnt;
2192
2193 spin_unlock_irq(host_lock);
2194 if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
2195 SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun,
2196 ctx2abort, (HZ*2) /* 2 second timeout */,CAN_SLEEP)
2197 < 0) {
2198
2199 /* The TM request failed and the subsequent FW-reload failed!
2200 * Fatal error case.
2201 */
2202 printk(MYIOC_s_WARN_FMT "Error issuing abort task! (sc=%p)\n",
2203 hd->ioc->name, SCpnt);
2204
2205 /* We must clear our pending flag before clearing our state.
2206 */
2207 hd->tmPending = 0;
2208 hd->tmState = TM_STATE_NONE;
2209
2210 spin_lock_irq(host_lock);
2211
2212 /* Unmap the DMA buffers, if any. */
2213 if (SCpnt->use_sg) {
2214 pci_unmap_sg(ioc->pcidev, (struct scatterlist *) SCpnt->request_buffer,
2215 SCpnt->use_sg, SCpnt->sc_data_direction);
2216 } else if (SCpnt->request_bufflen) {
2217 pci_unmap_single(ioc->pcidev, SCpnt->SCp.dma_handle,
2218 SCpnt->request_bufflen, SCpnt->sc_data_direction);
2219 }
2220 hd->ScsiLookup[scpnt_idx] = NULL;
2221 SCpnt->result = DID_RESET << 16;
2222 SCpnt->scsi_done(SCpnt); /* Issue the command callback */
2223 mptscsih_freeChainBuffers(ioc, scpnt_idx);
2224 mpt_free_msg_frame(ioc, mf);
2225 return FAILED;
2226 }
2227 spin_lock_irq(host_lock);
2228 return SUCCESS;
2229
2230 }
2231
2232 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2233 /**
2234 * mptscsih_dev_reset - Perform a SCSI TARGET_RESET! new_eh variant
2235 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
2236 *
2237 * (linux scsi_host_template.eh_dev_reset_handler routine)
2238 *
2239 * Returns SUCCESS or FAILED.
2240 */
2241 static int
2242 mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
2243 {
2244 MPT_SCSI_HOST *hd;
2245 spinlock_t *host_lock = SCpnt->device->host->host_lock;
2246
2247 /* If we can't locate our host adapter structure, return FAILED status.
2248 */
2249 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
2250 dtmprintk((KERN_WARNING MYNAM ": mptscsih_dev_reset: "
2251 "Can't locate host! (sc=%p)\n",
2252 SCpnt));
2253 return FAILED;
2254 }
2255
2256 if (hd->resetPending)
2257 return FAILED;
2258
2259 printk(KERN_WARNING MYNAM ": %s: >> Attempting target reset! (sc=%p)\n",
2260 hd->ioc->name, SCpnt);
2261
2262 /* Supported for FC only.
2263 */
2264 if (hd->ioc->bus_type == SCSI)
2265 return FAILED;
2266
2267 spin_unlock_irq(host_lock);
2268 if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
2269 SCpnt->device->channel, SCpnt->device->id,
2270 0, 0, (HZ*5) /* 5 second timeout */, CAN_SLEEP)
2271 < 0){
2272 /* The TM request failed and the subsequent FW-reload failed!
2273 * Fatal error case.
2274 */
2275 printk(MYIOC_s_WARN_FMT "Error processing TaskMgmt request (sc=%p)\n",
2276 hd->ioc->name, SCpnt);
2277 hd->tmPending = 0;
2278 hd->tmState = TM_STATE_NONE;
2279 spin_lock_irq(host_lock);
2280 return FAILED;
2281 }
2282 spin_lock_irq(host_lock);
2283 return SUCCESS;
2284
2285 }
2286
2287 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2288 /**
2289 * mptscsih_bus_reset - Perform a SCSI BUS_RESET! new_eh variant
2290 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
2291 *
2292 * (linux scsi_host_template.eh_bus_reset_handler routine)
2293 *
2294 * Returns SUCCESS or FAILED.
2295 */
2296 static int
2297 mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
2298 {
2299 MPT_SCSI_HOST *hd;
2300 spinlock_t *host_lock = SCpnt->device->host->host_lock;
2301
2302 /* If we can't locate our host adapter structure, return FAILED status.
2303 */
2304 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
2305 dtmprintk((KERN_WARNING MYNAM ": mptscsih_bus_reset: "
2306 "Can't locate host! (sc=%p)\n",
2307 SCpnt ) );
2308 return FAILED;
2309 }
2310
2311 printk(KERN_WARNING MYNAM ": %s: >> Attempting bus reset! (sc=%p)\n",
2312 hd->ioc->name, SCpnt);
2313
2314 if (hd->timeouts < -1)
2315 hd->timeouts++;
2316
2317 /* We are now ready to execute the task management request. */
2318 spin_unlock_irq(host_lock);
2319 if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
2320 SCpnt->device->channel, 0, 0, 0, (HZ*5) /* 5 second timeout */, CAN_SLEEP)
2321 < 0){
2322
2323 /* The TM request failed and the subsequent FW-reload failed!
2324 * Fatal error case.
2325 */
2326 printk(MYIOC_s_WARN_FMT
2327 "Error processing TaskMgmt request (sc=%p)\n",
2328 hd->ioc->name, SCpnt);
2329 hd->tmPending = 0;
2330 hd->tmState = TM_STATE_NONE;
2331 spin_lock_irq(host_lock);
2332 return FAILED;
2333 }
2334 spin_lock_irq(host_lock);
2335 return SUCCESS;
2336 }
2337
2338 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2339 /**
2340 * mptscsih_host_reset - Perform a SCSI host adapter RESET!
2341 * new_eh variant
2342 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
2343 *
2344 * (linux scsi_host_template.eh_host_reset_handler routine)
2345 *
2346 * Returns SUCCESS or FAILED.
2347 */
2348 static int
2349 mptscsih_host_reset(struct scsi_cmnd *SCpnt)
2350 {
2351 MPT_SCSI_HOST * hd;
2352 int status = SUCCESS;
2353 spinlock_t *host_lock = SCpnt->device->host->host_lock;
2354
2355 /* If we can't locate the host to reset, then we failed. */
2356 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
2357 dtmprintk( ( KERN_WARNING MYNAM ": mptscsih_host_reset: "
2358 "Can't locate host! (sc=%p)\n",
2359 SCpnt ) );
2360 return FAILED;
2361 }
2362
2363 printk(KERN_WARNING MYNAM ": %s: >> Attempting host reset! (sc=%p)\n",
2364 hd->ioc->name, SCpnt);
2365
2366 /* If our attempts to reset the host failed, then return a failed
2367 * status. The host will be taken off line by the SCSI mid-layer.
2368 */
2369 spin_unlock_irq(host_lock);
2370 if (mpt_HardResetHandler(hd->ioc, CAN_SLEEP) < 0){
2371 status = FAILED;
2372 } else {
2373 /* Make sure TM pending is cleared and TM state is set to
2374 * NONE.
2375 */
2376 hd->tmPending = 0;
2377 hd->tmState = TM_STATE_NONE;
2378 }
2379 spin_lock_irq(host_lock);
2380
2381
2382 dtmprintk( ( KERN_WARNING MYNAM ": mptscsih_host_reset: "
2383 "Status = %s\n",
2384 (status == SUCCESS) ? "SUCCESS" : "FAILED" ) );
2385
2386 return status;
2387 }
2388
2389 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2390 /**
2391 * mptscsih_tm_pending_wait - wait for pending task management request to
2392 * complete.
2393 * @hd: Pointer to MPT host structure.
2394 *
2395 * Returns {SUCCESS,FAILED}.
2396 */
2397 static int
2398 mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd)
2399 {
2400 unsigned long flags;
2401 int loop_count = 10 * 4; /* Wait 10 seconds */
2402 int status = FAILED;
2403
2404 do {
2405 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
2406 if (hd->tmState == TM_STATE_NONE) {
2407 hd->tmState = TM_STATE_IN_PROGRESS;
2408 hd->tmPending = 1;
2409 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2410 status = SUCCESS;
2411 break;
2412 }
2413 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2414 msleep(250);
2415 } while (--loop_count);
2416
2417 return status;
2418 }
2419
2420 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2421 /**
2422 * mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
2423 * @ioc: Pointer to MPT_ADAPTER structure
2424 * @mf: Pointer to SCSI task mgmt request frame
2425 * @mr: Pointer to SCSI task mgmt reply frame
2426 *
2427 * This routine is called from mptbase.c::mpt_interrupt() at the completion
2428 * of any SCSI task management request.
2429 * This routine is registered with the MPT (base) driver at driver
2430 * load/init time via the mpt_register() API call.
2431 *
2432 * Returns 1 indicating alloc'd request frame ptr should be freed.
2433 */
2434 static int
2435 mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
2436 {
2437 SCSITaskMgmtReply_t *pScsiTmReply;
2438 SCSITaskMgmt_t *pScsiTmReq;
2439 MPT_SCSI_HOST *hd;
2440 unsigned long flags;
2441 u16 iocstatus;
2442 u8 tmType;
2443
2444 dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt completed (mf=%p,mr=%p)\n",
2445 ioc->name, mf, mr));
2446 if (ioc->sh) {
2447 /* Depending on the thread, a timer is activated for
2448 * the TM request. Delete this timer on completion of TM.
2449 * Decrement count of outstanding TM requests.
2450 */
2451 hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
2452 if (hd->tmPtr) {
2453 del_timer(&hd->TMtimer);
2454 }
2455 } else {
2456 dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt Complete: NULL Scsi Host Ptr\n",
2457 ioc->name));
2458 return 1;
2459 }
2460
2461 if (mr == NULL) {
2462 dtmprintk((MYIOC_s_WARN_FMT "ERROR! TaskMgmt Reply: NULL Request %p\n",
2463 ioc->name, mf));
2464 return 1;
2465 } else {
2466 pScsiTmReply = (SCSITaskMgmtReply_t*)mr;
2467 pScsiTmReq = (SCSITaskMgmt_t*)mf;
2468
2469 /* Figure out if this was ABORT_TASK, TARGET_RESET, or BUS_RESET! */
2470 tmType = pScsiTmReq->TaskType;
2471
2472 dtmprintk((MYIOC_s_WARN_FMT " TaskType = %d, TerminationCount=%d\n",
2473 ioc->name, tmType, le32_to_cpu(pScsiTmReply->TerminationCount)));
2474 DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply);
2475
2476 iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2477 dtmprintk((MYIOC_s_WARN_FMT " SCSI TaskMgmt (%d) IOCStatus=%04x IOCLogInfo=%08x\n",
2478 ioc->name, tmType, iocstatus, le32_to_cpu(pScsiTmReply->IOCLogInfo)));
2479 /* Error? (anything non-zero?) */
2480 if (iocstatus) {
2481
2482 /* clear flags and continue.
2483 */
2484 if (tmType == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK)
2485 hd->abortSCpnt = NULL;
2486
2487 /* If an internal command is present
2488 * or the TM failed - reload the FW.
2489 * FC FW may respond FAILED to an ABORT
2490 */
2491 if (tmType == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
2492 if ((hd->cmdPtr) ||
2493 (iocstatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED)) {
2494 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0) {
2495 printk((KERN_WARNING
2496 " Firmware Reload FAILED!!\n"));
2497 }
2498 }
2499 }
2500 } else {
2501 dtmprintk((MYIOC_s_WARN_FMT " TaskMgmt SUCCESS\n", ioc->name));
2502
2503 hd->abortSCpnt = NULL;
2504
2505 }
2506 }
2507
2508 hd->tmPtr = NULL;
2509 spin_lock_irqsave(&ioc->FreeQlock, flags);
2510 hd->tmPending = 0;
2511 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2512 hd->tmState = TM_STATE_NONE;
2513
2514 return 1;
2515 }
2516
2517 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2518 /*
2519 * This is anyones guess quite frankly.
2520 */
2521 static int
2522 mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
2523 sector_t capacity, int geom[])
2524 {
2525 int heads;
2526 int sectors;
2527 sector_t cylinders;
2528 ulong dummy;
2529
2530 heads = 64;
2531 sectors = 32;
2532
2533 dummy = heads * sectors;
2534 cylinders = capacity;
2535 sector_div(cylinders,dummy);
2536
2537 /*
2538 * Handle extended translation size for logical drives
2539 * > 1Gb
2540 */
2541 if ((ulong)capacity >= 0x200000) {
2542 heads = 255;
2543 sectors = 63;
2544 dummy = heads * sectors;
2545 cylinders = capacity;
2546 sector_div(cylinders,dummy);
2547 }
2548
2549 /* return result */
2550 geom[0] = heads;
2551 geom[1] = sectors;
2552 geom[2] = cylinders;
2553
2554 dprintk((KERN_NOTICE
2555 ": bios_param: Id=%i Lun=%i Channel=%i CHS=%i/%i/%i\n",
2556 sdev->id, sdev->lun,sdev->channel,(int)cylinders,heads,sectors));
2557
2558 return 0;
2559 }
2560
2561 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2562 /*
2563 * OS entry point to allow host driver to alloc memory
2564 * for each scsi device. Called once per device the bus scan.
2565 * Return non-zero if allocation fails.
2566 * Init memory once per id (not LUN).
2567 */
2568 static int
2569 mptscsih_slave_alloc(struct scsi_device *device)
2570 {
2571 struct Scsi_Host *host = device->host;
2572 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
2573 VirtDevice *vdev;
2574 uint target = device->id;
2575
2576 if (hd == NULL)
2577 return -ENODEV;
2578
2579 if ((vdev = hd->Targets[target]) != NULL)
2580 goto out;
2581
2582 vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL);
2583 if (!vdev) {
2584 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
2585 hd->ioc->name, sizeof(VirtDevice));
2586 return -ENOMEM;
2587 }
2588
2589 memset(vdev, 0, sizeof(VirtDevice));
2590 vdev->tflags = MPT_TARGET_FLAGS_Q_YES;
2591 vdev->ioc_id = hd->ioc->id;
2592 vdev->target_id = device->id;
2593 vdev->bus_id = device->channel;
2594 vdev->raidVolume = 0;
2595 hd->Targets[device->id] = vdev;
2596 if (hd->ioc->bus_type == SCSI) {
2597 if (hd->ioc->spi_data.isRaid & (1 << device->id)) {
2598 vdev->raidVolume = 1;
2599 ddvtprintk((KERN_INFO
2600 "RAID Volume @ id %d\n", device->id));
2601 }
2602 } else {
2603 vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
2604 }
2605
2606 out:
2607 vdev->num_luns++;
2608 return 0;
2609 }
2610
2611 static int mptscsih_is_raid_volume(MPT_SCSI_HOST *hd, uint id)
2612 {
2613 int i;
2614
2615 if (!hd->ioc->spi_data.isRaid || !hd->ioc->spi_data.pIocPg3)
2616 return 0;
2617
2618 for (i = 0; i < hd->ioc->spi_data.pIocPg3->NumPhysDisks; i++) {
2619 if (id == hd->ioc->spi_data.pIocPg3->PhysDisk[i].PhysDiskID)
2620 return 1;
2621 }
2622
2623 return 0;
2624 }
2625
2626 /*
2627 * OS entry point to allow for host driver to free allocated memory
2628 * Called if no device present or device being unloaded
2629 */
2630 static void
2631 mptscsih_slave_destroy(struct scsi_device *device)
2632 {
2633 struct Scsi_Host *host = device->host;
2634 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
2635 VirtDevice *vdev;
2636 uint target = device->id;
2637 uint lun = device->lun;
2638
2639 if (hd == NULL)
2640 return;
2641
2642 mptscsih_search_running_cmds(hd, target, lun);
2643
2644 vdev = hd->Targets[target];
2645 vdev->luns[0] &= ~(1 << lun);
2646 if (--vdev->num_luns)
2647 return;
2648
2649 kfree(hd->Targets[target]);
2650 hd->Targets[target] = NULL;
2651
2652 if (hd->ioc->bus_type == SCSI) {
2653 if (mptscsih_is_raid_volume(hd, target)) {
2654 hd->ioc->spi_data.forceDv |= MPT_SCSICFG_RELOAD_IOC_PG3;
2655 } else {
2656 hd->ioc->spi_data.dvStatus[target] =
2657 MPT_SCSICFG_NEGOTIATE;
2658
2659 if (!hd->negoNvram) {
2660 hd->ioc->spi_data.dvStatus[target] |=
2661 MPT_SCSICFG_DV_NOT_DONE;
2662 }
2663 }
2664 }
2665 }
2666
2667 static void
2668 mptscsih_set_queue_depth(struct scsi_device *device, MPT_SCSI_HOST *hd,
2669 VirtDevice *pTarget, int qdepth)
2670 {
2671 int max_depth;
2672 int tagged;
2673
2674 if (hd->ioc->bus_type == SCSI) {
2675 if (pTarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) {
2676 if (!(pTarget->tflags & MPT_TARGET_FLAGS_Q_YES))
2677 max_depth = 1;
2678 else if (((pTarget->inq_data[0] & 0x1f) == 0x00) &&
2679 (pTarget->minSyncFactor <= MPT_ULTRA160 ))
2680 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2681 else
2682 max_depth = MPT_SCSI_CMD_PER_DEV_LOW;
2683 } else {
2684 /* error case - No Inq. Data */
2685 max_depth = 1;
2686 }
2687 } else
2688 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2689
2690 if (qdepth > max_depth)
2691 qdepth = max_depth;
2692 if (qdepth == 1)
2693 tagged = 0;
2694 else
2695 tagged = MSG_SIMPLE_TAG;
2696
2697 scsi_adjust_queue_depth(device, tagged, qdepth);
2698 }
2699
2700
2701 /*
2702 * OS entry point to adjust the queue_depths on a per-device basis.
2703 * Called once per device the bus scan. Use it to force the queue_depth
2704 * member to 1 if a device does not support Q tags.
2705 * Return non-zero if fails.
2706 */
2707 static int
2708 mptscsih_slave_configure(struct scsi_device *device)
2709 {
2710 struct Scsi_Host *sh = device->host;
2711 VirtDevice *pTarget;
2712 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sh->hostdata;
2713
2714 if ((hd == NULL) || (hd->Targets == NULL)) {
2715 return 0;
2716 }
2717
2718 dsprintk((MYIOC_s_INFO_FMT
2719 "device @ %p, id=%d, LUN=%d, channel=%d\n",
2720 hd->ioc->name, device, device->id, device->lun, device->channel));
2721 dsprintk((MYIOC_s_INFO_FMT
2722 "sdtr %d wdtr %d ppr %d inq length=%d\n",
2723 hd->ioc->name, device->sdtr, device->wdtr,
2724 device->ppr, device->inquiry_len));
2725
2726 if (device->id > sh->max_id) {
2727 /* error case, should never happen */
2728 scsi_adjust_queue_depth(device, 0, 1);
2729 goto slave_configure_exit;
2730 }
2731
2732 pTarget = hd->Targets[device->id];
2733
2734 if (pTarget == NULL) {
2735 /* Driver doesn't know about this device.
2736 * Kernel may generate a "Dummy Lun 0" which
2737 * may become a real Lun if a
2738 * "scsi add-single-device" command is executed
2739 * while the driver is active (hot-plug a
2740 * device). LSI Raid controllers need
2741 * queue_depth set to DEV_HIGH for this reason.
2742 */
2743 scsi_adjust_queue_depth(device, MSG_SIMPLE_TAG,
2744 MPT_SCSI_CMD_PER_DEV_HIGH);
2745 goto slave_configure_exit;
2746 }
2747
2748 mptscsih_initTarget(hd, device->channel, device->id, device->lun,
2749 device->inquiry, device->inquiry_len );
2750 mptscsih_set_queue_depth(device, hd, pTarget, MPT_SCSI_CMD_PER_DEV_HIGH);
2751
2752 dsprintk((MYIOC_s_INFO_FMT
2753 "Queue depth=%d, tflags=%x\n",
2754 hd->ioc->name, device->queue_depth, pTarget->tflags));
2755
2756 dsprintk((MYIOC_s_INFO_FMT
2757 "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
2758 hd->ioc->name, pTarget->negoFlags, pTarget->maxOffset, pTarget->minSyncFactor));
2759
2760 slave_configure_exit:
2761
2762 dsprintk((MYIOC_s_INFO_FMT
2763 "tagged %d, simple %d, ordered %d\n",
2764 hd->ioc->name,device->tagged_supported, device->simple_tags,
2765 device->ordered_tags));
2766
2767 return 0;
2768 }
2769
2770 static ssize_t
2771 mptscsih_store_queue_depth(struct device *dev, const char *buf, size_t count)
2772 {
2773 int depth;
2774 struct scsi_device *sdev = to_scsi_device(dev);
2775 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) sdev->host->hostdata;
2776 VirtDevice *pTarget;
2777
2778 depth = simple_strtoul(buf, NULL, 0);
2779 if (depth == 0)
2780 return -EINVAL;
2781 pTarget = hd->Targets[sdev->id];
2782 if (pTarget == NULL)
2783 return -EINVAL;
2784 mptscsih_set_queue_depth(sdev, (MPT_SCSI_HOST *) sdev->host->hostdata,
2785 pTarget, depth);
2786 return count;
2787 }
2788
2789 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2790 /*
2791 * Private routines...
2792 */
2793
2794 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2795 /* Utility function to copy sense data from the scsi_cmnd buffer
2796 * to the FC and SCSI target structures.
2797 *
2798 */
2799 static void
2800 copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
2801 {
2802 VirtDevice *target;
2803 SCSIIORequest_t *pReq;
2804 u32 sense_count = le32_to_cpu(pScsiReply->SenseCount);
2805 int index;
2806
2807 /* Get target structure
2808 */
2809 pReq = (SCSIIORequest_t *) mf;
2810 index = (int) pReq->TargetID;
2811 target = hd->Targets[index];
2812
2813 if (sense_count) {
2814 u8 *sense_data;
2815 int req_index;
2816
2817 /* Copy the sense received into the scsi command block. */
2818 req_index = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2819 sense_data = ((u8 *)hd->ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC));
2820 memcpy(sc->sense_buffer, sense_data, SNS_LEN(sc));
2821
2822 /* Log SMART data (asc = 0x5D, non-IM case only) if required.
2823 */
2824 if ((hd->ioc->events) && (hd->ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) {
2825 if ((sense_data[12] == 0x5D) && (target->raidVolume == 0)) {
2826 int idx;
2827 MPT_ADAPTER *ioc = hd->ioc;
2828
2829 idx = ioc->eventContext % ioc->eventLogSize;
2830 ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
2831 ioc->events[idx].eventContext = ioc->eventContext;
2832
2833 ioc->events[idx].data[0] = (pReq->LUN[1] << 24) ||
2834 (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) ||
2835 (pReq->Bus << 8) || pReq->TargetID;
2836
2837 ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12];
2838
2839 ioc->eventContext++;
2840 }
2841 }
2842 } else {
2843 dprintk((MYIOC_s_INFO_FMT "Hmmm... SenseData len=0! (?)\n",
2844 hd->ioc->name));
2845 }
2846 }
2847
2848 static u32
2849 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc)
2850 {
2851 MPT_SCSI_HOST *hd;
2852 int i;
2853
2854 hd = (MPT_SCSI_HOST *) sc->device->host->hostdata;
2855
2856 for (i = 0; i < hd->ioc->req_depth; i++) {
2857 if (hd->ScsiLookup[i] == sc) {
2858 return i;
2859 }
2860 }
2861
2862 return -1;
2863 }
2864
2865 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2866 static int
2867 mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2868 {
2869 MPT_SCSI_HOST *hd;
2870 unsigned long flags;
2871
2872 dtmprintk((KERN_WARNING MYNAM
2873 ": IOC %s_reset routed to SCSI host driver!\n",
2874 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
2875 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
2876
2877 /* If a FW reload request arrives after base installed but
2878 * before all scsi hosts have been attached, then an alt_ioc
2879 * may have a NULL sh pointer.
2880 */
2881 if ((ioc->sh == NULL) || (ioc->sh->hostdata == NULL))
2882 return 0;
2883 else
2884 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2885
2886 if (reset_phase == MPT_IOC_SETUP_RESET) {
2887 dtmprintk((MYIOC_s_WARN_FMT "Setup-Diag Reset\n", ioc->name));
2888
2889 /* Clean Up:
2890 * 1. Set Hard Reset Pending Flag
2891 * All new commands go to doneQ
2892 */
2893 hd->resetPending = 1;
2894
2895 } else if (reset_phase == MPT_IOC_PRE_RESET) {
2896 dtmprintk((MYIOC_s_WARN_FMT "Pre-Diag Reset\n", ioc->name));
2897
2898 /* 2. Flush running commands
2899 * Clean ScsiLookup (and associated memory)
2900 * AND clean mytaskQ
2901 */
2902
2903 /* 2b. Reply to OS all known outstanding I/O commands.
2904 */
2905 mptscsih_flush_running_cmds(hd);
2906
2907 /* 2c. If there was an internal command that
2908 * has not completed, configuration or io request,
2909 * free these resources.
2910 */
2911 if (hd->cmdPtr) {
2912 del_timer(&hd->timer);
2913 mpt_free_msg_frame(ioc, hd->cmdPtr);
2914 }
2915
2916 /* 2d. If a task management has not completed,
2917 * free resources associated with this request.
2918 */
2919 if (hd->tmPtr) {
2920 del_timer(&hd->TMtimer);
2921 mpt_free_msg_frame(ioc, hd->tmPtr);
2922 }
2923
2924 dtmprintk((MYIOC_s_WARN_FMT "Pre-Reset complete.\n", ioc->name));
2925
2926 } else {
2927 dtmprintk((MYIOC_s_WARN_FMT "Post-Diag Reset\n", ioc->name));
2928
2929 /* Once a FW reload begins, all new OS commands are
2930 * redirected to the doneQ w/ a reset status.
2931 * Init all control structures.
2932 */
2933
2934 /* ScsiLookup initialization
2935 */
2936 {
2937 int ii;
2938 for (ii=0; ii < hd->ioc->req_depth; ii++)
2939 hd->ScsiLookup[ii] = NULL;
2940 }
2941
2942 /* 2. Chain Buffer initialization
2943 */
2944
2945 /* 3. tmPtr clear
2946 */
2947 if (hd->tmPtr) {
2948 hd->tmPtr = NULL;
2949 }
2950
2951 /* 4. Renegotiate to all devices, if SCSI
2952 */
2953 if (ioc->bus_type == SCSI) {
2954 dnegoprintk(("writeSDP1: ALL_IDS USE_NVRAM\n"));
2955 mptscsih_writeSDP1(hd, 0, 0, MPT_SCSICFG_ALL_IDS | MPT_SCSICFG_USE_NVRAM);
2956 }
2957
2958 /* 5. Enable new commands to be posted
2959 */
2960 spin_lock_irqsave(&ioc->FreeQlock, flags);
2961 hd->tmPending = 0;
2962 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2963 hd->resetPending = 0;
2964 hd->tmState = TM_STATE_NONE;
2965
2966 /* 6. If there was an internal command,
2967 * wake this process up.
2968 */
2969 if (hd->cmdPtr) {
2970 /*
2971 * Wake up the original calling thread
2972 */
2973 hd->pLocal = &hd->localReply;
2974 hd->pLocal->completion = MPT_SCANDV_DID_RESET;
2975 scandv_wait_done = 1;
2976 wake_up(&scandv_waitq);
2977 hd->cmdPtr = NULL;
2978 }
2979
2980 /* 7. Set flag to force DV and re-read IOC Page 3
2981 */
2982 if (ioc->bus_type == SCSI) {
2983 ioc->spi_data.forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
2984 ddvtprintk(("Set reload IOC Pg3 Flag\n"));
2985 }
2986
2987 dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name));
2988
2989 }
2990
2991 return 1; /* currently means nothing really */
2992 }
2993
2994 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2995 static int
2996 mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2997 {
2998 MPT_SCSI_HOST *hd;
2999 u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
3000
3001 devtprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
3002 ioc->name, event));
3003
3004 switch (event) {
3005 case MPI_EVENT_UNIT_ATTENTION: /* 03 */
3006 /* FIXME! */
3007 break;
3008 case MPI_EVENT_IOC_BUS_RESET: /* 04 */
3009 case MPI_EVENT_EXT_BUS_RESET: /* 05 */
3010 hd = NULL;
3011 if (ioc->sh) {
3012 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
3013 if (hd && (ioc->bus_type == SCSI) && (hd->soft_resets < -1))
3014 hd->soft_resets++;
3015 }
3016 break;
3017 case MPI_EVENT_LOGOUT: /* 09 */
3018 /* FIXME! */
3019 break;
3020
3021 /*
3022 * CHECKME! Don't think we need to do
3023 * anything for these, but...
3024 */
3025 case MPI_EVENT_RESCAN: /* 06 */
3026 case MPI_EVENT_LINK_STATUS_CHANGE: /* 07 */
3027 case MPI_EVENT_LOOP_STATE_CHANGE: /* 08 */
3028 /*
3029 * CHECKME! Falling thru...
3030 */
3031 break;
3032
3033 case MPI_EVENT_INTEGRATED_RAID: /* 0B */
3034 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
3035 /* negoNvram set to 0 if DV enabled and to USE_NVRAM if
3036 * if DV disabled. Need to check for target mode.
3037 */
3038 hd = NULL;
3039 if (ioc->sh)
3040 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
3041
3042 if (hd && (ioc->bus_type == SCSI) && (hd->negoNvram == 0)) {
3043 ScsiCfgData *pSpi;
3044 Ioc3PhysDisk_t *pPDisk;
3045 int numPDisk;
3046 u8 reason;
3047 u8 physDiskNum;
3048
3049 reason = (le32_to_cpu(pEvReply->Data[0]) & 0x00FF0000) >> 16;
3050 if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
3051 /* New or replaced disk.
3052 * Set DV flag and schedule DV.
3053 */
3054 pSpi = &ioc->spi_data;
3055 physDiskNum = (le32_to_cpu(pEvReply->Data[0]) & 0xFF000000) >> 24;
3056 ddvtprintk(("DV requested for phys disk id %d\n", physDiskNum));
3057 if (pSpi->pIocPg3) {
3058 pPDisk = pSpi->pIocPg3->PhysDisk;
3059 numPDisk =pSpi->pIocPg3->NumPhysDisks;
3060
3061 while (numPDisk) {
3062 if (physDiskNum == pPDisk->PhysDiskNum) {
3063 pSpi->dvStatus[pPDisk->PhysDiskID] = (MPT_SCSICFG_NEED_DV | MPT_SCSICFG_DV_NOT_DONE);
3064 pSpi->forceDv = MPT_SCSICFG_NEED_DV;
3065 ddvtprintk(("NEED_DV set for phys disk id %d\n", pPDisk->PhysDiskID));
3066 break;
3067 }
3068 pPDisk++;
3069 numPDisk--;
3070 }
3071
3072 if (numPDisk == 0) {
3073 /* The physical disk that needs DV was not found
3074 * in the stored IOC Page 3. The driver must reload
3075 * this page. DV routine will set the NEED_DV flag for
3076 * all phys disks that have DV_NOT_DONE set.
3077 */
3078 pSpi->forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
3079 ddvtprintk(("phys disk %d not found. Setting reload IOC Pg3 Flag\n", physDiskNum));
3080 }
3081 }
3082 }
3083 }
3084 #endif
3085
3086 #if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY)
3087 printk("Raid Event RF: ");
3088 {
3089 u32 *m = (u32 *)pEvReply;
3090 int ii;
3091 int n = (int)pEvReply->MsgLength;
3092 for (ii=6; ii < n; ii++)
3093 printk(" %08x", le32_to_cpu(m[ii]));
3094 printk("\n");
3095 }
3096 #endif
3097 break;
3098
3099 case MPI_EVENT_NONE: /* 00 */
3100 case MPI_EVENT_LOG_DATA: /* 01 */
3101 case MPI_EVENT_STATE_CHANGE: /* 02 */
3102 case MPI_EVENT_EVENT_CHANGE: /* 0A */
3103 default:
3104 dprintk((KERN_INFO " Ignoring event (=%02Xh)\n", event));
3105 break;
3106 }
3107
3108 return 1; /* currently means nothing really */
3109 }
3110
3111 static struct device_attribute mptscsih_queue_depth_attr = {
3112 .attr = {
3113 .name = "queue_depth",
3114 .mode = S_IWUSR,
3115 },
3116 .store = mptscsih_store_queue_depth,
3117 };
3118
3119 static struct device_attribute *mptscsih_dev_attrs[] = {
3120 &mptscsih_queue_depth_attr,
3121 NULL,
3122 };
3123
3124 static struct scsi_host_template driver_template = {
3125 .proc_name = "mptscsih",
3126 .proc_info = mptscsih_proc_info,
3127 .name = "MPT SCSI Host",
3128 .info = mptscsih_info,
3129 .queuecommand = mptscsih_qcmd,
3130 .slave_alloc = mptscsih_slave_alloc,
3131 .slave_configure = mptscsih_slave_configure,
3132 .slave_destroy = mptscsih_slave_destroy,
3133 .eh_abort_handler = mptscsih_abort,
3134 .eh_device_reset_handler = mptscsih_dev_reset,
3135 .eh_bus_reset_handler = mptscsih_bus_reset,
3136 .eh_host_reset_handler = mptscsih_host_reset,
3137 .bios_param = mptscsih_bios_param,
3138 .can_queue = MPT_SCSI_CAN_QUEUE,
3139 .this_id = -1,
3140 .sg_tablesize = MPT_SCSI_SG_DEPTH,
3141 .max_sectors = 8192,
3142 .cmd_per_lun = 7,
3143 .use_clustering = ENABLE_CLUSTERING,
3144 .sdev_attrs = mptscsih_dev_attrs,
3145 };
3146
3147 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3148 /*
3149 * mptscsih_initTarget - Target, LUN alloc/free functionality.
3150 * @hd: Pointer to MPT_SCSI_HOST structure
3151 * @bus_id: Bus number (?)
3152 * @target_id: SCSI target id
3153 * @lun: SCSI LUN id
3154 * @data: Pointer to data
3155 * @dlen: Number of INQUIRY bytes
3156 *
3157 * NOTE: It's only SAFE to call this routine if data points to
3158 * sane & valid STANDARD INQUIRY data!
3159 *
3160 * Allocate and initialize memory for this target.
3161 * Save inquiry data.
3162 *
3163 */
3164 static void
3165 mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *data, int dlen)
3166 {
3167 int indexed_lun, lun_index;
3168 VirtDevice *vdev;
3169 ScsiCfgData *pSpi;
3170 char data_56;
3171
3172 dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n",
3173 hd->ioc->name, bus_id, target_id, lun, hd));
3174
3175 /* Is LUN supported? If so, upper 2 bits will be 0
3176 * in first byte of inquiry data.
3177 */
3178 if (data[0] & 0xe0)
3179 return;
3180
3181 if ((vdev = hd->Targets[target_id]) == NULL) {
3182 return;
3183 }
3184
3185 lun_index = (lun >> 5); /* 32 luns per lun_index */
3186 indexed_lun = (lun % 32);
3187 vdev->luns[lun_index] |= (1 << indexed_lun);
3188
3189 if (hd->ioc->bus_type == SCSI) {
3190 if ((data[0] == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) {
3191 /* Treat all Processors as SAF-TE if
3192 * command line option is set */
3193 vdev->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
3194 mptscsih_writeIOCPage4(hd, target_id, bus_id);
3195 }else if ((data[0] == TYPE_PROCESSOR) &&
3196 !(vdev->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) {
3197 if ( dlen > 49 ) {
3198 vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
3199 if ( data[44] == 'S' &&
3200 data[45] == 'A' &&
3201 data[46] == 'F' &&
3202 data[47] == '-' &&
3203 data[48] == 'T' &&
3204 data[49] == 'E' ) {
3205 vdev->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
3206 mptscsih_writeIOCPage4(hd, target_id, bus_id);
3207 }
3208 }
3209 }
3210 if (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY)) {
3211 if ( dlen > 8 ) {
3212 memcpy (vdev->inq_data, data, 8);
3213 } else {
3214 memcpy (vdev->inq_data, data, dlen);
3215 }
3216
3217 /* If have not done DV, set the DV flag.
3218 */
3219 pSpi = &hd->ioc->spi_data;
3220 if ((data[0] == TYPE_TAPE) || (data[0] == TYPE_PROCESSOR)) {
3221 if (pSpi->dvStatus[target_id] & MPT_SCSICFG_DV_NOT_DONE)
3222 pSpi->dvStatus[target_id] |= MPT_SCSICFG_NEED_DV;
3223 }
3224
3225 vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
3226
3227
3228 data_56 = 0x0F; /* Default to full capabilities if Inq data length is < 57 */
3229 if (dlen > 56) {
3230 if ( (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_56))) {
3231 /* Update the target capabilities
3232 */
3233 data_56 = data[56];
3234 vdev->tflags |= MPT_TARGET_FLAGS_VALID_56;
3235 }
3236 }
3237 mptscsih_setTargetNegoParms(hd, vdev, data_56);
3238 } else {
3239 /* Initial Inquiry may not request enough data bytes to
3240 * obtain byte 57. DV will; if target doesn't return
3241 * at least 57 bytes, data[56] will be zero. */
3242 if (dlen > 56) {
3243 if ( (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_56))) {
3244 /* Update the target capabilities
3245 */
3246 data_56 = data[56];
3247 vdev->tflags |= MPT_TARGET_FLAGS_VALID_56;
3248 mptscsih_setTargetNegoParms(hd, vdev, data_56);
3249 }
3250 }
3251 }
3252 }
3253 }
3254
3255 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3256 /*
3257 * Update the target negotiation parameters based on the
3258 * the Inquiry data, adapter capabilities, and NVRAM settings.
3259 *
3260 */
3261 static void
3262 mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56)
3263 {
3264 ScsiCfgData *pspi_data = &hd->ioc->spi_data;
3265 int id = (int) target->target_id;
3266 int nvram;
3267 VirtDevice *vdev;
3268 int ii;
3269 u8 width = MPT_NARROW;
3270 u8 factor = MPT_ASYNC;
3271 u8 offset = 0;
3272 u8 version, nfactor;
3273 u8 noQas = 1;
3274
3275 target->negoFlags = pspi_data->noQas;
3276
3277 /* noQas == 0 => device supports QAS. Need byte 56 of Inq to determine
3278 * support. If available, default QAS to off and allow enabling.
3279 * If not available, default QAS to on, turn off for non-disks.
3280 */
3281
3282 /* Set flags based on Inquiry data
3283 */
3284 version = target->inq_data[2] & 0x07;
3285 if (version < 2) {
3286 width = 0;
3287 factor = MPT_ULTRA2;
3288 offset = pspi_data->maxSyncOffset;
3289 target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
3290 } else {
3291 if (target->inq_data[7] & 0x20) {
3292 width = 1;
3293 }
3294
3295 if (target->inq_data[7] & 0x10) {
3296 factor = pspi_data->minSyncFactor;
3297 if (target->tflags & MPT_TARGET_FLAGS_VALID_56) {
3298 /* bits 2 & 3 show Clocking support */
3299 if ((byte56 & 0x0C) == 0)
3300 factor = MPT_ULTRA2;
3301 else {
3302 if ((byte56 & 0x03) == 0)
3303 factor = MPT_ULTRA160;
3304 else {
3305 factor = MPT_ULTRA320;
3306 if (byte56 & 0x02)
3307 {
3308 ddvtprintk((KERN_INFO "Enabling QAS due to byte56=%02x on id=%d!\n", byte56, id));
3309 noQas = 0;
3310 }
3311 if (target->inq_data[0] == TYPE_TAPE) {
3312 if (byte56 & 0x01)
3313 target->negoFlags |= MPT_TAPE_NEGO_IDP;
3314 }
3315 }
3316 }
3317 } else {
3318 ddvtprintk((KERN_INFO "Enabling QAS on id=%d due to ~TARGET_FLAGS_VALID_56!\n", id));
3319 noQas = 0;
3320 }
3321
3322 offset = pspi_data->maxSyncOffset;
3323
3324 /* If RAID, never disable QAS
3325 * else if non RAID, do not disable
3326 * QAS if bit 1 is set
3327 * bit 1 QAS support, non-raid only
3328 * bit 0 IU support
3329 */
3330 if (target->raidVolume == 1) {
3331 noQas = 0;
3332 }
3333 } else {
3334 factor = MPT_ASYNC;
3335 offset = 0;
3336 }
3337 }
3338
3339 if ( (target->inq_data[7] & 0x02) == 0) {
3340 target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
3341 }
3342
3343 /* Update tflags based on NVRAM settings. (SCSI only)
3344 */
3345 if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
3346 nvram = pspi_data->nvram[id];
3347 nfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
3348
3349 if (width)
3350 width = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
3351
3352 if (offset > 0) {
3353 /* Ensure factor is set to the
3354 * maximum of: adapter, nvram, inquiry
3355 */
3356 if (nfactor) {
3357 if (nfactor < pspi_data->minSyncFactor )
3358 nfactor = pspi_data->minSyncFactor;
3359
3360 factor = max(factor, nfactor);
3361 if (factor == MPT_ASYNC)
3362 offset = 0;
3363 } else {
3364 offset = 0;
3365 factor = MPT_ASYNC;
3366 }
3367 } else {
3368 factor = MPT_ASYNC;
3369 }
3370 }
3371
3372 /* Make sure data is consistent
3373 */
3374 if ((!width) && (factor < MPT_ULTRA2)) {
3375 factor = MPT_ULTRA2;
3376 }
3377
3378 /* Save the data to the target structure.
3379 */
3380 target->minSyncFactor = factor;
3381 target->maxOffset = offset;
3382 target->maxWidth = width;
3383
3384 target->tflags |= MPT_TARGET_FLAGS_VALID_NEGO;
3385
3386 /* Disable unused features.
3387 */
3388 if (!width)
3389 target->negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
3390
3391 if (!offset)
3392 target->negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
3393
3394 if ( factor > MPT_ULTRA320 )
3395 noQas = 0;
3396
3397 /* GEM, processor WORKAROUND
3398 */
3399 if ((target->inq_data[0] == TYPE_PROCESSOR) || (target->inq_data[0] > 0x08)) {
3400 target->negoFlags |= (MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC);
3401 pspi_data->dvStatus[id] |= MPT_SCSICFG_BLK_NEGO;
3402 } else {
3403 if (noQas && (pspi_data->noQas == 0)) {
3404 pspi_data->noQas |= MPT_TARGET_NO_NEGO_QAS;
3405 target->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
3406
3407 /* Disable QAS in a mixed configuration case
3408 */
3409
3410 ddvtprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id));
3411 for (ii = 0; ii < id; ii++) {
3412 if ( (vdev = hd->Targets[ii]) ) {
3413 vdev->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
3414 mptscsih_writeSDP1(hd, 0, ii, vdev->negoFlags);
3415 }
3416 }
3417 }
3418 }
3419
3420 /* Write SDP1 on this I/O to this target */
3421 if (pspi_data->dvStatus[id] & MPT_SCSICFG_NEGOTIATE) {
3422 ddvtprintk((KERN_INFO "MPT_SCSICFG_NEGOTIATE on id=%d!\n", id));
3423 mptscsih_writeSDP1(hd, 0, id, hd->negoNvram);
3424 pspi_data->dvStatus[id] &= ~MPT_SCSICFG_NEGOTIATE;
3425 } else if (pspi_data->dvStatus[id] & MPT_SCSICFG_BLK_NEGO) {
3426 ddvtprintk((KERN_INFO "MPT_SCSICFG_BLK_NEGO on id=%d!\n", id));
3427 mptscsih_writeSDP1(hd, 0, id, MPT_SCSICFG_BLK_NEGO);
3428 pspi_data->dvStatus[id] &= ~MPT_SCSICFG_BLK_NEGO;
3429 }
3430 }
3431
3432 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3433 /* If DV disabled (negoNvram set to USE_NVARM) or if not LUN 0, return.
3434 * Else set the NEED_DV flag after Read Capacity Issued (disks)
3435 * or Mode Sense (cdroms).
3436 *
3437 * Tapes, initTarget will set this flag on completion of Inquiry command.
3438 * Called only if DV_NOT_DONE flag is set
3439 */
3440 static void mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq)
3441 {
3442 u8 cmd;
3443 ScsiCfgData *pSpi;
3444
3445 ddvtprintk((" set_dvflags: id=%d lun=%d negoNvram=%x cmd=%x\n",
3446 pReq->TargetID, pReq->LUN[1], hd->negoNvram, pReq->CDB[0]));
3447
3448 if ((pReq->LUN[1] != 0) || (hd->negoNvram != 0))
3449 return;
3450
3451 cmd = pReq->CDB[0];
3452
3453 if ((cmd == READ_CAPACITY) || (cmd == MODE_SENSE)) {
3454 pSpi = &hd->ioc->spi_data;
3455 if ((pSpi->isRaid & (1 << pReq->TargetID)) && pSpi->pIocPg3) {
3456 /* Set NEED_DV for all hidden disks
3457 */
3458 Ioc3PhysDisk_t *pPDisk = pSpi->pIocPg3->PhysDisk;
3459 int numPDisk = pSpi->pIocPg3->NumPhysDisks;
3460
3461 while (numPDisk) {
3462 pSpi->dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV;
3463 ddvtprintk(("NEED_DV set for phys disk id %d\n", pPDisk->PhysDiskID));
3464 pPDisk++;
3465 numPDisk--;
3466 }
3467 }
3468 pSpi->dvStatus[pReq->TargetID] |= MPT_SCSICFG_NEED_DV;
3469 ddvtprintk(("NEED_DV set for visible disk id %d\n", pReq->TargetID));
3470 }
3471 }
3472
3473 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3474 /*
3475 * If no Target, bus reset on 1st I/O. Set the flag to
3476 * prevent any future negotiations to this device.
3477 */
3478 static void mptscsih_no_negotiate(MPT_SCSI_HOST *hd, int target_id)
3479 {
3480
3481 if ((hd->Targets) && (hd->Targets[target_id] == NULL))
3482 hd->ioc->spi_data.dvStatus[target_id] |= MPT_SCSICFG_BLK_NEGO;
3483
3484 return;
3485 }
3486
3487 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3488 /*
3489 * SCSI Config Page functionality ...
3490 */
3491 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3492 /* mptscsih_setDevicePage1Flags - add Requested and Configuration fields flags
3493 * based on width, factor and offset parameters.
3494 * @width: bus width
3495 * @factor: sync factor
3496 * @offset: sync offset
3497 * @requestedPtr: pointer to requested values (updated)
3498 * @configurationPtr: pointer to configuration values (updated)
3499 * @flags: flags to block WDTR or SDTR negotiation
3500 *
3501 * Return: None.
3502 *
3503 * Remark: Called by writeSDP1 and _dv_params
3504 */
3505 static void
3506 mptscsih_setDevicePage1Flags (u8 width, u8 factor, u8 offset, int *requestedPtr, int *configurationPtr, u8 flags)
3507 {
3508 u8 nowide = flags & MPT_TARGET_NO_NEGO_WIDE;
3509 u8 nosync = flags & MPT_TARGET_NO_NEGO_SYNC;
3510
3511 *configurationPtr = 0;
3512 *requestedPtr = width ? MPI_SCSIDEVPAGE1_RP_WIDE : 0;
3513 *requestedPtr |= (offset << 16) | (factor << 8);
3514
3515 if (width && offset && !nowide && !nosync) {
3516 if (factor < MPT_ULTRA160) {
3517 *requestedPtr |= (MPI_SCSIDEVPAGE1_RP_IU + MPI_SCSIDEVPAGE1_RP_DT);
3518 if ((flags & MPT_TARGET_NO_NEGO_QAS) == 0)
3519 *requestedPtr |= MPI_SCSIDEVPAGE1_RP_QAS;
3520 if (flags & MPT_TAPE_NEGO_IDP)
3521 *requestedPtr |= 0x08000000;
3522 } else if (factor < MPT_ULTRA2) {
3523 *requestedPtr |= MPI_SCSIDEVPAGE1_RP_DT;
3524 }
3525 }
3526
3527 if (nowide)
3528 *configurationPtr |= MPI_SCSIDEVPAGE1_CONF_WDTR_DISALLOWED;
3529
3530 if (nosync)
3531 *configurationPtr |= MPI_SCSIDEVPAGE1_CONF_SDTR_DISALLOWED;
3532
3533 return;
3534 }
3535
3536 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3537 /* mptscsih_writeSDP1 - write SCSI Device Page 1
3538 * @hd: Pointer to a SCSI Host Strucutre
3539 * @portnum: IOC port number
3540 * @target_id: writeSDP1 for single ID
3541 * @flags: MPT_SCSICFG_ALL_IDS, MPT_SCSICFG_USE_NVRAM, MPT_SCSICFG_BLK_NEGO
3542 *
3543 * Return: -EFAULT if read of config page header fails
3544 * or 0 if success.
3545 *
3546 * Remark: If a target has been found, the settings from the
3547 * target structure are used, else the device is set
3548 * to async/narrow.
3549 *
3550 * Remark: Called during init and after a FW reload.
3551 * Remark: We do not wait for a return, write pages sequentially.
3552 */
3553 static int
3554 mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
3555 {
3556 MPT_ADAPTER *ioc = hd->ioc;
3557 Config_t *pReq;
3558 SCSIDevicePage1_t *pData;
3559 VirtDevice *pTarget;
3560 MPT_FRAME_HDR *mf;
3561 dma_addr_t dataDma;
3562 u16 req_idx;
3563 u32 frameOffset;
3564 u32 requested, configuration, flagsLength;
3565 int ii, nvram;
3566 int id = 0, maxid = 0;
3567 u8 width;
3568 u8 factor;
3569 u8 offset;
3570 u8 bus = 0;
3571 u8 negoFlags;
3572 u8 maxwidth, maxoffset, maxfactor;
3573
3574 if (ioc->spi_data.sdp1length == 0)
3575 return 0;
3576
3577 if (flags & MPT_SCSICFG_ALL_IDS) {
3578 id = 0;
3579 maxid = ioc->sh->max_id - 1;
3580 } else if (ioc->sh) {
3581 id = target_id;
3582 maxid = min_t(int, id, ioc->sh->max_id - 1);
3583 }
3584
3585 for (; id <= maxid; id++) {
3586
3587 if (id == ioc->pfacts[portnum].PortSCSIID)
3588 continue;
3589
3590 /* Use NVRAM to get adapter and target maximums
3591 * Data over-riden by target structure information, if present
3592 */
3593 maxwidth = ioc->spi_data.maxBusWidth;
3594 maxoffset = ioc->spi_data.maxSyncOffset;
3595 maxfactor = ioc->spi_data.minSyncFactor;
3596 if (ioc->spi_data.nvram && (ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
3597 nvram = ioc->spi_data.nvram[id];
3598
3599 if (maxwidth)
3600 maxwidth = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
3601
3602 if (maxoffset > 0) {
3603 maxfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
3604 if (maxfactor == 0) {
3605 /* Key for async */
3606 maxfactor = MPT_ASYNC;
3607 maxoffset = 0;
3608 } else if (maxfactor < ioc->spi_data.minSyncFactor) {
3609 maxfactor = ioc->spi_data.minSyncFactor;
3610 }
3611 } else
3612 maxfactor = MPT_ASYNC;
3613 }
3614
3615 /* Set the negotiation flags.
3616 */
3617 negoFlags = ioc->spi_data.noQas;
3618 if (!maxwidth)
3619 negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
3620
3621 if (!maxoffset)
3622 negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
3623
3624 if (flags & MPT_SCSICFG_USE_NVRAM) {
3625 width = maxwidth;
3626 factor = maxfactor;
3627 offset = maxoffset;
3628 } else {
3629 width = 0;
3630 factor = MPT_ASYNC;
3631 offset = 0;
3632 //negoFlags = 0;
3633 //negoFlags = MPT_TARGET_NO_NEGO_SYNC;
3634 }
3635
3636 /* If id is not a raid volume, get the updated
3637 * transmission settings from the target structure.
3638 */
3639 if (hd->Targets && (pTarget = hd->Targets[id]) && !pTarget->raidVolume) {
3640 width = pTarget->maxWidth;
3641 factor = pTarget->minSyncFactor;
3642 offset = pTarget->maxOffset;
3643 negoFlags = pTarget->negoFlags;
3644 }
3645
3646 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
3647 /* Force to async and narrow if DV has not been executed
3648 * for this ID
3649 */
3650 if ((hd->ioc->spi_data.dvStatus[id] & MPT_SCSICFG_DV_NOT_DONE) != 0) {
3651 width = 0;
3652 factor = MPT_ASYNC;
3653 offset = 0;
3654 }
3655 #endif
3656
3657 if (flags & MPT_SCSICFG_BLK_NEGO)
3658 negoFlags = MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC;
3659
3660 mptscsih_setDevicePage1Flags(width, factor, offset,
3661 &requested, &configuration, negoFlags);
3662 dnegoprintk(("writeSDP1: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
3663 target_id, width, factor, offset, negoFlags, requested, configuration));
3664
3665 /* Get a MF for this command.
3666 */
3667 if ((mf = mpt_get_msg_frame(ScsiDoneCtx, ioc)) == NULL) {
3668 dprintk((MYIOC_s_WARN_FMT "write SDP1: no msg frames!\n",
3669 ioc->name));
3670 return -EAGAIN;
3671 }
3672
3673 ddvprintk((MYIOC_s_INFO_FMT "WriteSDP1 (mf=%p, id=%d, req=0x%x, cfg=0x%x)\n",
3674 hd->ioc->name, mf, id, requested, configuration));
3675
3676
3677 /* Set the request and the data pointers.
3678 * Request takes: 36 bytes (32 bit SGE)
3679 * SCSI Device Page 1 requires 16 bytes
3680 * 40 + 16 <= size of SCSI IO Request = 56 bytes
3681 * and MF size >= 64 bytes.
3682 * Place data at end of MF.
3683 */
3684 pReq = (Config_t *)mf;
3685
3686 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3687 frameOffset = ioc->req_sz - sizeof(SCSIDevicePage1_t);
3688
3689 pData = (SCSIDevicePage1_t *)((u8 *) mf + frameOffset);
3690 dataDma = ioc->req_frames_dma + (req_idx * ioc->req_sz) + frameOffset;
3691
3692 /* Complete the request frame (same for all requests).
3693 */
3694 pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
3695 pReq->Reserved = 0;
3696 pReq->ChainOffset = 0;
3697 pReq->Function = MPI_FUNCTION_CONFIG;
3698 pReq->ExtPageLength = 0;
3699 pReq->ExtPageType = 0;
3700 pReq->MsgFlags = 0;
3701 for (ii=0; ii < 8; ii++) {
3702 pReq->Reserved2[ii] = 0;
3703 }
3704 pReq->Header.PageVersion = ioc->spi_data.sdp1version;
3705 pReq->Header.PageLength = ioc->spi_data.sdp1length;
3706 pReq->Header.PageNumber = 1;
3707 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
3708 pReq->PageAddress = cpu_to_le32(id | (bus << 8 ));
3709
3710 /* Add a SGE to the config request.
3711 */
3712 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE | ioc->spi_data.sdp1length * 4;
3713
3714 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma);
3715
3716 /* Set up the common data portion
3717 */
3718 pData->Header.PageVersion = pReq->Header.PageVersion;
3719 pData->Header.PageLength = pReq->Header.PageLength;
3720 pData->Header.PageNumber = pReq->Header.PageNumber;
3721 pData->Header.PageType = pReq->Header.PageType;
3722 pData->RequestedParameters = cpu_to_le32(requested);
3723 pData->Reserved = 0;
3724 pData->Configuration = cpu_to_le32(configuration);
3725
3726 dprintk((MYIOC_s_INFO_FMT
3727 "write SDP1: id %d pgaddr 0x%x req 0x%x config 0x%x\n",
3728 ioc->name, id, (id | (bus<<8)),
3729 requested, configuration));
3730
3731 mpt_put_msg_frame(ScsiDoneCtx, ioc, mf);
3732 }
3733
3734 return 0;
3735 }
3736
3737 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3738 /* mptscsih_writeIOCPage4 - write IOC Page 4
3739 * @hd: Pointer to a SCSI Host Structure
3740 * @target_id: write IOC Page4 for this ID & Bus
3741 *
3742 * Return: -EAGAIN if unable to obtain a Message Frame
3743 * or 0 if success.
3744 *
3745 * Remark: We do not wait for a return, write pages sequentially.
3746 */
3747 static int
3748 mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus)
3749 {
3750 MPT_ADAPTER *ioc = hd->ioc;
3751 Config_t *pReq;
3752 IOCPage4_t *IOCPage4Ptr;
3753 MPT_FRAME_HDR *mf;
3754 dma_addr_t dataDma;
3755 u16 req_idx;
3756 u32 frameOffset;
3757 u32 flagsLength;
3758 int ii;
3759
3760 /* Get a MF for this command.
3761 */
3762 if ((mf = mpt_get_msg_frame(ScsiDoneCtx, ioc)) == NULL) {
3763 dprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n",
3764 ioc->name));
3765 return -EAGAIN;
3766 }
3767
3768 /* Set the request and the data pointers.
3769 * Place data at end of MF.
3770 */
3771 pReq = (Config_t *)mf;
3772
3773 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3774 frameOffset = ioc->req_sz - sizeof(IOCPage4_t);
3775
3776 /* Complete the request frame (same for all requests).
3777 */
3778 pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
3779 pReq->Reserved = 0;
3780 pReq->ChainOffset = 0;
3781 pReq->Function = MPI_FUNCTION_CONFIG;
3782 pReq->ExtPageLength = 0;
3783 pReq->ExtPageType = 0;
3784 pReq->MsgFlags = 0;
3785 for (ii=0; ii < 8; ii++) {
3786 pReq->Reserved2[ii] = 0;
3787 }
3788
3789 IOCPage4Ptr = ioc->spi_data.pIocPg4;
3790 dataDma = ioc->spi_data.IocPg4_dma;
3791 ii = IOCPage4Ptr->ActiveSEP++;
3792 IOCPage4Ptr->SEP[ii].SEPTargetID = target_id;
3793 IOCPage4Ptr->SEP[ii].SEPBus = bus;
3794 pReq->Header = IOCPage4Ptr->Header;
3795 pReq->PageAddress = cpu_to_le32(target_id | (bus << 8 ));
3796
3797 /* Add a SGE to the config request.
3798 */
3799 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE |
3800 (IOCPage4Ptr->Header.PageLength + ii) * 4;
3801
3802 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma);
3803
3804 dinitprintk((MYIOC_s_INFO_FMT
3805 "writeIOCPage4: MaxSEP=%d ActiveSEP=%d id=%d bus=%d\n",
3806 ioc->name, IOCPage4Ptr->MaxSEP, IOCPage4Ptr->ActiveSEP, target_id, bus));
3807
3808 mpt_put_msg_frame(ScsiDoneCtx, ioc, mf);
3809
3810 return 0;
3811 }
3812
3813 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3814 /* mptscsih_taskmgmt_timeout - Call back for timeout on a
3815 * task management request.
3816 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
3817 *
3818 */
3819 static void mptscsih_taskmgmt_timeout(unsigned long data)
3820 {
3821 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) data;
3822
3823 dtmprintk((KERN_WARNING MYNAM ": %s: mptscsih_taskmgmt_timeout: "
3824 "TM request timed out!\n", hd->ioc->name));
3825
3826 /* Delete the timer that triggered this callback.
3827 * Remark: del_timer checks to make sure timer is active
3828 * before deleting.
3829 */
3830 del_timer(&hd->TMtimer);
3831
3832 /* Call the reset handler. Already had a TM request
3833 * timeout - so issue a diagnostic reset
3834 */
3835 INIT_WORK(&mptscsih_rstTask, mptscsih_schedule_reset, (void *)hd);
3836 schedule_work(&mptscsih_rstTask);
3837 return;
3838 }
3839
3840 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3841 /* mptscsih_schedule_reset - Call back for timeout on a
3842 * task management request.
3843 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
3844 *
3845 */
3846 static void
3847 mptscsih_schedule_reset(void *arg)
3848 {
3849 MPT_SCSI_HOST *hd;
3850 hd = (MPT_SCSI_HOST *) arg;
3851
3852 if (mpt_HardResetHandler(hd->ioc, CAN_SLEEP) < 0) {
3853 printk((KERN_WARNING " Firmware Reload FAILED!!\n"));
3854 } else {
3855 /* Because we have reset the IOC, no TM requests can be
3856 * pending. So let's make sure the tmPending flag is reset.
3857 */
3858 dtmprintk((KERN_WARNING MYNAM
3859 ": %s: mptscsih_taskmgmt_timeout\n",
3860 hd->ioc->name));
3861 hd->tmPending = 0;
3862 }
3863
3864 return;
3865 }
3866
3867 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3868 /*
3869 * Bus Scan and Domain Validation functionality ...
3870 */
3871
3872 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3873 /*
3874 * mptscsih_scandv_complete - Scan and DV callback routine registered
3875 * to Fustion MPT (base) driver.
3876 *
3877 * @ioc: Pointer to MPT_ADAPTER structure
3878 * @mf: Pointer to original MPT request frame
3879 * @mr: Pointer to MPT reply frame (NULL if TurboReply)
3880 *
3881 * This routine is called from mpt.c::mpt_interrupt() at the completion
3882 * of any SCSI IO request.
3883 * This routine is registered with the Fusion MPT (base) driver at driver
3884 * load/init time via the mpt_register() API call.
3885 *
3886 * Returns 1 indicating alloc'd request frame ptr should be freed.
3887 *
3888 * Remark: Sets a completion code and (possibly) saves sense data
3889 * in the IOC member localReply structure.
3890 * Used ONLY for DV and other internal commands.
3891 */
3892 static int
3893 mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
3894 {
3895 MPT_SCSI_HOST *hd;
3896 SCSIIORequest_t *pReq;
3897 int completionCode;
3898 u16 req_idx;
3899
3900 if ((mf == NULL) ||
3901 (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) {
3902 printk(MYIOC_s_ERR_FMT
3903 "ScanDvComplete, %s req frame ptr! (=%p)\n",
3904 ioc->name, mf?"BAD":"NULL", (void *) mf);
3905 goto wakeup;
3906 }
3907
3908 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
3909 del_timer(&hd->timer);
3910 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3911 hd->ScsiLookup[req_idx] = NULL;
3912 pReq = (SCSIIORequest_t *) mf;
3913
3914 if (mf != hd->cmdPtr) {
3915 printk(MYIOC_s_WARN_FMT "ScanDvComplete (mf=%p, cmdPtr=%p, idx=%d)\n",
3916 hd->ioc->name, (void *)mf, (void *) hd->cmdPtr, req_idx);
3917 }
3918 hd->cmdPtr = NULL;
3919
3920 ddvprintk((MYIOC_s_INFO_FMT "ScanDvComplete (mf=%p,mr=%p,idx=%d)\n",
3921 hd->ioc->name, mf, mr, req_idx));
3922
3923 hd->pLocal = &hd->localReply;
3924 hd->pLocal->scsiStatus = 0;
3925
3926 /* If target struct exists, clear sense valid flag.
3927 */
3928 if (mr == NULL) {
3929 completionCode = MPT_SCANDV_GOOD;
3930 } else {
3931 SCSIIOReply_t *pReply;
3932 u16 status;
3933 u8 scsi_status;
3934
3935 pReply = (SCSIIOReply_t *) mr;
3936
3937 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
3938 scsi_status = pReply->SCSIStatus;
3939
3940 ddvtprintk((KERN_NOTICE " IOCStatus=%04xh, SCSIState=%02xh, SCSIStatus=%02xh, IOCLogInfo=%08xh\n",
3941 status, pReply->SCSIState, scsi_status,
3942 le32_to_cpu(pReply->IOCLogInfo)));
3943
3944 switch(status) {
3945
3946 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
3947 completionCode = MPT_SCANDV_SELECTION_TIMEOUT;
3948 break;
3949
3950 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
3951 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
3952 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
3953 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
3954 completionCode = MPT_SCANDV_DID_RESET;
3955 break;
3956
3957 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
3958 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
3959 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
3960 if (pReply->Function == MPI_FUNCTION_CONFIG) {
3961 ConfigReply_t *pr = (ConfigReply_t *)mr;
3962 completionCode = MPT_SCANDV_GOOD;
3963 hd->pLocal->header.PageVersion = pr->Header.PageVersion;
3964 hd->pLocal->header.PageLength = pr->Header.PageLength;
3965 hd->pLocal->header.PageNumber = pr->Header.PageNumber;
3966 hd->pLocal->header.PageType = pr->Header.PageType;
3967
3968 } else if (pReply->Function == MPI_FUNCTION_RAID_ACTION) {
3969 /* If the RAID Volume request is successful,
3970 * return GOOD, else indicate that
3971 * some type of error occurred.
3972 */
3973 MpiRaidActionReply_t *pr = (MpiRaidActionReply_t *)mr;
3974 if (pr->ActionStatus == MPI_RAID_ACTION_ASTATUS_SUCCESS)
3975 completionCode = MPT_SCANDV_GOOD;
3976 else
3977 completionCode = MPT_SCANDV_SOME_ERROR;
3978
3979 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID) {
3980 u8 *sense_data;
3981 int sz;
3982
3983 /* save sense data in global structure
3984 */
3985 completionCode = MPT_SCANDV_SENSE;
3986 hd->pLocal->scsiStatus = scsi_status;
3987 sense_data = ((u8 *)hd->ioc->sense_buf_pool +
3988 (req_idx * MPT_SENSE_BUFFER_ALLOC));
3989
3990 sz = min_t(int, pReq->SenseBufferLength,
3991 SCSI_STD_SENSE_BYTES);
3992 memcpy(hd->pLocal->sense, sense_data, sz);
3993
3994 ddvprintk((KERN_NOTICE " Check Condition, sense ptr %p\n",
3995 sense_data));
3996 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_FAILED) {
3997 if (pReq->CDB[0] == INQUIRY)
3998 completionCode = MPT_SCANDV_ISSUE_SENSE;
3999 else
4000 completionCode = MPT_SCANDV_DID_RESET;
4001 }
4002 else if (pReply->SCSIState & MPI_SCSI_STATE_NO_SCSI_STATUS)
4003 completionCode = MPT_SCANDV_DID_RESET;
4004 else if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
4005 completionCode = MPT_SCANDV_DID_RESET;
4006 else {
4007 completionCode = MPT_SCANDV_GOOD;
4008 hd->pLocal->scsiStatus = scsi_status;
4009 }
4010 break;
4011
4012 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
4013 if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
4014 completionCode = MPT_SCANDV_DID_RESET;
4015 else
4016 completionCode = MPT_SCANDV_SOME_ERROR;
4017 break;
4018
4019 default:
4020 completionCode = MPT_SCANDV_SOME_ERROR;
4021 break;
4022
4023 } /* switch(status) */
4024
4025 ddvtprintk((KERN_NOTICE " completionCode set to %08xh\n",
4026 completionCode));
4027 } /* end of address reply case */
4028
4029 hd->pLocal->completion = completionCode;
4030
4031 /* MF and RF are freed in mpt_interrupt
4032 */
4033 wakeup:
4034 /* Free Chain buffers (will never chain) in scan or dv */
4035 //mptscsih_freeChainBuffers(ioc, req_idx);
4036
4037 /*
4038 * Wake up the original calling thread
4039 */
4040 scandv_wait_done = 1;
4041 wake_up(&scandv_waitq);
4042
4043 return 1;
4044 }
4045
4046 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4047 /* mptscsih_timer_expired - Call back for timer process.
4048 * Used only for dv functionality.
4049 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
4050 *
4051 */
4052 static void mptscsih_timer_expired(unsigned long data)
4053 {
4054 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) data;
4055
4056 ddvprintk((MYIOC_s_WARN_FMT "Timer Expired! Cmd %p\n", hd->ioc->name, hd->cmdPtr));
4057
4058 if (hd->cmdPtr) {
4059 MPIHeader_t *cmd = (MPIHeader_t *)hd->cmdPtr;
4060
4061 if (cmd->Function == MPI_FUNCTION_SCSI_IO_REQUEST) {
4062 /* Desire to issue a task management request here.
4063 * TM requests MUST be single threaded.
4064 * If old eh code and no TM current, issue request.
4065 * If new eh code, do nothing. Wait for OS cmd timeout
4066 * for bus reset.
4067 */
4068 ddvtprintk((MYIOC_s_NOTE_FMT "DV Cmd Timeout: NoOp\n", hd->ioc->name));
4069 } else {
4070 /* Perform a FW reload */
4071 if (mpt_HardResetHandler(hd->ioc, NO_SLEEP) < 0) {
4072 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", hd->ioc->name);
4073 }
4074 }
4075 } else {
4076 /* This should NEVER happen */
4077 printk(MYIOC_s_WARN_FMT "Null cmdPtr!!!!\n", hd->ioc->name);
4078 }
4079
4080 /* No more processing.
4081 * TM call will generate an interrupt for SCSI TM Management.
4082 * The FW will reply to all outstanding commands, callback will finish cleanup.
4083 * Hard reset clean-up will free all resources.
4084 */
4085 ddvprintk((MYIOC_s_WARN_FMT "Timer Expired Complete!\n", hd->ioc->name));
4086
4087 return;
4088 }
4089
4090 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
4091 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4092 /* mptscsih_do_raid - Format and Issue a RAID volume request message.
4093 * @hd: Pointer to scsi host structure
4094 * @action: What do be done.
4095 * @id: Logical target id.
4096 * @bus: Target locations bus.
4097 *
4098 * Returns: < 0 on a fatal error
4099 * 0 on success
4100 *
4101 * Remark: Wait to return until reply processed by the ISR.
4102 */
4103 static int
4104 mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io)
4105 {
4106 MpiRaidActionRequest_t *pReq;
4107 MPT_FRAME_HDR *mf;
4108 int in_isr;
4109
4110 in_isr = in_interrupt();
4111 if (in_isr) {
4112 dprintk((MYIOC_s_WARN_FMT "Internal raid request not allowed in ISR context!\n",
4113 hd->ioc->name));
4114 return -EPERM;
4115 }
4116
4117 /* Get and Populate a free Frame
4118 */
4119 if ((mf = mpt_get_msg_frame(ScsiScanDvCtx, hd->ioc)) == NULL) {
4120 ddvprintk((MYIOC_s_WARN_FMT "_do_raid: no msg frames!\n",
4121 hd->ioc->name));
4122 return -EAGAIN;
4123 }
4124 pReq = (MpiRaidActionRequest_t *)mf;
4125 pReq->Action = action;
4126 pReq->Reserved1 = 0;
4127 pReq->ChainOffset = 0;
4128 pReq->Function = MPI_FUNCTION_RAID_ACTION;
4129 pReq->VolumeID = io->id;
4130 pReq->VolumeBus = io->bus;
4131 pReq->PhysDiskNum = io->physDiskNum;
4132 pReq->MsgFlags = 0;
4133 pReq->Reserved2 = 0;
4134 pReq->ActionDataWord = 0; /* Reserved for this action */
4135 //pReq->ActionDataSGE = 0;
4136
4137 mpt_add_sge((char *)&pReq->ActionDataSGE,
4138 MPT_SGE_FLAGS_SSIMPLE_READ | 0, (dma_addr_t) -1);
4139
4140 ddvprintk((MYIOC_s_INFO_FMT "RAID Volume action %x id %d\n",
4141 hd->ioc->name, action, io->id));
4142
4143 hd->pLocal = NULL;
4144 hd->timer.expires = jiffies + HZ*10; /* 10 second timeout */
4145 scandv_wait_done = 0;
4146
4147 /* Save cmd pointer, for resource free if timeout or
4148 * FW reload occurs
4149 */
4150 hd->cmdPtr = mf;
4151
4152 add_timer(&hd->timer);
4153 mpt_put_msg_frame(ScsiScanDvCtx, hd->ioc, mf);
4154 wait_event(scandv_waitq, scandv_wait_done);
4155
4156 if ((hd->pLocal == NULL) || (hd->pLocal->completion != MPT_SCANDV_GOOD))
4157 return -1;
4158
4159 return 0;
4160 }
4161 #endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */
4162
4163 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4164 /**
4165 * mptscsih_do_cmd - Do internal command.
4166 * @hd: MPT_SCSI_HOST pointer
4167 * @io: INTERNAL_CMD pointer.
4168 *
4169 * Issue the specified internally generated command and do command
4170 * specific cleanup. For bus scan / DV only.
4171 * NOTES: If command is Inquiry and status is good,
4172 * initialize a target structure, save the data
4173 *
4174 * Remark: Single threaded access only.
4175 *
4176 * Return:
4177 * < 0 if an illegal command or no resources
4178 *
4179 * 0 if good
4180 *
4181 * > 0 if command complete but some type of completion error.
4182 */
4183 static int
4184 mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
4185 {
4186 MPT_FRAME_HDR *mf;
4187 SCSIIORequest_t *pScsiReq;
4188 SCSIIORequest_t ReqCopy;
4189 int my_idx, ii, dir;
4190 int rc, cmdTimeout;
4191 int in_isr;
4192 char cmdLen;
4193 char CDB[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
4194 char cmd = io->cmd;
4195
4196 in_isr = in_interrupt();
4197 if (in_isr) {
4198 dprintk((MYIOC_s_WARN_FMT "Internal SCSI IO request not allowed in ISR context!\n",
4199 hd->ioc->name));
4200 return -EPERM;
4201 }
4202
4203
4204 /* Set command specific information
4205 */
4206 switch (cmd) {
4207 case INQUIRY:
4208 cmdLen = 6;
4209 dir = MPI_SCSIIO_CONTROL_READ;
4210 CDB[0] = cmd;
4211 CDB[4] = io->size;
4212 cmdTimeout = 10;
4213 break;
4214
4215 case TEST_UNIT_READY:
4216 cmdLen = 6;
4217 dir = MPI_SCSIIO_CONTROL_READ;
4218 cmdTimeout = 10;
4219 break;
4220
4221 case START_STOP:
4222 cmdLen = 6;
4223 dir = MPI_SCSIIO_CONTROL_READ;
4224 CDB[0] = cmd;
4225 CDB[4] = 1; /*Spin up the disk */
4226 cmdTimeout = 15;
4227 break;
4228
4229 case REQUEST_SENSE:
4230 cmdLen = 6;
4231 CDB[0] = cmd;
4232 CDB[4] = io->size;
4233 dir = MPI_SCSIIO_CONTROL_READ;
4234 cmdTimeout = 10;
4235 break;
4236
4237 case READ_BUFFER:
4238 cmdLen = 10;
4239 dir = MPI_SCSIIO_CONTROL_READ;
4240 CDB[0] = cmd;
4241 if (io->flags & MPT_ICFLAG_ECHO) {
4242 CDB[1] = 0x0A;
4243 } else {
4244 CDB[1] = 0x02;
4245 }
4246
4247 if (io->flags & MPT_ICFLAG_BUF_CAP) {
4248 CDB[1] |= 0x01;
4249 }
4250 CDB[6] = (io->size >> 16) & 0xFF;
4251 CDB[7] = (io->size >> 8) & 0xFF;
4252 CDB[8] = io->size & 0xFF;
4253 cmdTimeout = 10;
4254 break;
4255
4256 case WRITE_BUFFER:
4257 cmdLen = 10;
4258 dir = MPI_SCSIIO_CONTROL_WRITE;
4259 CDB[0] = cmd;
4260 if (io->flags & MPT_ICFLAG_ECHO) {
4261 CDB[1] = 0x0A;
4262 } else {
4263 CDB[1] = 0x02;
4264 }
4265 CDB[6] = (io->size >> 16) & 0xFF;
4266 CDB[7] = (io->size >> 8) & 0xFF;
4267 CDB[8] = io->size & 0xFF;
4268 cmdTimeout = 10;
4269 break;
4270
4271 case RESERVE:
4272 cmdLen = 6;
4273 dir = MPI_SCSIIO_CONTROL_READ;
4274 CDB[0] = cmd;
4275 cmdTimeout = 10;
4276 break;
4277
4278 case RELEASE:
4279 cmdLen = 6;
4280 dir = MPI_SCSIIO_CONTROL_READ;
4281 CDB[0] = cmd;
4282 cmdTimeout = 10;
4283 break;
4284
4285 case SYNCHRONIZE_CACHE:
4286 cmdLen = 10;
4287 dir = MPI_SCSIIO_CONTROL_READ;
4288 CDB[0] = cmd;
4289 // CDB[1] = 0x02; /* set immediate bit */
4290 cmdTimeout = 10;
4291 break;
4292
4293 default:
4294 /* Error Case */
4295 return -EFAULT;
4296 }
4297
4298 /* Get and Populate a free Frame
4299 */
4300 if ((mf = mpt_get_msg_frame(ScsiScanDvCtx, hd->ioc)) == NULL) {
4301 ddvprintk((MYIOC_s_WARN_FMT "No msg frames!\n",
4302 hd->ioc->name));
4303 return -EBUSY;
4304 }
4305
4306 pScsiReq = (SCSIIORequest_t *) mf;
4307
4308 /* Get the request index */
4309 my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
4310 ADD_INDEX_LOG(my_idx); /* for debug */
4311
4312 if (io->flags & MPT_ICFLAG_PHYS_DISK) {
4313 pScsiReq->TargetID = io->physDiskNum;
4314 pScsiReq->Bus = 0;
4315 pScsiReq->ChainOffset = 0;
4316 pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
4317 } else {
4318 pScsiReq->TargetID = io->id;
4319 pScsiReq->Bus = io->bus;
4320 pScsiReq->ChainOffset = 0;
4321 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
4322 }
4323
4324 pScsiReq->CDBLength = cmdLen;
4325 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
4326
4327 pScsiReq->Reserved = 0;
4328
4329 pScsiReq->MsgFlags = mpt_msg_flags();
4330 /* MsgContext set in mpt_get_msg_fram call */
4331
4332 for (ii=0; ii < 8; ii++)
4333 pScsiReq->LUN[ii] = 0;
4334 pScsiReq->LUN[1] = io->lun;
4335
4336 if (io->flags & MPT_ICFLAG_TAGGED_CMD)
4337 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ);
4338 else
4339 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
4340
4341 if (cmd == REQUEST_SENSE) {
4342 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
4343 ddvprintk((MYIOC_s_INFO_FMT "Untagged! 0x%2x\n",
4344 hd->ioc->name, cmd));
4345 }
4346
4347 for (ii=0; ii < 16; ii++)
4348 pScsiReq->CDB[ii] = CDB[ii];
4349
4350 pScsiReq->DataLength = cpu_to_le32(io->size);
4351 pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
4352 + (my_idx * MPT_SENSE_BUFFER_ALLOC));
4353
4354 ddvprintk((MYIOC_s_INFO_FMT "Sending Command 0x%x for (%d:%d:%d)\n",
4355 hd->ioc->name, cmd, io->bus, io->id, io->lun));
4356
4357 if (dir == MPI_SCSIIO_CONTROL_READ) {
4358 mpt_add_sge((char *) &pScsiReq->SGL,
4359 MPT_SGE_FLAGS_SSIMPLE_READ | io->size,
4360 io->data_dma);
4361 } else {
4362 mpt_add_sge((char *) &pScsiReq->SGL,
4363 MPT_SGE_FLAGS_SSIMPLE_WRITE | io->size,
4364 io->data_dma);
4365 }
4366
4367 /* The ISR will free the request frame, but we need
4368 * the information to initialize the target. Duplicate.
4369 */
4370 memcpy(&ReqCopy, pScsiReq, sizeof(SCSIIORequest_t));
4371
4372 /* Issue this command after:
4373 * finish init
4374 * add timer
4375 * Wait until the reply has been received
4376 * ScsiScanDvCtx callback function will
4377 * set hd->pLocal;
4378 * set scandv_wait_done and call wake_up
4379 */
4380 hd->pLocal = NULL;
4381 hd->timer.expires = jiffies + HZ*cmdTimeout;
4382 scandv_wait_done = 0;
4383
4384 /* Save cmd pointer, for resource free if timeout or
4385 * FW reload occurs
4386 */
4387 hd->cmdPtr = mf;
4388
4389 add_timer(&hd->timer);
4390 mpt_put_msg_frame(ScsiScanDvCtx, hd->ioc, mf);
4391 wait_event(scandv_waitq, scandv_wait_done);
4392
4393 if (hd->pLocal) {
4394 rc = hd->pLocal->completion;
4395 hd->pLocal->skip = 0;
4396
4397 /* Always set fatal error codes in some cases.
4398 */
4399 if (rc == MPT_SCANDV_SELECTION_TIMEOUT)
4400 rc = -ENXIO;
4401 else if (rc == MPT_SCANDV_SOME_ERROR)
4402 rc = -rc;
4403 } else {
4404 rc = -EFAULT;
4405 /* This should never happen. */
4406 ddvprintk((MYIOC_s_INFO_FMT "_do_cmd: Null pLocal!!!\n",
4407 hd->ioc->name));
4408 }
4409
4410 return rc;
4411 }
4412
4413 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4414 /**
4415 * mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
4416 * @hd: Pointer to MPT_SCSI_HOST structure
4417 * @portnum: IOC port number
4418 *
4419 * Uses the ISR, but with special processing.
4420 * MUST be single-threaded.
4421 *
4422 * Return: 0 on completion
4423 */
4424 static int
4425 mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum)
4426 {
4427 MPT_ADAPTER *ioc= hd->ioc;
4428 VirtDevice *pTarget;
4429 SCSIDevicePage1_t *pcfg1Data = NULL;
4430 INTERNAL_CMD iocmd;
4431 CONFIGPARMS cfg;
4432 dma_addr_t cfg1_dma_addr = -1;
4433 ConfigPageHeader_t header1;
4434 int bus = 0;
4435 int id = 0;
4436 int lun;
4437 int indexed_lun, lun_index;
4438 int hostId = ioc->pfacts[portnum].PortSCSIID;
4439 int max_id;
4440 int requested, configuration, data;
4441 int doConfig = 0;
4442 u8 flags, factor;
4443
4444 max_id = ioc->sh->max_id - 1;
4445
4446 /* Following parameters will not change
4447 * in this routine.
4448 */
4449 iocmd.cmd = SYNCHRONIZE_CACHE;
4450 iocmd.flags = 0;
4451 iocmd.physDiskNum = -1;
4452 iocmd.data = NULL;
4453 iocmd.data_dma = -1;
4454 iocmd.size = 0;
4455 iocmd.rsvd = iocmd.rsvd2 = 0;
4456
4457 /* No SCSI hosts
4458 */
4459 if (hd->Targets == NULL)
4460 return 0;
4461
4462 /* Skip the host
4463 */
4464 if (id == hostId)
4465 id++;
4466
4467 /* Write SDP1 for all SCSI devices
4468 * Alloc memory and set up config buffer
4469 */
4470 if (ioc->bus_type == SCSI) {
4471 if (ioc->spi_data.sdp1length > 0) {
4472 pcfg1Data = (SCSIDevicePage1_t *)pci_alloc_consistent(ioc->pcidev,
4473 ioc->spi_data.sdp1length * 4, &cfg1_dma_addr);
4474
4475 if (pcfg1Data != NULL) {
4476 doConfig = 1;
4477 header1.PageVersion = ioc->spi_data.sdp1version;
4478 header1.PageLength = ioc->spi_data.sdp1length;
4479 header1.PageNumber = 1;
4480 header1.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4481 cfg.hdr = &header1;
4482 cfg.physAddr = cfg1_dma_addr;
4483 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4484 cfg.dir = 1;
4485 cfg.timeout = 0;
4486 }
4487 }
4488 }
4489
4490 /* loop through all devices on this port
4491 */
4492 while (bus < MPT_MAX_BUS) {
4493 iocmd.bus = bus;
4494 iocmd.id = id;
4495 pTarget = hd->Targets[(int)id];
4496
4497 if (doConfig) {
4498
4499 /* Set the negotiation flags */
4500 if (pTarget && (pTarget = hd->Targets[id]) && !pTarget->raidVolume) {
4501 flags = pTarget->negoFlags;
4502 } else {
4503 flags = hd->ioc->spi_data.noQas;
4504 if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
4505 data = hd->ioc->spi_data.nvram[id];
4506
4507 if (data & MPT_NVRAM_WIDE_DISABLE)
4508 flags |= MPT_TARGET_NO_NEGO_WIDE;
4509
4510 factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT;
4511 if ((factor == 0) || (factor == MPT_ASYNC))
4512 flags |= MPT_TARGET_NO_NEGO_SYNC;
4513 }
4514 }
4515
4516 /* Force to async, narrow */
4517 mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested,
4518 &configuration, flags);
4519 dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC "
4520 "offset=0 negoFlags=%x request=%x config=%x\n",
4521 id, flags, requested, configuration));
4522 pcfg1Data->RequestedParameters = le32_to_cpu(requested);
4523 pcfg1Data->Reserved = 0;
4524 pcfg1Data->Configuration = le32_to_cpu(configuration);
4525 cfg.pageAddr = (bus<<8) | id;
4526 mpt_config(hd->ioc, &cfg);
4527 }
4528
4529 /* If target Ptr NULL or if this target is NOT a disk, skip.
4530 */
4531 if ((pTarget) && (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)){
4532 for (lun=0; lun <= MPT_LAST_LUN; lun++) {
4533 /* If LUN present, issue the command
4534 */
4535 lun_index = (lun >> 5); /* 32 luns per lun_index */
4536 indexed_lun = (lun % 32);
4537 if (pTarget->luns[lun_index] & (1<<indexed_lun)) {
4538 iocmd.lun = lun;
4539 (void) mptscsih_do_cmd(hd, &iocmd);
4540 }
4541 }
4542 }
4543
4544 /* get next relevant device */
4545 id++;
4546
4547 if (id == hostId)
4548 id++;
4549
4550 if (id > max_id) {
4551 id = 0;
4552 bus++;
4553 }
4554 }
4555
4556 if (pcfg1Data) {
4557 pci_free_consistent(ioc->pcidev, header1.PageLength * 4, pcfg1Data, cfg1_dma_addr);
4558 }
4559
4560 return 0;
4561 }
4562
4563 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
4564 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4565 /**
4566 * mptscsih_domainValidation - Top level handler for domain validation.
4567 * @hd: Pointer to MPT_SCSI_HOST structure.
4568 *
4569 * Uses the ISR, but with special processing.
4570 * Called from schedule, should not be in interrupt mode.
4571 * While thread alive, do dv for all devices needing dv
4572 *
4573 * Return: None.
4574 */
4575 static void
4576 mptscsih_domainValidation(void *arg)
4577 {
4578 MPT_SCSI_HOST *hd;
4579 MPT_ADAPTER *ioc;
4580 unsigned long flags;
4581 int id, maxid, dvStatus, did;
4582 int ii, isPhysDisk;
4583
4584 spin_lock_irqsave(&dvtaskQ_lock, flags);
4585 dvtaskQ_active = 1;
4586 if (dvtaskQ_release) {
4587 dvtaskQ_active = 0;
4588 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4589 return;
4590 }
4591 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4592
4593 /* For this ioc, loop through all devices and do dv to each device.
4594 * When complete with this ioc, search through the ioc list, and
4595 * for each scsi ioc found, do dv for all devices. Exit when no
4596 * device needs dv.
4597 */
4598 did = 1;
4599 while (did) {
4600 did = 0;
4601 list_for_each_entry(ioc, &ioc_list, list) {
4602 spin_lock_irqsave(&dvtaskQ_lock, flags);
4603 if (dvtaskQ_release) {
4604 dvtaskQ_active = 0;
4605 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4606 return;
4607 }
4608 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4609
4610 msleep(250);
4611
4612 /* DV only to SCSI adapters */
4613 if (ioc->bus_type != SCSI)
4614 continue;
4615
4616 /* Make sure everything looks ok */
4617 if (ioc->sh == NULL)
4618 continue;
4619
4620 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
4621 if (hd == NULL)
4622 continue;
4623
4624 if ((ioc->spi_data.forceDv & MPT_SCSICFG_RELOAD_IOC_PG3) != 0) {
4625 mpt_read_ioc_pg_3(ioc);
4626 if (ioc->spi_data.pIocPg3) {
4627 Ioc3PhysDisk_t *pPDisk = ioc->spi_data.pIocPg3->PhysDisk;
4628 int numPDisk = ioc->spi_data.pIocPg3->NumPhysDisks;
4629
4630 while (numPDisk) {
4631 if (ioc->spi_data.dvStatus[pPDisk->PhysDiskID] & MPT_SCSICFG_DV_NOT_DONE)
4632 ioc->spi_data.dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV;
4633
4634 pPDisk++;
4635 numPDisk--;
4636 }
4637 }
4638 ioc->spi_data.forceDv &= ~MPT_SCSICFG_RELOAD_IOC_PG3;
4639 }
4640
4641 maxid = min_t(int, ioc->sh->max_id, MPT_MAX_SCSI_DEVICES);
4642
4643 for (id = 0; id < maxid; id++) {
4644 spin_lock_irqsave(&dvtaskQ_lock, flags);
4645 if (dvtaskQ_release) {
4646 dvtaskQ_active = 0;
4647 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4648 return;
4649 }
4650 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4651 dvStatus = hd->ioc->spi_data.dvStatus[id];
4652
4653 if (dvStatus & MPT_SCSICFG_NEED_DV) {
4654 did++;
4655 hd->ioc->spi_data.dvStatus[id] |= MPT_SCSICFG_DV_PENDING;
4656 hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_NEED_DV;
4657
4658 msleep(250);
4659
4660 /* If hidden phys disk, block IO's to all
4661 * raid volumes
4662 * else, process normally
4663 */
4664 isPhysDisk = mptscsih_is_phys_disk(ioc, id);
4665 if (isPhysDisk) {
4666 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4667 if (hd->ioc->spi_data.isRaid & (1 << ii)) {
4668 hd->ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_DV_PENDING;
4669 }
4670 }
4671 }
4672
4673 if (mptscsih_doDv(hd, 0, id) == 1) {
4674 /* Untagged device was busy, try again
4675 */
4676 hd->ioc->spi_data.dvStatus[id] |= MPT_SCSICFG_NEED_DV;
4677 hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_PENDING;
4678 } else {
4679 /* DV is complete. Clear flags.
4680 */
4681 hd->ioc->spi_data.dvStatus[id] &= ~(MPT_SCSICFG_DV_NOT_DONE | MPT_SCSICFG_DV_PENDING);
4682 }
4683
4684 if (isPhysDisk) {
4685 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4686 if (hd->ioc->spi_data.isRaid & (1 << ii)) {
4687 hd->ioc->spi_data.dvStatus[ii] &= ~MPT_SCSICFG_DV_PENDING;
4688 }
4689 }
4690 }
4691
4692 if (hd->ioc->spi_data.noQas)
4693 mptscsih_qas_check(hd, id);
4694 }
4695 }
4696 }
4697 }
4698
4699 spin_lock_irqsave(&dvtaskQ_lock, flags);
4700 dvtaskQ_active = 0;
4701 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4702
4703 return;
4704 }
4705
4706 /* Search IOC page 3 to determine if this is hidden physical disk
4707 */
4708 static int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id)
4709 {
4710 if (ioc->spi_data.pIocPg3) {
4711 Ioc3PhysDisk_t *pPDisk = ioc->spi_data.pIocPg3->PhysDisk;
4712 int numPDisk = ioc->spi_data.pIocPg3->NumPhysDisks;
4713
4714 while (numPDisk) {
4715 if (pPDisk->PhysDiskID == id) {
4716 return 1;
4717 }
4718 pPDisk++;
4719 numPDisk--;
4720 }
4721 }
4722 return 0;
4723 }
4724
4725 /* Write SDP1 if no QAS has been enabled
4726 */
4727 static void mptscsih_qas_check(MPT_SCSI_HOST *hd, int id)
4728 {
4729 VirtDevice *pTarget;
4730 int ii;
4731
4732 if (hd->Targets == NULL)
4733 return;
4734
4735 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4736 if (ii == id)
4737 continue;
4738
4739 if ((hd->ioc->spi_data.dvStatus[ii] & MPT_SCSICFG_DV_NOT_DONE) != 0)
4740 continue;
4741
4742 pTarget = hd->Targets[ii];
4743
4744 if ((pTarget != NULL) && (!pTarget->raidVolume)) {
4745 if ((pTarget->negoFlags & hd->ioc->spi_data.noQas) == 0) {
4746 pTarget->negoFlags |= hd->ioc->spi_data.noQas;
4747 dnegoprintk(("writeSDP1: id=%d flags=0\n", id));
4748 mptscsih_writeSDP1(hd, 0, ii, 0);
4749 }
4750 } else {
4751 if (mptscsih_is_phys_disk(hd->ioc, ii) == 1) {
4752 dnegoprintk(("writeSDP1: id=%d SCSICFG_USE_NVRAM\n", id));
4753 mptscsih_writeSDP1(hd, 0, ii, MPT_SCSICFG_USE_NVRAM);
4754 }
4755 }
4756 }
4757 return;
4758 }
4759
4760
4761
4762 #define MPT_GET_NVRAM_VALS 0x01
4763 #define MPT_UPDATE_MAX 0x02
4764 #define MPT_SET_MAX 0x04
4765 #define MPT_SET_MIN 0x08
4766 #define MPT_FALLBACK 0x10
4767 #define MPT_SAVE 0x20
4768
4769 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4770 /**
4771 * mptscsih_doDv - Perform domain validation to a target.
4772 * @hd: Pointer to MPT_SCSI_HOST structure.
4773 * @portnum: IOC port number.
4774 * @target: Physical ID of this target
4775 *
4776 * Uses the ISR, but with special processing.
4777 * MUST be single-threaded.
4778 * Test will exit if target is at async & narrow.
4779 *
4780 * Return: None.
4781 */
4782 static int
4783 mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
4784 {
4785 MPT_ADAPTER *ioc = hd->ioc;
4786 VirtDevice *pTarget;
4787 SCSIDevicePage1_t *pcfg1Data;
4788 SCSIDevicePage0_t *pcfg0Data;
4789 u8 *pbuf1;
4790 u8 *pbuf2;
4791 u8 *pDvBuf;
4792 dma_addr_t dvbuf_dma = -1;
4793 dma_addr_t buf1_dma = -1;
4794 dma_addr_t buf2_dma = -1;
4795 dma_addr_t cfg1_dma_addr = -1;
4796 dma_addr_t cfg0_dma_addr = -1;
4797 ConfigPageHeader_t header1;
4798 ConfigPageHeader_t header0;
4799 DVPARAMETERS dv;
4800 INTERNAL_CMD iocmd;
4801 CONFIGPARMS cfg;
4802 int dv_alloc = 0;
4803 int rc, sz = 0;
4804 int bufsize = 0;
4805 int dataBufSize = 0;
4806 int echoBufSize = 0;
4807 int notDone;
4808 int patt;
4809 int repeat;
4810 int retcode = 0;
4811 int nfactor = MPT_ULTRA320;
4812 char firstPass = 1;
4813 char doFallback = 0;
4814 char readPage0;
4815 char bus, lun;
4816 char inq0 = 0;
4817
4818 if (ioc->spi_data.sdp1length == 0)
4819 return 0;
4820
4821 if (ioc->spi_data.sdp0length == 0)
4822 return 0;
4823
4824 /* If multiple buses are used, require that the initiator
4825 * id be the same on all buses.
4826 */
4827 if (id == ioc->pfacts[0].PortSCSIID)
4828 return 0;
4829
4830 lun = 0;
4831 bus = (u8) bus_number;
4832 ddvtprintk((MYIOC_s_NOTE_FMT
4833 "DV started: bus=%d, id=%d dv @ %p\n",
4834 ioc->name, bus, id, &dv));
4835
4836 /* Prep DV structure
4837 */
4838 memset (&dv, 0, sizeof(DVPARAMETERS));
4839 dv.id = id;
4840
4841 /* Populate tmax with the current maximum
4842 * transfer parameters for this target.
4843 * Exit if narrow and async.
4844 */
4845 dv.cmd = MPT_GET_NVRAM_VALS;
4846 mptscsih_dv_parms(hd, &dv, NULL);
4847
4848 /* Prep SCSI IO structure
4849 */
4850 iocmd.id = id;
4851 iocmd.bus = bus;
4852 iocmd.lun = lun;
4853 iocmd.flags = 0;
4854 iocmd.physDiskNum = -1;
4855 iocmd.rsvd = iocmd.rsvd2 = 0;
4856
4857 pTarget = hd->Targets[id];
4858
4859 /* Use tagged commands if possible.
4860 */
4861 if (pTarget) {
4862 if (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)
4863 iocmd.flags |= MPT_ICFLAG_TAGGED_CMD;
4864 else {
4865 if (hd->ioc->facts.FWVersion.Word < 0x01000600)
4866 return 0;
4867
4868 if ((hd->ioc->facts.FWVersion.Word >= 0x01010000) &&
4869 (hd->ioc->facts.FWVersion.Word < 0x01010B00))
4870 return 0;
4871 }
4872 }
4873
4874 /* Prep cfg structure
4875 */
4876 cfg.pageAddr = (bus<<8) | id;
4877 cfg.hdr = NULL;
4878
4879 /* Prep SDP0 header
4880 */
4881 header0.PageVersion = ioc->spi_data.sdp0version;
4882 header0.PageLength = ioc->spi_data.sdp0length;
4883 header0.PageNumber = 0;
4884 header0.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4885
4886 /* Prep SDP1 header
4887 */
4888 header1.PageVersion = ioc->spi_data.sdp1version;
4889 header1.PageLength = ioc->spi_data.sdp1length;
4890 header1.PageNumber = 1;
4891 header1.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4892
4893 if (header0.PageLength & 1)
4894 dv_alloc = (header0.PageLength * 4) + 4;
4895
4896 dv_alloc += (2048 + (header1.PageLength * 4));
4897
4898 pDvBuf = pci_alloc_consistent(ioc->pcidev, dv_alloc, &dvbuf_dma);
4899 if (pDvBuf == NULL)
4900 return 0;
4901
4902 sz = 0;
4903 pbuf1 = (u8 *)pDvBuf;
4904 buf1_dma = dvbuf_dma;
4905 sz +=1024;
4906
4907 pbuf2 = (u8 *) (pDvBuf + sz);
4908 buf2_dma = dvbuf_dma + sz;
4909 sz +=1024;
4910
4911 pcfg0Data = (SCSIDevicePage0_t *) (pDvBuf + sz);
4912 cfg0_dma_addr = dvbuf_dma + sz;
4913 sz += header0.PageLength * 4;
4914
4915 /* 8-byte alignment
4916 */
4917 if (header0.PageLength & 1)
4918 sz += 4;
4919
4920 pcfg1Data = (SCSIDevicePage1_t *) (pDvBuf + sz);
4921 cfg1_dma_addr = dvbuf_dma + sz;
4922
4923 /* Skip this ID? Set cfg.hdr to force config page write
4924 */
4925 {
4926 ScsiCfgData *pspi_data = &hd->ioc->spi_data;
4927 if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
4928 /* Set the factor from nvram */
4929 nfactor = (pspi_data->nvram[id] & MPT_NVRAM_SYNC_MASK) >> 8;
4930 if (nfactor < pspi_data->minSyncFactor )
4931 nfactor = pspi_data->minSyncFactor;
4932
4933 if (!(pspi_data->nvram[id] & MPT_NVRAM_ID_SCAN_ENABLE) ||
4934 (pspi_data->PortFlags == MPI_SCSIPORTPAGE2_PORT_FLAGS_OFF_DV) ) {
4935
4936 ddvprintk((MYIOC_s_NOTE_FMT "DV Skipped: bus, id, lun (%d, %d, %d)\n",
4937 ioc->name, bus, id, lun));
4938
4939 dv.cmd = MPT_SET_MAX;
4940 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
4941 cfg.hdr = &header1;
4942
4943 /* Save the final negotiated settings to
4944 * SCSI device page 1.
4945 */
4946 cfg.physAddr = cfg1_dma_addr;
4947 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4948 cfg.dir = 1;
4949 mpt_config(hd->ioc, &cfg);
4950 goto target_done;
4951 }
4952 }
4953 }
4954
4955 /* Finish iocmd inititialization - hidden or visible disk? */
4956 if (ioc->spi_data.pIocPg3) {
4957 /* Search IOC page 3 for matching id
4958 */
4959 Ioc3PhysDisk_t *pPDisk = ioc->spi_data.pIocPg3->PhysDisk;
4960 int numPDisk = ioc->spi_data.pIocPg3->NumPhysDisks;
4961
4962 while (numPDisk) {
4963 if (pPDisk->PhysDiskID == id) {
4964 /* match */
4965 iocmd.flags |= MPT_ICFLAG_PHYS_DISK;
4966 iocmd.physDiskNum = pPDisk->PhysDiskNum;
4967
4968 /* Quiesce the IM
4969 */
4970 if (mptscsih_do_raid(hd, MPI_RAID_ACTION_QUIESCE_PHYS_IO, &iocmd) < 0) {
4971 ddvprintk((MYIOC_s_ERR_FMT "RAID Queisce FAILED!\n", ioc->name));
4972 goto target_done;
4973 }
4974 break;
4975 }
4976 pPDisk++;
4977 numPDisk--;
4978 }
4979 }
4980
4981 /* RAID Volume ID's may double for a physical device. If RAID but
4982 * not a physical ID as well, skip DV.
4983 */
4984 if ((hd->ioc->spi_data.isRaid & (1 << id)) && !(iocmd.flags & MPT_ICFLAG_PHYS_DISK))
4985 goto target_done;
4986
4987
4988 /* Basic Test.
4989 * Async & Narrow - Inquiry
4990 * Async & Narrow - Inquiry
4991 * Maximum transfer rate - Inquiry
4992 * Compare buffers:
4993 * If compare, test complete.
4994 * If miscompare and first pass, repeat
4995 * If miscompare and not first pass, fall back and repeat
4996 */
4997 hd->pLocal = NULL;
4998 readPage0 = 0;
4999 sz = SCSI_MAX_INQUIRY_BYTES;
5000 rc = MPT_SCANDV_GOOD;
5001 while (1) {
5002 ddvprintk((MYIOC_s_NOTE_FMT "DV: Start Basic test on id=%d\n", ioc->name, id));
5003 retcode = 0;
5004 dv.cmd = MPT_SET_MIN;
5005 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5006
5007 cfg.hdr = &header1;
5008 cfg.physAddr = cfg1_dma_addr;
5009 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5010 cfg.dir = 1;
5011 if (mpt_config(hd->ioc, &cfg) != 0)
5012 goto target_done;
5013
5014 /* Wide - narrow - wide workaround case
5015 */
5016 if ((rc == MPT_SCANDV_ISSUE_SENSE) && dv.max.width) {
5017 /* Send an untagged command to reset disk Qs corrupted
5018 * when a parity error occurs on a Request Sense.
5019 */
5020 if ((hd->ioc->facts.FWVersion.Word >= 0x01000600) ||
5021 ((hd->ioc->facts.FWVersion.Word >= 0x01010000) &&
5022 (hd->ioc->facts.FWVersion.Word < 0x01010B00)) ) {
5023
5024 iocmd.cmd = REQUEST_SENSE;
5025 iocmd.data_dma = buf1_dma;
5026 iocmd.data = pbuf1;
5027 iocmd.size = 0x12;
5028 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5029 goto target_done;
5030 else {
5031 if (hd->pLocal == NULL)
5032 goto target_done;
5033 rc = hd->pLocal->completion;
5034 if ((rc == MPT_SCANDV_GOOD) || (rc == MPT_SCANDV_SENSE)) {
5035 dv.max.width = 0;
5036 doFallback = 0;
5037 } else
5038 goto target_done;
5039 }
5040 } else
5041 goto target_done;
5042 }
5043
5044 iocmd.cmd = INQUIRY;
5045 iocmd.data_dma = buf1_dma;
5046 iocmd.data = pbuf1;
5047 iocmd.size = sz;
5048 memset(pbuf1, 0x00, sz);
5049 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5050 goto target_done;
5051 else {
5052 if (hd->pLocal == NULL)
5053 goto target_done;
5054 rc = hd->pLocal->completion;
5055 if (rc == MPT_SCANDV_GOOD) {
5056 if (hd->pLocal->scsiStatus == SAM_STAT_BUSY) {
5057 if ((iocmd.flags & MPT_ICFLAG_TAGGED_CMD) == 0)
5058 retcode = 1;
5059 else
5060 retcode = 0;
5061
5062 goto target_done;
5063 }
5064 } else if (rc == MPT_SCANDV_SENSE) {
5065 ;
5066 } else {
5067 /* If first command doesn't complete
5068 * with a good status or with a check condition,
5069 * exit.
5070 */
5071 goto target_done;
5072 }
5073 }
5074
5075 /* Reset the size for disks
5076 */
5077 inq0 = (*pbuf1) & 0x1F;
5078 if ((inq0 == 0) && pTarget && !pTarget->raidVolume) {
5079 sz = 0x40;
5080 iocmd.size = sz;
5081 }
5082
5083 /* Another GEM workaround. Check peripheral device type,
5084 * if PROCESSOR, quit DV.
5085 */
5086 if (inq0 == TYPE_PROCESSOR) {
5087 mptscsih_initTarget(hd,
5088 bus,
5089 id,
5090 lun,
5091 pbuf1,
5092 sz);
5093 goto target_done;
5094 }
5095
5096 if (inq0 > 0x08)
5097 goto target_done;
5098
5099 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5100 goto target_done;
5101
5102 if (sz == 0x40) {
5103 if ((pTarget->maxWidth == 1) && (pTarget->maxOffset) && (nfactor < 0x0A)
5104 && (pTarget->minSyncFactor > 0x09)) {
5105 if ((pbuf1[56] & 0x04) == 0)
5106 ;
5107 else if ((pbuf1[56] & 0x01) == 1) {
5108 pTarget->minSyncFactor =
5109 nfactor > MPT_ULTRA320 ? nfactor : MPT_ULTRA320;
5110 } else {
5111 pTarget->minSyncFactor =
5112 nfactor > MPT_ULTRA160 ? nfactor : MPT_ULTRA160;
5113 }
5114
5115 dv.max.factor = pTarget->minSyncFactor;
5116
5117 if ((pbuf1[56] & 0x02) == 0) {
5118 pTarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
5119 hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS;
5120 ddvprintk((MYIOC_s_NOTE_FMT
5121 "DV: Start Basic noQas on id=%d due to pbuf1[56]=%x\n",
5122 ioc->name, id, pbuf1[56]));
5123 }
5124 }
5125 }
5126
5127 if (doFallback)
5128 dv.cmd = MPT_FALLBACK;
5129 else
5130 dv.cmd = MPT_SET_MAX;
5131
5132 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5133 if (mpt_config(hd->ioc, &cfg) != 0)
5134 goto target_done;
5135
5136 if ((!dv.now.width) && (!dv.now.offset))
5137 goto target_done;
5138
5139 iocmd.cmd = INQUIRY;
5140 iocmd.data_dma = buf2_dma;
5141 iocmd.data = pbuf2;
5142 iocmd.size = sz;
5143 memset(pbuf2, 0x00, sz);
5144 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5145 goto target_done;
5146 else if (hd->pLocal == NULL)
5147 goto target_done;
5148 else {
5149 /* Save the return code.
5150 * If this is the first pass,
5151 * read SCSI Device Page 0
5152 * and update the target max parameters.
5153 */
5154 rc = hd->pLocal->completion;
5155 doFallback = 0;
5156 if (rc == MPT_SCANDV_GOOD) {
5157 if (!readPage0) {
5158 u32 sdp0_info;
5159 u32 sdp0_nego;
5160
5161 cfg.hdr = &header0;
5162 cfg.physAddr = cfg0_dma_addr;
5163 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5164 cfg.dir = 0;
5165
5166 if (mpt_config(hd->ioc, &cfg) != 0)
5167 goto target_done;
5168
5169 sdp0_info = le32_to_cpu(pcfg0Data->Information) & 0x0E;
5170 sdp0_nego = (le32_to_cpu(pcfg0Data->NegotiatedParameters) & 0xFF00 ) >> 8;
5171
5172 /* Quantum and Fujitsu workarounds.
5173 * Quantum: PPR U320 -> PPR reply with Ultra2 and wide
5174 * Fujitsu: PPR U320 -> Msg Reject and Ultra2 and wide
5175 * Resetart with a request for U160.
5176 */
5177 if ((dv.now.factor == MPT_ULTRA320) && (sdp0_nego == MPT_ULTRA2)) {
5178 doFallback = 1;
5179 } else {
5180 dv.cmd = MPT_UPDATE_MAX;
5181 mptscsih_dv_parms(hd, &dv, (void *)pcfg0Data);
5182 /* Update the SCSI device page 1 area
5183 */
5184 pcfg1Data->RequestedParameters = pcfg0Data->NegotiatedParameters;
5185 readPage0 = 1;
5186 }
5187 }
5188
5189 /* Quantum workaround. Restart this test will the fallback
5190 * flag set.
5191 */
5192 if (doFallback == 0) {
5193 if (memcmp(pbuf1, pbuf2, sz) != 0) {
5194 if (!firstPass)
5195 doFallback = 1;
5196 } else {
5197 ddvprintk((MYIOC_s_NOTE_FMT
5198 "DV:Inquiry compared id=%d, calling initTarget\n", ioc->name, id));
5199 hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_NOT_DONE;
5200 mptscsih_initTarget(hd,
5201 bus,
5202 id,
5203 lun,
5204 pbuf1,
5205 sz);
5206 break; /* test complete */
5207 }
5208 }
5209
5210
5211 } else if (rc == MPT_SCANDV_ISSUE_SENSE)
5212 doFallback = 1; /* set fallback flag */
5213 else if ((rc == MPT_SCANDV_DID_RESET) ||
5214 (rc == MPT_SCANDV_SENSE) ||
5215 (rc == MPT_SCANDV_FALLBACK))
5216 doFallback = 1; /* set fallback flag */
5217 else
5218 goto target_done;
5219
5220 firstPass = 0;
5221 }
5222 }
5223 ddvprintk((MYIOC_s_NOTE_FMT "DV: Basic test on id=%d completed OK.\n", ioc->name, id));
5224
5225 if (driver_setup.dv == 0)
5226 goto target_done;
5227
5228 inq0 = (*pbuf1) & 0x1F;
5229
5230 /* Continue only for disks
5231 */
5232 if (inq0 != 0)
5233 goto target_done;
5234
5235 if ( ioc->spi_data.PortFlags == MPI_SCSIPORTPAGE2_PORT_FLAGS_BASIC_DV_ONLY )
5236 goto target_done;
5237
5238 /* Start the Enhanced Test.
5239 * 0) issue TUR to clear out check conditions
5240 * 1) read capacity of echo (regular) buffer
5241 * 2) reserve device
5242 * 3) do write-read-compare data pattern test
5243 * 4) release
5244 * 5) update nego parms to target struct
5245 */
5246 cfg.hdr = &header1;
5247 cfg.physAddr = cfg1_dma_addr;
5248 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5249 cfg.dir = 1;
5250
5251 iocmd.cmd = TEST_UNIT_READY;
5252 iocmd.data_dma = -1;
5253 iocmd.data = NULL;
5254 iocmd.size = 0;
5255 notDone = 1;
5256 while (notDone) {
5257 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5258 goto target_done;
5259
5260 if (hd->pLocal == NULL)
5261 goto target_done;
5262
5263 rc = hd->pLocal->completion;
5264 if (rc == MPT_SCANDV_GOOD)
5265 notDone = 0;
5266 else if (rc == MPT_SCANDV_SENSE) {
5267 u8 skey = hd->pLocal->sense[2] & 0x0F;
5268 u8 asc = hd->pLocal->sense[12];
5269 u8 ascq = hd->pLocal->sense[13];
5270 ddvprintk((MYIOC_s_INFO_FMT
5271 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
5272 ioc->name, skey, asc, ascq));
5273
5274 if (skey == UNIT_ATTENTION)
5275 notDone++; /* repeat */
5276 else if ((skey == NOT_READY) &&
5277 (asc == 0x04)&&(ascq == 0x01)) {
5278 /* wait then repeat */
5279 mdelay (2000);
5280 notDone++;
5281 } else if ((skey == NOT_READY) && (asc == 0x3A)) {
5282 /* no medium, try read test anyway */
5283 notDone = 0;
5284 } else {
5285 /* All other errors are fatal.
5286 */
5287 ddvprintk((MYIOC_s_INFO_FMT "DV: fatal error.",
5288 ioc->name));
5289 goto target_done;
5290 }
5291 } else
5292 goto target_done;
5293 }
5294
5295 iocmd.cmd = READ_BUFFER;
5296 iocmd.data_dma = buf1_dma;
5297 iocmd.data = pbuf1;
5298 iocmd.size = 4;
5299 iocmd.flags |= MPT_ICFLAG_BUF_CAP;
5300
5301 dataBufSize = 0;
5302 echoBufSize = 0;
5303 for (patt = 0; patt < 2; patt++) {
5304 if (patt == 0)
5305 iocmd.flags |= MPT_ICFLAG_ECHO;
5306 else
5307 iocmd.flags &= ~MPT_ICFLAG_ECHO;
5308
5309 notDone = 1;
5310 while (notDone) {
5311 bufsize = 0;
5312
5313 /* If not ready after 8 trials,
5314 * give up on this device.
5315 */
5316 if (notDone > 8)
5317 goto target_done;
5318
5319 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5320 goto target_done;
5321 else if (hd->pLocal == NULL)
5322 goto target_done;
5323 else {
5324 rc = hd->pLocal->completion;
5325 ddvprintk(("ReadBuffer Comp Code %d", rc));
5326 ddvprintk((" buff: %0x %0x %0x %0x\n",
5327 pbuf1[0], pbuf1[1], pbuf1[2], pbuf1[3]));
5328
5329 if (rc == MPT_SCANDV_GOOD) {
5330 notDone = 0;
5331 if (iocmd.flags & MPT_ICFLAG_ECHO) {
5332 bufsize = ((pbuf1[2] & 0x1F) <<8) | pbuf1[3];
5333 } else {
5334 bufsize = pbuf1[1]<<16 | pbuf1[2]<<8 | pbuf1[3];
5335 }
5336 } else if (rc == MPT_SCANDV_SENSE) {
5337 u8 skey = hd->pLocal->sense[2] & 0x0F;
5338 u8 asc = hd->pLocal->sense[12];
5339 u8 ascq = hd->pLocal->sense[13];
5340 ddvprintk((MYIOC_s_INFO_FMT
5341 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
5342 ioc->name, skey, asc, ascq));
5343 if (skey == ILLEGAL_REQUEST) {
5344 notDone = 0;
5345 } else if (skey == UNIT_ATTENTION) {
5346 notDone++; /* repeat */
5347 } else if ((skey == NOT_READY) &&
5348 (asc == 0x04)&&(ascq == 0x01)) {
5349 /* wait then repeat */
5350 mdelay (2000);
5351 notDone++;
5352 } else {
5353 /* All other errors are fatal.
5354 */
5355 ddvprintk((MYIOC_s_INFO_FMT "DV: fatal error.",
5356 ioc->name));
5357 goto target_done;
5358 }
5359 } else {
5360 /* All other errors are fatal
5361 */
5362 goto target_done;
5363 }
5364 }
5365 }
5366
5367 if (iocmd.flags & MPT_ICFLAG_ECHO)
5368 echoBufSize = bufsize;
5369 else
5370 dataBufSize = bufsize;
5371 }
5372 sz = 0;
5373 iocmd.flags &= ~MPT_ICFLAG_BUF_CAP;
5374
5375 /* Use echo buffers if possible,
5376 * Exit if both buffers are 0.
5377 */
5378 if (echoBufSize > 0) {
5379 iocmd.flags |= MPT_ICFLAG_ECHO;
5380 if (dataBufSize > 0)
5381 bufsize = min(echoBufSize, dataBufSize);
5382 else
5383 bufsize = echoBufSize;
5384 } else if (dataBufSize == 0)
5385 goto target_done;
5386
5387 ddvprintk((MYIOC_s_INFO_FMT "%s Buffer Capacity %d\n", ioc->name,
5388 (iocmd.flags & MPT_ICFLAG_ECHO) ? "Echo" : " ", bufsize));
5389
5390 /* Data buffers for write-read-compare test max 1K.
5391 */
5392 sz = min(bufsize, 1024);
5393
5394 /* --- loop ----
5395 * On first pass, always issue a reserve.
5396 * On additional loops, only if a reset has occurred.
5397 * iocmd.flags indicates if echo or regular buffer
5398 */
5399 for (patt = 0; patt < 4; patt++) {
5400 ddvprintk(("Pattern %d\n", patt));
5401 if ((iocmd.flags & MPT_ICFLAG_RESERVED) && (iocmd.flags & MPT_ICFLAG_DID_RESET)) {
5402 iocmd.cmd = TEST_UNIT_READY;
5403 iocmd.data_dma = -1;
5404 iocmd.data = NULL;
5405 iocmd.size = 0;
5406 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5407 goto target_done;
5408
5409 iocmd.cmd = RELEASE;
5410 iocmd.data_dma = -1;
5411 iocmd.data = NULL;
5412 iocmd.size = 0;
5413 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5414 goto target_done;
5415 else if (hd->pLocal == NULL)
5416 goto target_done;
5417 else {
5418 rc = hd->pLocal->completion;
5419 ddvprintk(("Release rc %d\n", rc));
5420 if (rc == MPT_SCANDV_GOOD)
5421 iocmd.flags &= ~MPT_ICFLAG_RESERVED;
5422 else
5423 goto target_done;
5424 }
5425 iocmd.flags &= ~MPT_ICFLAG_RESERVED;
5426 }
5427 iocmd.flags &= ~MPT_ICFLAG_DID_RESET;
5428
5429 repeat = 5;
5430 while (repeat && (!(iocmd.flags & MPT_ICFLAG_RESERVED))) {
5431 iocmd.cmd = RESERVE;
5432 iocmd.data_dma = -1;
5433 iocmd.data = NULL;
5434 iocmd.size = 0;
5435 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5436 goto target_done;
5437 else if (hd->pLocal == NULL)
5438 goto target_done;
5439 else {
5440 rc = hd->pLocal->completion;
5441 if (rc == MPT_SCANDV_GOOD) {
5442 iocmd.flags |= MPT_ICFLAG_RESERVED;
5443 } else if (rc == MPT_SCANDV_SENSE) {
5444 /* Wait if coming ready
5445 */
5446 u8 skey = hd->pLocal->sense[2] & 0x0F;
5447 u8 asc = hd->pLocal->sense[12];
5448 u8 ascq = hd->pLocal->sense[13];
5449 ddvprintk((MYIOC_s_INFO_FMT
5450 "DV: Reserve Failed: ", ioc->name));
5451 ddvprintk(("SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
5452 skey, asc, ascq));
5453
5454 if ((skey == NOT_READY) && (asc == 0x04)&&
5455 (ascq == 0x01)) {
5456 /* wait then repeat */
5457 mdelay (2000);
5458 notDone++;
5459 } else {
5460 ddvprintk((MYIOC_s_INFO_FMT
5461 "DV: Reserved Failed.", ioc->name));
5462 goto target_done;
5463 }
5464 } else {
5465 ddvprintk((MYIOC_s_INFO_FMT "DV: Reserved Failed.",
5466 ioc->name));
5467 goto target_done;
5468 }
5469 }
5470 }
5471
5472 mptscsih_fillbuf(pbuf1, sz, patt, 1);
5473 iocmd.cmd = WRITE_BUFFER;
5474 iocmd.data_dma = buf1_dma;
5475 iocmd.data = pbuf1;
5476 iocmd.size = sz;
5477 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5478 goto target_done;
5479 else if (hd->pLocal == NULL)
5480 goto target_done;
5481 else {
5482 rc = hd->pLocal->completion;
5483 if (rc == MPT_SCANDV_GOOD)
5484 ; /* Issue read buffer */
5485 else if (rc == MPT_SCANDV_DID_RESET) {
5486 /* If using echo buffers, reset to data buffers.
5487 * Else do Fallback and restart
5488 * this test (re-issue reserve
5489 * because of bus reset).
5490 */
5491 if ((iocmd.flags & MPT_ICFLAG_ECHO) && (dataBufSize >= bufsize)) {
5492 iocmd.flags &= ~MPT_ICFLAG_ECHO;
5493 } else {
5494 dv.cmd = MPT_FALLBACK;
5495 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5496
5497 if (mpt_config(hd->ioc, &cfg) != 0)
5498 goto target_done;
5499
5500 if ((!dv.now.width) && (!dv.now.offset))
5501 goto target_done;
5502 }
5503
5504 iocmd.flags |= MPT_ICFLAG_DID_RESET;
5505 patt = -1;
5506 continue;
5507 } else if (rc == MPT_SCANDV_SENSE) {
5508 /* Restart data test if UA, else quit.
5509 */
5510 u8 skey = hd->pLocal->sense[2] & 0x0F;
5511 ddvprintk((MYIOC_s_INFO_FMT
5512 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n", ioc->name, skey,
5513 hd->pLocal->sense[12], hd->pLocal->sense[13]));
5514 if (skey == UNIT_ATTENTION) {
5515 patt = -1;
5516 continue;
5517 } else if (skey == ILLEGAL_REQUEST) {
5518 if (iocmd.flags & MPT_ICFLAG_ECHO) {
5519 if (dataBufSize >= bufsize) {
5520 iocmd.flags &= ~MPT_ICFLAG_ECHO;
5521 patt = -1;
5522 continue;
5523 }
5524 }
5525 goto target_done;
5526 }
5527 else
5528 goto target_done;
5529 } else {
5530 /* fatal error */
5531 goto target_done;
5532 }
5533 }
5534
5535 iocmd.cmd = READ_BUFFER;
5536 iocmd.data_dma = buf2_dma;
5537 iocmd.data = pbuf2;
5538 iocmd.size = sz;
5539 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5540 goto target_done;
5541 else if (hd->pLocal == NULL)
5542 goto target_done;
5543 else {
5544 rc = hd->pLocal->completion;
5545 if (rc == MPT_SCANDV_GOOD) {
5546 /* If buffers compare,
5547 * go to next pattern,
5548 * else, do a fallback and restart
5549 * data transfer test.
5550 */
5551 if (memcmp (pbuf1, pbuf2, sz) == 0) {
5552 ; /* goto next pattern */
5553 } else {
5554 /* Miscompare with Echo buffer, go to data buffer,
5555 * if that buffer exists.
5556 * Miscompare with Data buffer, check first 4 bytes,
5557 * some devices return capacity. Exit in this case.
5558 */
5559 if (iocmd.flags & MPT_ICFLAG_ECHO) {
5560 if (dataBufSize >= bufsize)
5561 iocmd.flags &= ~MPT_ICFLAG_ECHO;
5562 else
5563 goto target_done;
5564 } else {
5565 if (dataBufSize == (pbuf2[1]<<16 | pbuf2[2]<<8 | pbuf2[3])) {
5566 /* Argh. Device returning wrong data.
5567 * Quit DV for this device.
5568 */
5569 goto target_done;
5570 }
5571
5572 /* Had an actual miscompare. Slow down.*/
5573 dv.cmd = MPT_FALLBACK;
5574 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5575
5576 if (mpt_config(hd->ioc, &cfg) != 0)
5577 goto target_done;
5578
5579 if ((!dv.now.width) && (!dv.now.offset))
5580 goto target_done;
5581 }
5582
5583 patt = -1;
5584 continue;
5585 }
5586 } else if (rc == MPT_SCANDV_DID_RESET) {
5587 /* Do Fallback and restart
5588 * this test (re-issue reserve
5589 * because of bus reset).
5590 */
5591 dv.cmd = MPT_FALLBACK;
5592 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5593
5594 if (mpt_config(hd->ioc, &cfg) != 0)
5595 goto target_done;
5596
5597 if ((!dv.now.width) && (!dv.now.offset))
5598 goto target_done;
5599
5600 iocmd.flags |= MPT_ICFLAG_DID_RESET;
5601 patt = -1;
5602 continue;
5603 } else if (rc == MPT_SCANDV_SENSE) {
5604 /* Restart data test if UA, else quit.
5605 */
5606 u8 skey = hd->pLocal->sense[2] & 0x0F;
5607 ddvprintk((MYIOC_s_INFO_FMT
5608 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n", ioc->name, skey,
5609 hd->pLocal->sense[12], hd->pLocal->sense[13]));
5610 if (skey == UNIT_ATTENTION) {
5611 patt = -1;
5612 continue;
5613 }
5614 else
5615 goto target_done;
5616 } else {
5617 /* fatal error */
5618 goto target_done;
5619 }
5620 }
5621
5622 } /* --- end of patt loop ---- */
5623
5624 target_done:
5625 if (iocmd.flags & MPT_ICFLAG_RESERVED) {
5626 iocmd.cmd = RELEASE;
5627 iocmd.data_dma = -1;
5628 iocmd.data = NULL;
5629 iocmd.size = 0;
5630 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5631 printk(MYIOC_s_INFO_FMT "DV: Release failed. id %d",
5632 ioc->name, id);
5633 else if (hd->pLocal) {
5634 if (hd->pLocal->completion == MPT_SCANDV_GOOD)
5635 iocmd.flags &= ~MPT_ICFLAG_RESERVED;
5636 } else {
5637 printk(MYIOC_s_INFO_FMT "DV: Release failed. id %d",
5638 ioc->name, id);
5639 }
5640 }
5641
5642
5643 /* Set if cfg1_dma_addr contents is valid
5644 */
5645 if ((cfg.hdr != NULL) && (retcode == 0)){
5646 /* If disk, not U320, disable QAS
5647 */
5648 if ((inq0 == 0) && (dv.now.factor > MPT_ULTRA320)) {
5649 hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS;
5650 ddvprintk((MYIOC_s_NOTE_FMT
5651 "noQas set due to id=%d has factor=%x\n", ioc->name, id, dv.now.factor));
5652 }
5653
5654 dv.cmd = MPT_SAVE;
5655 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5656
5657 /* Double writes to SDP1 can cause problems,
5658 * skip save of the final negotiated settings to
5659 * SCSI device page 1.
5660 *
5661 cfg.hdr = &header1;
5662 cfg.physAddr = cfg1_dma_addr;
5663 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5664 cfg.dir = 1;
5665 mpt_config(hd->ioc, &cfg);
5666 */
5667 }
5668
5669 /* If this is a RAID Passthrough, enable internal IOs
5670 */
5671 if (iocmd.flags & MPT_ICFLAG_PHYS_DISK) {
5672 if (mptscsih_do_raid(hd, MPI_RAID_ACTION_ENABLE_PHYS_IO, &iocmd) < 0)
5673 ddvprintk((MYIOC_s_ERR_FMT "RAID Enable FAILED!\n", ioc->name));
5674 }
5675
5676 /* Done with the DV scan of the current target
5677 */
5678 if (pDvBuf)
5679 pci_free_consistent(ioc->pcidev, dv_alloc, pDvBuf, dvbuf_dma);
5680
5681 ddvtprintk((MYIOC_s_INFO_FMT "DV Done id=%d\n",
5682 ioc->name, id));
5683
5684 return retcode;
5685 }
5686
5687 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5688 /* mptscsih_dv_parms - perform a variety of operations on the
5689 * parameters used for negotiation.
5690 * @hd: Pointer to a SCSI host.
5691 * @dv: Pointer to a structure that contains the maximum and current
5692 * negotiated parameters.
5693 */
5694 static void
5695 mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
5696 {
5697 VirtDevice *pTarget;
5698 SCSIDevicePage0_t *pPage0;
5699 SCSIDevicePage1_t *pPage1;
5700 int val = 0, data, configuration;
5701 u8 width = 0;
5702 u8 offset = 0;
5703 u8 factor = 0;
5704 u8 negoFlags = 0;
5705 u8 cmd = dv->cmd;
5706 u8 id = dv->id;
5707
5708 switch (cmd) {
5709 case MPT_GET_NVRAM_VALS:
5710 ddvprintk((MYIOC_s_NOTE_FMT "Getting NVRAM: ",
5711 hd->ioc->name));
5712 /* Get the NVRAM values and save in tmax
5713 * If not an LVD bus, the adapter minSyncFactor has been
5714 * already throttled back.
5715 */
5716 if ((hd->Targets)&&((pTarget = hd->Targets[(int)id]) != NULL) && !pTarget->raidVolume) {
5717 width = pTarget->maxWidth;
5718 offset = pTarget->maxOffset;
5719 factor = pTarget->minSyncFactor;
5720 negoFlags = pTarget->negoFlags;
5721 } else {
5722 if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
5723 data = hd->ioc->spi_data.nvram[id];
5724 width = data & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
5725 if ((offset = hd->ioc->spi_data.maxSyncOffset) == 0)
5726 factor = MPT_ASYNC;
5727 else {
5728 factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT;
5729 if ((factor == 0) || (factor == MPT_ASYNC)){
5730 factor = MPT_ASYNC;
5731 offset = 0;
5732 }
5733 }
5734 } else {
5735 width = MPT_NARROW;
5736 offset = 0;
5737 factor = MPT_ASYNC;
5738 }
5739
5740 /* Set the negotiation flags */
5741 negoFlags = hd->ioc->spi_data.noQas;
5742 if (!width)
5743 negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
5744
5745 if (!offset)
5746 negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
5747 }
5748
5749 /* limit by adapter capabilities */
5750 width = min(width, hd->ioc->spi_data.maxBusWidth);
5751 offset = min(offset, hd->ioc->spi_data.maxSyncOffset);
5752 factor = max(factor, hd->ioc->spi_data.minSyncFactor);
5753
5754 /* Check Consistency */
5755 if (offset && (factor < MPT_ULTRA2) && !width)
5756 factor = MPT_ULTRA2;
5757
5758 dv->max.width = width;
5759 dv->max.offset = offset;
5760 dv->max.factor = factor;
5761 dv->max.flags = negoFlags;
5762 ddvprintk((" id=%d width=%d factor=%x offset=%x flags=%x\n",
5763 id, width, factor, offset, negoFlags));
5764 break;
5765
5766 case MPT_UPDATE_MAX:
5767 ddvprintk((MYIOC_s_NOTE_FMT
5768 "Updating with SDP0 Data: ", hd->ioc->name));
5769 /* Update tmax values with those from Device Page 0.*/
5770 pPage0 = (SCSIDevicePage0_t *) pPage;
5771 if (pPage0) {
5772 val = cpu_to_le32(pPage0->NegotiatedParameters);
5773 dv->max.width = val & MPI_SCSIDEVPAGE0_NP_WIDE ? 1 : 0;
5774 dv->max.offset = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK) >> 16;
5775 dv->max.factor = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK) >> 8;
5776 }
5777
5778 dv->now.width = dv->max.width;
5779 dv->now.offset = dv->max.offset;
5780 dv->now.factor = dv->max.factor;
5781 ddvprintk(("id=%d width=%d factor=%x offset=%x flags=%x\n",
5782 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags));
5783 break;
5784
5785 case MPT_SET_MAX:
5786 ddvprintk((MYIOC_s_NOTE_FMT "Setting Max: ",
5787 hd->ioc->name));
5788 /* Set current to the max values. Update the config page.*/
5789 dv->now.width = dv->max.width;
5790 dv->now.offset = dv->max.offset;
5791 dv->now.factor = dv->max.factor;
5792 dv->now.flags = dv->max.flags;
5793
5794 pPage1 = (SCSIDevicePage1_t *)pPage;
5795 if (pPage1) {
5796 mptscsih_setDevicePage1Flags (dv->now.width, dv->now.factor,
5797 dv->now.offset, &val, &configuration, dv->now.flags);
5798 dnegoprintk(("Setting Max: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
5799 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags, val, configuration));
5800 pPage1->RequestedParameters = le32_to_cpu(val);
5801 pPage1->Reserved = 0;
5802 pPage1->Configuration = le32_to_cpu(configuration);
5803 }
5804
5805 ddvprintk(("id=%d width=%d factor=%x offset=%x flags=%x request=%x configuration=%x\n",
5806 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags, val, configuration));
5807 break;
5808
5809 case MPT_SET_MIN:
5810 ddvprintk((MYIOC_s_NOTE_FMT "Setting Min: ",
5811 hd->ioc->name));
5812 /* Set page to asynchronous and narrow
5813 * Do not update now, breaks fallback routine. */
5814 width = MPT_NARROW;
5815 offset = 0;
5816 factor = MPT_ASYNC;
5817 negoFlags = dv->max.flags;
5818
5819 pPage1 = (SCSIDevicePage1_t *)pPage;
5820 if (pPage1) {
5821 mptscsih_setDevicePage1Flags (width, factor,
5822 offset, &val, &configuration, negoFlags);
5823 dnegoprintk(("Setting Min: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
5824 id, width, factor, offset, negoFlags, val, configuration));
5825 pPage1->RequestedParameters = le32_to_cpu(val);
5826 pPage1->Reserved = 0;
5827 pPage1->Configuration = le32_to_cpu(configuration);
5828 }
5829 ddvprintk(("id=%d width=%d factor=%x offset=%x request=%x config=%x negoFlags=%x\n",
5830 id, width, factor, offset, val, configuration, negoFlags));
5831 break;
5832
5833 case MPT_FALLBACK:
5834 ddvprintk((MYIOC_s_NOTE_FMT
5835 "Fallback: Start: offset %d, factor %x, width %d \n",
5836 hd->ioc->name, dv->now.offset,
5837 dv->now.factor, dv->now.width));
5838 width = dv->now.width;
5839 offset = dv->now.offset;
5840 factor = dv->now.factor;
5841 if ((offset) && (dv->max.width)) {
5842 if (factor < MPT_ULTRA160)
5843 factor = MPT_ULTRA160;
5844 else if (factor < MPT_ULTRA2) {
5845 factor = MPT_ULTRA2;
5846 width = MPT_WIDE;
5847 } else if ((factor == MPT_ULTRA2) && width) {
5848 factor = MPT_ULTRA2;
5849 width = MPT_NARROW;
5850 } else if (factor < MPT_ULTRA) {
5851 factor = MPT_ULTRA;
5852 width = MPT_WIDE;
5853 } else if ((factor == MPT_ULTRA) && width) {
5854 width = MPT_NARROW;
5855 } else if (factor < MPT_FAST) {
5856 factor = MPT_FAST;
5857 width = MPT_WIDE;
5858 } else if ((factor == MPT_FAST) && width) {
5859 factor = MPT_FAST;
5860 width = MPT_NARROW;
5861 } else if (factor < MPT_SCSI) {
5862 factor = MPT_SCSI;
5863 width = MPT_WIDE;
5864 } else if ((factor == MPT_SCSI) && width) {
5865 factor = MPT_SCSI;
5866 width = MPT_NARROW;
5867 } else {
5868 factor = MPT_ASYNC;
5869 offset = 0;
5870 }
5871
5872 } else if (offset) {
5873 width = MPT_NARROW;
5874 if (factor < MPT_ULTRA)
5875 factor = MPT_ULTRA;
5876 else if (factor < MPT_FAST)
5877 factor = MPT_FAST;
5878 else if (factor < MPT_SCSI)
5879 factor = MPT_SCSI;
5880 else {
5881 factor = MPT_ASYNC;
5882 offset = 0;
5883 }
5884
5885 } else {
5886 width = MPT_NARROW;
5887 factor = MPT_ASYNC;
5888 }
5889 dv->max.flags |= MPT_TARGET_NO_NEGO_QAS;
5890 dv->max.flags &= ~MPT_TAPE_NEGO_IDP;
5891
5892 dv->now.width = width;
5893 dv->now.offset = offset;
5894 dv->now.factor = factor;
5895 dv->now.flags = dv->max.flags;
5896
5897 pPage1 = (SCSIDevicePage1_t *)pPage;
5898 if (pPage1) {
5899 mptscsih_setDevicePage1Flags (width, factor, offset, &val,
5900 &configuration, dv->now.flags);
5901 dnegoprintk(("Finish: id=%d width=%d offset=%d factor=%x flags=%x request=%x config=%x\n",
5902 id, width, offset, factor, dv->now.flags, val, configuration));
5903
5904 pPage1->RequestedParameters = le32_to_cpu(val);
5905 pPage1->Reserved = 0;
5906 pPage1->Configuration = le32_to_cpu(configuration);
5907 }
5908
5909 ddvprintk(("Finish: id=%d offset=%d factor=%x width=%d request=%x config=%x\n",
5910 id, dv->now.offset, dv->now.factor, dv->now.width, val, configuration));
5911 break;
5912
5913 case MPT_SAVE:
5914 ddvprintk((MYIOC_s_NOTE_FMT
5915 "Saving to Target structure: ", hd->ioc->name));
5916 ddvprintk(("id=%d width=%x factor=%x offset=%d flags=%x\n",
5917 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags));
5918
5919 /* Save these values to target structures
5920 * or overwrite nvram (phys disks only).
5921 */
5922
5923 if ((hd->Targets)&&((pTarget = hd->Targets[(int)id]) != NULL) && !pTarget->raidVolume ) {
5924 pTarget->maxWidth = dv->now.width;
5925 pTarget->maxOffset = dv->now.offset;
5926 pTarget->minSyncFactor = dv->now.factor;
5927 pTarget->negoFlags = dv->now.flags;
5928 } else {
5929 /* Preserv all flags, use
5930 * read-modify-write algorithm
5931 */
5932 if (hd->ioc->spi_data.nvram) {
5933 data = hd->ioc->spi_data.nvram[id];
5934
5935 if (dv->now.width)
5936 data &= ~MPT_NVRAM_WIDE_DISABLE;
5937 else
5938 data |= MPT_NVRAM_WIDE_DISABLE;
5939
5940 if (!dv->now.offset)
5941 factor = MPT_ASYNC;
5942
5943 data &= ~MPT_NVRAM_SYNC_MASK;
5944 data |= (dv->now.factor << MPT_NVRAM_SYNC_SHIFT) & MPT_NVRAM_SYNC_MASK;
5945
5946 hd->ioc->spi_data.nvram[id] = data;
5947 }
5948 }
5949 break;
5950 }
5951 }
5952
5953 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5954 /* mptscsih_fillbuf - fill a buffer with a special data pattern
5955 * cleanup. For bus scan only.
5956 *
5957 * @buffer: Pointer to data buffer to be filled.
5958 * @size: Number of bytes to fill
5959 * @index: Pattern index
5960 * @width: bus width, 0 (8 bits) or 1 (16 bits)
5961 */
5962 static void
5963 mptscsih_fillbuf(char *buffer, int size, int index, int width)
5964 {
5965 char *ptr = buffer;
5966 int ii;
5967 char byte;
5968 short val;
5969
5970 switch (index) {
5971 case 0:
5972
5973 if (width) {
5974 /* Pattern: 0000 FFFF 0000 FFFF
5975 */
5976 for (ii=0; ii < size; ii++, ptr++) {
5977 if (ii & 0x02)
5978 *ptr = 0xFF;
5979 else
5980 *ptr = 0x00;
5981 }
5982 } else {
5983 /* Pattern: 00 FF 00 FF
5984 */
5985 for (ii=0; ii < size; ii++, ptr++) {
5986 if (ii & 0x01)
5987 *ptr = 0xFF;
5988 else
5989 *ptr = 0x00;
5990 }
5991 }
5992 break;
5993
5994 case 1:
5995 if (width) {
5996 /* Pattern: 5555 AAAA 5555 AAAA 5555
5997 */
5998 for (ii=0; ii < size; ii++, ptr++) {
5999 if (ii & 0x02)
6000 *ptr = 0xAA;
6001 else
6002 *ptr = 0x55;
6003 }
6004 } else {
6005 /* Pattern: 55 AA 55 AA 55
6006 */
6007 for (ii=0; ii < size; ii++, ptr++) {
6008 if (ii & 0x01)
6009 *ptr = 0xAA;
6010 else
6011 *ptr = 0x55;
6012 }
6013 }
6014 break;
6015
6016 case 2:
6017 /* Pattern: 00 01 02 03 04 05
6018 * ... FE FF 00 01..
6019 */
6020 for (ii=0; ii < size; ii++, ptr++)
6021 *ptr = (char) ii;
6022 break;
6023
6024 case 3:
6025 if (width) {
6026 /* Wide Pattern: FFFE 0001 FFFD 0002
6027 * ... 4000 DFFF 8000 EFFF
6028 */
6029 byte = 0;
6030 for (ii=0; ii < size/2; ii++) {
6031 /* Create the base pattern
6032 */
6033 val = (1 << byte);
6034 /* every 64 (0x40) bytes flip the pattern
6035 * since we fill 2 bytes / iteration,
6036 * test for ii = 0x20
6037 */
6038 if (ii & 0x20)
6039 val = ~(val);
6040
6041 if (ii & 0x01) {
6042 *ptr = (char)( (val & 0xFF00) >> 8);
6043 ptr++;
6044 *ptr = (char)(val & 0xFF);
6045 byte++;
6046 byte &= 0x0F;
6047 } else {
6048 val = ~val;
6049 *ptr = (char)( (val & 0xFF00) >> 8);
6050 ptr++;
6051 *ptr = (char)(val & 0xFF);
6052 }
6053
6054 ptr++;
6055 }
6056 } else {
6057 /* Narrow Pattern: FE 01 FD 02 FB 04
6058 * .. 7F 80 01 FE 02 FD ... 80 7F
6059 */
6060 byte = 0;
6061 for (ii=0; ii < size; ii++, ptr++) {
6062 /* Base pattern - first 32 bytes
6063 */
6064 if (ii & 0x01) {
6065 *ptr = (1 << byte);
6066 byte++;
6067 byte &= 0x07;
6068 } else {
6069 *ptr = (char) (~(1 << byte));
6070 }
6071
6072 /* Flip the pattern every 32 bytes
6073 */
6074 if (ii & 0x20)
6075 *ptr = ~(*ptr);
6076 }
6077 }
6078 break;
6079 }
6080 }
6081 #endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */
6082
6083 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6084
6085 module_init(mptscsih_init);
6086 module_exit(mptscsih_exit);
6087
|
This page was automatically generated by the
LXR engine.
|