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