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