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