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