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