[PATCH] message: fix-up schedule_timeout() usage
[linux-2.6.git] / drivers / message / fusion / mptscsih.c
1 /*
2  *  linux/drivers/message/fusion/mptscsih.c
3  *      For use with LSI Logic PCI chip/adapter(s)
4  *      running LSI Logic Fusion MPT (Message Passing Technology) firmware.
5  *
6  *  Copyright (c) 1999-2005 LSI Logic Corporation
7  *  (mailto:mpt_linux_developer@lsil.com)
8  *
9  */
10 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
11 /*
12     This program is free software; you can redistribute it and/or modify
13     it under the terms of the GNU General Public License as published by
14     the Free Software Foundation; version 2 of the License.
15
16     This program is distributed in the hope that it will be useful,
17     but WITHOUT ANY WARRANTY; without even the implied warranty of
18     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19     GNU General Public License for more details.
20
21     NO WARRANTY
22     THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
23     CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
24     LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
25     MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
26     solely responsible for determining the appropriateness of using and
27     distributing the Program and assumes all risks associated with its
28     exercise of rights under this Agreement, including but not limited to
29     the risks and costs of program errors, damage to or loss of data,
30     programs or equipment, and unavailability or interruption of operations.
31
32     DISCLAIMER OF LIABILITY
33     NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
34     DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
35     DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
36     ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
37     TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
38     USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
39     HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
40
41     You should have received a copy of the GNU General Public License
42     along with this program; if not, write to the Free Software
43     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
44 */
45 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
46
47 #include "linux_compat.h"       /* linux-2.6 tweaks */
48 #include <linux/module.h>
49 #include <linux/kernel.h>
50 #include <linux/init.h>
51 #include <linux/errno.h>
52 #include <linux/kdev_t.h>
53 #include <linux/blkdev.h>
54 #include <linux/delay.h>        /* for mdelay */
55 #include <linux/interrupt.h>    /* needed for in_interrupt() proto */
56 #include <linux/reboot.h>       /* notifier code */
57 #include <linux/sched.h>
58 #include <linux/workqueue.h>
59
60 #include <scsi/scsi.h>
61 #include <scsi/scsi_cmnd.h>
62 #include <scsi/scsi_device.h>
63 #include <scsi/scsi_host.h>
64 #include <scsi/scsi_tcq.h>
65 #include <scsi/scsi_dbg.h>
66
67 #include "mptbase.h"
68 #include "mptscsih.h"
69
70 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
71 #define my_NAME         "Fusion MPT SCSI Host driver"
72 #define my_VERSION      MPT_LINUX_VERSION_COMMON
73 #define MYNAM           "mptscsih"
74
75 MODULE_AUTHOR(MODULEAUTHOR);
76 MODULE_DESCRIPTION(my_NAME);
77 MODULE_LICENSE("GPL");
78
79 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
80
81 typedef struct _BIG_SENSE_BUF {
82         u8              data[MPT_SENSE_BUFFER_ALLOC];
83 } BIG_SENSE_BUF;
84
85 #define MPT_SCANDV_GOOD                 (0x00000000) /* must be 0 */
86 #define MPT_SCANDV_DID_RESET            (0x00000001)
87 #define MPT_SCANDV_SENSE                (0x00000002)
88 #define MPT_SCANDV_SOME_ERROR           (0x00000004)
89 #define MPT_SCANDV_SELECTION_TIMEOUT    (0x00000008)
90 #define MPT_SCANDV_ISSUE_SENSE          (0x00000010)
91 #define MPT_SCANDV_FALLBACK             (0x00000020)
92
93 #define MPT_SCANDV_MAX_RETRIES          (10)
94
95 #define MPT_ICFLAG_BUF_CAP      0x01    /* ReadBuffer Read Capacity format */
96 #define MPT_ICFLAG_ECHO         0x02    /* ReadBuffer Echo buffer format */
97 #define MPT_ICFLAG_EBOS         0x04    /* ReadBuffer Echo buffer has EBOS */
98 #define MPT_ICFLAG_PHYS_DISK    0x08    /* Any SCSI IO but do Phys Disk Format */
99 #define MPT_ICFLAG_TAGGED_CMD   0x10    /* Do tagged IO */
100 #define MPT_ICFLAG_DID_RESET    0x20    /* Bus Reset occurred with this command */
101 #define MPT_ICFLAG_RESERVED     0x40    /* Reserved has been issued */
102
103 typedef struct _internal_cmd {
104         char            *data;          /* data pointer */
105         dma_addr_t      data_dma;       /* data dma address */
106         int             size;           /* transfer size */
107         u8              cmd;            /* SCSI Op Code */
108         u8              bus;            /* bus number */
109         u8              id;             /* SCSI ID (virtual) */
110         u8              lun;
111         u8              flags;          /* Bit Field - See above */
112         u8              physDiskNum;    /* Phys disk number, -1 else */
113         u8              rsvd2;
114         u8              rsvd;
115 } INTERNAL_CMD;
116
117 typedef struct _negoparms {
118         u8 width;
119         u8 offset;
120         u8 factor;
121         u8 flags;
122 } NEGOPARMS;
123
124 typedef struct _dv_parameters {
125         NEGOPARMS        max;
126         NEGOPARMS        now;
127         u8               cmd;
128         u8               id;
129         u16              pad1;
130 } DVPARAMETERS;
131
132 /*
133  *  Other private/forward protos...
134  */
135 int             mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
136 static void     mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq);
137 int             mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
138
139 static int      mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
140                                  SCSIIORequest_t *pReq, int req_idx);
141 static void     mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx);
142 static void     mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply);
143 static int      mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd);
144 static int      mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout );
145 static u32      SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc);
146
147 static int      mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout);
148 static int      mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout);
149
150 int             mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
151 int             mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
152
153 static void     mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *data, int dlen);
154 static void     mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56);
155 static void     mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq);
156 static void     mptscsih_setDevicePage1Flags (u8 width, u8 factor, u8 offset, int *requestedPtr, int *configurationPtr, u8 flags);
157 static void     mptscsih_no_negotiate(MPT_SCSI_HOST *hd, int target_id);
158 static int      mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target, int flags);
159 static int      mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus);
160 int             mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
161 static int      mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
162 static int      mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum);
163
164 static struct work_struct   mptscsih_persistTask;
165
166 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
167 static int      mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io);
168 static void     mptscsih_domainValidation(void *hd);
169 static int      mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id);
170 static void     mptscsih_qas_check(MPT_SCSI_HOST *hd, int id);
171 static int      mptscsih_doDv(MPT_SCSI_HOST *hd, int channel, int target);
172 static void     mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage);
173 static void     mptscsih_fillbuf(char *buffer, int size, int index, int width);
174 static void     mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id);
175 #endif
176
177 void            mptscsih_remove(struct pci_dev *);
178 void            mptscsih_shutdown(struct pci_dev *);
179 #ifdef CONFIG_PM
180 int             mptscsih_suspend(struct pci_dev *pdev, pm_message_t state);
181 int             mptscsih_resume(struct pci_dev *pdev);
182 #endif
183
184 #define SNS_LEN(scp)    sizeof((scp)->sense_buffer)
185
186 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
187 /*
188  * Domain Validation task structure
189  */
190 static DEFINE_SPINLOCK(dvtaskQ_lock);
191 static int dvtaskQ_active = 0;
192 static int dvtaskQ_release = 0;
193 static struct work_struct       dvTaskQ_task;
194 #endif
195
196 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
197 /**
198  *      mptscsih_add_sge - Place a simple SGE at address pAddr.
199  *      @pAddr: virtual address for SGE
200  *      @flagslength: SGE flags and data transfer length
201  *      @dma_addr: Physical address
202  *
203  *      This routine places a MPT request frame back on the MPT adapter's
204  *      FreeQ.
205  */
206 static inline void
207 mptscsih_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
208 {
209         if (sizeof(dma_addr_t) == sizeof(u64)) {
210                 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
211                 u32 tmp = dma_addr & 0xFFFFFFFF;
212
213                 pSge->FlagsLength = cpu_to_le32(flagslength);
214                 pSge->Address.Low = cpu_to_le32(tmp);
215                 tmp = (u32) ((u64)dma_addr >> 32);
216                 pSge->Address.High = cpu_to_le32(tmp);
217
218         } else {
219                 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
220                 pSge->FlagsLength = cpu_to_le32(flagslength);
221                 pSge->Address = cpu_to_le32(dma_addr);
222         }
223 } /* mptscsih_add_sge() */
224
225 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
226 /**
227  *      mptscsih_add_chain - Place a chain SGE at address pAddr.
228  *      @pAddr: virtual address for SGE
229  *      @next: nextChainOffset value (u32's)
230  *      @length: length of next SGL segment
231  *      @dma_addr: Physical address
232  *
233  *      This routine places a MPT request frame back on the MPT adapter's
234  *      FreeQ.
235  */
236 static inline void
237 mptscsih_add_chain(char *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
238 {
239         if (sizeof(dma_addr_t) == sizeof(u64)) {
240                 SGEChain64_t *pChain = (SGEChain64_t *) pAddr;
241                 u32 tmp = dma_addr & 0xFFFFFFFF;
242
243                 pChain->Length = cpu_to_le16(length);
244                 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size();
245
246                 pChain->NextChainOffset = next;
247
248                 pChain->Address.Low = cpu_to_le32(tmp);
249                 tmp = (u32) ((u64)dma_addr >> 32);
250                 pChain->Address.High = cpu_to_le32(tmp);
251         } else {
252                 SGEChain32_t *pChain = (SGEChain32_t *) pAddr;
253                 pChain->Length = cpu_to_le16(length);
254                 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size();
255                 pChain->NextChainOffset = next;
256                 pChain->Address = cpu_to_le32(dma_addr);
257         }
258 } /* mptscsih_add_chain() */
259
260 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
261 /*
262  *      mptscsih_getFreeChainBuffer - Function to get a free chain
263  *      from the MPT_SCSI_HOST FreeChainQ.
264  *      @ioc: Pointer to MPT_ADAPTER structure
265  *      @req_idx: Index of the SCSI IO request frame. (output)
266  *
267  *      return SUCCESS or FAILED
268  */
269 static inline int
270 mptscsih_getFreeChainBuffer(MPT_ADAPTER *ioc, int *retIndex)
271 {
272         MPT_FRAME_HDR *chainBuf;
273         unsigned long flags;
274         int rc;
275         int chain_idx;
276
277         dsgprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer called\n",
278                         ioc->name));
279         spin_lock_irqsave(&ioc->FreeQlock, flags);
280         if (!list_empty(&ioc->FreeChainQ)) {
281                 int offset;
282
283                 chainBuf = list_entry(ioc->FreeChainQ.next, MPT_FRAME_HDR,
284                                 u.frame.linkage.list);
285                 list_del(&chainBuf->u.frame.linkage.list);
286                 offset = (u8 *)chainBuf - (u8 *)ioc->ChainBuffer;
287                 chain_idx = offset / ioc->req_sz;
288                 rc = SUCCESS;
289                 dsgprintk((MYIOC_s_ERR_FMT "getFreeChainBuffer chainBuf=%p ChainBuffer=%p offset=%d chain_idx=%d\n",
290                         ioc->name, chainBuf, ioc->ChainBuffer, offset, chain_idx));
291         } else {
292                 rc = FAILED;
293                 chain_idx = MPT_HOST_NO_CHAIN;
294                 dfailprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer failed\n",
295                         ioc->name));
296         }
297         spin_unlock_irqrestore(&ioc->FreeQlock, flags);
298
299         *retIndex = chain_idx;
300         return rc;
301 } /* mptscsih_getFreeChainBuffer() */
302
303 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
304 /*
305  *      mptscsih_AddSGE - Add a SGE (plus chain buffers) to the
306  *      SCSIIORequest_t Message Frame.
307  *      @ioc: Pointer to MPT_ADAPTER structure
308  *      @SCpnt: Pointer to scsi_cmnd structure
309  *      @pReq: Pointer to SCSIIORequest_t structure
310  *
311  *      Returns ...
312  */
313 static int
314 mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
315                 SCSIIORequest_t *pReq, int req_idx)
316 {
317         char    *psge;
318         char    *chainSge;
319         struct scatterlist *sg;
320         int      frm_sz;
321         int      sges_left, sg_done;
322         int      chain_idx = MPT_HOST_NO_CHAIN;
323         int      sgeOffset;
324         int      numSgeSlots, numSgeThisFrame;
325         u32      sgflags, sgdir, thisxfer = 0;
326         int      chain_dma_off = 0;
327         int      newIndex;
328         int      ii;
329         dma_addr_t v2;
330         u32     RequestNB;
331
332         sgdir = le32_to_cpu(pReq->Control) & MPI_SCSIIO_CONTROL_DATADIRECTION_MASK;
333         if (sgdir == MPI_SCSIIO_CONTROL_WRITE)  {
334                 sgdir = MPT_TRANSFER_HOST_TO_IOC;
335         } else {
336                 sgdir = MPT_TRANSFER_IOC_TO_HOST;
337         }
338
339         psge = (char *) &pReq->SGL;
340         frm_sz = ioc->req_sz;
341
342         /* Map the data portion, if any.
343          * sges_left  = 0 if no data transfer.
344          */
345         if ( (sges_left = SCpnt->use_sg) ) {
346                 sges_left = pci_map_sg(ioc->pcidev,
347                                (struct scatterlist *) SCpnt->request_buffer,
348                                SCpnt->use_sg,
349                                SCpnt->sc_data_direction);
350                 if (sges_left == 0)
351                         return FAILED;
352         } else if (SCpnt->request_bufflen) {
353                 SCpnt->SCp.dma_handle = pci_map_single(ioc->pcidev,
354                                       SCpnt->request_buffer,
355                                       SCpnt->request_bufflen,
356                                       SCpnt->sc_data_direction);
357                 dsgprintk((MYIOC_s_INFO_FMT "SG: non-SG for %p, len=%d\n",
358                                 ioc->name, SCpnt, SCpnt->request_bufflen));
359                 mptscsih_add_sge((char *) &pReq->SGL,
360                         0xD1000000|MPT_SGE_FLAGS_ADDRESSING|sgdir|SCpnt->request_bufflen,
361                         SCpnt->SCp.dma_handle);
362
363                 return SUCCESS;
364         }
365
366         /* Handle the SG case.
367          */
368         sg = (struct scatterlist *) SCpnt->request_buffer;
369         sg_done  = 0;
370         sgeOffset = sizeof(SCSIIORequest_t) - sizeof(SGE_IO_UNION);
371         chainSge = NULL;
372
373         /* Prior to entering this loop - the following must be set
374          * current MF:  sgeOffset (bytes)
375          *              chainSge (Null if original MF is not a chain buffer)
376          *              sg_done (num SGE done for this MF)
377          */
378
379 nextSGEset:
380         numSgeSlots = ((frm_sz - sgeOffset) / (sizeof(u32) + sizeof(dma_addr_t)) );
381         numSgeThisFrame = (sges_left < numSgeSlots) ? sges_left : numSgeSlots;
382
383         sgflags = MPT_SGE_FLAGS_SIMPLE_ELEMENT | MPT_SGE_FLAGS_ADDRESSING | sgdir;
384
385         /* Get first (num - 1) SG elements
386          * Skip any SG entries with a length of 0
387          * NOTE: at finish, sg and psge pointed to NEXT data/location positions
388          */
389         for (ii=0; ii < (numSgeThisFrame-1); ii++) {
390                 thisxfer = sg_dma_len(sg);
391                 if (thisxfer == 0) {
392                         sg ++; /* Get next SG element from the OS */
393                         sg_done++;
394                         continue;
395                 }
396
397                 v2 = sg_dma_address(sg);
398                 mptscsih_add_sge(psge, sgflags | thisxfer, v2);
399
400                 sg++;           /* Get next SG element from the OS */
401                 psge += (sizeof(u32) + sizeof(dma_addr_t));
402                 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
403                 sg_done++;
404         }
405
406         if (numSgeThisFrame == sges_left) {
407                 /* Add last element, end of buffer and end of list flags.
408                  */
409                 sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT |
410                                 MPT_SGE_FLAGS_END_OF_BUFFER |
411                                 MPT_SGE_FLAGS_END_OF_LIST;
412
413                 /* Add last SGE and set termination flags.
414                  * Note: Last SGE may have a length of 0 - which should be ok.
415                  */
416                 thisxfer = sg_dma_len(sg);
417
418                 v2 = sg_dma_address(sg);
419                 mptscsih_add_sge(psge, sgflags | thisxfer, v2);
420                 /*
421                 sg++;
422                 psge += (sizeof(u32) + sizeof(dma_addr_t));
423                 */
424                 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
425                 sg_done++;
426
427                 if (chainSge) {
428                         /* The current buffer is a chain buffer,
429                          * but there is not another one.
430                          * Update the chain element
431                          * Offset and Length fields.
432                          */
433                         mptscsih_add_chain((char *)chainSge, 0, sgeOffset, ioc->ChainBufferDMA + chain_dma_off);
434                 } else {
435                         /* The current buffer is the original MF
436                          * and there is no Chain buffer.
437                          */
438                         pReq->ChainOffset = 0;
439                         RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor)  + 1) & 0x03;
440                         dsgprintk((MYIOC_s_INFO_FMT
441                             "Single Buffer RequestNB=%x, sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
442                         ioc->RequestNB[req_idx] = RequestNB;
443                 }
444         } else {
445                 /* At least one chain buffer is needed.
446                  * Complete the first MF
447                  *  - last SGE element, set the LastElement bit
448                  *  - set ChainOffset (words) for orig MF
449                  *             (OR finish previous MF chain buffer)
450                  *  - update MFStructPtr ChainIndex
451                  *  - Populate chain element
452                  * Also
453                  * Loop until done.
454                  */
455
456                 dsgprintk((MYIOC_s_INFO_FMT "SG: Chain Required! sg done %d\n",
457                                 ioc->name, sg_done));
458
459                 /* Set LAST_ELEMENT flag for last non-chain element
460                  * in the buffer. Since psge points at the NEXT
461                  * SGE element, go back one SGE element, update the flags
462                  * and reset the pointer. (Note: sgflags & thisxfer are already
463                  * set properly).
464                  */
465                 if (sg_done) {
466                         u32 *ptmp = (u32 *) (psge - (sizeof(u32) + sizeof(dma_addr_t)));
467                         sgflags = le32_to_cpu(*ptmp);
468                         sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT;
469                         *ptmp = cpu_to_le32(sgflags);
470                 }
471
472                 if (chainSge) {
473                         /* The current buffer is a chain buffer.
474                          * chainSge points to the previous Chain Element.
475                          * Update its chain element Offset and Length (must
476                          * include chain element size) fields.
477                          * Old chain element is now complete.
478                          */
479                         u8 nextChain = (u8) (sgeOffset >> 2);
480                         sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
481                         mptscsih_add_chain((char *)chainSge, nextChain, sgeOffset, ioc->ChainBufferDMA + chain_dma_off);
482                 } else {
483                         /* The original MF buffer requires a chain buffer -
484                          * set the offset.
485                          * Last element in this MF is a chain element.
486                          */
487                         pReq->ChainOffset = (u8) (sgeOffset >> 2);
488                         RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor)  + 1) & 0x03;
489                         dsgprintk((MYIOC_s_ERR_FMT "Chain Buffer Needed, RequestNB=%x sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
490                         ioc->RequestNB[req_idx] = RequestNB;
491                 }
492
493                 sges_left -= sg_done;
494
495
496                 /* NOTE: psge points to the beginning of the chain element
497                  * in current buffer. Get a chain buffer.
498                  */
499                 if ((mptscsih_getFreeChainBuffer(ioc, &newIndex)) == FAILED) {
500                         dfailprintk((MYIOC_s_INFO_FMT
501                             "getFreeChainBuffer FAILED SCSI cmd=%02x (%p)\n",
502                             ioc->name, pReq->CDB[0], SCpnt));
503                         return FAILED;
504                 }
505
506                 /* Update the tracking arrays.
507                  * If chainSge == NULL, update ReqToChain, else ChainToChain
508                  */
509                 if (chainSge) {
510                         ioc->ChainToChain[chain_idx] = newIndex;
511                 } else {
512                         ioc->ReqToChain[req_idx] = newIndex;
513                 }
514                 chain_idx = newIndex;
515                 chain_dma_off = ioc->req_sz * chain_idx;
516
517                 /* Populate the chainSGE for the current buffer.
518                  * - Set chain buffer pointer to psge and fill
519                  *   out the Address and Flags fields.
520                  */
521                 chainSge = (char *) psge;
522                 dsgprintk((KERN_INFO "  Current buff @ %p (index 0x%x)",
523                                 psge, req_idx));
524
525                 /* Start the SGE for the next buffer
526                  */
527                 psge = (char *) (ioc->ChainBuffer + chain_dma_off);
528                 sgeOffset = 0;
529                 sg_done = 0;
530
531                 dsgprintk((KERN_INFO "  Chain buff @ %p (index 0x%x)\n",
532                                 psge, chain_idx));
533
534                 /* Start the SGE for the next buffer
535                  */
536
537                 goto nextSGEset;
538         }
539
540         return SUCCESS;
541 } /* mptscsih_AddSGE() */
542
543 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
544 /*
545  *      mptscsih_io_done - Main SCSI IO callback routine registered to
546  *      Fusion MPT (base) driver
547  *      @ioc: Pointer to MPT_ADAPTER structure
548  *      @mf: Pointer to original MPT request frame
549  *      @r: Pointer to MPT reply frame (NULL if TurboReply)
550  *
551  *      This routine is called from mpt.c::mpt_interrupt() at the completion
552  *      of any SCSI IO request.
553  *      This routine is registered with the Fusion MPT (base) driver at driver
554  *      load/init time via the mpt_register() API call.
555  *
556  *      Returns 1 indicating alloc'd request frame ptr should be freed.
557  */
558 int
559 mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
560 {
561         struct scsi_cmnd        *sc;
562         MPT_SCSI_HOST   *hd;
563         SCSIIORequest_t *pScsiReq;
564         SCSIIOReply_t   *pScsiReply;
565         u16              req_idx;
566
567         hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
568
569         req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
570         sc = hd->ScsiLookup[req_idx];
571         if (sc == NULL) {
572                 MPIHeader_t *hdr = (MPIHeader_t *)mf;
573
574                 /* Remark: writeSDP1 will use the ScsiDoneCtx
575                  * If a SCSI I/O cmd, device disabled by OS and
576                  * completion done. Cannot touch sc struct. Just free mem.
577                  */
578                 if (hdr->Function == MPI_FUNCTION_SCSI_IO_REQUEST)
579                         printk(MYIOC_s_ERR_FMT "NULL ScsiCmd ptr!\n",
580                         ioc->name);
581
582                 mptscsih_freeChainBuffers(ioc, req_idx);
583                 return 1;
584         }
585
586         sc->result = DID_OK << 16;              /* Set default reply as OK */
587         pScsiReq = (SCSIIORequest_t *) mf;
588         pScsiReply = (SCSIIOReply_t *) mr;
589
590         if((ioc->facts.MsgVersion >= MPI_VERSION_01_05) && pScsiReply){
591                 dmfprintk((MYIOC_s_INFO_FMT
592                         "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d,task-tag=%d)\n",
593                         ioc->name, mf, mr, sc, req_idx, pScsiReply->TaskTag));
594         }else{
595                 dmfprintk((MYIOC_s_INFO_FMT
596                         "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n",
597                         ioc->name, mf, mr, sc, req_idx));
598         }
599
600         if (pScsiReply == NULL) {
601                 /* special context reply handling */
602                 ;
603         } else {
604                 u32      xfer_cnt;
605                 u16      status;
606                 u8       scsi_state, scsi_status;
607
608                 status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK;
609                 scsi_state = pScsiReply->SCSIState;
610                 scsi_status = pScsiReply->SCSIStatus;
611                 xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
612                 sc->resid = sc->request_bufflen - xfer_cnt;
613
614                 /*
615                  *  if we get a data underrun indication, yet no data was
616                  *  transferred and the SCSI status indicates that the
617                  *  command was never started, change the data underrun
618                  *  to success
619                  */
620                 if (status == MPI_IOCSTATUS_SCSI_DATA_UNDERRUN && xfer_cnt == 0 &&
621                     (scsi_status == MPI_SCSI_STATUS_BUSY ||
622                      scsi_status == MPI_SCSI_STATUS_RESERVATION_CONFLICT ||
623                      scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)) {
624                         status = MPI_IOCSTATUS_SUCCESS;
625                 }
626
627                 dreplyprintk((KERN_NOTICE "Reply ha=%d id=%d lun=%d:\n"
628                         "IOCStatus=%04xh SCSIState=%02xh SCSIStatus=%02xh\n"
629                         "resid=%d bufflen=%d xfer_cnt=%d\n",
630                         ioc->id, pScsiReq->TargetID, pScsiReq->LUN[1],
631                         status, scsi_state, scsi_status, sc->resid,
632                         sc->request_bufflen, xfer_cnt));
633
634                 if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)
635                         mptscsih_copy_sense_data(sc, hd, mf, pScsiReply);
636
637                 /*
638                  *  Look for + dump FCP ResponseInfo[]!
639                  */
640                 if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID &&
641                     pScsiReply->ResponseInfo) {
642                         printk(KERN_NOTICE "ha=%d id=%d lun=%d: "
643                         "FCP_ResponseInfo=%08xh\n",
644                         ioc->id, pScsiReq->TargetID, pScsiReq->LUN[1],
645                         le32_to_cpu(pScsiReply->ResponseInfo));
646                 }
647
648                 switch(status) {
649                 case MPI_IOCSTATUS_BUSY:                        /* 0x0002 */
650                         /* CHECKME!
651                          * Maybe: DRIVER_BUSY | SUGGEST_RETRY | DID_SOFT_ERROR (retry)
652                          * But not: DID_BUS_BUSY lest one risk
653                          * killing interrupt handler:-(
654                          */
655                         sc->result = SAM_STAT_BUSY;
656                         break;
657
658                 case MPI_IOCSTATUS_SCSI_INVALID_BUS:            /* 0x0041 */
659                 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID:       /* 0x0042 */
660                         sc->result = DID_BAD_TARGET << 16;
661                         break;
662
663                 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE:       /* 0x0043 */
664                         /* Spoof to SCSI Selection Timeout! */
665                         sc->result = DID_NO_CONNECT << 16;
666
667                         if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF)
668                                 hd->sel_timeout[pScsiReq->TargetID]++;
669                         break;
670
671                 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED:        /* 0x0048 */
672                 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED:         /* 0x004B */
673                 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED:         /* 0x004C */
674                         /* Linux handles an unsolicited DID_RESET better
675                          * than an unsolicited DID_ABORT.
676                          */
677                         sc->result = DID_RESET << 16;
678
679                         /* GEM Workaround. */
680                         if (ioc->bus_type == SCSI)
681                                 mptscsih_no_negotiate(hd, sc->device->id);
682                         break;
683
684                 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:      /* 0x0049 */
685                         sc->resid = sc->request_bufflen - xfer_cnt;
686                         if((xfer_cnt==0)||(sc->underflow > xfer_cnt))
687                                 sc->result=DID_SOFT_ERROR << 16;
688                         else /* Sufficient data transfer occurred */
689                                 sc->result = (DID_OK << 16) | scsi_status;
690                         dreplyprintk((KERN_NOTICE 
691                             "RESIDUAL_MISMATCH: result=%x on id=%d\n", sc->result, sc->device->id));
692                         break;
693
694                 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN:          /* 0x0045 */
695                         /*
696                          *  Do upfront check for valid SenseData and give it
697                          *  precedence!
698                          */
699                         sc->result = (DID_OK << 16) | scsi_status;
700                         if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
701                                 /* Have already saved the status and sense data
702                                  */
703                                 ;
704                         } else {
705                                 if (xfer_cnt < sc->underflow) {
706                                         if (scsi_status == SAM_STAT_BUSY)
707                                                 sc->result = SAM_STAT_BUSY;
708                                         else
709                                                 sc->result = DID_SOFT_ERROR << 16;
710                                 }
711                                 if (scsi_state & (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)) {
712                                         /* What to do?
713                                         */
714                                         sc->result = DID_SOFT_ERROR << 16;
715                                 }
716                                 else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
717                                         /*  Not real sure here either...  */
718                                         sc->result = DID_RESET << 16;
719                                 }
720                         }
721
722                         dreplyprintk((KERN_NOTICE "  sc->underflow={report ERR if < %02xh bytes xfer'd}\n",
723                                         sc->underflow));
724                         dreplyprintk((KERN_NOTICE "  ActBytesXferd=%02xh\n", xfer_cnt));
725                         /* Report Queue Full
726                          */
727                         if (scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)
728                                 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
729
730                         break;
731
732                 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR:        /* 0x0040 */
733                 case MPI_IOCSTATUS_SUCCESS:                     /* 0x0000 */
734                         if (scsi_status == MPI_SCSI_STATUS_BUSY)
735                                 sc->result = (DID_BUS_BUSY << 16) | scsi_status;
736                         else
737                                 sc->result = (DID_OK << 16) | scsi_status;
738                         if (scsi_state == 0) {
739                                 ;
740                         } else if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
741                                 /*
742                                  * If running against circa 200003dd 909 MPT f/w,
743                                  * may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL
744                                  * (QUEUE_FULL) returned from device! --> get 0x0000?128
745                                  * and with SenseBytes set to 0.
746                                  */
747                                 if (pScsiReply->SCSIStatus == MPI_SCSI_STATUS_TASK_SET_FULL)
748                                         mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
749
750                         }
751                         else if (scsi_state &
752                                  (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)
753                            ) {
754                                 /*
755                                  * What to do?
756                                  */
757                                 sc->result = DID_SOFT_ERROR << 16;
758                         }
759                         else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
760                                 /*  Not real sure here either...  */
761                                 sc->result = DID_RESET << 16;
762                         }
763                         else if (scsi_state & MPI_SCSI_STATE_QUEUE_TAG_REJECTED) {
764                                 /* Device Inq. data indicates that it supports
765                                  * QTags, but rejects QTag messages.
766                                  * This command completed OK.
767                                  *
768                                  * Not real sure here either so do nothing...  */
769                         }
770
771                         if (sc->result == MPI_SCSI_STATUS_TASK_SET_FULL)
772                                 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
773
774                         /* Add handling of:
775                          * Reservation Conflict, Busy,
776                          * Command Terminated, CHECK
777                          */
778                         break;
779
780                 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR:         /* 0x0047 */
781                         sc->result = DID_SOFT_ERROR << 16;
782                         break;
783
784                 case MPI_IOCSTATUS_INVALID_FUNCTION:            /* 0x0001 */
785                 case MPI_IOCSTATUS_INVALID_SGL:                 /* 0x0003 */
786                 case MPI_IOCSTATUS_INTERNAL_ERROR:              /* 0x0004 */
787                 case MPI_IOCSTATUS_RESERVED:                    /* 0x0005 */
788                 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES:      /* 0x0006 */
789                 case MPI_IOCSTATUS_INVALID_FIELD:               /* 0x0007 */
790                 case MPI_IOCSTATUS_INVALID_STATE:               /* 0x0008 */
791                 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN:           /* 0x0044 */
792                 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR:          /* 0x0046 */
793                 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED:       /* 0x004A */
794                 default:
795                         /*
796                          * What to do?
797                          */
798                         sc->result = DID_SOFT_ERROR << 16;
799                         break;
800
801                 }       /* switch(status) */
802
803                 dreplyprintk((KERN_NOTICE "  sc->result is %08xh\n", sc->result));
804         } /* end of address reply case */
805
806         /* Unmap the DMA buffers, if any. */
807         if (sc->use_sg) {
808                 pci_unmap_sg(ioc->pcidev, (struct scatterlist *) sc->request_buffer,
809                             sc->use_sg, sc->sc_data_direction);
810         } else if (sc->request_bufflen) {
811                 pci_unmap_single(ioc->pcidev, sc->SCp.dma_handle,
812                                 sc->request_bufflen, sc->sc_data_direction);
813         }
814
815         hd->ScsiLookup[req_idx] = NULL;
816
817         sc->scsi_done(sc);              /* Issue the command callback */
818
819         /* Free Chain buffers */
820         mptscsih_freeChainBuffers(ioc, req_idx);
821         return 1;
822 }
823
824 /*
825  *      mptscsih_flush_running_cmds - For each command found, search
826  *              Scsi_Host instance taskQ and reply to OS.
827  *              Called only if recovering from a FW reload.
828  *      @hd: Pointer to a SCSI HOST structure
829  *
830  *      Returns: None.
831  *
832  *      Must be called while new I/Os are being queued.
833  */
834 static void
835 mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
836 {
837         MPT_ADAPTER *ioc = hd->ioc;
838         struct scsi_cmnd        *SCpnt;
839         MPT_FRAME_HDR   *mf;
840         int              ii;
841         int              max = ioc->req_depth;
842
843         dprintk((KERN_INFO MYNAM ": flush_ScsiLookup called\n"));
844         for (ii= 0; ii < max; ii++) {
845                 if ((SCpnt = hd->ScsiLookup[ii]) != NULL) {
846
847                         /* Command found.
848                          */
849
850                         /* Null ScsiLookup index
851                          */
852                         hd->ScsiLookup[ii] = NULL;
853
854                         mf = MPT_INDEX_2_MFPTR(ioc, ii);
855                         dmfprintk(( "flush: ScsiDone (mf=%p,sc=%p)\n",
856                                         mf, SCpnt));
857
858                         /* Set status, free OS resources (SG DMA buffers)
859                          * Do OS callback
860                          * Free driver resources (chain, msg buffers)
861                          */
862                         if (SCpnt->use_sg) {
863                                 pci_unmap_sg(ioc->pcidev,
864                                         (struct scatterlist *) SCpnt->request_buffer,
865                                         SCpnt->use_sg,
866                                         SCpnt->sc_data_direction);
867                         } else if (SCpnt->request_bufflen) {
868                                 pci_unmap_single(ioc->pcidev,
869                                         SCpnt->SCp.dma_handle,
870                                         SCpnt->request_bufflen,
871                                         SCpnt->sc_data_direction);
872                         }
873                         SCpnt->result = DID_RESET << 16;
874                         SCpnt->host_scribble = NULL;
875
876                         /* Free Chain buffers */
877                         mptscsih_freeChainBuffers(ioc, ii);
878
879                         /* Free Message frames */
880                         mpt_free_msg_frame(ioc, mf);
881
882                         SCpnt->scsi_done(SCpnt);        /* Issue the command callback */
883                 }
884         }
885
886         return;
887 }
888
889 /*
890  *      mptscsih_search_running_cmds - Delete any commands associated
891  *              with the specified target and lun. Function called only
892  *              when a lun is disable by mid-layer.
893  *              Do NOT access the referenced scsi_cmnd structure or
894  *              members. Will cause either a paging or NULL ptr error.
895  *      @hd: Pointer to a SCSI HOST structure
896  *      @target: target id
897  *      @lun: lun
898  *
899  *      Returns: None.
900  *
901  *      Called from slave_destroy.
902  */
903 static void
904 mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, uint target, uint lun)
905 {
906         SCSIIORequest_t *mf = NULL;
907         int              ii;
908         int              max = hd->ioc->req_depth;
909         struct scsi_cmnd *sc;
910
911         dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n",
912                         target, lun, max));
913
914         for (ii=0; ii < max; ii++) {
915                 if ((sc = hd->ScsiLookup[ii]) != NULL) {
916
917                         mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii);
918
919                         dsprintk(( "search_running: found (sc=%p, mf = %p) target %d, lun %d \n",
920                                         hd->ScsiLookup[ii], mf, mf->TargetID, mf->LUN[1]));
921
922                         if ((mf->TargetID != ((u8)target)) || (mf->LUN[1] != ((u8) lun)))
923                                 continue;
924
925                         /* Cleanup
926                          */
927                         hd->ScsiLookup[ii] = NULL;
928                         mptscsih_freeChainBuffers(hd->ioc, ii);
929                         mpt_free_msg_frame(hd->ioc, (MPT_FRAME_HDR *)mf);
930                         if (sc->use_sg) {
931                                 pci_unmap_sg(hd->ioc->pcidev,
932                                 (struct scatterlist *) sc->request_buffer,
933                                         sc->use_sg,
934                                         sc->sc_data_direction);
935                         } else if (sc->request_bufflen) {
936                                 pci_unmap_single(hd->ioc->pcidev,
937                                         sc->SCp.dma_handle,
938                                         sc->request_bufflen,
939                                         sc->sc_data_direction);
940                         }
941                         sc->host_scribble = NULL;
942                         sc->result = DID_NO_CONNECT << 16;
943                         sc->scsi_done(sc);
944                 }
945         }
946         return;
947 }
948
949 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
950
951 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
952 /*
953  *      mptscsih_report_queue_full - Report QUEUE_FULL status returned
954  *      from a SCSI target device.
955  *      @sc: Pointer to scsi_cmnd structure
956  *      @pScsiReply: Pointer to SCSIIOReply_t
957  *      @pScsiReq: Pointer to original SCSI request
958  *
959  *      This routine periodically reports QUEUE_FULL status returned from a
960  *      SCSI target device.  It reports this to the console via kernel
961  *      printk() API call, not more than once every 10 seconds.
962  */
963 static void
964 mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq)
965 {
966         long time = jiffies;
967         MPT_SCSI_HOST           *hd;
968
969         if (sc->device == NULL)
970                 return;
971         if (sc->device->host == NULL)
972                 return;
973         if ((hd = (MPT_SCSI_HOST *)sc->device->host->hostdata) == NULL)
974                 return;
975
976         if (time - hd->last_queue_full > 10 * HZ) {
977                 dprintk((MYIOC_s_WARN_FMT "Device (%d:%d:%d) reported QUEUE_FULL!\n",
978                                 hd->ioc->name, 0, sc->device->id, sc->device->lun));
979                 hd->last_queue_full = time;
980         }
981 }
982
983 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
984 /*
985  *      mptscsih_remove - Removed scsi devices
986  *      @pdev: Pointer to pci_dev structure
987  *
988  *
989  */
990 void
991 mptscsih_remove(struct pci_dev *pdev)
992 {
993         MPT_ADAPTER             *ioc = pci_get_drvdata(pdev);
994         struct Scsi_Host        *host = ioc->sh;
995         MPT_SCSI_HOST           *hd;
996         int                     count;
997         unsigned long           flags;
998         int sz1;
999
1000         if(!host) {
1001                 mpt_detach(pdev);
1002                 return;
1003         }
1004
1005         scsi_remove_host(host);
1006
1007         if((hd = (MPT_SCSI_HOST *)host->hostdata) == NULL)
1008                 return;
1009
1010 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1011         /* Check DV thread active */
1012         count = 10 * HZ;
1013         spin_lock_irqsave(&dvtaskQ_lock, flags);
1014         if (dvtaskQ_active) {
1015                 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
1016                 while(dvtaskQ_active && --count)
1017                         schedule_timeout_interruptible(1);
1018         } else {
1019                 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
1020         }
1021         if (!count)
1022                 printk(KERN_ERR MYNAM ": ERROR - DV thread still active!\n");
1023 #if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY)
1024         else
1025                 printk(KERN_ERR MYNAM ": DV thread orig %d, count %d\n", 10 * HZ, count);
1026 #endif
1027 #endif
1028
1029         mptscsih_shutdown(pdev);
1030
1031         sz1=0;
1032
1033         if (hd->ScsiLookup != NULL) {
1034                 sz1 = hd->ioc->req_depth * sizeof(void *);
1035                 kfree(hd->ScsiLookup);
1036                 hd->ScsiLookup = NULL;
1037         }
1038
1039         /*
1040          * Free pointer array.
1041          */
1042         kfree(hd->Targets);
1043         hd->Targets = NULL;
1044
1045         dprintk((MYIOC_s_INFO_FMT
1046             "Free'd ScsiLookup (%d) memory\n",
1047             hd->ioc->name, sz1));
1048
1049         kfree(hd->info_kbuf);
1050
1051         /* NULL the Scsi_Host pointer
1052          */
1053         hd->ioc->sh = NULL;
1054
1055         scsi_host_put(host);
1056
1057         mpt_detach(pdev);
1058
1059 }
1060
1061 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1062 /*
1063  *      mptscsih_shutdown - reboot notifier
1064  *
1065  */
1066 void
1067 mptscsih_shutdown(struct pci_dev *pdev)
1068 {
1069         MPT_ADAPTER             *ioc = pci_get_drvdata(pdev);
1070         struct Scsi_Host        *host = ioc->sh;
1071         MPT_SCSI_HOST           *hd;
1072
1073         if(!host)
1074                 return;
1075
1076         hd = (MPT_SCSI_HOST *)host->hostdata;
1077
1078         /* Flush the cache of this adapter
1079          */
1080         if(hd != NULL)
1081                 mptscsih_synchronize_cache(hd, 0);
1082
1083 }
1084
1085 #ifdef CONFIG_PM
1086 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1087 /*
1088  *      mptscsih_suspend - Fusion MPT scsi driver suspend routine.
1089  *
1090  *
1091  */
1092 int
1093 mptscsih_suspend(struct pci_dev *pdev, pm_message_t state)
1094 {
1095         mptscsih_shutdown(pdev);
1096         return mpt_suspend(pdev,state);
1097 }
1098
1099 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1100 /*
1101  *      mptscsih_resume - Fusion MPT scsi driver resume routine.
1102  *
1103  *
1104  */
1105 int
1106 mptscsih_resume(struct pci_dev *pdev)
1107 {
1108         MPT_ADAPTER             *ioc = pci_get_drvdata(pdev);
1109         struct Scsi_Host        *host = ioc->sh;
1110         MPT_SCSI_HOST           *hd;
1111
1112         mpt_resume(pdev);
1113
1114         if(!host)
1115                 return 0;
1116
1117         hd = (MPT_SCSI_HOST *)host->hostdata;
1118         if(!hd)
1119                 return 0;
1120
1121 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1122         {
1123         unsigned long lflags;
1124         spin_lock_irqsave(&dvtaskQ_lock, lflags);
1125         if (!dvtaskQ_active) {
1126                 dvtaskQ_active = 1;
1127                 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1128                 INIT_WORK(&dvTaskQ_task,
1129                   mptscsih_domainValidation, (void *) hd);
1130                 schedule_work(&dvTaskQ_task);
1131         } else {
1132                 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1133         }
1134         }
1135 #endif
1136         return 0;
1137 }
1138
1139 #endif
1140
1141 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1142 /**
1143  *      mptscsih_info - Return information about MPT adapter
1144  *      @SChost: Pointer to Scsi_Host structure
1145  *
1146  *      (linux scsi_host_template.info routine)
1147  *
1148  *      Returns pointer to buffer where information was written.
1149  */
1150 const char *
1151 mptscsih_info(struct Scsi_Host *SChost)
1152 {
1153         MPT_SCSI_HOST *h;
1154         int size = 0;
1155
1156         h = (MPT_SCSI_HOST *)SChost->hostdata;
1157
1158         if (h) {
1159                 if (h->info_kbuf == NULL)
1160                         if ((h->info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)
1161                                 return h->info_kbuf;
1162                 h->info_kbuf[0] = '\0';
1163
1164                 mpt_print_ioc_summary(h->ioc, h->info_kbuf, &size, 0, 0);
1165                 h->info_kbuf[size-1] = '\0';
1166         }
1167
1168         return h->info_kbuf;
1169 }
1170
1171 struct info_str {
1172         char *buffer;
1173         int   length;
1174         int   offset;
1175         int   pos;
1176 };
1177
1178 static void
1179 mptscsih_copy_mem_info(struct info_str *info, char *data, int len)
1180 {
1181         if (info->pos + len > info->length)
1182                 len = info->length - info->pos;
1183
1184         if (info->pos + len < info->offset) {
1185                 info->pos += len;
1186                 return;
1187         }
1188
1189         if (info->pos < info->offset) {
1190                 data += (info->offset - info->pos);
1191                 len  -= (info->offset - info->pos);
1192         }
1193
1194         if (len > 0) {
1195                 memcpy(info->buffer + info->pos, data, len);
1196                 info->pos += len;
1197         }
1198 }
1199
1200 static int
1201 mptscsih_copy_info(struct info_str *info, char *fmt, ...)
1202 {
1203         va_list args;
1204         char buf[81];
1205         int len;
1206
1207         va_start(args, fmt);
1208         len = vsprintf(buf, fmt, args);
1209         va_end(args);
1210
1211         mptscsih_copy_mem_info(info, buf, len);
1212         return len;
1213 }
1214
1215 static int
1216 mptscsih_host_info(MPT_ADAPTER *ioc, char *pbuf, off_t offset, int len)
1217 {
1218         struct info_str info;
1219
1220         info.buffer     = pbuf;
1221         info.length     = len;
1222         info.offset     = offset;
1223         info.pos        = 0;
1224
1225         mptscsih_copy_info(&info, "%s: %s, ", ioc->name, ioc->prod_name);
1226         mptscsih_copy_info(&info, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING, ioc->facts.FWVersion.Word);
1227         mptscsih_copy_info(&info, "Ports=%d, ", ioc->facts.NumberOfPorts);
1228         mptscsih_copy_info(&info, "MaxQ=%d\n", ioc->req_depth);
1229
1230         return ((info.pos > info.offset) ? info.pos - info.offset : 0);
1231 }
1232
1233 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1234 /**
1235  *      mptscsih_proc_info - Return information about MPT adapter
1236  *
1237  *      (linux scsi_host_template.info routine)
1238  *
1239  *      buffer: if write, user data; if read, buffer for user
1240  *      length: if write, return length;
1241  *      offset: if write, 0; if read, the current offset into the buffer from
1242  *              the previous read.
1243  *      hostno: scsi host number
1244  *      func:   if write = 1; if read = 0
1245  */
1246 int
1247 mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
1248                         int length, int func)
1249 {
1250         MPT_SCSI_HOST   *hd = (MPT_SCSI_HOST *)host->hostdata;
1251         MPT_ADAPTER     *ioc = hd->ioc;
1252         int size = 0;
1253
1254         if (func) {
1255                 /*
1256                  * write is not supported
1257                  */
1258         } else {
1259                 if (start)
1260                         *start = buffer;
1261
1262                 size = mptscsih_host_info(ioc, buffer, offset, length);
1263         }
1264
1265         return size;
1266 }
1267
1268 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1269 #define ADD_INDEX_LOG(req_ent)  do { } while(0)
1270
1271 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1272 /**
1273  *      mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine.
1274  *      @SCpnt: Pointer to scsi_cmnd structure
1275  *      @done: Pointer SCSI mid-layer IO completion function
1276  *
1277  *      (linux scsi_host_template.queuecommand routine)
1278  *      This is the primary SCSI IO start routine.  Create a MPI SCSIIORequest
1279  *      from a linux scsi_cmnd request and send it to the IOC.
1280  *
1281  *      Returns 0. (rtn value discarded by linux scsi mid-layer)
1282  */
1283 int
1284 mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1285 {
1286         MPT_SCSI_HOST           *hd;
1287         MPT_FRAME_HDR           *mf;
1288         SCSIIORequest_t         *pScsiReq;
1289         VirtDevice              *pTarget = SCpnt->device->hostdata;
1290         int      lun;
1291         u32      datalen;
1292         u32      scsictl;
1293         u32      scsidir;
1294         u32      cmd_len;
1295         int      my_idx;
1296         int      ii;
1297
1298         hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata;
1299         lun = SCpnt->device->lun;
1300         SCpnt->scsi_done = done;
1301
1302         dmfprintk((MYIOC_s_INFO_FMT "qcmd: SCpnt=%p, done()=%p\n",
1303                         (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt, done));
1304
1305         if (hd->resetPending) {
1306                 dtmprintk((MYIOC_s_WARN_FMT "qcmd: SCpnt=%p timeout + 60HZ\n",
1307                         (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt));
1308                 return SCSI_MLQUEUE_HOST_BUSY;
1309         }
1310
1311         /*
1312          *  Put together a MPT SCSI request...
1313          */
1314         if ((mf = mpt_get_msg_frame(hd->ioc->DoneCtx, hd->ioc)) == NULL) {
1315                 dprintk((MYIOC_s_WARN_FMT "QueueCmd, no msg frames!!\n",
1316                                 hd->ioc->name));
1317                 return SCSI_MLQUEUE_HOST_BUSY;
1318         }
1319
1320         pScsiReq = (SCSIIORequest_t *) mf;
1321
1322         my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
1323
1324         ADD_INDEX_LOG(my_idx);
1325
1326         /*    TUR's being issued with scsictl=0x02000000 (DATA_IN)!
1327          *    Seems we may receive a buffer (datalen>0) even when there
1328          *    will be no data transfer!  GRRRRR...
1329          */
1330         if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
1331                 datalen = SCpnt->request_bufflen;
1332                 scsidir = MPI_SCSIIO_CONTROL_READ;      /* DATA IN  (host<--ioc<--dev) */
1333         } else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
1334                 datalen = SCpnt->request_bufflen;
1335                 scsidir = MPI_SCSIIO_CONTROL_WRITE;     /* DATA OUT (host-->ioc-->dev) */
1336         } else {
1337                 datalen = 0;
1338                 scsidir = MPI_SCSIIO_CONTROL_NODATATRANSFER;
1339         }
1340
1341         /* Default to untagged. Once a target structure has been allocated,
1342          * use the Inquiry data to determine if device supports tagged.
1343          */
1344         if (pTarget
1345             && (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)
1346             && (SCpnt->device->tagged_supported)) {
1347                 scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
1348         } else {
1349                 scsictl = scsidir | MPI_SCSIIO_CONTROL_UNTAGGED;
1350         }
1351
1352         /* Use the above information to set up the message frame
1353          */
1354         pScsiReq->TargetID = (u8) pTarget->target_id;
1355         pScsiReq->Bus = pTarget->bus_id;
1356         pScsiReq->ChainOffset = 0;
1357         pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
1358         pScsiReq->CDBLength = SCpnt->cmd_len;
1359         pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
1360         pScsiReq->Reserved = 0;
1361         pScsiReq->MsgFlags = mpt_msg_flags();
1362         pScsiReq->LUN[0] = 0;
1363         pScsiReq->LUN[1] = lun;
1364         pScsiReq->LUN[2] = 0;
1365         pScsiReq->LUN[3] = 0;
1366         pScsiReq->LUN[4] = 0;
1367         pScsiReq->LUN[5] = 0;
1368         pScsiReq->LUN[6] = 0;
1369         pScsiReq->LUN[7] = 0;
1370         pScsiReq->Control = cpu_to_le32(scsictl);
1371
1372         /*
1373          *  Write SCSI CDB into the message
1374          */
1375         cmd_len = SCpnt->cmd_len;
1376         for (ii=0; ii < cmd_len; ii++)
1377                 pScsiReq->CDB[ii] = SCpnt->cmnd[ii];
1378
1379         for (ii=cmd_len; ii < 16; ii++)
1380                 pScsiReq->CDB[ii] = 0;
1381
1382         /* DataLength */
1383         pScsiReq->DataLength = cpu_to_le32(datalen);
1384
1385         /* SenseBuffer low address */
1386         pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
1387                                            + (my_idx * MPT_SENSE_BUFFER_ALLOC));
1388
1389         /* Now add the SG list
1390          * Always have a SGE even if null length.
1391          */
1392         if (datalen == 0) {
1393                 /* Add a NULL SGE */
1394                 mptscsih_add_sge((char *)&pScsiReq->SGL, MPT_SGE_FLAGS_SSIMPLE_READ | 0,
1395                         (dma_addr_t) -1);
1396         } else {
1397                 /* Add a 32 or 64 bit SGE */
1398                 if (mptscsih_AddSGE(hd->ioc, SCpnt, pScsiReq, my_idx) != SUCCESS)
1399                         goto fail;
1400         }
1401
1402         hd->ScsiLookup[my_idx] = SCpnt;
1403         SCpnt->host_scribble = NULL;
1404
1405 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1406         if (hd->ioc->bus_type == SCSI) {
1407                 int dvStatus = hd->ioc->spi_data.dvStatus[pTarget->target_id];
1408                 int issueCmd = 1;
1409
1410                 if (dvStatus || hd->ioc->spi_data.forceDv) {
1411
1412                         if ((dvStatus & MPT_SCSICFG_NEED_DV) ||
1413                                 (hd->ioc->spi_data.forceDv & MPT_SCSICFG_NEED_DV)) {
1414                                 unsigned long lflags;
1415                                 /* Schedule DV if necessary */
1416                                 spin_lock_irqsave(&dvtaskQ_lock, lflags);
1417                                 if (!dvtaskQ_active) {
1418                                         dvtaskQ_active = 1;
1419                                         spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1420                                         INIT_WORK(&dvTaskQ_task, mptscsih_domainValidation, (void *) hd);
1421
1422                                         schedule_work(&dvTaskQ_task);
1423                                 } else {
1424                                         spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1425                                 }
1426                                 hd->ioc->spi_data.forceDv &= ~MPT_SCSICFG_NEED_DV;
1427                         }
1428
1429                         /* Trying to do DV to this target, extend timeout.
1430                          * Wait to issue until flag is clear
1431                          */
1432                         if (dvStatus & MPT_SCSICFG_DV_PENDING) {
1433                                 mod_timer(&SCpnt->eh_timeout, jiffies + 40 * HZ);
1434                                 issueCmd = 0;
1435                         }
1436
1437                         /* Set the DV flags.
1438                          */
1439                         if (dvStatus & MPT_SCSICFG_DV_NOT_DONE)
1440                                 mptscsih_set_dvflags(hd, pScsiReq);
1441
1442                         if (!issueCmd)
1443                                 goto fail;
1444                 }
1445         }
1446 #endif
1447
1448         mpt_put_msg_frame(hd->ioc->DoneCtx, hd->ioc, mf);
1449         dmfprintk((MYIOC_s_INFO_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n",
1450                         hd->ioc->name, SCpnt, mf, my_idx));
1451         DBG_DUMP_REQUEST_FRAME(mf)
1452         return 0;
1453
1454  fail:
1455         hd->ScsiLookup[my_idx] = NULL;
1456         mptscsih_freeChainBuffers(hd->ioc, my_idx);
1457         mpt_free_msg_frame(hd->ioc, mf);
1458         return SCSI_MLQUEUE_HOST_BUSY;
1459 }
1460
1461 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1462 /*
1463  *      mptscsih_freeChainBuffers - Function to free chain buffers associated
1464  *      with a SCSI IO request
1465  *      @hd: Pointer to the MPT_SCSI_HOST instance
1466  *      @req_idx: Index of the SCSI IO request frame.
1467  *
1468  *      Called if SG chain buffer allocation fails and mptscsih callbacks.
1469  *      No return.
1470  */
1471 static void
1472 mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
1473 {
1474         MPT_FRAME_HDR *chain;
1475         unsigned long flags;
1476         int chain_idx;
1477         int next;
1478
1479         /* Get the first chain index and reset
1480          * tracker state.
1481          */
1482         chain_idx = ioc->ReqToChain[req_idx];
1483         ioc->ReqToChain[req_idx] = MPT_HOST_NO_CHAIN;
1484
1485         while (chain_idx != MPT_HOST_NO_CHAIN) {
1486
1487                 /* Save the next chain buffer index */
1488                 next = ioc->ChainToChain[chain_idx];
1489
1490                 /* Free this chain buffer and reset
1491                  * tracker
1492                  */
1493                 ioc->ChainToChain[chain_idx] = MPT_HOST_NO_CHAIN;
1494
1495                 chain = (MPT_FRAME_HDR *) (ioc->ChainBuffer
1496                                         + (chain_idx * ioc->req_sz));
1497
1498                 spin_lock_irqsave(&ioc->FreeQlock, flags);
1499                 list_add_tail(&chain->u.frame.linkage.list, &ioc->FreeChainQ);
1500                 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1501
1502                 dmfprintk((MYIOC_s_INFO_FMT "FreeChainBuffers (index %d)\n",
1503                                 ioc->name, chain_idx));
1504
1505                 /* handle next */
1506                 chain_idx = next;
1507         }
1508         return;
1509 }
1510
1511 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1512 /*
1513  *      Reset Handling
1514  */
1515
1516 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1517 /*
1518  *      mptscsih_TMHandler - Generic handler for SCSI Task Management.
1519  *      Fall through to mpt_HardResetHandler if: not operational, too many
1520  *      failed TM requests or handshake failure.
1521  *
1522  *      @ioc: Pointer to MPT_ADAPTER structure
1523  *      @type: Task Management type
1524  *      @target: Logical Target ID for reset (if appropriate)
1525  *      @lun: Logical Unit for reset (if appropriate)
1526  *      @ctx2abort: Context for the task to be aborted (if appropriate)
1527  *
1528  *      Remark: Currently invoked from a non-interrupt thread (_bh).
1529  *
1530  *      Remark: With old EH code, at most 1 SCSI TaskMgmt function per IOC
1531  *      will be active.
1532  *
1533  *      Returns 0 for SUCCESS or -1 if FAILED.
1534  */
1535 static int
1536 mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout)
1537 {
1538         MPT_ADAPTER     *ioc;
1539         int              rc = -1;
1540         int              doTask = 1;
1541         u32              ioc_raw_state;
1542         unsigned long    flags;
1543
1544         /* If FW is being reloaded currently, return success to
1545          * the calling function.
1546          */
1547         if (hd == NULL)
1548                 return 0;
1549
1550         ioc = hd->ioc;
1551         if (ioc == NULL) {
1552                 printk(KERN_ERR MYNAM " TMHandler" " NULL ioc!\n");
1553                 return FAILED;
1554         }
1555         dtmprintk((MYIOC_s_INFO_FMT "TMHandler Entered!\n", ioc->name));
1556
1557         // SJR - CHECKME - Can we avoid this here?
1558         // (mpt_HardResetHandler has this check...)
1559         spin_lock_irqsave(&ioc->diagLock, flags);
1560         if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)) {
1561                 spin_unlock_irqrestore(&ioc->diagLock, flags);
1562                 return FAILED;
1563         }
1564         spin_unlock_irqrestore(&ioc->diagLock, flags);
1565
1566         /*  Wait a fixed amount of time for the TM pending flag to be cleared.
1567          *  If we time out and not bus reset, then we return a FAILED status to the caller.
1568          *  The call to mptscsih_tm_pending_wait() will set the pending flag if we are
1569          *  successful. Otherwise, reload the FW.
1570          */
1571         if (mptscsih_tm_pending_wait(hd) == FAILED) {
1572                 if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
1573                         dtmprintk((KERN_INFO MYNAM ": %s: TMHandler abort: "
1574                            "Timed out waiting for last TM (%d) to complete! \n",
1575                            hd->ioc->name, hd->tmPending));
1576                         return FAILED;
1577                 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) {
1578                         dtmprintk((KERN_INFO MYNAM ": %s: TMHandler target reset: "
1579                            "Timed out waiting for last TM (%d) to complete! \n",
1580                            hd->ioc->name, hd->tmPending));
1581                         return FAILED;
1582                 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
1583                         dtmprintk((KERN_INFO MYNAM ": %s: TMHandler bus reset: "
1584                            "Timed out waiting for last TM (%d) to complete! \n",
1585                            hd->ioc->name, hd->tmPending));
1586                         if (hd->tmPending & (1 << MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS))
1587                                 return FAILED;
1588
1589                         doTask = 0;
1590                 }
1591         } else {
1592                 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
1593                 hd->tmPending |=  (1 << type);
1594                 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1595         }
1596
1597         /* Is operational?
1598          */
1599         ioc_raw_state = mpt_GetIocState(hd->ioc, 0);
1600
1601 #ifdef MPT_DEBUG_RESET
1602         if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) {
1603                 printk(MYIOC_s_WARN_FMT
1604                         "TM Handler: IOC Not operational(0x%x)!\n",
1605                         hd->ioc->name, ioc_raw_state);
1606         }
1607 #endif
1608
1609         if (doTask && ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL)
1610                                 && !(ioc_raw_state & MPI_DOORBELL_ACTIVE)) {
1611
1612                 /* Isse the Task Mgmt request.
1613                  */
1614                 if (hd->hard_resets < -1)
1615                         hd->hard_resets++;
1616                 rc = mptscsih_IssueTaskMgmt(hd, type, channel, target, lun, ctx2abort, timeout);
1617                 if (rc) {
1618                         printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n", hd->ioc->name);
1619                 } else {
1620                         dtmprintk((MYIOC_s_INFO_FMT "Issue of TaskMgmt Successful!\n", hd->ioc->name));
1621                 }
1622         }
1623
1624         /* Only fall through to the HRH if this is a bus reset
1625          */
1626         if ((type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) && (rc ||
1627                 ioc->reload_fw || (ioc->alt_ioc && ioc->alt_ioc->reload_fw))) {
1628                 dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
1629                          hd->ioc->name));
1630                 rc = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
1631         }
1632
1633         dtmprintk((MYIOC_s_INFO_FMT "TMHandler rc = %d!\n", hd->ioc->name, rc));
1634
1635         return rc;
1636 }
1637
1638
1639 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1640 /*
1641  *      mptscsih_IssueTaskMgmt - Generic send Task Management function.
1642  *      @hd: Pointer to MPT_SCSI_HOST structure
1643  *      @type: Task Management type
1644  *      @target: Logical Target ID for reset (if appropriate)
1645  *      @lun: Logical Unit for reset (if appropriate)
1646  *      @ctx2abort: Context for the task to be aborted (if appropriate)
1647  *
1648  *      Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
1649  *      or a non-interrupt thread.  In the former, must not call schedule().
1650  *
1651  *      Not all fields are meaningfull for all task types.
1652  *
1653  *      Returns 0 for SUCCESS, -999 for "no msg frames",
1654  *      else other non-zero value returned.
1655  */
1656 static int
1657 mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout)
1658 {
1659         MPT_FRAME_HDR   *mf;
1660         SCSITaskMgmt_t  *pScsiTm;
1661         int              ii;
1662         int              retval;
1663
1664         /* Return Fail to calling function if no message frames available.
1665          */
1666         if ((mf = mpt_get_msg_frame(hd->ioc->TaskCtx, hd->ioc)) == NULL) {
1667                 dfailprintk((MYIOC_s_ERR_FMT "IssueTaskMgmt, no msg frames!!\n",
1668                                 hd->ioc->name));
1669                 return FAILED;
1670         }
1671         dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt request @ %p\n",
1672                         hd->ioc->name, mf));
1673
1674         /* Format the Request
1675          */
1676         pScsiTm = (SCSITaskMgmt_t *) mf;
1677         pScsiTm->TargetID = target;
1678         pScsiTm->Bus = channel;
1679         pScsiTm->ChainOffset = 0;
1680         pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
1681
1682         pScsiTm->Reserved = 0;
1683         pScsiTm->TaskType = type;
1684         pScsiTm->Reserved1 = 0;
1685         pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)
1686                     ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0;
1687
1688         for (ii= 0; ii < 8; ii++) {
1689                 pScsiTm->LUN[ii] = 0;
1690         }
1691         pScsiTm->LUN[1] = lun;
1692
1693         for (ii=0; ii < 7; ii++)
1694                 pScsiTm->Reserved2[ii] = 0;
1695
1696         pScsiTm->TaskMsgContext = ctx2abort;
1697
1698         dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt: ctx2abort (0x%08x) type=%d\n",
1699                         hd->ioc->name, ctx2abort, type));
1700
1701         DBG_DUMP_TM_REQUEST_FRAME((u32 *)pScsiTm);
1702
1703         if ((retval = mpt_send_handshake_request(hd->ioc->TaskCtx, hd->ioc,
1704                 sizeof(SCSITaskMgmt_t), (u32*)pScsiTm,
1705                 CAN_SLEEP)) != 0) {
1706                 dfailprintk((MYIOC_s_ERR_FMT "_send_handshake FAILED!"
1707                         " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
1708                         hd->ioc, mf));
1709                 mpt_free_msg_frame(hd->ioc, mf);
1710                 return retval;
1711         }
1712
1713         if(mptscsih_tm_wait_for_completion(hd, timeout) == FAILED) {
1714                 dfailprintk((MYIOC_s_ERR_FMT "_wait_for_completion FAILED!"
1715                         " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
1716                         hd->ioc, mf));
1717                 mpt_free_msg_frame(hd->ioc, mf);
1718                 dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
1719                          hd->ioc->name));
1720                 retval = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
1721         }
1722
1723         return retval;
1724 }
1725
1726 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1727 /**
1728  *      mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant
1729  *      @SCpnt: Pointer to scsi_cmnd structure, IO to be aborted
1730  *
1731  *      (linux scsi_host_template.eh_abort_handler routine)
1732  *
1733  *      Returns SUCCESS or FAILED.
1734  */
1735 int
1736 mptscsih_abort(struct scsi_cmnd * SCpnt)
1737 {
1738         MPT_SCSI_HOST   *hd;
1739         MPT_ADAPTER     *ioc;
1740         MPT_FRAME_HDR   *mf;
1741         u32              ctx2abort;
1742         int              scpnt_idx;
1743         int              retval;
1744
1745         /* If we can't locate our host adapter structure, return FAILED status.
1746          */
1747         if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL) {
1748                 SCpnt->result = DID_RESET << 16;
1749                 SCpnt->scsi_done(SCpnt);
1750                 dfailprintk((KERN_INFO MYNAM ": mptscsih_abort: "
1751                            "Can't locate host! (sc=%p)\n",
1752                            SCpnt));
1753                 return FAILED;
1754         }
1755
1756         ioc = hd->ioc;
1757         if (hd->resetPending) {
1758                 return FAILED;
1759         }
1760
1761         if (hd->timeouts < -1)
1762                 hd->timeouts++;
1763
1764         /* Find this command
1765          */
1766         if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) {
1767                 /* Cmd not found in ScsiLookup.
1768                  * Do OS callback.
1769                  */
1770                 SCpnt->result = DID_RESET << 16;
1771                 dtmprintk((KERN_INFO MYNAM ": %s: mptscsih_abort: "
1772                            "Command not in the active list! (sc=%p)\n",
1773                            hd->ioc->name, SCpnt));
1774                 return SUCCESS;
1775         }
1776
1777         printk(KERN_WARNING MYNAM ": %s: attempting task abort! (sc=%p)\n",
1778                hd->ioc->name, SCpnt);
1779         scsi_print_command(SCpnt);
1780
1781         /* Most important!  Set TaskMsgContext to SCpnt's MsgContext!
1782          * (the IO to be ABORT'd)
1783          *
1784          * NOTE: Since we do not byteswap MsgContext, we do not
1785          *       swap it here either.  It is an opaque cookie to
1786          *       the controller, so it does not matter. -DaveM
1787          */
1788         mf = MPT_INDEX_2_MFPTR(hd->ioc, scpnt_idx);
1789         ctx2abort = mf->u.frame.hwhdr.msgctxu.MsgContext;
1790
1791         hd->abortSCpnt = SCpnt;
1792
1793         retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
1794                 SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun,
1795                 ctx2abort, 2 /* 2 second timeout */);
1796
1797         printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n",
1798                 hd->ioc->name,
1799                 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1800
1801         if (retval == 0)
1802                 return SUCCESS;
1803
1804         if(retval != FAILED ) {
1805                 hd->tmPending = 0;
1806                 hd->tmState = TM_STATE_NONE;
1807         }
1808         return FAILED;
1809 }
1810
1811 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1812 /**
1813  *      mptscsih_dev_reset - Perform a SCSI TARGET_RESET!  new_eh variant
1814  *      @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1815  *
1816  *      (linux scsi_host_template.eh_dev_reset_handler routine)
1817  *
1818  *      Returns SUCCESS or FAILED.
1819  */
1820 int
1821 mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
1822 {
1823         MPT_SCSI_HOST   *hd;
1824         int              retval;
1825
1826         /* If we can't locate our host adapter structure, return FAILED status.
1827          */
1828         if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1829                 dtmprintk((KERN_INFO MYNAM ": mptscsih_dev_reset: "
1830                            "Can't locate host! (sc=%p)\n",
1831                            SCpnt));
1832                 return FAILED;
1833         }
1834
1835         if (hd->resetPending)
1836                 return FAILED;
1837
1838         printk(KERN_WARNING MYNAM ": %s: attempting target reset! (sc=%p)\n",
1839                hd->ioc->name, SCpnt);
1840         scsi_print_command(SCpnt);
1841
1842         retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
1843                 SCpnt->device->channel, SCpnt->device->id,
1844                 0, 0, 5 /* 5 second timeout */);
1845
1846         printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n",
1847                 hd->ioc->name,
1848                 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1849
1850         if (retval == 0)
1851                 return SUCCESS;
1852
1853         if(retval != FAILED ) {
1854                 hd->tmPending = 0;
1855                 hd->tmState = TM_STATE_NONE;
1856         }
1857         return FAILED;
1858 }
1859
1860 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1861 /**
1862  *      mptscsih_bus_reset - Perform a SCSI BUS_RESET!  new_eh variant
1863  *      @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1864  *
1865  *      (linux scsi_host_template.eh_bus_reset_handler routine)
1866  *
1867  *      Returns SUCCESS or FAILED.
1868  */
1869 int
1870 mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
1871 {
1872         MPT_SCSI_HOST   *hd;
1873         int              retval;
1874
1875         /* If we can't locate our host adapter structure, return FAILED status.
1876          */
1877         if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1878                 dtmprintk((KERN_INFO MYNAM ": mptscsih_bus_reset: "
1879                            "Can't locate host! (sc=%p)\n",
1880                            SCpnt ) );
1881                 return FAILED;
1882         }
1883
1884         printk(KERN_WARNING MYNAM ": %s: attempting bus reset! (sc=%p)\n",
1885                hd->ioc->name, SCpnt);
1886         scsi_print_command(SCpnt);
1887
1888         if (hd->timeouts < -1)
1889                 hd->timeouts++;
1890
1891         retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
1892                 SCpnt->device->channel, 0, 0, 0, 5 /* 5 second timeout */);
1893
1894         printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n",
1895                 hd->ioc->name,
1896                 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1897
1898         if (retval == 0)
1899                 return SUCCESS;
1900
1901         if(retval != FAILED ) {
1902                 hd->tmPending = 0;
1903                 hd->tmState = TM_STATE_NONE;
1904         }
1905         return FAILED;
1906 }
1907
1908 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1909 /**
1910  *      mptscsih_host_reset - Perform a SCSI host adapter RESET!
1911  *      new_eh variant
1912  *      @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1913  *
1914  *      (linux scsi_host_template.eh_host_reset_handler routine)
1915  *
1916  *      Returns SUCCESS or FAILED.
1917  */
1918 int
1919 mptscsih_host_reset(struct scsi_cmnd *SCpnt)
1920 {
1921         MPT_SCSI_HOST *  hd;
1922         int              status = SUCCESS;
1923
1924         /*  If we can't locate the host to reset, then we failed. */
1925         if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1926                 dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
1927                              "Can't locate host! (sc=%p)\n",
1928                              SCpnt ) );
1929                 return FAILED;
1930         }
1931
1932         printk(KERN_WARNING MYNAM ": %s: Attempting host reset! (sc=%p)\n",
1933                hd->ioc->name, SCpnt);
1934
1935         /*  If our attempts to reset the host failed, then return a failed
1936          *  status.  The host will be taken off line by the SCSI mid-layer.
1937          */
1938         if (mpt_HardResetHandler(hd->ioc, CAN_SLEEP) < 0){
1939                 status = FAILED;
1940         } else {
1941                 /*  Make sure TM pending is cleared and TM state is set to
1942                  *  NONE.
1943                  */
1944                 hd->tmPending = 0;
1945                 hd->tmState = TM_STATE_NONE;
1946         }
1947
1948         dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
1949                      "Status = %s\n",
1950                      (status == SUCCESS) ? "SUCCESS" : "FAILED" ) );
1951
1952         return status;
1953 }
1954
1955 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1956 /**
1957  *      mptscsih_tm_pending_wait - wait for pending task management request to
1958  *              complete.
1959  *      @hd: Pointer to MPT host structure.
1960  *
1961  *      Returns {SUCCESS,FAILED}.
1962  */
1963 static int
1964 mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd)
1965 {
1966         unsigned long  flags;
1967         int            loop_count = 4 * 10;  /* Wait 10 seconds */
1968         int            status = FAILED;
1969
1970         do {
1971                 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
1972                 if (hd->tmState == TM_STATE_NONE) {
1973                         hd->tmState = TM_STATE_IN_PROGRESS;
1974                         hd->tmPending = 1;
1975                         spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1976                         status = SUCCESS;
1977                         break;
1978                 }
1979                 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1980                 msleep(250);
1981         } while (--loop_count);
1982
1983         return status;
1984 }
1985
1986 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1987 /**
1988  *      mptscsih_tm_wait_for_completion - wait for completion of TM task
1989  *      @hd: Pointer to MPT host structure.
1990  *
1991  *      Returns {SUCCESS,FAILED}.
1992  */
1993 static int
1994 mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout )
1995 {
1996         unsigned long  flags;
1997         int            loop_count = 4 * timeout;
1998         int            status = FAILED;
1999
2000         do {
2001                 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
2002                 if(hd->tmPending == 0) {
2003                         status = SUCCESS;
2004                         spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2005                         break;
2006                 }
2007                 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2008                 msleep_interruptible(250);
2009         } while (--loop_count);
2010
2011         return status;
2012 }
2013
2014 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2015 /**
2016  *      mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
2017  *      @ioc: Pointer to MPT_ADAPTER structure
2018  *      @mf: Pointer to SCSI task mgmt request frame
2019  *      @mr: Pointer to SCSI task mgmt reply frame
2020  *
2021  *      This routine is called from mptbase.c::mpt_interrupt() at the completion
2022  *      of any SCSI task management request.
2023  *      This routine is registered with the MPT (base) driver at driver
2024  *      load/init time via the mpt_register() API call.
2025  *
2026  *      Returns 1 indicating alloc'd request frame ptr should be freed.
2027  */
2028 int
2029 mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
2030 {
2031         SCSITaskMgmtReply_t     *pScsiTmReply;
2032         SCSITaskMgmt_t          *pScsiTmReq;
2033         MPT_SCSI_HOST           *hd;
2034         unsigned long            flags;
2035         u16                      iocstatus;
2036         u8                       tmType;
2037
2038         dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt completed (mf=%p,mr=%p)\n",
2039                         ioc->name, mf, mr));
2040         if (ioc->sh) {
2041                 /* Depending on the thread, a timer is activated for
2042                  * the TM request.  Delete this timer on completion of TM.
2043                  * Decrement count of outstanding TM requests.
2044                  */
2045                 hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
2046         } else {
2047                 dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt Complete: NULL Scsi Host Ptr\n",
2048                         ioc->name));
2049                 return 1;
2050         }
2051
2052         if (mr == NULL) {
2053                 dtmprintk((MYIOC_s_WARN_FMT "ERROR! TaskMgmt Reply: NULL Request %p\n",
2054                         ioc->name, mf));
2055                 return 1;
2056         } else {
2057                 pScsiTmReply = (SCSITaskMgmtReply_t*)mr;
2058                 pScsiTmReq = (SCSITaskMgmt_t*)mf;
2059
2060                 /* Figure out if this was ABORT_TASK, TARGET_RESET, or BUS_RESET! */
2061                 tmType = pScsiTmReq->TaskType;
2062
2063                 dtmprintk((MYIOC_s_WARN_FMT "  TaskType = %d, TerminationCount=%d\n",
2064                                 ioc->name, tmType, le32_to_cpu(pScsiTmReply->TerminationCount)));
2065                 DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply);
2066
2067                 iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2068                 dtmprintk((MYIOC_s_WARN_FMT "  SCSI TaskMgmt (%d) IOCStatus=%04x IOCLogInfo=%08x\n",
2069                         ioc->name, tmType, iocstatus, le32_to_cpu(pScsiTmReply->IOCLogInfo)));
2070                 /* Error?  (anything non-zero?) */
2071                 if (iocstatus) {
2072
2073                         /* clear flags and continue.
2074                          */
2075                         if (tmType == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK)
2076                                 hd->abortSCpnt = NULL;
2077
2078                         /* If an internal command is present
2079                          * or the TM failed - reload the FW.
2080                          * FC FW may respond FAILED to an ABORT
2081                          */
2082                         if (tmType == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
2083                                 if ((hd->cmdPtr) ||
2084                                     (iocstatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED)) {
2085                                         if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0) {
2086                                                 printk((KERN_WARNING
2087                                                         " Firmware Reload FAILED!!\n"));
2088                                         }
2089                                 }
2090                         }
2091                 } else {
2092                         dtmprintk((MYIOC_s_WARN_FMT " TaskMgmt SUCCESS\n", ioc->name));
2093
2094                         hd->abortSCpnt = NULL;
2095
2096                 }
2097         }
2098
2099         spin_lock_irqsave(&ioc->FreeQlock, flags);
2100         hd->tmPending = 0;
2101         spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2102         hd->tmState = TM_STATE_NONE;
2103
2104         return 1;
2105 }
2106
2107 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2108 /*
2109  *      This is anyones guess quite frankly.
2110  */
2111 int
2112 mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
2113                 sector_t capacity, int geom[])
2114 {
2115         int             heads;
2116         int             sectors;
2117         sector_t        cylinders;
2118         ulong           dummy;
2119
2120         heads = 64;
2121         sectors = 32;
2122
2123         dummy = heads * sectors;
2124         cylinders = capacity;
2125         sector_div(cylinders,dummy);
2126
2127         /*
2128          * Handle extended translation size for logical drives
2129          * > 1Gb
2130          */
2131         if ((ulong)capacity >= 0x200000) {
2132                 heads = 255;
2133                 sectors = 63;
2134                 dummy = heads * sectors;
2135                 cylinders = capacity;
2136                 sector_div(cylinders,dummy);
2137         }
2138
2139         /* return result */
2140         geom[0] = heads;
2141         geom[1] = sectors;
2142         geom[2] = cylinders;
2143
2144         dprintk((KERN_NOTICE
2145                 ": bios_param: Id=%i Lun=%i Channel=%i CHS=%i/%i/%i\n",
2146                 sdev->id, sdev->lun,sdev->channel,(int)cylinders,heads,sectors));
2147
2148         return 0;
2149 }
2150
2151 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2152 /*
2153  *      OS entry point to allow host driver to alloc memory
2154  *      for each scsi device. Called once per device the bus scan.
2155  *      Return non-zero if allocation fails.
2156  *      Init memory once per id (not LUN).
2157  */
2158 int
2159 mptscsih_slave_alloc(struct scsi_device *device)
2160 {
2161         struct Scsi_Host        *host = device->host;
2162         MPT_SCSI_HOST           *hd = (MPT_SCSI_HOST *)host->hostdata;
2163         VirtDevice              *vdev;
2164         uint                    target = device->id;
2165
2166         if (hd == NULL)
2167                 return -ENODEV;
2168
2169         if ((vdev = hd->Targets[target]) != NULL)
2170                 goto out;
2171
2172         vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL);
2173         if (!vdev) {
2174                 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
2175                                 hd->ioc->name, sizeof(VirtDevice));
2176                 return -ENOMEM;
2177         }
2178
2179         memset(vdev, 0, sizeof(VirtDevice));
2180         vdev->tflags = MPT_TARGET_FLAGS_Q_YES;
2181         vdev->ioc_id = hd->ioc->id;
2182         vdev->target_id = device->id;
2183         vdev->bus_id = device->channel;
2184         vdev->raidVolume = 0;
2185         hd->Targets[device->id] = vdev;
2186         if (hd->ioc->bus_type == SCSI) {
2187                 if (hd->ioc->raid_data.isRaid & (1 << device->id)) {
2188                         vdev->raidVolume = 1;
2189                         ddvtprintk((KERN_INFO
2190                             "RAID Volume @ id %d\n", device->id));
2191                 }
2192         } else {
2193                 vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
2194         }
2195
2196  out:
2197         vdev->num_luns++;
2198         device->hostdata = vdev;
2199         return 0;
2200 }
2201
2202 /*
2203  *      OS entry point to allow for host driver to free allocated memory
2204  *      Called if no device present or device being unloaded
2205  */
2206 void
2207 mptscsih_slave_destroy(struct scsi_device *device)
2208 {
2209         struct Scsi_Host        *host = device->host;
2210         MPT_SCSI_HOST           *hd = (MPT_SCSI_HOST *)host->hostdata;
2211         VirtDevice              *vdev;
2212         uint                    target = device->id;
2213         uint                    lun = device->lun;
2214
2215         if (hd == NULL)
2216                 return;
2217
2218         mptscsih_search_running_cmds(hd, target, lun);
2219
2220         vdev = hd->Targets[target];
2221         vdev->luns[0] &= ~(1 << lun);
2222         if (--vdev->num_luns)
2223                 return;
2224
2225         kfree(hd->Targets[target]);
2226         hd->Targets[target] = NULL;
2227
2228         if (hd->ioc->bus_type == SCSI) {
2229                 if (mptscsih_is_phys_disk(hd->ioc, target)) {
2230                         hd->ioc->spi_data.forceDv |= MPT_SCSICFG_RELOAD_IOC_PG3;
2231                 } else {
2232                         hd->ioc->spi_data.dvStatus[target] =
2233                                 MPT_SCSICFG_NEGOTIATE;
2234
2235                         if (!hd->negoNvram) {
2236                                 hd->ioc->spi_data.dvStatus[target] |=
2237                                         MPT_SCSICFG_DV_NOT_DONE;
2238                         }
2239                 }
2240         }
2241 }
2242
2243 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2244 /*
2245  *      mptscsih_change_queue_depth - This function will set a devices queue depth
2246  *      @sdev: per scsi_device pointer
2247  *      @qdepth: requested queue depth
2248  *
2249  *      Adding support for new 'change_queue_depth' api.
2250 */
2251 int
2252 mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
2253 {
2254         MPT_SCSI_HOST   *hd = (MPT_SCSI_HOST *)sdev->host->hostdata;
2255         VirtDevice *pTarget;
2256         int     max_depth;
2257         int     tagged;
2258
2259         if (hd == NULL)
2260                 return 0;
2261         if (!(pTarget = hd->Targets[sdev->id]))
2262                 return 0;
2263
2264         if (hd->ioc->bus_type == SCSI) {
2265                 if (pTarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) {
2266                         if (!(pTarget->tflags & MPT_TARGET_FLAGS_Q_YES))
2267                                 max_depth = 1;
2268                         else if (((pTarget->inq_data[0] & 0x1f) == 0x00) &&
2269                                  (pTarget->minSyncFactor <= MPT_ULTRA160 ))
2270                                 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2271                         else
2272                                 max_depth = MPT_SCSI_CMD_PER_DEV_LOW;
2273                 } else {
2274                         /* error case - No Inq. Data */
2275                         max_depth = 1;
2276                 }
2277         } else
2278                 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2279
2280         if (qdepth > max_depth)
2281                 qdepth = max_depth;
2282         if (qdepth == 1)
2283                 tagged = 0;
2284         else
2285                 tagged = MSG_SIMPLE_TAG;
2286
2287         scsi_adjust_queue_depth(sdev, tagged, qdepth);
2288         return sdev->queue_depth;
2289 }
2290
2291 /*
2292  *      OS entry point to adjust the queue_depths on a per-device basis.
2293  *      Called once per device the bus scan. Use it to force the queue_depth
2294  *      member to 1 if a device does not support Q tags.
2295  *      Return non-zero if fails.
2296  */
2297 int
2298 mptscsih_slave_configure(struct scsi_device *device)
2299 {
2300         struct Scsi_Host        *sh = device->host;
2301         VirtDevice              *pTarget;
2302         MPT_SCSI_HOST           *hd = (MPT_SCSI_HOST *)sh->hostdata;
2303
2304         if ((hd == NULL) || (hd->Targets == NULL)) {
2305                 return 0;
2306         }
2307
2308         dsprintk((MYIOC_s_INFO_FMT
2309                 "device @ %p, id=%d, LUN=%d, channel=%d\n",
2310                 hd->ioc->name, device, device->id, device->lun, device->channel));
2311         dsprintk((MYIOC_s_INFO_FMT
2312                 "sdtr %d wdtr %d ppr %d inq length=%d\n",
2313                 hd->ioc->name, device->sdtr, device->wdtr,
2314                 device->ppr, device->inquiry_len));
2315
2316         if (device->id > sh->max_id) {
2317                 /* error case, should never happen */
2318                 scsi_adjust_queue_depth(device, 0, 1);
2319                 goto slave_configure_exit;
2320         }
2321
2322         pTarget = hd->Targets[device->id];
2323
2324         if (pTarget == NULL) {
2325                 /* Driver doesn't know about this device.
2326                  * Kernel may generate a "Dummy Lun 0" which
2327                  * may become a real Lun if a
2328                  * "scsi add-single-device" command is executed
2329                  * while the driver is active (hot-plug a
2330                  * device).  LSI Raid controllers need
2331                  * queue_depth set to DEV_HIGH for this reason.
2332                  */
2333                 scsi_adjust_queue_depth(device, MSG_SIMPLE_TAG,
2334                         MPT_SCSI_CMD_PER_DEV_HIGH);
2335                 goto slave_configure_exit;
2336         }
2337
2338         mptscsih_initTarget(hd, device->channel, device->id, device->lun,
2339                 device->inquiry, device->inquiry_len );
2340         mptscsih_change_queue_depth(device, MPT_SCSI_CMD_PER_DEV_HIGH);
2341
2342         dsprintk((MYIOC_s_INFO_FMT
2343                 "Queue depth=%d, tflags=%x\n",
2344                 hd->ioc->name, device->queue_depth, pTarget->tflags));
2345
2346         dsprintk((MYIOC_s_INFO_FMT
2347                 "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
2348                 hd->ioc->name, pTarget->negoFlags, pTarget->maxOffset, pTarget->minSyncFactor));
2349
2350 slave_configure_exit:
2351
2352         dsprintk((MYIOC_s_INFO_FMT
2353                 "tagged %d, simple %d, ordered %d\n",
2354                 hd->ioc->name,device->tagged_supported, device->simple_tags,
2355                 device->ordered_tags));
2356
2357         return 0;
2358 }
2359
2360 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2361 /*
2362  *  Private routines...
2363  */
2364
2365 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2366 /* Utility function to copy sense data from the scsi_cmnd buffer
2367  * to the FC and SCSI target structures.
2368  *
2369  */
2370 static void
2371 mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
2372 {
2373         VirtDevice      *target;
2374         SCSIIORequest_t *pReq;
2375         u32              sense_count = le32_to_cpu(pScsiReply->SenseCount);
2376         int              index;
2377
2378         /* Get target structure
2379          */
2380         pReq = (SCSIIORequest_t *) mf;
2381         index = (int) pReq->TargetID;
2382         target = hd->Targets[index];
2383
2384         if (sense_count) {
2385                 u8 *sense_data;
2386                 int req_index;
2387
2388                 /* Copy the sense received into the scsi command block. */
2389                 req_index = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2390                 sense_data = ((u8 *)hd->ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC));
2391                 memcpy(sc->sense_buffer, sense_data, SNS_LEN(sc));
2392
2393                 /* Log SMART data (asc = 0x5D, non-IM case only) if required.
2394                  */
2395                 if ((hd->ioc->events) && (hd->ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) {
2396                         if ((sense_data[12] == 0x5D) && (target->raidVolume == 0)) {
2397                                 int idx;
2398                                 MPT_ADAPTER *ioc = hd->ioc;
2399
2400                                 idx = ioc->eventContext % ioc->eventLogSize;
2401                                 ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
2402                                 ioc->events[idx].eventContext = ioc->eventContext;
2403
2404                                 ioc->events[idx].data[0] = (pReq->LUN[1] << 24) ||
2405                                         (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) ||
2406                                         (pReq->Bus << 8) || pReq->TargetID;
2407
2408                                 ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12];
2409
2410                                 ioc->eventContext++;
2411                         }
2412                 }
2413         } else {
2414                 dprintk((MYIOC_s_INFO_FMT "Hmmm... SenseData len=0! (?)\n",
2415                                 hd->ioc->name));
2416         }
2417 }
2418
2419 static u32
2420 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc)
2421 {
2422         MPT_SCSI_HOST *hd;
2423         int i;
2424
2425         hd = (MPT_SCSI_HOST *) sc->device->host->hostdata;
2426
2427         for (i = 0; i < hd->ioc->req_depth; i++) {
2428                 if (hd->ScsiLookup[i] == sc) {
2429                         return i;
2430                 }
2431         }
2432
2433         return -1;
2434 }
2435
2436 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2437 int
2438 mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2439 {
2440         MPT_SCSI_HOST   *hd;
2441         unsigned long    flags;
2442         int             ii;
2443
2444         dtmprintk((KERN_WARNING MYNAM
2445                         ": IOC %s_reset routed to SCSI host driver!\n",
2446                         reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
2447                         reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
2448
2449         /* If a FW reload request arrives after base installed but
2450          * before all scsi hosts have been attached, then an alt_ioc
2451          * may have a NULL sh pointer.
2452          */
2453         if ((ioc->sh == NULL) || (ioc->sh->hostdata == NULL))
2454                 return 0;
2455         else
2456                 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2457
2458         if (reset_phase == MPT_IOC_SETUP_RESET) {
2459                 dtmprintk((MYIOC_s_WARN_FMT "Setup-Diag Reset\n", ioc->name));
2460
2461                 /* Clean Up:
2462                  * 1. Set Hard Reset Pending Flag
2463                  * All new commands go to doneQ
2464                  */
2465                 hd->resetPending = 1;
2466
2467         } else if (reset_phase == MPT_IOC_PRE_RESET) {
2468                 dtmprintk((MYIOC_s_WARN_FMT "Pre-Diag Reset\n", ioc->name));
2469
2470                 /* 2. Flush running commands
2471                  *      Clean ScsiLookup (and associated memory)
2472                  *      AND clean mytaskQ
2473                  */
2474
2475                 /* 2b. Reply to OS all known outstanding I/O commands.
2476                  */
2477                 mptscsih_flush_running_cmds(hd);
2478
2479                 /* 2c. If there was an internal command that
2480                  * has not completed, configuration or io request,
2481                  * free these resources.
2482                  */
2483                 if (hd->cmdPtr) {
2484                         del_timer(&hd->timer);
2485                         mpt_free_msg_frame(ioc, hd->cmdPtr);
2486                 }
2487
2488                 dtmprintk((MYIOC_s_WARN_FMT "Pre-Reset complete.\n", ioc->name));
2489
2490         } else {
2491                 dtmprintk((MYIOC_s_WARN_FMT "Post-Diag Reset\n", ioc->name));
2492
2493                 /* Once a FW reload begins, all new OS commands are
2494                  * redirected to the doneQ w/ a reset status.
2495                  * Init all control structures.
2496                  */
2497
2498                 /* ScsiLookup initialization
2499                  */
2500                 for (ii=0; ii < hd->ioc->req_depth; ii++)
2501                         hd->ScsiLookup[ii] = NULL;
2502
2503                 /* 2. Chain Buffer initialization
2504                  */
2505
2506                 /* 4. Renegotiate to all devices, if SCSI
2507                  */
2508                 if (ioc->bus_type == SCSI) {
2509                         dnegoprintk(("writeSDP1: ALL_IDS USE_NVRAM\n"));
2510                         mptscsih_writeSDP1(hd, 0, 0, MPT_SCSICFG_ALL_IDS | MPT_SCSICFG_USE_NVRAM);
2511                 }
2512
2513                 /* 5. Enable new commands to be posted
2514                  */
2515                 spin_lock_irqsave(&ioc->FreeQlock, flags);
2516                 hd->tmPending = 0;
2517                 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2518                 hd->resetPending = 0;
2519                 hd->tmState = TM_STATE_NONE;
2520
2521                 /* 6. If there was an internal command,
2522                  * wake this process up.
2523                  */
2524                 if (hd->cmdPtr) {
2525                         /*
2526                          * Wake up the original calling thread
2527                          */
2528                         hd->pLocal = &hd->localReply;
2529                         hd->pLocal->completion = MPT_SCANDV_DID_RESET;
2530                         hd->scandv_wait_done = 1;
2531                         wake_up(&hd->scandv_waitq);
2532                         hd->cmdPtr = NULL;
2533                 }
2534
2535                 /* 7. Set flag to force DV and re-read IOC Page 3
2536                  */
2537                 if (ioc->bus_type == SCSI) {
2538                         ioc->spi_data.forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
2539                         ddvtprintk(("Set reload IOC Pg3 Flag\n"));
2540                 }
2541
2542                 dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name));
2543
2544         }
2545
2546         return 1;               /* currently means nothing really */
2547 }
2548
2549 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2550 /* work queue thread to clear the persitency table */
2551 static void
2552 mptscsih_sas_persist_clear_table(void * arg)
2553 {
2554         MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg;
2555
2556         mptbase_sas_persist_operation(ioc, MPI_SAS_OP_CLEAR_NOT_PRESENT);
2557 }
2558
2559 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2560 int
2561 mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2562 {
2563         MPT_SCSI_HOST *hd;
2564         u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
2565
2566         devtprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
2567                         ioc->name, event));
2568
2569         if (ioc->sh == NULL ||
2570                 ((hd = (MPT_SCSI_HOST *)ioc->sh->hostdata) == NULL))
2571                 return 1;
2572
2573         switch (event) {
2574         case MPI_EVENT_UNIT_ATTENTION:                  /* 03 */
2575                 /* FIXME! */
2576                 break;
2577         case MPI_EVENT_IOC_BUS_RESET:                   /* 04 */
2578         case MPI_EVENT_EXT_BUS_RESET:                   /* 05 */
2579                 if (hd && (ioc->bus_type == SCSI) && (hd->soft_resets < -1))
2580                         hd->soft_resets++;
2581                 break;
2582         case MPI_EVENT_LOGOUT:                          /* 09 */
2583                 /* FIXME! */
2584                 break;
2585
2586                 /*
2587                  *  CHECKME! Don't think we need to do
2588                  *  anything for these, but...
2589                  */
2590         case MPI_EVENT_RESCAN:                          /* 06 */
2591         case MPI_EVENT_LINK_STATUS_CHANGE:              /* 07 */
2592         case MPI_EVENT_LOOP_STATE_CHANGE:               /* 08 */
2593                 /*
2594                  *  CHECKME!  Falling thru...
2595                  */
2596                 break;
2597
2598         case MPI_EVENT_INTEGRATED_RAID:                 /* 0B */
2599         {
2600                 pMpiEventDataRaid_t pRaidEventData =
2601                     (pMpiEventDataRaid_t) pEvReply->Data;
2602 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
2603                 /* Domain Validation Needed */
2604                 if (ioc->bus_type == SCSI &&
2605                     pRaidEventData->ReasonCode ==
2606                     MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED)
2607                         mptscsih_set_dvflags_raid(hd, pRaidEventData->PhysDiskNum);
2608 #endif
2609                 break;
2610         }
2611
2612         /* Persistent table is full. */
2613         case MPI_EVENT_PERSISTENT_TABLE_FULL:
2614                 INIT_WORK(&mptscsih_persistTask,
2615                     mptscsih_sas_persist_clear_table,(void *)ioc);
2616                 schedule_work(&mptscsih_persistTask);
2617                 break;
2618
2619         case MPI_EVENT_NONE:                            /* 00 */
2620         case MPI_EVENT_LOG_DATA:                        /* 01 */
2621         case MPI_EVENT_STATE_CHANGE:                    /* 02 */
2622         case MPI_EVENT_EVENT_CHANGE:                    /* 0A */
2623         default:
2624                 dprintk((KERN_INFO "  Ignoring event (=%02Xh)\n", event));
2625                 break;
2626         }
2627
2628         return 1;               /* currently means nothing really */
2629 }
2630
2631 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2632 /*
2633  *      mptscsih_initTarget - Target, LUN alloc/free functionality.
2634  *      @hd: Pointer to MPT_SCSI_HOST structure
2635  *      @bus_id: Bus number (?)
2636  *      @target_id: SCSI target id
2637  *      @lun: SCSI LUN id
2638  *      @data: Pointer to data
2639  *      @dlen: Number of INQUIRY bytes
2640  *
2641  *      NOTE: It's only SAFE to call this routine if data points to
2642  *      sane & valid STANDARD INQUIRY data!
2643  *
2644  *      Allocate and initialize memory for this target.
2645  *      Save inquiry data.
2646  *
2647  */
2648 static void
2649 mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *data, int dlen)
2650 {
2651         int             indexed_lun, lun_index;
2652         VirtDevice      *vdev;
2653         SpiCfgData      *pSpi;
2654         char            data_56;
2655
2656         dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n",
2657                         hd->ioc->name, bus_id, target_id, lun, hd));
2658
2659         /*
2660          * If the peripheral qualifier filter is enabled then if the target reports a 0x1
2661          * (i.e. The targer is capable of supporting the specified peripheral device type
2662          * on this logical unit; however, the physical device is not currently connected
2663          * to this logical unit) it will be converted to a 0x3 (i.e. The target is not
2664          * capable of supporting a physical device on this logical unit). This is to work
2665          * around a bug in th emid-layer in some distributions in which the mid-layer will
2666          * continue to try to communicate to the LUN and evntually create a dummy LUN.
2667         */
2668         if (hd->mpt_pq_filter && dlen && (data[0] & 0xE0))
2669                 data[0] |= 0x40;
2670
2671         /* Is LUN supported? If so, upper 2 bits will be 0
2672         * in first byte of inquiry data.
2673         */
2674         if (data[0] & 0xe0)
2675                 return;
2676
2677         if ((vdev = hd->Targets[target_id]) == NULL) {
2678                 return;
2679         }
2680
2681         lun_index = (lun >> 5);  /* 32 luns per lun_index */
2682         indexed_lun = (lun % 32);
2683         vdev->luns[lun_index] |= (1 << indexed_lun);
2684
2685         if (hd->ioc->bus_type == SCSI) {
2686                 if ((data[0] == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) {
2687                         /* Treat all Processors as SAF-TE if
2688                          * command line option is set */
2689                         vdev->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
2690                         mptscsih_writeIOCPage4(hd, target_id, bus_id);
2691                 }else if ((data[0] == TYPE_PROCESSOR) &&
2692                         !(vdev->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) {
2693                         if ( dlen > 49 ) {
2694                                 vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
2695                                 if ( data[44] == 'S' &&
2696                                      data[45] == 'A' &&
2697                                      data[46] == 'F' &&
2698                                      data[47] == '-' &&
2699                                      data[48] == 'T' &&
2700                                      data[49] == 'E' ) {
2701                                         vdev->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
2702                                         mptscsih_writeIOCPage4(hd, target_id, bus_id);
2703                                 }
2704                         }
2705                 }
2706                 if (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY)) {
2707                         if ( dlen > 8 ) {
2708                                 memcpy (vdev->inq_data, data, 8);
2709                         } else {
2710                                 memcpy (vdev->inq_data, data, dlen);
2711                         }
2712
2713                         /* If have not done DV, set the DV flag.
2714                          */
2715                         pSpi = &hd->ioc->spi_data;
2716                         if ((data[0] == TYPE_TAPE) || (data[0] == TYPE_PROCESSOR)) {
2717                                 if (pSpi->dvStatus[target_id] & MPT_SCSICFG_DV_NOT_DONE)
2718                                         pSpi->dvStatus[target_id] |= MPT_SCSICFG_NEED_DV;
2719                         }
2720
2721                         vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
2722
2723
2724                         data_56 = 0x0F;  /* Default to full capabilities if Inq data length is < 57 */
2725                         if (dlen > 56) {
2726                                 if ( (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_56))) {
2727                                 /* Update the target capabilities
2728                                  */
2729                                         data_56 = data[56];
2730                                         vdev->tflags |= MPT_TARGET_FLAGS_VALID_56;
2731                                 }
2732                         }
2733                         mptscsih_setTargetNegoParms(hd, vdev, data_56);
2734                 } else {
2735                         /* Initial Inquiry may not request enough data bytes to
2736                          * obtain byte 57.  DV will; if target doesn't return
2737                          * at least 57 bytes, data[56] will be zero. */
2738                         if (dlen > 56) {
2739                                 if ( (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_56))) {
2740                                 /* Update the target capabilities
2741                                  */
2742                                         data_56 = data[56];
2743                                         vdev->tflags |= MPT_TARGET_FLAGS_VALID_56;
2744                                         mptscsih_setTargetNegoParms(hd, vdev, data_56);
2745                                 }
2746                         }
2747                 }
2748         }
2749 }
2750
2751 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2752 /*
2753  *  Update the target negotiation parameters based on the
2754  *  the Inquiry data, adapter capabilities, and NVRAM settings.
2755  *
2756  */
2757 static void
2758 mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56)
2759 {
2760         SpiCfgData *pspi_data = &hd->ioc->spi_data;
2761         int  id = (int) target->target_id;
2762         int  nvram;
2763         VirtDevice      *vdev;
2764         int ii;
2765         u8 width = MPT_NARROW;
2766         u8 factor = MPT_ASYNC;
2767         u8 offset = 0;
2768         u8 version, nfactor;
2769         u8 noQas = 1;
2770
2771         target->negoFlags = pspi_data->noQas;
2772
2773         /* noQas == 0 => device supports QAS. Need byte 56 of Inq to determine
2774          * support. If available, default QAS to off and allow enabling.
2775          * If not available, default QAS to on, turn off for non-disks.
2776          */
2777
2778         /* Set flags based on Inquiry data
2779          */
2780         version = target->inq_data[2] & 0x07;
2781         if (version < 2) {
2782                 width = 0;
2783                 factor = MPT_ULTRA2;
2784                 offset = pspi_data->maxSyncOffset;
2785                 target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
2786         } else {
2787                 if (target->inq_data[7] & 0x20) {
2788                         width = 1;
2789                 }
2790
2791                 if (target->inq_data[7] & 0x10) {
2792                         factor = pspi_data->minSyncFactor;
2793                         if (target->tflags & MPT_TARGET_FLAGS_VALID_56) {
2794                                 /* bits 2 & 3 show Clocking support */
2795                                 if ((byte56 & 0x0C) == 0)
2796                                         factor = MPT_ULTRA2;
2797                                 else {
2798                                         if ((byte56 & 0x03) == 0)
2799                                                 factor = MPT_ULTRA160;
2800                                         else {
2801                                                 factor = MPT_ULTRA320;
2802                                                 if (byte56 & 0x02)
2803                                                 {
2804                                                         ddvtprintk((KERN_INFO "Enabling QAS due to byte56=%02x on id=%d!\n", byte56, id));
2805                                                         noQas = 0;
2806                                                 }
2807                                                 if (target->inq_data[0] == TYPE_TAPE) {
2808                                                         if (byte56 & 0x01)
2809                                                                 target->negoFlags |= MPT_TAPE_NEGO_IDP;
2810                                                 }
2811                                         }
2812                                 }
2813                         } else {
2814                                 ddvtprintk((KERN_INFO "Enabling QAS on id=%d due to ~TARGET_FLAGS_VALID_56!\n", id));
2815                                 noQas = 0;
2816                         }
2817
2818                         offset = pspi_data->maxSyncOffset;
2819
2820                         /* If RAID, never disable QAS
2821                          * else if non RAID, do not disable
2822                          *   QAS if bit 1 is set
2823                          * bit 1 QAS support, non-raid only
2824                          * bit 0 IU support
2825                          */
2826                         if (target->raidVolume == 1) {
2827                                 noQas = 0;
2828                         }
2829                 } else {
2830                         factor = MPT_ASYNC;
2831                         offset = 0;
2832                 }
2833         }
2834
2835         if ( (target->inq_data[7] & 0x02) == 0) {
2836                 target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
2837         }
2838
2839         /* Update tflags based on NVRAM settings. (SCSI only)
2840          */
2841         if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
2842                 nvram = pspi_data->nvram[id];
2843                 nfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
2844
2845                 if (width)
2846                         width = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
2847
2848                 if (offset > 0) {
2849                         /* Ensure factor is set to the
2850                          * maximum of: adapter, nvram, inquiry
2851                          */
2852                         if (nfactor) {
2853                                 if (nfactor < pspi_data->minSyncFactor )
2854                                         nfactor = pspi_data->minSyncFactor;
2855
2856                                 factor = max(factor, nfactor);
2857                                 if (factor == MPT_ASYNC)
2858                                         offset = 0;
2859                         } else {
2860                                 offset = 0;
2861                                 factor = MPT_ASYNC;
2862                 }
2863                 } else {
2864                         factor = MPT_ASYNC;
2865                 }
2866         }
2867
2868         /* Make sure data is consistent
2869          */
2870         if ((!width) && (factor < MPT_ULTRA2)) {
2871                 factor = MPT_ULTRA2;
2872         }
2873
2874         /* Save the data to the target structure.
2875          */
2876         target->minSyncFactor = factor;
2877         target->maxOffset = offset;
2878         target->maxWidth = width;
2879
2880         target->tflags |= MPT_TARGET_FLAGS_VALID_NEGO;
2881
2882         /* Disable unused features.
2883          */
2884         if (!width)
2885                 target->negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
2886
2887         if (!offset)
2888                 target->negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
2889
2890         if ( factor > MPT_ULTRA320 )
2891                 noQas = 0;
2892
2893         /* GEM, processor WORKAROUND
2894          */
2895         if ((target->inq_data[0] == TYPE_PROCESSOR) || (target->inq_data[0] > 0x08)) {
2896                 target->negoFlags |= (MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC);
2897                 pspi_data->dvStatus[id] |= MPT_SCSICFG_BLK_NEGO;
2898         } else {
2899                 if (noQas && (pspi_data->noQas == 0)) {
2900                         pspi_data->noQas |= MPT_TARGET_NO_NEGO_QAS;
2901                         target->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
2902
2903                         /* Disable QAS in a mixed configuration case
2904                         */
2905
2906                         ddvtprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id));
2907                         for (ii = 0; ii < id; ii++) {
2908                                 if ( (vdev = hd->Targets[ii]) ) {
2909                                         vdev->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
2910                                         mptscsih_writeSDP1(hd, 0, ii, vdev->negoFlags);
2911                                 }
2912                         }
2913                 }
2914         }
2915
2916         /* Write SDP1 on this I/O to this target */
2917         if (pspi_data->dvStatus[id] & MPT_SCSICFG_NEGOTIATE) {
2918                 ddvtprintk((KERN_INFO "MPT_SCSICFG_NEGOTIATE on id=%d!\n", id));
2919                 mptscsih_writeSDP1(hd, 0, id, hd->negoNvram);
2920                 pspi_data->dvStatus[id] &= ~MPT_SCSICFG_NEGOTIATE;
2921         } else if (pspi_data->dvStatus[id] & MPT_SCSICFG_BLK_NEGO) {
2922                 ddvtprintk((KERN_INFO "MPT_SCSICFG_BLK_NEGO on id=%d!\n", id));
2923                 mptscsih_writeSDP1(hd, 0, id, MPT_SCSICFG_BLK_NEGO);
2924                 pspi_data->dvStatus[id] &= ~MPT_SCSICFG_BLK_NEGO;
2925         }
2926 }
2927
2928 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2929 /* If DV disabled (negoNvram set to USE_NVARM) or if not LUN 0, return.
2930  * Else set the NEED_DV flag after Read Capacity Issued (disks)
2931  * or Mode Sense (cdroms).
2932  *
2933  * Tapes, initTarget will set this flag on completion of Inquiry command.
2934  * Called only if DV_NOT_DONE flag is set
2935  */
2936 static void
2937 mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq)
2938 {
2939         MPT_ADAPTER     *ioc = hd->ioc;
2940         u8 cmd;
2941         SpiCfgData      *pSpi;
2942
2943         ddvtprintk((MYIOC_s_NOTE_FMT
2944                 " set_dvflags: id=%d lun=%d negoNvram=%x cmd=%x\n",
2945                 hd->ioc->name, pReq->TargetID, pReq->LUN[1], hd->negoNvram, pReq->CDB[0]));
2946
2947         if ((pReq->LUN[1] != 0) || (hd->negoNvram != 0))
2948                 return;
2949
2950         cmd = pReq->CDB[0];
2951
2952         if ((cmd == READ_CAPACITY) || (cmd == MODE_SENSE)) {
2953                 pSpi = &ioc->spi_data;
2954                 if ((ioc->raid_data.isRaid & (1 << pReq->TargetID)) && ioc->raid_data.pIocPg3) {
2955                         /* Set NEED_DV for all hidden disks
2956                          */
2957                         Ioc3PhysDisk_t *pPDisk =  ioc->raid_data.pIocPg3->PhysDisk;
2958                         int             numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
2959
2960                         while (numPDisk) {
2961                                 pSpi->dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV;
2962                                 ddvtprintk(("NEED_DV set for phys disk id %d\n", pPDisk->PhysDiskID));
2963                                 pPDisk++;
2964                                 numPDisk--;
2965                         }
2966                 }
2967                 pSpi->dvStatus[pReq->TargetID] |= MPT_SCSICFG_NEED_DV;
2968                 ddvtprintk(("NEED_DV set for visible disk id %d\n", pReq->TargetID));
2969         }
2970 }
2971
2972 /* mptscsih_raid_set_dv_flags()
2973  *
2974  * New or replaced disk. Set DV flag and schedule DV.
2975  */
2976 static void
2977 mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id)
2978 {
2979         MPT_ADAPTER     *ioc = hd->ioc;
2980         SpiCfgData      *pSpi = &ioc->spi_data;
2981         Ioc3PhysDisk_t  *pPDisk;
2982         int              numPDisk;
2983
2984         if (hd->negoNvram != 0)
2985                 return;
2986
2987         ddvtprintk(("DV requested for phys disk id %d\n", id));
2988         if (ioc->raid_data.pIocPg3) {
2989                 pPDisk =  ioc->raid_data.pIocPg3->PhysDisk;
2990                 numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
2991                 while (numPDisk) {
2992                         if (id == pPDisk->PhysDiskNum) {
2993                                 pSpi->dvStatus[pPDisk->PhysDiskID] =
2994                                     (MPT_SCSICFG_NEED_DV | MPT_SCSICFG_DV_NOT_DONE);
2995                                 pSpi->forceDv = MPT_SCSICFG_NEED_DV;
2996                                 ddvtprintk(("NEED_DV set for phys disk id %d\n",
2997                                     pPDisk->PhysDiskID));
2998                                 break;
2999                         }
3000                         pPDisk++;
3001                         numPDisk--;
3002                 }
3003
3004                 if (numPDisk == 0) {
3005                         /* The physical disk that needs DV was not found
3006                          * in the stored IOC Page 3. The driver must reload
3007                          * this page. DV routine will set the NEED_DV flag for
3008                          * all phys disks that have DV_NOT_DONE set.
3009                          */
3010                         pSpi->forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
3011                         ddvtprintk(("phys disk %d not found. Setting reload IOC Pg3 Flag\n",id));
3012                 }
3013         }
3014 }
3015
3016 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3017 /*
3018  * If no Target, bus reset on 1st I/O. Set the flag to
3019  * prevent any future negotiations to this device.
3020  */
3021 static void
3022 mptscsih_no_negotiate(MPT_SCSI_HOST *hd, int target_id)
3023 {
3024
3025         if ((hd->Targets) && (hd->Targets[target_id] == NULL))
3026                 hd->ioc->spi_data.dvStatus[target_id] |= MPT_SCSICFG_BLK_NEGO;
3027
3028         return;
3029 }
3030
3031 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3032 /*
3033  *  SCSI Config Page functionality ...
3034  */
3035 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3036 /*      mptscsih_setDevicePage1Flags  - add Requested and Configuration fields flags
3037  *      based on width, factor and offset parameters.
3038  *      @width: bus width
3039  *      @factor: sync factor
3040  *      @offset: sync offset
3041  *      @requestedPtr: pointer to requested values (updated)
3042  *      @configurationPtr: pointer to configuration values (updated)
3043  *      @flags: flags to block WDTR or SDTR negotiation
3044  *
3045  *      Return: None.
3046  *
3047  *      Remark: Called by writeSDP1 and _dv_params
3048  */
3049 static void
3050 mptscsih_setDevicePage1Flags (u8 width, u8 factor, u8 offset, int *requestedPtr, int *configurationPtr, u8 flags)
3051 {
3052         u8 nowide = flags & MPT_TARGET_NO_NEGO_WIDE;
3053         u8 nosync = flags & MPT_TARGET_NO_NEGO_SYNC;
3054
3055         *configurationPtr = 0;
3056         *requestedPtr = width ? MPI_SCSIDEVPAGE1_RP_WIDE : 0;
3057         *requestedPtr |= (offset << 16) | (factor << 8);
3058
3059         if (width && offset && !nowide && !nosync) {
3060                 if (factor < MPT_ULTRA160) {
3061                         *requestedPtr |= (MPI_SCSIDEVPAGE1_RP_IU + MPI_SCSIDEVPAGE1_RP_DT);
3062                         if ((flags & MPT_TARGET_NO_NEGO_QAS) == 0)