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