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