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