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