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