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