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