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