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