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