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