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