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