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