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