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