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