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