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