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