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