OSDN Git Service

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