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