[SCSI] fusion - bump version - 3.04.04
[linux-2.6.git] / drivers / message / fusion / mptscsih.c
1 /*
2  *  linux/drivers/message/fusion/mptscsih.c
3  *      For use with LSI Logic PCI chip/adapter(s)
4  *      running LSI Logic Fusion MPT (Message Passing Technology) firmware.
5  *
6  *  Copyright (c) 1999-2007 LSI Logic Corporation
7  *  (mailto:mpt_linux_developer@lsi.com)
8  *
9  */
10 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
11 /*
12     This program is free software; you can redistribute it and/or modify
13     it under the terms of the GNU General Public License as published by
14     the Free Software Foundation; version 2 of the License.
15
16     This program is distributed in the hope that it will be useful,
17     but WITHOUT ANY WARRANTY; without even the implied warranty of
18     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19     GNU General Public License for more details.
20
21     NO WARRANTY
22     THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
23     CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
24     LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
25     MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
26     solely responsible for determining the appropriateness of using and
27     distributing the Program and assumes all risks associated with its
28     exercise of rights under this Agreement, including but not limited to
29     the risks and costs of program errors, damage to or loss of data,
30     programs or equipment, and unavailability or interruption of operations.
31
32     DISCLAIMER OF LIABILITY
33     NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
34     DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
35     DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
36     ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
37     TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
38     USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
39     HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
40
41     You should have received a copy of the GNU General Public License
42     along with this program; if not, write to the Free Software
43     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
44 */
45 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
46
47 #include "linux_compat.h"       /* linux-2.6 tweaks */
48 #include <linux/module.h>
49 #include <linux/kernel.h>
50 #include <linux/init.h>
51 #include <linux/errno.h>
52 #include <linux/kdev_t.h>
53 #include <linux/blkdev.h>
54 #include <linux/delay.h>        /* for mdelay */
55 #include <linux/interrupt.h>    /* needed for in_interrupt() proto */
56 #include <linux/reboot.h>       /* notifier code */
57 #include <linux/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 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         u32              ioc_raw_state;
1563         unsigned long    flags;
1564
1565         ioc = hd->ioc;
1566         dtmprintk((MYIOC_s_INFO_FMT "TMHandler Entered!\n", ioc->name));
1567
1568         // SJR - CHECKME - Can we avoid this here?
1569         // (mpt_HardResetHandler has this check...)
1570         spin_lock_irqsave(&ioc->diagLock, flags);
1571         if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)) {
1572                 spin_unlock_irqrestore(&ioc->diagLock, flags);
1573                 return FAILED;
1574         }
1575         spin_unlock_irqrestore(&ioc->diagLock, flags);
1576
1577         /*  Wait a fixed amount of time for the TM pending flag to be cleared.
1578          *  If we time out and not bus reset, then we return a FAILED status
1579          *  to the caller.
1580          *  The call to mptscsih_tm_pending_wait() will set the pending flag
1581          *  if we are
1582          *  successful. Otherwise, reload the FW.
1583          */
1584         if (mptscsih_tm_pending_wait(hd) == FAILED) {
1585                 if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
1586                         dtmprintk((KERN_INFO MYNAM ": %s: TMHandler abort: "
1587                            "Timed out waiting for last TM (%d) to complete! \n",
1588                            hd->ioc->name, hd->tmPending));
1589                         return FAILED;
1590                 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) {
1591                         dtmprintk((KERN_INFO MYNAM ": %s: TMHandler target "
1592                                 "reset: Timed out waiting for last TM (%d) "
1593                                 "to complete! \n", hd->ioc->name,
1594                                 hd->tmPending));
1595                         return FAILED;
1596                 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
1597                         dtmprintk((KERN_INFO MYNAM ": %s: TMHandler bus reset: "
1598                            "Timed out waiting for last TM (%d) to complete! \n",
1599                            hd->ioc->name, hd->tmPending));
1600                         return FAILED;
1601                 }
1602         } else {
1603                 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
1604                 hd->tmPending |=  (1 << type);
1605                 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1606         }
1607
1608         ioc_raw_state = mpt_GetIocState(hd->ioc, 0);
1609
1610         if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) {
1611                 printk(MYIOC_s_WARN_FMT
1612                         "TM Handler for type=%x: IOC Not operational (0x%x)!\n",
1613                         ioc->name, type, ioc_raw_state);
1614                 printk(KERN_WARNING " Issuing HardReset!!\n");
1615                 if (mpt_HardResetHandler(ioc, CAN_SLEEP) < 0)
1616                         printk((KERN_WARNING "TMHandler: HardReset "
1617                                 "FAILED!!\n"));
1618                 return FAILED;
1619         }
1620
1621         if (ioc_raw_state & MPI_DOORBELL_ACTIVE) {
1622                 printk(MYIOC_s_WARN_FMT
1623                         "TM Handler for type=%x: ioc_state: "
1624                         "DOORBELL_ACTIVE (0x%x)!\n",
1625                         ioc->name, type, ioc_raw_state);
1626                 return FAILED;
1627         }
1628
1629         /* Isse the Task Mgmt request.
1630          */
1631         if (hd->hard_resets < -1)
1632                 hd->hard_resets++;
1633
1634         rc = mptscsih_IssueTaskMgmt(hd, type, channel, id, lun,
1635             ctx2abort, timeout);
1636         if (rc)
1637                 printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n",
1638                        hd->ioc->name);
1639         else
1640                 dtmprintk((MYIOC_s_INFO_FMT "Issue of TaskMgmt Successful!\n",
1641                            hd->ioc->name));
1642
1643         dtmprintk((MYIOC_s_INFO_FMT "TMHandler rc = %d!\n", hd->ioc->name, rc));
1644
1645         return rc;
1646 }
1647
1648
1649 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1650 /**
1651  *      mptscsih_IssueTaskMgmt - Generic send Task Management function.
1652  *      @hd: Pointer to MPT_SCSI_HOST structure
1653  *      @type: Task Management type
1654  *      @id: Logical Target ID for reset (if appropriate)
1655  *      @lun: Logical Unit for reset (if appropriate)
1656  *      @ctx2abort: Context for the task to be aborted (if appropriate)
1657  *
1658  *      Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
1659  *      or a non-interrupt thread.  In the former, must not call schedule().
1660  *
1661  *      Not all fields are meaningfull for all task types.
1662  *
1663  *      Returns 0 for SUCCESS, or FAILED.
1664  *
1665  **/
1666 static int
1667 mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout)
1668 {
1669         MPT_FRAME_HDR   *mf;
1670         SCSITaskMgmt_t  *pScsiTm;
1671         int              ii;
1672         int              retval;
1673
1674         /* Return Fail to calling function if no message frames available.
1675          */
1676         if ((mf = mpt_get_msg_frame(hd->ioc->TaskCtx, hd->ioc)) == NULL) {
1677                 dfailprintk((MYIOC_s_ERR_FMT "IssueTaskMgmt, no msg frames!!\n",
1678                                 hd->ioc->name));
1679                 return FAILED;
1680         }
1681         dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt request @ %p\n",
1682                         hd->ioc->name, mf));
1683
1684         /* Format the Request
1685          */
1686         pScsiTm = (SCSITaskMgmt_t *) mf;
1687         pScsiTm->TargetID = id;
1688         pScsiTm->Bus = channel;
1689         pScsiTm->ChainOffset = 0;
1690         pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
1691
1692         pScsiTm->Reserved = 0;
1693         pScsiTm->TaskType = type;
1694         pScsiTm->Reserved1 = 0;
1695         pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)
1696                     ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0;
1697
1698         int_to_scsilun(lun, (struct scsi_lun *)pScsiTm->LUN);
1699
1700         for (ii=0; ii < 7; ii++)
1701                 pScsiTm->Reserved2[ii] = 0;
1702
1703         pScsiTm->TaskMsgContext = ctx2abort;
1704
1705         dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt: ctx2abort (0x%08x) "
1706                 "type=%d\n", hd->ioc->name, ctx2abort, type));
1707
1708         DBG_DUMP_TM_REQUEST_FRAME((u32 *)pScsiTm);
1709
1710         if ((retval = mpt_send_handshake_request(hd->ioc->TaskCtx, hd->ioc,
1711                 sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, CAN_SLEEP)) != 0) {
1712                 dfailprintk((MYIOC_s_ERR_FMT "send_handshake FAILED!"
1713                         " (hd %p, ioc %p, mf %p, rc=%d) \n", hd->ioc->name, hd,
1714                         hd->ioc, mf, retval));
1715                 goto fail_out;
1716         }
1717
1718         if(mptscsih_tm_wait_for_completion(hd, timeout) == FAILED) {
1719                 dfailprintk((MYIOC_s_ERR_FMT "task management request TIMED OUT!"
1720                         " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
1721                         hd->ioc, mf));
1722                 dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
1723                          hd->ioc->name));
1724                 retval = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
1725                 dtmprintk((MYIOC_s_INFO_FMT "rc=%d \n",
1726                          hd->ioc->name, retval));
1727                 goto fail_out;
1728         }
1729
1730         /*
1731          * Handle success case, see if theres a non-zero ioc_status.
1732          */
1733         if (hd->tm_iocstatus == MPI_IOCSTATUS_SUCCESS ||
1734            hd->tm_iocstatus == MPI_IOCSTATUS_SCSI_TASK_TERMINATED ||
1735            hd->tm_iocstatus == MPI_IOCSTATUS_SCSI_IOC_TERMINATED)
1736                 retval = 0;
1737         else
1738                 retval = FAILED;
1739
1740         return retval;
1741
1742  fail_out:
1743
1744         /*
1745          * Free task managment mf, and corresponding tm flags
1746          */
1747         mpt_free_msg_frame(hd->ioc, mf);
1748         hd->tmPending = 0;
1749         hd->tmState = TM_STATE_NONE;
1750         return FAILED;
1751 }
1752
1753 static int
1754 mptscsih_get_tm_timeout(MPT_ADAPTER *ioc)
1755 {
1756         switch (ioc->bus_type) {
1757         case FC:
1758                 return 40;
1759         case SAS:
1760                 return 10;
1761         case SPI:
1762         default:
1763                 return 2;
1764         }
1765 }
1766
1767 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1768 /**
1769  *      mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant
1770  *      @SCpnt: Pointer to scsi_cmnd structure, IO to be aborted
1771  *
1772  *      (linux scsi_host_template.eh_abort_handler routine)
1773  *
1774  *      Returns SUCCESS or FAILED.
1775  **/
1776 int
1777 mptscsih_abort(struct scsi_cmnd * SCpnt)
1778 {
1779         MPT_SCSI_HOST   *hd;
1780         MPT_FRAME_HDR   *mf;
1781         u32              ctx2abort;
1782         int              scpnt_idx;
1783         int              retval;
1784         VirtDevice       *vdev;
1785         ulong            sn = SCpnt->serial_number;
1786
1787         /* If we can't locate our host adapter structure, return FAILED status.
1788          */
1789         if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL) {
1790                 SCpnt->result = DID_RESET << 16;
1791                 SCpnt->scsi_done(SCpnt);
1792                 dfailprintk((KERN_INFO MYNAM ": mptscsih_abort: "
1793                            "Can't locate host! (sc=%p)\n",
1794                            SCpnt));
1795                 return FAILED;
1796         }
1797
1798         /* Find this command
1799          */
1800         if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) {
1801                 /* Cmd not found in ScsiLookup.
1802                  * Do OS callback.
1803                  */
1804                 SCpnt->result = DID_RESET << 16;
1805                 dtmprintk((KERN_INFO MYNAM ": %s: mptscsih_abort: "
1806                            "Command not in the active list! (sc=%p)\n",
1807                            hd->ioc->name, SCpnt));
1808                 return SUCCESS;
1809         }
1810
1811         if (hd->resetPending)
1812                 return FAILED;
1813
1814         if (hd->timeouts < -1)
1815                 hd->timeouts++;
1816
1817         printk(KERN_WARNING MYNAM ": %s: attempting task abort! (sc=%p)\n",
1818                hd->ioc->name, SCpnt);
1819         scsi_print_command(SCpnt);
1820
1821         /* Most important!  Set TaskMsgContext to SCpnt's MsgContext!
1822          * (the IO to be ABORT'd)
1823          *
1824          * NOTE: Since we do not byteswap MsgContext, we do not
1825          *       swap it here either.  It is an opaque cookie to
1826          *       the controller, so it does not matter. -DaveM
1827          */
1828         mf = MPT_INDEX_2_MFPTR(hd->ioc, scpnt_idx);
1829         ctx2abort = mf->u.frame.hwhdr.msgctxu.MsgContext;
1830
1831         hd->abortSCpnt = SCpnt;
1832
1833         vdev = SCpnt->device->hostdata;
1834         retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
1835                 vdev->vtarget->channel, vdev->vtarget->id, vdev->lun,
1836                 ctx2abort, mptscsih_get_tm_timeout(hd->ioc));
1837
1838         if (SCPNT_TO_LOOKUP_IDX(SCpnt) == scpnt_idx &&
1839             SCpnt->serial_number == sn)
1840                 retval = FAILED;
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         else
1849                 return FAILED;
1850 }
1851
1852 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1853 /**
1854  *      mptscsih_dev_reset - Perform a SCSI TARGET_RESET!  new_eh variant
1855  *      @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1856  *
1857  *      (linux scsi_host_template.eh_dev_reset_handler routine)
1858  *
1859  *      Returns SUCCESS or FAILED.
1860  **/
1861 int
1862 mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
1863 {
1864         MPT_SCSI_HOST   *hd;
1865         int              retval;
1866         VirtDevice       *vdev;
1867
1868         /* If we can't locate our host adapter structure, return FAILED status.
1869          */
1870         if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1871                 dtmprintk((KERN_INFO MYNAM ": mptscsih_dev_reset: "
1872                            "Can't locate host! (sc=%p)\n",
1873                            SCpnt));
1874                 return FAILED;
1875         }
1876
1877         if (hd->resetPending)
1878                 return FAILED;
1879
1880         printk(KERN_WARNING MYNAM ": %s: attempting target reset! (sc=%p)\n",
1881                hd->ioc->name, SCpnt);
1882         scsi_print_command(SCpnt);
1883
1884         vdev = SCpnt->device->hostdata;
1885         retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
1886                 vdev->vtarget->channel, vdev->vtarget->id,
1887                 0, 0, mptscsih_get_tm_timeout(hd->ioc));
1888
1889         printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n",
1890                 hd->ioc->name,
1891                 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1892
1893         if (retval == 0)
1894                 return SUCCESS;
1895         else
1896                 return FAILED;
1897 }
1898
1899
1900 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1901 /**
1902  *      mptscsih_bus_reset - Perform a SCSI BUS_RESET!  new_eh variant
1903  *      @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1904  *
1905  *      (linux scsi_host_template.eh_bus_reset_handler routine)
1906  *
1907  *      Returns SUCCESS or FAILED.
1908  **/
1909 int
1910 mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
1911 {
1912         MPT_SCSI_HOST   *hd;
1913         int              retval;
1914         VirtDevice       *vdev;
1915
1916         /* If we can't locate our host adapter structure, return FAILED status.
1917          */
1918         if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1919                 dtmprintk((KERN_INFO MYNAM ": mptscsih_bus_reset: "
1920                            "Can't locate host! (sc=%p)\n",
1921                            SCpnt ) );
1922                 return FAILED;
1923         }
1924
1925         printk(KERN_WARNING MYNAM ": %s: attempting bus reset! (sc=%p)\n",
1926                hd->ioc->name, SCpnt);
1927         scsi_print_command(SCpnt);
1928
1929         if (hd->timeouts < -1)
1930                 hd->timeouts++;
1931
1932         vdev = SCpnt->device->hostdata;
1933         retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
1934                 vdev->vtarget->channel, 0, 0, 0, mptscsih_get_tm_timeout(hd->ioc));
1935
1936         printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n",
1937                 hd->ioc->name,
1938                 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1939
1940         if (retval == 0)
1941                 return SUCCESS;
1942         else
1943                 return FAILED;
1944 }
1945
1946 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1947 /**
1948  *      mptscsih_host_reset - Perform a SCSI host adapter RESET (new_eh variant)
1949  *      @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1950  *
1951  *      (linux scsi_host_template.eh_host_reset_handler routine)
1952  *
1953  *      Returns SUCCESS or FAILED.
1954  */
1955 int
1956 mptscsih_host_reset(struct scsi_cmnd *SCpnt)
1957 {
1958         MPT_SCSI_HOST *  hd;
1959         int              status = SUCCESS;
1960
1961         /*  If we can't locate the host to reset, then we failed. */
1962         if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1963                 dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
1964                              "Can't locate host! (sc=%p)\n",
1965                              SCpnt ) );
1966                 return FAILED;
1967         }
1968
1969         printk(KERN_WARNING MYNAM ": %s: Attempting host reset! (sc=%p)\n",
1970                hd->ioc->name, SCpnt);
1971
1972         /*  If our attempts to reset the host failed, then return a failed
1973          *  status.  The host will be taken off line by the SCSI mid-layer.
1974          */
1975         if (mpt_HardResetHandler(hd->ioc, CAN_SLEEP) < 0){
1976                 status = FAILED;
1977         } else {
1978                 /*  Make sure TM pending is cleared and TM state is set to
1979                  *  NONE.
1980                  */
1981                 hd->tmPending = 0;
1982                 hd->tmState = TM_STATE_NONE;
1983         }
1984
1985         dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
1986                      "Status = %s\n",
1987                      (status == SUCCESS) ? "SUCCESS" : "FAILED" ) );
1988
1989         return status;
1990 }
1991
1992 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1993 /**
1994  *      mptscsih_tm_pending_wait - wait for pending task management request to complete
1995  *      @hd: Pointer to MPT host structure.
1996  *
1997  *      Returns {SUCCESS,FAILED}.
1998  */
1999 static int
2000 mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd)
2001 {
2002         unsigned long  flags;
2003         int            loop_count = 4 * 10;  /* Wait 10 seconds */
2004         int            status = FAILED;
2005
2006         do {
2007                 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
2008                 if (hd->tmState == TM_STATE_NONE) {
2009                         hd->tmState = TM_STATE_IN_PROGRESS;
2010                         hd->tmPending = 1;
2011                         spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2012                         status = SUCCESS;
2013                         break;
2014                 }
2015                 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2016                 msleep(250);
2017         } while (--loop_count);
2018
2019         return status;
2020 }
2021
2022 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2023 /**
2024  *      mptscsih_tm_wait_for_completion - wait for completion of TM task
2025  *      @hd: Pointer to MPT host structure.
2026  *
2027  *      Returns {SUCCESS,FAILED}.
2028  */
2029 static int
2030 mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout )
2031 {
2032         unsigned long  flags;
2033         int            loop_count = 4 * timeout;
2034         int            status = FAILED;
2035
2036         do {
2037                 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
2038                 if(hd->tmPending == 0) {
2039                         status = SUCCESS;
2040                         spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2041                         break;
2042                 }
2043                 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2044                 msleep(250);
2045         } while (--loop_count);
2046
2047         return status;
2048 }
2049
2050 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2051 static void
2052 mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code)
2053 {
2054         char *desc;
2055
2056         switch (response_code) {
2057         case MPI_SCSITASKMGMT_RSP_TM_COMPLETE:
2058                 desc = "The task completed.";
2059                 break;
2060         case MPI_SCSITASKMGMT_RSP_INVALID_FRAME:
2061                 desc = "The IOC received an invalid frame status.";
2062                 break;
2063         case MPI_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED:
2064                 desc = "The task type is not supported.";
2065                 break;
2066         case MPI_SCSITASKMGMT_RSP_TM_FAILED:
2067                 desc = "The requested task failed.";
2068                 break;
2069         case MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED:
2070                 desc = "The task completed successfully.";
2071                 break;
2072         case MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN:
2073                 desc = "The LUN request is invalid.";
2074                 break;
2075         case MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC:
2076                 desc = "The task is in the IOC queue and has not been sent to target.";
2077                 break;
2078         default:
2079                 desc = "unknown";
2080                 break;
2081         }
2082         printk(MYIOC_s_INFO_FMT "Response Code(0x%08x): F/W: %s\n",
2083                 ioc->name, response_code, desc);
2084 }
2085
2086 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2087 /**
2088  *      mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
2089  *      @ioc: Pointer to MPT_ADAPTER structure
2090  *      @mf: Pointer to SCSI task mgmt request frame
2091  *      @mr: Pointer to SCSI task mgmt reply frame
2092  *
2093  *      This routine is called from mptbase.c::mpt_interrupt() at the completion
2094  *      of any SCSI task management request.
2095  *      This routine is registered with the MPT (base) driver at driver
2096  *      load/init time via the mpt_register() API call.
2097  *
2098  *      Returns 1 indicating alloc'd request frame ptr should be freed.
2099  **/
2100 int
2101 mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
2102 {
2103         SCSITaskMgmtReply_t     *pScsiTmReply;
2104         SCSITaskMgmt_t          *pScsiTmReq;
2105         MPT_SCSI_HOST           *hd;
2106         unsigned long            flags;
2107         u16                      iocstatus;
2108         u8                       tmType;
2109         u32                      termination_count;
2110
2111         dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt completed (mf=%p,mr=%p)\n",
2112             ioc->name, mf, mr));
2113         if (!ioc->sh) {
2114                 dtmprintk((MYIOC_s_WARN_FMT
2115                     "TaskMgmt Complete: NULL Scsi Host Ptr\n", ioc->name));
2116                 return 1;
2117         }
2118
2119         if (mr == NULL) {
2120                 dtmprintk((MYIOC_s_WARN_FMT
2121                     "ERROR! TaskMgmt Reply: NULL Request %p\n", ioc->name, mf));
2122                 return 1;
2123         }
2124
2125         hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
2126         pScsiTmReply = (SCSITaskMgmtReply_t*)mr;
2127         pScsiTmReq = (SCSITaskMgmt_t*)mf;
2128         tmType = pScsiTmReq->TaskType;
2129         iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2130         termination_count = le32_to_cpu(pScsiTmReply->TerminationCount);
2131
2132         if (ioc->facts.MsgVersion >= MPI_VERSION_01_05 &&
2133             pScsiTmReply->ResponseCode)
2134                 mptscsih_taskmgmt_response_code(ioc,
2135                     pScsiTmReply->ResponseCode);
2136         DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply);
2137
2138 #if defined(MPT_DEBUG_REPLY) || defined(MPT_DEBUG_TM)
2139         printk("%s: ha=%d [%d:%d:0] task_type=0x%02X "
2140             "iocstatus=0x%04X\n\tloginfo=0x%08X response_code=0x%02X "
2141             "term_cmnds=%d\n", __FUNCTION__, ioc->id, pScsiTmReply->Bus,
2142             pScsiTmReply->TargetID, pScsiTmReq->TaskType,
2143             le16_to_cpu(pScsiTmReply->IOCStatus),
2144             le32_to_cpu(pScsiTmReply->IOCLogInfo),pScsiTmReply->ResponseCode,
2145             le32_to_cpu(pScsiTmReply->TerminationCount));
2146 #endif
2147         if (!iocstatus) {
2148                 dtmprintk((MYIOC_s_WARN_FMT " TaskMgmt SUCCESS\n", ioc->name));
2149                         hd->abortSCpnt = NULL;
2150                 goto out;
2151         }
2152
2153         /* Error?  (anything non-zero?) */
2154
2155         /* clear flags and continue.
2156          */
2157         switch (tmType) {
2158
2159         case MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK:
2160                 if (termination_count == 1)
2161                         iocstatus = MPI_IOCSTATUS_SCSI_TASK_TERMINATED;
2162                 hd->abortSCpnt = NULL;
2163                 break;
2164
2165         case MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS:
2166
2167                 /* If an internal command is present
2168                  * or the TM failed - reload the FW.
2169                  * FC FW may respond FAILED to an ABORT
2170                  */
2171                 if (iocstatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED ||
2172                     hd->cmdPtr)
2173                         if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
2174                                 printk((KERN_WARNING " Firmware Reload FAILED!!\n"));
2175                 break;
2176
2177         case MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET:
2178         default:
2179                 break;
2180         }
2181
2182  out:
2183         spin_lock_irqsave(&ioc->FreeQlock, flags);
2184         hd->tmPending = 0;
2185         hd->tmState = TM_STATE_NONE;
2186         hd->tm_iocstatus = iocstatus;
2187         spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2188
2189         return 1;
2190 }
2191
2192 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2193 /*
2194  *      This is anyones guess quite frankly.
2195  */
2196 int
2197 mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
2198                 sector_t capacity, int geom[])
2199 {
2200         int             heads;
2201         int             sectors;
2202         sector_t        cylinders;
2203         ulong           dummy;
2204
2205         heads = 64;
2206         sectors = 32;
2207
2208         dummy = heads * sectors;
2209         cylinders = capacity;
2210         sector_div(cylinders,dummy);
2211
2212         /*
2213          * Handle extended translation size for logical drives
2214          * > 1Gb
2215          */
2216         if ((ulong)capacity >= 0x200000) {
2217                 heads = 255;
2218                 sectors = 63;
2219                 dummy = heads * sectors;
2220                 cylinders = capacity;
2221                 sector_div(cylinders,dummy);
2222         }
2223
2224         /* return result */
2225         geom[0] = heads;
2226         geom[1] = sectors;
2227         geom[2] = cylinders;
2228
2229         dprintk((KERN_NOTICE
2230                 ": bios_param: Id=%i Lun=%i Channel=%i CHS=%i/%i/%i\n",
2231                 sdev->id, sdev->lun, sdev->channel, (int)cylinders, heads, sectors));
2232
2233         return 0;
2234 }
2235
2236 /* Search IOC page 3 to determine if this is hidden physical disk
2237  *
2238  */
2239 int
2240 mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id)
2241 {
2242         struct inactive_raid_component_info *component_info;
2243         int i;
2244         int rc = 0;
2245
2246         if (!ioc->raid_data.pIocPg3)
2247                 goto out;
2248         for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2249                 if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) &&
2250                     (channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) {
2251                         rc = 1;
2252                         goto out;
2253                 }
2254         }
2255
2256         /*
2257          * Check inactive list for matching phys disks
2258          */
2259         if (list_empty(&ioc->raid_data.inactive_list))
2260                 goto out;
2261
2262         down(&ioc->raid_data.inactive_list_mutex);
2263         list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
2264             list) {
2265                 if ((component_info->d.PhysDiskID == id) &&
2266                     (component_info->d.PhysDiskBus == channel))
2267                         rc = 1;
2268         }
2269         up(&ioc->raid_data.inactive_list_mutex);
2270
2271  out:
2272         return rc;
2273 }
2274 EXPORT_SYMBOL(mptscsih_is_phys_disk);
2275
2276 u8
2277 mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id)
2278 {
2279         struct inactive_raid_component_info *component_info;
2280         int i;
2281         int rc = -ENXIO;
2282
2283         if (!ioc->raid_data.pIocPg3)
2284                 goto out;
2285         for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2286                 if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) &&
2287                     (channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) {
2288                         rc = ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum;
2289                         goto out;
2290                 }
2291         }
2292
2293         /*
2294          * Check inactive list for matching phys disks
2295          */
2296         if (list_empty(&ioc->raid_data.inactive_list))
2297                 goto out;
2298
2299         down(&ioc->raid_data.inactive_list_mutex);
2300         list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
2301             list) {
2302                 if ((component_info->d.PhysDiskID == id) &&
2303                     (component_info->d.PhysDiskBus == channel))
2304                         rc = component_info->d.PhysDiskNum;
2305         }
2306         up(&ioc->raid_data.inactive_list_mutex);
2307
2308  out:
2309         return rc;
2310 }
2311 EXPORT_SYMBOL(mptscsih_raid_id_to_num);
2312
2313 /*
2314  *      OS entry point to allow for host driver to free allocated memory
2315  *      Called if no device present or device being unloaded
2316  */
2317 void
2318 mptscsih_slave_destroy(struct scsi_device *sdev)
2319 {
2320         struct Scsi_Host        *host = sdev->host;
2321         MPT_SCSI_HOST           *hd = (MPT_SCSI_HOST *)host->hostdata;
2322         VirtTarget              *vtarget;
2323         VirtDevice              *vdevice;
2324         struct scsi_target      *starget;
2325
2326         starget = scsi_target(sdev);
2327         vtarget = starget->hostdata;
2328         vdevice = sdev->hostdata;
2329
2330         mptscsih_search_running_cmds(hd, vdevice);
2331         vtarget->num_luns--;
2332         mptscsih_synchronize_cache(hd, vdevice);
2333         kfree(vdevice);
2334         sdev->hostdata = NULL;
2335 }
2336
2337 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2338 /*
2339  *      mptscsih_change_queue_depth - This function will set a devices queue depth
2340  *      @sdev: per scsi_device pointer
2341  *      @qdepth: requested queue depth
2342  *
2343  *      Adding support for new 'change_queue_depth' api.
2344 */
2345 int
2346 mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
2347 {
2348         MPT_SCSI_HOST           *hd = (MPT_SCSI_HOST *)sdev->host->hostdata;
2349         VirtTarget              *vtarget;
2350         struct scsi_target      *starget;
2351         int                     max_depth;
2352         int                     tagged;
2353
2354         starget = scsi_target(sdev);
2355         vtarget = starget->hostdata;
2356
2357         if (hd->ioc->bus_type == SPI) {
2358                 if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
2359                         max_depth = 1;
2360                 else if (sdev->type == TYPE_DISK &&
2361                          vtarget->minSyncFactor <= MPT_ULTRA160)
2362                         max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2363                 else
2364                         max_depth = MPT_SCSI_CMD_PER_DEV_LOW;
2365         } else
2366                 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2367
2368         if (qdepth > max_depth)
2369                 qdepth = max_depth;
2370         if (qdepth == 1)
2371                 tagged = 0;
2372         else
2373                 tagged = MSG_SIMPLE_TAG;
2374
2375         scsi_adjust_queue_depth(sdev, tagged, qdepth);
2376         return sdev->queue_depth;
2377 }
2378
2379 /*
2380  *      OS entry point to adjust the queue_depths on a per-device basis.
2381  *      Called once per device the bus scan. Use it to force the queue_depth
2382  *      member to 1 if a device does not support Q tags.
2383  *      Return non-zero if fails.
2384  */
2385 int
2386 mptscsih_slave_configure(struct scsi_device *sdev)
2387 {
2388         struct Scsi_Host        *sh = sdev->host;
2389         VirtTarget              *vtarget;
2390         VirtDevice              *vdevice;
2391         struct scsi_target      *starget;
2392         MPT_SCSI_HOST           *hd = (MPT_SCSI_HOST *)sh->hostdata;
2393
2394         starget = scsi_target(sdev);
2395         vtarget = starget->hostdata;
2396         vdevice = sdev->hostdata;
2397
2398         dsprintk((MYIOC_s_INFO_FMT
2399                 "device @ %p, channel=%d, id=%d, lun=%d\n",
2400                 hd->ioc->name, sdev, sdev->channel, sdev->id, sdev->lun));
2401         if (hd->ioc->bus_type == SPI)
2402                 dsprintk((MYIOC_s_INFO_FMT
2403                     "sdtr %d wdtr %d ppr %d inq length=%d\n",
2404                     hd->ioc->name, sdev->sdtr, sdev->wdtr,
2405                     sdev->ppr, sdev->inquiry_len));
2406
2407         if (sdev->id > sh->max_id) {
2408                 /* error case, should never happen */
2409                 scsi_adjust_queue_depth(sdev, 0, 1);
2410                 goto slave_configure_exit;
2411         }
2412
2413         vdevice->configured_lun = 1;
2414         mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH);
2415
2416         dsprintk((MYIOC_s_INFO_FMT
2417                 "Queue depth=%d, tflags=%x\n",
2418                 hd->ioc->name, sdev->queue_depth, vtarget->tflags));
2419
2420         if (hd->ioc->bus_type == SPI)
2421                 dsprintk((MYIOC_s_INFO_FMT
2422                     "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
2423                     hd->ioc->name, vtarget->negoFlags, vtarget->maxOffset,
2424                     vtarget->minSyncFactor));
2425
2426 slave_configure_exit:
2427
2428         dsprintk((MYIOC_s_INFO_FMT
2429                 "tagged %d, simple %d, ordered %d\n",
2430                 hd->ioc->name,sdev->tagged_supported, sdev->simple_tags,
2431                 sdev->ordered_tags));
2432
2433         return 0;
2434 }
2435
2436 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2437 /*
2438  *  Private routines...
2439  */
2440
2441 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2442 /* Utility function to copy sense data from the scsi_cmnd buffer
2443  * to the FC and SCSI target structures.
2444  *
2445  */
2446 static void
2447 mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
2448 {
2449         VirtDevice      *vdev;
2450         SCSIIORequest_t *pReq;
2451         u32              sense_count = le32_to_cpu(pScsiReply->SenseCount);
2452
2453         /* Get target structure
2454          */
2455         pReq = (SCSIIORequest_t *) mf;
2456         vdev = sc->device->hostdata;
2457
2458         if (sense_count) {
2459                 u8 *sense_data;
2460                 int req_index;
2461
2462                 /* Copy the sense received into the scsi command block. */
2463                 req_index = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2464                 sense_data = ((u8 *)hd->ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC));
2465                 memcpy(sc->sense_buffer, sense_data, SNS_LEN(sc));
2466
2467                 /* Log SMART data (asc = 0x5D, non-IM case only) if required.
2468                  */
2469                 if ((hd->ioc->events) && (hd->ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) {
2470                         if ((sense_data[12] == 0x5D) && (vdev->vtarget->raidVolume == 0)) {
2471                                 int idx;
2472                                 MPT_ADAPTER *ioc = hd->ioc;
2473
2474                                 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
2475                                 ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
2476                                 ioc->events[idx].eventContext = ioc->eventContext;
2477
2478                                 ioc->events[idx].data[0] = (pReq->LUN[1] << 24) ||
2479                                         (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) ||
2480                                         (sc->device->channel << 8) || sc->device->id;
2481
2482                                 ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12];
2483
2484                                 ioc->eventContext++;
2485                                 if (hd->ioc->pcidev->vendor ==
2486                                     PCI_VENDOR_ID_IBM) {
2487                                         mptscsih_issue_sep_command(hd->ioc,
2488                                             vdev->vtarget, MPI_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT);
2489                                         vdev->vtarget->tflags |=
2490                                             MPT_TARGET_FLAGS_LED_ON;
2491                                 }
2492                         }
2493                 }
2494         } else {
2495                 dprintk((MYIOC_s_INFO_FMT "Hmmm... SenseData len=0! (?)\n",
2496                                 hd->ioc->name));
2497         }
2498 }
2499
2500 static int
2501 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc)
2502 {
2503         MPT_SCSI_HOST *hd;
2504         int i;
2505
2506         hd = (MPT_SCSI_HOST *) sc->device->host->hostdata;
2507
2508         for (i = 0; i < hd->ioc->req_depth; i++) {
2509                 if (hd->ScsiLookup[i] == sc) {
2510                         return i;
2511                 }
2512         }
2513
2514         return -1;
2515 }
2516
2517 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2518 int
2519 mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2520 {
2521         MPT_SCSI_HOST   *hd;
2522         unsigned long    flags;
2523         int             ii;
2524
2525         dtmprintk((KERN_WARNING MYNAM
2526                         ": IOC %s_reset routed to SCSI host driver!\n",
2527                         reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
2528                         reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
2529
2530         /* If a FW reload request arrives after base installed but
2531          * before all scsi hosts have been attached, then an alt_ioc
2532          * may have a NULL sh pointer.
2533          */
2534         if ((ioc->sh == NULL) || (ioc->sh->hostdata == NULL))
2535                 return 0;
2536         else
2537                 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2538
2539         if (reset_phase == MPT_IOC_SETUP_RESET) {
2540                 dtmprintk((MYIOC_s_WARN_FMT "Setup-Diag Reset\n", ioc->name));
2541
2542                 /* Clean Up:
2543                  * 1. Set Hard Reset Pending Flag
2544                  * All new commands go to doneQ
2545                  */
2546                 hd->resetPending = 1;
2547
2548         } else if (reset_phase == MPT_IOC_PRE_RESET) {
2549                 dtmprintk((MYIOC_s_WARN_FMT "Pre-Diag Reset\n", ioc->name));
2550
2551                 /* 2. Flush running commands
2552                  *      Clean ScsiLookup (and associated memory)
2553                  *      AND clean mytaskQ
2554                  */
2555
2556                 /* 2b. Reply to OS all known outstanding I/O commands.
2557                  */
2558                 mptscsih_flush_running_cmds(hd);
2559
2560                 /* 2c. If there was an internal command that
2561                  * has not completed, configuration or io request,
2562                  * free these resources.
2563                  */
2564                 if (hd->cmdPtr) {
2565                         del_timer(&hd->timer);
2566                         mpt_free_msg_frame(ioc, hd->cmdPtr);
2567                 }
2568
2569                 dtmprintk((MYIOC_s_WARN_FMT "Pre-Reset complete.\n", ioc->name));
2570
2571         } else {
2572                 dtmprintk((MYIOC_s_WARN_FMT "Post-Diag Reset\n", ioc->name));
2573
2574                 /* Once a FW reload begins, all new OS commands are
2575                  * redirected to the doneQ w/ a reset status.
2576                  * Init all control structures.
2577                  */
2578
2579                 /* ScsiLookup initialization
2580                  */
2581                 for (ii=0; ii < hd->ioc->req_depth; ii++)
2582                         hd->ScsiLookup[ii] = NULL;
2583
2584                 /* 2. Chain Buffer initialization
2585                  */
2586
2587                 /* 4. Renegotiate to all devices, if SPI
2588                  */
2589
2590                 /* 5. Enable new commands to be posted
2591                  */
2592                 spin_lock_irqsave(&ioc->FreeQlock, flags);
2593                 hd->tmPending = 0;
2594                 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2595                 hd->resetPending = 0;
2596                 hd->tmState = TM_STATE_NONE;
2597
2598                 /* 6. If there was an internal command,
2599                  * wake this process up.
2600                  */
2601                 if (hd->cmdPtr) {
2602                         /*
2603                          * Wake up the original calling thread
2604                          */
2605                         hd->pLocal = &hd->localReply;
2606                         hd->pLocal->completion = MPT_SCANDV_DID_RESET;
2607                         hd->scandv_wait_done = 1;
2608                         wake_up(&hd->scandv_waitq);
2609                         hd->cmdPtr = NULL;
2610                 }
2611
2612                 dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name));
2613
2614         }
2615
2616         return 1;               /* currently means nothing really */
2617 }
2618
2619 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2620 int
2621 mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2622 {
2623         MPT_SCSI_HOST *hd;
2624         u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
2625
2626         devtverboseprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
2627                         ioc->name, event));
2628
2629         if (ioc->sh == NULL ||
2630                 ((hd = (MPT_SCSI_HOST *)ioc->sh->hostdata) == NULL))
2631                 return 1;
2632
2633         switch (event) {
2634         case MPI_EVENT_UNIT_ATTENTION:                  /* 03 */
2635                 /* FIXME! */
2636                 break;
2637         case MPI_EVENT_IOC_BUS_RESET:                   /* 04 */
2638         case MPI_EVENT_EXT_BUS_RESET:                   /* 05 */
2639                 if (hd && (ioc->bus_type == SPI) && (hd->soft_resets < -1))
2640                         hd->soft_resets++;
2641                 break;
2642         case MPI_EVENT_LOGOUT:                          /* 09 */
2643                 /* FIXME! */
2644                 break;
2645
2646         case MPI_EVENT_RESCAN:                          /* 06 */
2647                 break;
2648
2649                 /*
2650                  *  CHECKME! Don't think we need to do
2651                  *  anything for these, but...
2652                  */
2653         case MPI_EVENT_LINK_STATUS_CHANGE:              /* 07 */
2654         case MPI_EVENT_LOOP_STATE_CHANGE:               /* 08 */
2655                 /*
2656                  *  CHECKME!  Falling thru...
2657                  */
2658                 break;
2659
2660         case MPI_EVENT_INTEGRATED_RAID:                 /* 0B */
2661                 break;
2662
2663         case MPI_EVENT_NONE:                            /* 00 */
2664         case MPI_EVENT_LOG_DATA:                        /* 01 */
2665         case MPI_EVENT_STATE_CHANGE:                    /* 02 */
2666         case MPI_EVENT_EVENT_CHANGE:                    /* 0A */
2667         default:
2668                 dprintk((KERN_INFO "  Ignoring event (=%02Xh)\n", event));
2669                 break;
2670         }
2671
2672         return 1;               /* currently means nothing really */
2673 }
2674
2675 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2676 /*
2677  *  Bus Scan and Domain Validation functionality ...
2678  */
2679
2680 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2681 /*
2682  *      mptscsih_scandv_complete - Scan and DV callback routine registered
2683  *      to Fustion MPT (base) driver.
2684  *
2685  *      @ioc: Pointer to MPT_ADAPTER structure
2686  *      @mf: Pointer to original MPT request frame
2687  *      @mr: Pointer to MPT reply frame (NULL if TurboReply)
2688  *
2689  *      This routine is called from mpt.c::mpt_interrupt() at the completion
2690  *      of any SCSI IO request.
2691  *      This routine is registered with the Fusion MPT (base) driver at driver
2692  *      load/init time via the mpt_register() API call.
2693  *
2694  *      Returns 1 indicating alloc'd request frame ptr should be freed.
2695  *
2696  *      Remark: Sets a completion code and (possibly) saves sense data
2697  *      in the IOC member localReply structure.
2698  *      Used ONLY for DV and other internal commands.
2699  */
2700 int
2701 mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
2702 {
2703         MPT_SCSI_HOST   *hd;
2704         SCSIIORequest_t *pReq;
2705         int              completionCode;
2706         u16              req_idx;
2707
2708         hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2709
2710         if ((mf == NULL) ||
2711             (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) {
2712                 printk(MYIOC_s_ERR_FMT
2713                         "ScanDvComplete, %s req frame ptr! (=%p)\n",
2714                                 ioc->name, mf?"BAD":"NULL", (void *) mf);
2715                 goto wakeup;
2716         }
2717
2718         del_timer(&hd->timer);
2719         req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2720         hd->ScsiLookup[req_idx] = NULL;
2721         pReq = (SCSIIORequest_t *) mf;
2722
2723         if (mf != hd->cmdPtr) {
2724                 printk(MYIOC_s_WARN_FMT "ScanDvComplete (mf=%p, cmdPtr=%p, idx=%d)\n",
2725                                 hd->ioc->name, (void *)mf, (void *) hd->cmdPtr, req_idx);
2726         }
2727         hd->cmdPtr = NULL;
2728
2729         ddvprintk((MYIOC_s_INFO_FMT "ScanDvComplete (mf=%p,mr=%p,idx=%d)\n",
2730                         hd->ioc->name, mf, mr, req_idx));
2731
2732         hd->pLocal = &hd->localReply;
2733         hd->pLocal->scsiStatus = 0;
2734
2735         /* If target struct exists, clear sense valid flag.
2736          */
2737         if (mr == NULL) {
2738                 completionCode = MPT_SCANDV_GOOD;
2739         } else {
2740                 SCSIIOReply_t   *pReply;
2741                 u16              status;
2742                 u8               scsi_status;
2743
2744                 pReply = (SCSIIOReply_t *) mr;
2745
2746                 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2747                 scsi_status = pReply->SCSIStatus;
2748
2749                 ddvtprintk((KERN_NOTICE "  IOCStatus=%04xh, SCSIState=%02xh, SCSIStatus=%02xh, IOCLogInfo=%08xh\n",
2750                              status, pReply->SCSIState, scsi_status,
2751                              le32_to_cpu(pReply->IOCLogInfo)));
2752
2753                 switch(status) {
2754
2755                 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE:       /* 0x0043 */
2756                         completionCode = MPT_SCANDV_SELECTION_TIMEOUT;
2757                         break;
2758
2759                 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR:          /* 0x0046 */
2760                 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED:        /* 0x0048 */
2761                 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED:         /* 0x004B */
2762                 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED:         /* 0x004C */
2763                         completionCode = MPT_SCANDV_DID_RESET;
2764                         break;
2765
2766                 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN:          /* 0x0045 */
2767                 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR:        /* 0x0040 */
2768                 case MPI_IOCSTATUS_SUCCESS:                     /* 0x0000 */
2769                         if (pReply->Function == MPI_FUNCTION_CONFIG) {
2770                                 ConfigReply_t *pr = (ConfigReply_t *)mr;
2771                                 completionCode = MPT_SCANDV_GOOD;
2772                                 hd->pLocal->header.PageVersion = pr->Header.PageVersion;
2773                                 hd->pLocal->header.PageLength = pr->Header.PageLength;
2774                                 hd->pLocal->header.PageNumber = pr->Header.PageNumber;
2775                                 hd->pLocal->header.PageType = pr->Header.PageType;
2776
2777                         } else if (pReply->Function == MPI_FUNCTION_RAID_ACTION) {
2778                                 /* If the RAID Volume request is successful,
2779                                  * return GOOD, else indicate that
2780                                  * some type of error occurred.
2781                                  */
2782                                 MpiRaidActionReply_t    *pr = (MpiRaidActionReply_t *)mr;
2783                                 if (le16_to_cpu(pr->ActionStatus) == MPI_RAID_ACTION_ASTATUS_SUCCESS)
2784                                         completionCode = MPT_SCANDV_GOOD;
2785                                 else
2786                                         completionCode = MPT_SCANDV_SOME_ERROR;
2787                                 memcpy(hd->pLocal->sense, pr, sizeof(hd->pLocal->sense));
2788
2789                         } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID) {
2790                                 u8              *sense_data;
2791                                 int              sz;
2792
2793                                 /* save sense data in global structure
2794                                  */
2795                                 completionCode = MPT_SCANDV_SENSE;
2796                                 hd->pLocal->scsiStatus = scsi_status;
2797                                 sense_data = ((u8 *)hd->ioc->sense_buf_pool +
2798                                         (req_idx * MPT_SENSE_BUFFER_ALLOC));
2799
2800                                 sz = min_t(int, pReq->SenseBufferLength,
2801                                                         SCSI_STD_SENSE_BYTES);
2802                                 memcpy(hd->pLocal->sense, sense_data, sz);
2803
2804                                 ddvprintk((KERN_NOTICE "  Check Condition, sense ptr %p\n",
2805                                                 sense_data));
2806                         } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_FAILED) {
2807                                 if (pReq->CDB[0] == INQUIRY)
2808                                         completionCode = MPT_SCANDV_ISSUE_SENSE;
2809                                 else
2810                                         completionCode = MPT_SCANDV_DID_RESET;
2811                         }
2812                         else if (pReply->SCSIState & MPI_SCSI_STATE_NO_SCSI_STATUS)
2813                                 completionCode = MPT_SCANDV_DID_RESET;
2814                         else if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
2815                                 completionCode = MPT_SCANDV_DID_RESET;
2816                         else {
2817                                 completionCode = MPT_SCANDV_GOOD;
2818                                 hd->pLocal->scsiStatus = scsi_status;
2819                         }
2820                         break;
2821
2822                 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR:         /* 0x0047 */
2823                         if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
2824                                 completionCode = MPT_SCANDV_DID_RESET;
2825                         else
2826                                 completionCode = MPT_SCANDV_SOME_ERROR;
2827                         break;
2828
2829                 default:
2830                         completionCode = MPT_SCANDV_SOME_ERROR;
2831                         break;
2832
2833                 }       /* switch(status) */
2834
2835                 ddvtprintk((KERN_NOTICE "  completionCode set to %08xh\n",
2836                                 completionCode));
2837         } /* end of address reply case */
2838
2839         hd->pLocal->completion = completionCode;
2840
2841         /* MF and RF are freed in mpt_interrupt
2842          */
2843 wakeup:
2844         /* Free Chain buffers (will never chain) in scan or dv */
2845         //mptscsih_freeChainBuffers(ioc, req_idx);
2846
2847         /*
2848          * Wake up the original calling thread
2849          */
2850         hd->scandv_wait_done = 1;
2851         wake_up(&hd->scandv_waitq);
2852
2853         return 1;
2854 }
2855
2856 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2857 /*      mptscsih_timer_expired - Call back for timer process.
2858  *      Used only for dv functionality.
2859  *      @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
2860  *
2861  */
2862 void
2863 mptscsih_timer_expired(unsigned long data)
2864 {
2865         MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) data;
2866
2867         ddvprintk((MYIOC_s_WARN_FMT "Timer Expired! Cmd %p\n", hd->ioc->name, hd->cmdPtr));
2868
2869         if (hd->cmdPtr) {
2870                 MPIHeader_t *cmd = (MPIHeader_t *)hd->cmdPtr;
2871
2872                 if (cmd->Function == MPI_FUNCTION_SCSI_IO_REQUEST) {
2873                         /* Desire to issue a task management request here.
2874                          * TM requests MUST be single threaded.
2875                          * If old eh code and no TM current, issue request.
2876                          * If new eh code, do nothing. Wait for OS cmd timeout
2877                          *      for bus reset.
2878                          */
2879                         ddvtprintk((MYIOC_s_NOTE_FMT "DV Cmd Timeout: NoOp\n", hd->ioc->name));
2880                 } else {
2881                         /* Perform a FW reload */
2882                         if (mpt_HardResetHandler(hd->ioc, NO_SLEEP) < 0) {
2883                                 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", hd->ioc->name);
2884                         }
2885                 }
2886         } else {
2887                 /* This should NEVER happen */
2888                 printk(MYIOC_s_WARN_FMT "Null cmdPtr!!!!\n", hd->ioc->name);
2889         }
2890
2891         /* No more processing.
2892          * TM call will generate an interrupt for SCSI TM Management.
2893          * The FW will reply to all outstanding commands, callback will finish cleanup.
2894          * Hard reset clean-up will free all resources.
2895          */
2896         ddvprintk((MYIOC_s_WARN_FMT "Timer Expired Complete!\n", hd->ioc->name));
2897
2898         return;
2899 }
2900
2901
2902 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2903 /**
2904  *      mptscsih_do_cmd - Do internal command.
2905  *      @hd: MPT_SCSI_HOST pointer
2906  *      @io: INTERNAL_CMD pointer.
2907  *
2908  *      Issue the specified internally generated command and do command
2909  *      specific cleanup. For bus scan / DV only.
2910  *      NOTES: If command is Inquiry and status is good,
2911  *      initialize a target structure, save the data
2912  *
2913  *      Remark: Single threaded access only.
2914  *
2915  *      Return:
2916  *              < 0 if an illegal command or no resources
2917  *
2918  *                 0 if good
2919  *
2920  *               > 0 if command complete but some type of completion error.
2921  */
2922 static int
2923 mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
2924 {
2925         MPT_FRAME_HDR   *mf;
2926         SCSIIORequest_t *pScsiReq;
2927         SCSIIORequest_t  ReqCopy;
2928         int              my_idx, ii, dir;
2929         int              rc, cmdTimeout;
2930         int             in_isr;
2931         char             cmdLen;
2932         char             CDB[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
2933         char             cmd = io->cmd;
2934
2935         in_isr = in_interrupt();
2936         if (in_isr) {
2937                 dprintk((MYIOC_s_WARN_FMT "Internal SCSI IO request not allowed in ISR context!\n",
2938                                 hd->ioc->name));
2939                 return -EPERM;
2940         }
2941
2942
2943         /* Set command specific information
2944          */
2945         switch (cmd) {
2946         case INQUIRY:
2947                 cmdLen = 6;
2948                 dir = MPI_SCSIIO_CONTROL_READ;
2949                 CDB[0] = cmd;
2950                 CDB[4] = io->size;
2951                 cmdTimeout = 10;
2952                 break;
2953
2954         case TEST_UNIT_READY:
2955                 cmdLen = 6;
2956                 dir = MPI_SCSIIO_CONTROL_READ;
2957                 cmdTimeout = 10;
2958                 break;
2959
2960         case START_STOP:
2961                 cmdLen = 6;
2962                 dir = MPI_SCSIIO_CONTROL_READ;
2963                 CDB[0] = cmd;
2964                 CDB[4] = 1;     /*Spin up the disk */
2965                 cmdTimeout = 15;
2966                 break;
2967
2968         case REQUEST_SENSE:
2969                 cmdLen = 6;
2970                 CDB[0] = cmd;
2971                 CDB[4] = io->size;
2972                 dir = MPI_SCSIIO_CONTROL_READ;
2973                 cmdTimeout = 10;
2974                 break;
2975
2976         case READ_BUFFER:
2977                 cmdLen = 10;
2978                 dir = MPI_SCSIIO_CONTROL_READ;
2979                 CDB[0] = cmd;
2980                 if (io->flags & MPT_ICFLAG_ECHO) {
2981                         CDB[1] = 0x0A;
2982                 } else {
2983                         CDB[1] = 0x02;
2984                 }
2985
2986                 if (io->flags & MPT_ICFLAG_BUF_CAP) {
2987                         CDB[1] |= 0x01;
2988                 }
2989                 CDB[6] = (io->size >> 16) & 0xFF;
2990                 CDB[7] = (io->size >>  8) & 0xFF;
2991                 CDB[8] = io->size & 0xFF;
2992                 cmdTimeout = 10;
2993                 break;
2994
2995         case WRITE_BUFFER:
2996                 cmdLen = 10;
2997                 dir = MPI_SCSIIO_CONTROL_WRITE;
2998                 CDB[0] = cmd;
2999                 if (io->flags & MPT_ICFLAG_ECHO) {
3000                         CDB[1] = 0x0A;
3001                 } else {
3002                         CDB[1] = 0x02;
3003                 }
3004                 CDB[6] = (io->size >> 16) & 0xFF;
3005                 CDB[7] = (io->size >>  8) & 0xFF;
3006                 CDB[8] = io->size & 0xFF;
3007                 cmdTimeout = 10;
3008                 break;
3009
3010         case RESERVE:
3011                 cmdLen = 6;
3012                 dir = MPI_SCSIIO_CONTROL_READ;
3013                 CDB[0] = cmd;
3014                 cmdTimeout = 10;
3015                 break;
3016
3017         case RELEASE:
3018                 cmdLen = 6;
3019                 dir = MPI_SCSIIO_CONTROL_READ;
3020                 CDB[0] = cmd;
3021                 cmdTimeout = 10;
3022                 break;
3023
3024         case SYNCHRONIZE_CACHE:
3025                 cmdLen = 10;
3026                 dir = MPI_SCSIIO_CONTROL_READ;
3027                 CDB[0] = cmd;
3028 //              CDB[1] = 0x02;  /* set immediate bit */
3029                 cmdTimeout = 10;
3030                 break;
3031
3032         default:
3033                 /* Error Case */
3034                 return -EFAULT;
3035         }
3036
3037         /* Get and Populate a free Frame
3038          */
3039         if ((mf = mpt_get_msg_frame(hd->ioc->InternalCtx, hd->ioc)) == NULL) {
3040                 ddvprintk((MYIOC_s_WARN_FMT "No msg frames!\n",
3041                                         hd->ioc->name));
3042                 return -EBUSY;
3043         }
3044
3045         pScsiReq = (SCSIIORequest_t *) mf;
3046
3047         /* Get the request index */
3048         my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3049         ADD_INDEX_LOG(my_idx); /* for debug */
3050
3051         if (io->flags & MPT_ICFLAG_PHYS_DISK) {
3052                 pScsiReq->TargetID = io->physDiskNum;
3053                 pScsiReq->Bus = 0;
3054                 pScsiReq->ChainOffset = 0;
3055                 pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
3056         } else {
3057                 pScsiReq->TargetID = io->id;
3058                 pScsiReq->Bus = io->channel;
3059                 pScsiReq->ChainOffset = 0;
3060                 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
3061         }
3062
3063         pScsiReq->CDBLength = cmdLen;
3064         pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
3065
3066         pScsiReq->Reserved = 0;
3067
3068         pScsiReq->MsgFlags = mpt_msg_flags();
3069         /* MsgContext set in mpt_get_msg_fram call  */
3070
3071         int_to_scsilun(io->lun, (struct scsi_lun *)pScsiReq->LUN);
3072
3073         if (io->flags & MPT_ICFLAG_TAGGED_CMD)
3074                 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ);
3075         else
3076                 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3077
3078         if (cmd == REQUEST_SENSE) {
3079                 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3080                 ddvprintk((MYIOC_s_INFO_FMT "Untagged! 0x%2x\n",
3081                         hd->ioc->name, cmd));
3082         }
3083
3084         for (ii=0; ii < 16; ii++)
3085                 pScsiReq->CDB[ii] = CDB[ii];
3086
3087         pScsiReq->DataLength = cpu_to_le32(io->size);
3088         pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
3089                                            + (my_idx * MPT_SENSE_BUFFER_ALLOC));
3090
3091         ddvprintk((MYIOC_s_INFO_FMT "Sending Command 0x%x for (%d:%d:%d)\n",
3092                         hd->ioc->name, cmd, io->channel, io->id, io->lun));
3093
3094         if (dir == MPI_SCSIIO_CONTROL_READ) {
3095                 mpt_add_sge((char *) &pScsiReq->SGL,
3096                         MPT_SGE_FLAGS_SSIMPLE_READ | io->size,
3097                         io->data_dma);
3098         } else {
3099                 mpt_add_sge((char *) &pScsiReq->SGL,
3100                         MPT_SGE_FLAGS_SSIMPLE_WRITE | io->size,
3101                         io->data_dma);
3102         }
3103
3104         /* The ISR will free the request frame, but we need
3105          * the information to initialize the target. Duplicate.
3106          */
3107         memcpy(&ReqCopy, pScsiReq, sizeof(SCSIIORequest_t));
3108
3109         /* Issue this command after:
3110          *      finish init
3111          *      add timer
3112          * Wait until the reply has been received
3113          *  ScsiScanDvCtx callback function will
3114          *      set hd->pLocal;
3115          *      set scandv_wait_done and call wake_up
3116          */
3117         hd->pLocal = NULL;
3118         hd->timer.expires = jiffies + HZ*cmdTimeout;
3119         hd->scandv_wait_done = 0;
3120
3121         /* Save cmd pointer, for resource free if timeout or
3122          * FW reload occurs
3123          */
3124         hd->cmdPtr = mf;
3125
3126         add_timer(&hd->timer);
3127         mpt_put_msg_frame(hd->ioc->InternalCtx, hd->ioc, mf);
3128         wait_event(hd->scandv_waitq, hd->scandv_wait_done);
3129
3130         if (hd->pLocal) {
3131                 rc = hd->pLocal->completion;
3132                 hd->pLocal->skip = 0;
3133
3134                 /* Always set fatal error codes in some cases.
3135                  */
3136                 if (rc == MPT_SCANDV_SELECTION_TIMEOUT)
3137                         rc = -ENXIO;
3138                 else if (rc == MPT_SCANDV_SOME_ERROR)
3139                         rc =  -rc;
3140         } else {
3141                 rc = -EFAULT;
3142                 /* This should never happen. */
3143                 ddvprintk((MYIOC_s_INFO_FMT "_do_cmd: Null pLocal!!!\n",
3144                                 hd->ioc->name));
3145         }
3146
3147         return rc;
3148 }
3149
3150 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3151 /**
3152  *      mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
3153  *      @hd: Pointer to a SCSI HOST structure
3154  *      @vdevice: virtual target device
3155  *
3156  *      Uses the ISR, but with special processing.
3157  *      MUST be single-threaded.
3158  *
3159  */
3160 static void
3161 mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
3162 {
3163         INTERNAL_CMD             iocmd;
3164
3165         /* Following parameters will not change
3166          * in this routine.
3167          */
3168         iocmd.cmd = SYNCHRONIZE_CACHE;
3169         iocmd.flags = 0;
3170         iocmd.physDiskNum = -1;
3171         iocmd.data = NULL;
3172         iocmd.data_dma = -1;
3173         iocmd.size = 0;
3174         iocmd.rsvd = iocmd.rsvd2 = 0;
3175         iocmd.channel = vdevice->vtarget->channel;
3176         iocmd.id = vdevice->vtarget->id;
3177         iocmd.lun = vdevice->lun;
3178
3179         if ((vdevice->vtarget->type == TYPE_DISK) &&
3180             (vdevice->configured_lun))
3181                 mptscsih_do_cmd(hd, &iocmd);
3182 }
3183
3184 EXPORT_SYMBOL(mptscsih_remove);
3185 EXPORT_SYMBOL(mptscsih_shutdown);
3186 #ifdef CONFIG_PM
3187 EXPORT_SYMBOL(mptscsih_suspend);
3188 EXPORT_SYMBOL(mptscsih_resume);
3189 #endif
3190 EXPORT_SYMBOL(mptscsih_proc_info);
3191 EXPORT_SYMBOL(mptscsih_info);
3192 EXPORT_SYMBOL(mptscsih_qcmd);
3193 EXPORT_SYMBOL(mptscsih_slave_destroy);
3194 EXPORT_SYMBOL(mptscsih_slave_configure);
3195 EXPORT_SYMBOL(mptscsih_abort);
3196 EXPORT_SYMBOL(mptscsih_dev_reset);
3197 EXPORT_SYMBOL(mptscsih_bus_reset);
3198 EXPORT_SYMBOL(mptscsih_host_reset);
3199 EXPORT_SYMBOL(mptscsih_bios_param);
3200 EXPORT_SYMBOL(mptscsih_io_done);
3201 EXPORT_SYMBOL(mptscsih_taskmgmt_complete);
3202 EXPORT_SYMBOL(mptscsih_scandv_complete);
3203 EXPORT_SYMBOL(mptscsih_event_process);
3204 EXPORT_SYMBOL(mptscsih_ioc_reset);
3205 EXPORT_SYMBOL(mptscsih_change_queue_depth);
3206 EXPORT_SYMBOL(mptscsih_timer_expired);
3207 EXPORT_SYMBOL(mptscsih_TMHandler);
3208
3209 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/