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