[SCSI] mpt fusion: removing references to hd->ioc
[linux-2.6] / drivers / message / fusion / mptscsih.c
1 /*
2  *  linux/drivers/message/fusion/mptscsih.c
3  *      For use with LSI PCI chip/adapter(s)
4  *      running LSI Fusion MPT (Message Passing Technology) firmware.
5  *
6  *  Copyright (c) 1999-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       *vdevice;
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                         vdevice = sc->device->hostdata;
774                         if (!vdevice)
775                                 break;
776                         vtarget = vdevice->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         MPT_ADAPTER *ioc = hd->ioc;
1040
1041         dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": search_running channel %d id %d lun %d max %d\n",
1042             ioc->name, vdevice->vtarget->channel, vdevice->vtarget->id, vdevice->lun, max));
1043
1044         for (ii=0; ii < max; ii++) {
1045                 if ((sc = hd->ScsiLookup[ii]) != NULL) {
1046
1047                         mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(ioc, ii);
1048                         if (mf == NULL)
1049                                 continue;
1050                         /* If the device is a hidden raid component, then its
1051                          * expected that the mf->function will be RAID_SCSI_IO
1052                          */
1053                         if (vdevice->vtarget->tflags &
1054                             MPT_TARGET_FLAGS_RAID_COMPONENT && mf->Function !=
1055                             MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)
1056                                 continue;
1057
1058                         int_to_scsilun(vdevice->lun, &lun);
1059                         if ((mf->Bus != vdevice->vtarget->channel) ||
1060                             (mf->TargetID != vdevice->vtarget->id) ||
1061                             memcmp(lun.scsi_lun, mf->LUN, 8))
1062                                 continue;
1063
1064                         /* Cleanup
1065                          */
1066                         hd->ScsiLookup[ii] = NULL;
1067                         mptscsih_freeChainBuffers(ioc, ii);
1068                         mpt_free_msg_frame(ioc, (MPT_FRAME_HDR *)mf);
1069                         if ((unsigned char *)mf != sc->host_scribble)
1070                                 continue;
1071                         scsi_dma_unmap(sc);
1072                         sc->host_scribble = NULL;
1073                         sc->result = DID_NO_CONNECT << 16;
1074                         sdev_printk(MYIOC_s_INFO_FMT, sc->device, "completing cmds: fw_channel %d,"
1075                            "fw_id %d, sc=%p, mf = %p, idx=%x\n", ioc->name, vdevice->vtarget->channel,
1076                            vdevice->vtarget->id, sc, mf, ii);
1077                         sc->scsi_done(sc);
1078                 }
1079         }
1080         return;
1081 }
1082
1083 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1084
1085 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1086 /*
1087  *      mptscsih_report_queue_full - Report QUEUE_FULL status returned
1088  *      from a SCSI target device.
1089  *      @sc: Pointer to scsi_cmnd structure
1090  *      @pScsiReply: Pointer to SCSIIOReply_t
1091  *      @pScsiReq: Pointer to original SCSI request
1092  *
1093  *      This routine periodically reports QUEUE_FULL status returned from a
1094  *      SCSI target device.  It reports this to the console via kernel
1095  *      printk() API call, not more than once every 10 seconds.
1096  */
1097 static void
1098 mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq)
1099 {
1100         long time = jiffies;
1101         MPT_SCSI_HOST           *hd;
1102         MPT_ADAPTER     *ioc;
1103
1104         if (sc->device == NULL)
1105                 return;
1106         if (sc->device->host == NULL)
1107                 return;
1108         if ((hd = (MPT_SCSI_HOST *)sc->device->host->hostdata) == NULL)
1109                 return;
1110         ioc = hd->ioc;
1111         if (time - hd->last_queue_full > 10 * HZ) {
1112                 dprintk(ioc, printk(MYIOC_s_WARN_FMT "Device (%d:%d:%d) reported QUEUE_FULL!\n",
1113                                 ioc->name, 0, sc->device->id, sc->device->lun));
1114                 hd->last_queue_full = time;
1115         }
1116 }
1117
1118 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1119 /*
1120  *      mptscsih_remove - Removed scsi devices
1121  *      @pdev: Pointer to pci_dev structure
1122  *
1123  *
1124  */
1125 void
1126 mptscsih_remove(struct pci_dev *pdev)
1127 {
1128         MPT_ADAPTER             *ioc = pci_get_drvdata(pdev);
1129         struct Scsi_Host        *host = ioc->sh;
1130         MPT_SCSI_HOST           *hd;
1131         int sz1;
1132
1133         if(!host) {
1134                 mpt_detach(pdev);
1135                 return;
1136         }
1137
1138         scsi_remove_host(host);
1139
1140         if((hd = (MPT_SCSI_HOST *)host->hostdata) == NULL)
1141                 return;
1142
1143         mptscsih_shutdown(pdev);
1144
1145         sz1=0;
1146
1147         if (hd->ScsiLookup != NULL) {
1148                 sz1 = ioc->req_depth * sizeof(void *);
1149                 kfree(hd->ScsiLookup);
1150                 hd->ScsiLookup = NULL;
1151         }
1152
1153         dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1154             "Free'd ScsiLookup (%d) memory\n",
1155             ioc->name, sz1));
1156
1157         kfree(hd->info_kbuf);
1158
1159         /* NULL the Scsi_Host pointer
1160          */
1161         ioc->sh = NULL;
1162
1163         scsi_host_put(host);
1164
1165         mpt_detach(pdev);
1166
1167 }
1168
1169 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1170 /*
1171  *      mptscsih_shutdown - reboot notifier
1172  *
1173  */
1174 void
1175 mptscsih_shutdown(struct pci_dev *pdev)
1176 {
1177         MPT_ADAPTER             *ioc = pci_get_drvdata(pdev);
1178         struct Scsi_Host        *host = ioc->sh;
1179         MPT_SCSI_HOST           *hd;
1180
1181         if(!host)
1182                 return;
1183
1184         hd = (MPT_SCSI_HOST *)host->hostdata;
1185
1186 }
1187
1188 #ifdef CONFIG_PM
1189 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1190 /*
1191  *      mptscsih_suspend - Fusion MPT scsi driver suspend routine.
1192  *
1193  *
1194  */
1195 int
1196 mptscsih_suspend(struct pci_dev *pdev, pm_message_t state)
1197 {
1198         mptscsih_shutdown(pdev);
1199         return mpt_suspend(pdev,state);
1200 }
1201
1202 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1203 /*
1204  *      mptscsih_resume - Fusion MPT scsi driver resume routine.
1205  *
1206  *
1207  */
1208 int
1209 mptscsih_resume(struct pci_dev *pdev)
1210 {
1211         return mpt_resume(pdev);
1212 }
1213
1214 #endif
1215
1216 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1217 /**
1218  *      mptscsih_info - Return information about MPT adapter
1219  *      @SChost: Pointer to Scsi_Host structure
1220  *
1221  *      (linux scsi_host_template.info routine)
1222  *
1223  *      Returns pointer to buffer where information was written.
1224  */
1225 const char *
1226 mptscsih_info(struct Scsi_Host *SChost)
1227 {
1228         MPT_SCSI_HOST *h;
1229         int size = 0;
1230
1231         h = (MPT_SCSI_HOST *)SChost->hostdata;
1232
1233         if (h) {
1234                 if (h->info_kbuf == NULL)
1235                         if ((h->info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)
1236                                 return h->info_kbuf;
1237                 h->info_kbuf[0] = '\0';
1238
1239                 mpt_print_ioc_summary(h->ioc, h->info_kbuf, &size, 0, 0);
1240                 h->info_kbuf[size-1] = '\0';
1241         }
1242
1243         return h->info_kbuf;
1244 }
1245
1246 struct info_str {
1247         char *buffer;
1248         int   length;
1249         int   offset;
1250         int   pos;
1251 };
1252
1253 static void
1254 mptscsih_copy_mem_info(struct info_str *info, char *data, int len)
1255 {
1256         if (info->pos + len > info->length)
1257                 len = info->length - info->pos;
1258
1259         if (info->pos + len < info->offset) {
1260                 info->pos += len;
1261                 return;
1262         }
1263
1264         if (info->pos < info->offset) {
1265                 data += (info->offset - info->pos);
1266                 len  -= (info->offset - info->pos);
1267         }
1268
1269         if (len > 0) {
1270                 memcpy(info->buffer + info->pos, data, len);
1271                 info->pos += len;
1272         }
1273 }
1274
1275 static int
1276 mptscsih_copy_info(struct info_str *info, char *fmt, ...)
1277 {
1278         va_list args;
1279         char buf[81];
1280         int len;
1281
1282         va_start(args, fmt);
1283         len = vsprintf(buf, fmt, args);
1284         va_end(args);
1285
1286         mptscsih_copy_mem_info(info, buf, len);
1287         return len;
1288 }
1289
1290 static int
1291 mptscsih_host_info(MPT_ADAPTER *ioc, char *pbuf, off_t offset, int len)
1292 {
1293         struct info_str info;
1294
1295         info.buffer     = pbuf;
1296         info.length     = len;
1297         info.offset     = offset;
1298         info.pos        = 0;
1299
1300         mptscsih_copy_info(&info, "%s: %s, ", ioc->name, ioc->prod_name);
1301         mptscsih_copy_info(&info, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING, ioc->facts.FWVersion.Word);
1302         mptscsih_copy_info(&info, "Ports=%d, ", ioc->facts.NumberOfPorts);
1303         mptscsih_copy_info(&info, "MaxQ=%d\n", ioc->req_depth);
1304
1305         return ((info.pos > info.offset) ? info.pos - info.offset : 0);
1306 }
1307
1308 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1309 /**
1310  *      mptscsih_proc_info - Return information about MPT adapter
1311  *      @host:   scsi host struct
1312  *      @buffer: if write, user data; if read, buffer for user
1313  *      @start: returns the buffer address
1314  *      @offset: if write, 0; if read, the current offset into the buffer from
1315  *               the previous read.
1316  *      @length: if write, return length;
1317  *      @func:   write = 1; read = 0
1318  *
1319  *      (linux scsi_host_template.info routine)
1320  */
1321 int
1322 mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
1323                         int length, int func)
1324 {
1325         MPT_SCSI_HOST   *hd = (MPT_SCSI_HOST *)host->hostdata;
1326         MPT_ADAPTER     *ioc = hd->ioc;
1327         int size = 0;
1328
1329         if (func) {
1330                 /*
1331                  * write is not supported
1332                  */
1333         } else {
1334                 if (start)
1335                         *start = buffer;
1336
1337                 size = mptscsih_host_info(ioc, buffer, offset, length);
1338         }
1339
1340         return size;
1341 }
1342
1343 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1344 #define ADD_INDEX_LOG(req_ent)  do { } while(0)
1345
1346 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1347 /**
1348  *      mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine.
1349  *      @SCpnt: Pointer to scsi_cmnd structure
1350  *      @done: Pointer SCSI mid-layer IO completion function
1351  *
1352  *      (linux scsi_host_template.queuecommand routine)
1353  *      This is the primary SCSI IO start routine.  Create a MPI SCSIIORequest
1354  *      from a linux scsi_cmnd request and send it to the IOC.
1355  *
1356  *      Returns 0. (rtn value discarded by linux scsi mid-layer)
1357  */
1358 int
1359 mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1360 {
1361         MPT_SCSI_HOST           *hd;
1362         MPT_FRAME_HDR           *mf;
1363         SCSIIORequest_t         *pScsiReq;
1364         VirtDevice              *vdevice = SCpnt->device->hostdata;
1365         int      lun;
1366         u32      datalen;
1367         u32      scsictl;
1368         u32      scsidir;
1369         u32      cmd_len;
1370         int      my_idx;
1371         int      ii;
1372         MPT_ADAPTER *ioc;
1373
1374         hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata;
1375         ioc = hd->ioc;
1376         lun = SCpnt->device->lun;
1377         SCpnt->scsi_done = done;
1378
1379         dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "qcmd: SCpnt=%p, done()=%p\n",
1380                 ioc->name, SCpnt, done));
1381
1382         if (hd->resetPending) {
1383                 dtmprintk(ioc, printk(MYIOC_s_WARN_FMT "qcmd: SCpnt=%p timeout + 60HZ\n",
1384                         ioc->name, SCpnt));
1385                 return SCSI_MLQUEUE_HOST_BUSY;
1386         }
1387
1388         /*
1389          *  Put together a MPT SCSI request...
1390          */
1391         if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
1392                 dprintk(ioc, printk(MYIOC_s_WARN_FMT "QueueCmd, no msg frames!!\n",
1393                                 ioc->name));
1394                 return SCSI_MLQUEUE_HOST_BUSY;
1395         }
1396
1397         pScsiReq = (SCSIIORequest_t *) mf;
1398
1399         my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
1400
1401         ADD_INDEX_LOG(my_idx);
1402
1403         /*    TUR's being issued with scsictl=0x02000000 (DATA_IN)!
1404          *    Seems we may receive a buffer (datalen>0) even when there
1405          *    will be no data transfer!  GRRRRR...
1406          */
1407         if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
1408                 datalen = scsi_bufflen(SCpnt);
1409                 scsidir = MPI_SCSIIO_CONTROL_READ;      /* DATA IN  (host<--ioc<--dev) */
1410         } else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
1411                 datalen = scsi_bufflen(SCpnt);
1412                 scsidir = MPI_SCSIIO_CONTROL_WRITE;     /* DATA OUT (host-->ioc-->dev) */
1413         } else {
1414                 datalen = 0;
1415                 scsidir = MPI_SCSIIO_CONTROL_NODATATRANSFER;
1416         }
1417
1418         /* Default to untagged. Once a target structure has been allocated,
1419          * use the Inquiry data to determine if device supports tagged.
1420          */
1421         if (vdevice
1422             && (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)
1423             && (SCpnt->device->tagged_supported)) {
1424                 scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
1425         } else {
1426                 scsictl = scsidir | MPI_SCSIIO_CONTROL_UNTAGGED;
1427         }
1428
1429         /* Use the above information to set up the message frame
1430          */
1431         pScsiReq->TargetID = (u8) vdevice->vtarget->id;
1432         pScsiReq->Bus = vdevice->vtarget->channel;
1433         pScsiReq->ChainOffset = 0;
1434         if (vdevice->vtarget->tflags &  MPT_TARGET_FLAGS_RAID_COMPONENT)
1435                 pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
1436         else
1437                 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
1438         pScsiReq->CDBLength = SCpnt->cmd_len;
1439         pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
1440         pScsiReq->Reserved = 0;
1441         pScsiReq->MsgFlags = mpt_msg_flags();
1442         int_to_scsilun(SCpnt->device->lun, (struct scsi_lun *)pScsiReq->LUN);
1443         pScsiReq->Control = cpu_to_le32(scsictl);
1444
1445         /*
1446          *  Write SCSI CDB into the message
1447          */
1448         cmd_len = SCpnt->cmd_len;
1449         for (ii=0; ii < cmd_len; ii++)
1450                 pScsiReq->CDB[ii] = SCpnt->cmnd[ii];
1451
1452         for (ii=cmd_len; ii < 16; ii++)
1453                 pScsiReq->CDB[ii] = 0;
1454
1455         /* DataLength */
1456         pScsiReq->DataLength = cpu_to_le32(datalen);
1457
1458         /* SenseBuffer low address */
1459         pScsiReq->SenseBufferLowAddr = cpu_to_le32(ioc->sense_buf_low_dma
1460                                            + (my_idx * MPT_SENSE_BUFFER_ALLOC));
1461
1462         /* Now add the SG list
1463          * Always have a SGE even if null length.
1464          */
1465         if (datalen == 0) {
1466                 /* Add a NULL SGE */
1467                 mptscsih_add_sge((char *)&pScsiReq->SGL, MPT_SGE_FLAGS_SSIMPLE_READ | 0,
1468                         (dma_addr_t) -1);
1469         } else {
1470                 /* Add a 32 or 64 bit SGE */
1471                 if (mptscsih_AddSGE(ioc, SCpnt, pScsiReq, my_idx) != SUCCESS)
1472                         goto fail;
1473         }
1474
1475         SCpnt->host_scribble = (unsigned char *)mf;
1476         hd->ScsiLookup[my_idx] = SCpnt;
1477
1478         mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
1479         dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n",
1480                         ioc->name, SCpnt, mf, my_idx));
1481         DBG_DUMP_REQUEST_FRAME(ioc, (u32 *)mf);
1482         return 0;
1483
1484  fail:
1485         hd->ScsiLookup[my_idx] = NULL;
1486         mptscsih_freeChainBuffers(ioc, my_idx);
1487         mpt_free_msg_frame(ioc, mf);
1488         return SCSI_MLQUEUE_HOST_BUSY;
1489 }
1490
1491 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1492 /*
1493  *      mptscsih_freeChainBuffers - Function to free chain buffers associated
1494  *      with a SCSI IO request
1495  *      @hd: Pointer to the MPT_SCSI_HOST instance
1496  *      @req_idx: Index of the SCSI IO request frame.
1497  *
1498  *      Called if SG chain buffer allocation fails and mptscsih callbacks.
1499  *      No return.
1500  */
1501 static void
1502 mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
1503 {
1504         MPT_FRAME_HDR *chain;
1505         unsigned long flags;
1506         int chain_idx;
1507         int next;
1508
1509         /* Get the first chain index and reset
1510          * tracker state.
1511          */
1512         chain_idx = ioc->ReqToChain[req_idx];
1513         ioc->ReqToChain[req_idx] = MPT_HOST_NO_CHAIN;
1514
1515         while (chain_idx != MPT_HOST_NO_CHAIN) {
1516
1517                 /* Save the next chain buffer index */
1518                 next = ioc->ChainToChain[chain_idx];
1519
1520                 /* Free this chain buffer and reset
1521                  * tracker
1522                  */
1523                 ioc->ChainToChain[chain_idx] = MPT_HOST_NO_CHAIN;
1524
1525                 chain = (MPT_FRAME_HDR *) (ioc->ChainBuffer
1526                                         + (chain_idx * ioc->req_sz));
1527
1528                 spin_lock_irqsave(&ioc->FreeQlock, flags);
1529                 list_add_tail(&chain->u.frame.linkage.list, &ioc->FreeChainQ);
1530                 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1531
1532                 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FreeChainBuffers (index %d)\n",
1533                                 ioc->name, chain_idx));
1534
1535                 /* handle next */
1536                 chain_idx = next;
1537         }
1538         return;
1539 }
1540
1541 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1542 /*
1543  *      Reset Handling
1544  */
1545
1546 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1547 /**
1548  *      mptscsih_TMHandler - Generic handler for SCSI Task Management.
1549  *      @hd: Pointer to MPT SCSI HOST structure
1550  *      @type: Task Management type
1551  *      @channel: channel number for task management
1552  *      @id: Logical Target ID for reset (if appropriate)
1553  *      @lun: Logical Unit for reset (if appropriate)
1554  *      @ctx2abort: Context for the task to be aborted (if appropriate)
1555  *      @timeout: timeout for task management control
1556  *
1557  *      Fall through to mpt_HardResetHandler if: not operational, too many
1558  *      failed TM requests or handshake failure.
1559  *
1560  *      Remark: Currently invoked from a non-interrupt thread (_bh).
1561  *
1562  *      Remark: With old EH code, at most 1 SCSI TaskMgmt function per IOC
1563  *      will be active.
1564  *
1565  *      Returns 0 for SUCCESS, or %FAILED.
1566  **/
1567 int
1568 mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout)
1569 {
1570         MPT_ADAPTER     *ioc;
1571         int              rc = -1;
1572         u32              ioc_raw_state;
1573         unsigned long    flags;
1574
1575         ioc = hd->ioc;
1576         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TMHandler Entered!\n", ioc->name));
1577
1578         // SJR - CHECKME - Can we avoid this here?
1579         // (mpt_HardResetHandler has this check...)
1580         spin_lock_irqsave(&ioc->diagLock, flags);
1581         if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)) {
1582                 spin_unlock_irqrestore(&ioc->diagLock, flags);
1583                 return FAILED;
1584         }
1585         spin_unlock_irqrestore(&ioc->diagLock, flags);
1586
1587         /*  Wait a fixed amount of time for the TM pending flag to be cleared.
1588          *  If we time out and not bus reset, then we return a FAILED status
1589          *  to the caller.
1590          *  The call to mptscsih_tm_pending_wait() will set the pending flag
1591          *  if we are
1592          *  successful. Otherwise, reload the FW.
1593          */
1594         if (mptscsih_tm_pending_wait(hd) == FAILED) {
1595                 if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
1596                         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TMHandler abort: "
1597                            "Timed out waiting for last TM (%d) to complete! \n",
1598                            ioc->name, hd->tmPending));
1599                         return FAILED;
1600                 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) {
1601                         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TMHandler target "
1602                                 "reset: Timed out waiting for last TM (%d) "
1603                                 "to complete! \n", ioc->name,
1604                                 hd->tmPending));
1605                         return FAILED;
1606                 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
1607                         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TMHandler bus reset: "
1608                            "Timed out waiting for last TM (%d) to complete! \n",
1609                           ioc->name, hd->tmPending));
1610                         return FAILED;
1611                 }
1612         } else {
1613                 spin_lock_irqsave(&ioc->FreeQlock, flags);
1614                 hd->tmPending |=  (1 << type);
1615                 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1616         }
1617
1618         ioc_raw_state = mpt_GetIocState(ioc, 0);
1619
1620         if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) {
1621                 printk(MYIOC_s_WARN_FMT
1622                         "TM Handler for type=%x: IOC Not operational (0x%x)!\n",
1623                         ioc->name, type, ioc_raw_state);
1624                 printk(MYIOC_s_WARN_FMT " Issuing HardReset!!\n", ioc->name);
1625                 if (mpt_HardResetHandler(ioc, CAN_SLEEP) < 0)
1626                         printk(MYIOC_s_WARN_FMT "TMHandler: HardReset "
1627                             "FAILED!!\n", ioc->name);
1628                 return FAILED;
1629         }
1630
1631         if (ioc_raw_state & MPI_DOORBELL_ACTIVE) {
1632                 printk(MYIOC_s_WARN_FMT
1633                         "TM Handler for type=%x: ioc_state: "
1634                         "DOORBELL_ACTIVE (0x%x)!\n",
1635                         ioc->name, type, ioc_raw_state);
1636                 return FAILED;
1637         }
1638
1639         /* Isse the Task Mgmt request.
1640          */
1641         if (hd->hard_resets < -1)
1642                 hd->hard_resets++;
1643
1644         rc = mptscsih_IssueTaskMgmt(hd, type, channel, id, lun,
1645             ctx2abort, timeout);
1646         if (rc)
1647                 printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n",
1648                        ioc->name);
1649         else
1650                 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Issue of TaskMgmt Successful!\n",
1651                            ioc->name));
1652
1653         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1654                         "TMHandler rc = %d!\n", ioc->name, rc));
1655
1656         return rc;
1657 }
1658
1659
1660 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1661 /**
1662  *      mptscsih_IssueTaskMgmt - Generic send Task Management function.
1663  *      @hd: Pointer to MPT_SCSI_HOST structure
1664  *      @type: Task Management type
1665  *      @channel: channel number for task management
1666  *      @id: Logical Target ID for reset (if appropriate)
1667  *      @lun: Logical Unit for reset (if appropriate)
1668  *      @ctx2abort: Context for the task to be aborted (if appropriate)
1669  *      @timeout: timeout for task management control
1670  *
1671  *      Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
1672  *      or a non-interrupt thread.  In the former, must not call schedule().
1673  *
1674  *      Not all fields are meaningfull for all task types.
1675  *
1676  *      Returns 0 for SUCCESS, or FAILED.
1677  *
1678  **/
1679 static int
1680 mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout)
1681 {
1682         MPT_FRAME_HDR   *mf;
1683         SCSITaskMgmt_t  *pScsiTm;
1684         int              ii;
1685         int              retval;
1686         MPT_ADAPTER     *ioc = hd->ioc;
1687
1688         /* Return Fail to calling function if no message frames available.
1689          */
1690         if ((mf = mpt_get_msg_frame(ioc->TaskCtx, ioc)) == NULL) {
1691                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "IssueTaskMgmt, no msg frames!!\n",
1692                                 ioc->name));
1693                 return FAILED;
1694         }
1695         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IssueTaskMgmt request @ %p\n",
1696                         ioc->name, mf));
1697
1698         /* Format the Request
1699          */
1700         pScsiTm = (SCSITaskMgmt_t *) mf;
1701         pScsiTm->TargetID = id;
1702         pScsiTm->Bus = channel;
1703         pScsiTm->ChainOffset = 0;
1704         pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
1705
1706         pScsiTm->Reserved = 0;
1707         pScsiTm->TaskType = type;
1708         pScsiTm->Reserved1 = 0;
1709         pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)
1710                     ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0;
1711
1712         int_to_scsilun(lun, (struct scsi_lun *)pScsiTm->LUN);
1713
1714         for (ii=0; ii < 7; ii++)
1715                 pScsiTm->Reserved2[ii] = 0;
1716
1717         pScsiTm->TaskMsgContext = ctx2abort;
1718
1719         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IssueTaskMgmt: ctx2abort (0x%08x) "
1720                 "type=%d\n", ioc->name, ctx2abort, type));
1721
1722         DBG_DUMP_TM_REQUEST_FRAME(ioc, (u32 *)pScsiTm);
1723
1724         if ((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q) &&
1725             (ioc->facts.MsgVersion >= MPI_VERSION_01_05))
1726                 mpt_put_msg_frame_hi_pri(ioc->TaskCtx, ioc, mf);
1727         else {
1728                 retval = mpt_send_handshake_request(ioc->TaskCtx, ioc,
1729                         sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, CAN_SLEEP);
1730                 if (retval) {
1731                         dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "send_handshake FAILED!"
1732                         " (hd %p, ioc %p, mf %p, rc=%d) \n", ioc->name, hd,
1733                         ioc, mf, retval));
1734                         goto fail_out;
1735                 }
1736         }
1737
1738         if(mptscsih_tm_wait_for_completion(hd, timeout) == FAILED) {
1739                 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "task management request TIMED OUT!"
1740                         " (hd %p, ioc %p, mf %p) \n", ioc->name, hd,
1741                         ioc, mf));
1742                 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling HardReset! \n",
1743                          ioc->name));
1744                 retval = mpt_HardResetHandler(ioc, CAN_SLEEP);
1745                 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "rc=%d \n",
1746                          ioc->name, retval));
1747                 goto fail_out;
1748         }
1749
1750         /*
1751          * Handle success case, see if theres a non-zero ioc_status.
1752          */
1753         if (hd->tm_iocstatus == MPI_IOCSTATUS_SUCCESS ||
1754            hd->tm_iocstatus == MPI_IOCSTATUS_SCSI_TASK_TERMINATED ||
1755            hd->tm_iocstatus == MPI_IOCSTATUS_SCSI_IOC_TERMINATED)
1756                 retval = 0;
1757         else
1758                 retval = FAILED;
1759
1760         return retval;
1761
1762  fail_out:
1763
1764         /*
1765          * Free task managment mf, and corresponding tm flags
1766          */
1767         mpt_free_msg_frame(ioc, mf);
1768         hd->tmPending = 0;
1769         hd->tmState = TM_STATE_NONE;
1770         return FAILED;
1771 }
1772
1773 static int
1774 mptscsih_get_tm_timeout(MPT_ADAPTER *ioc)
1775 {
1776         switch (ioc->bus_type) {
1777         case FC:
1778                 return 40;
1779         case SAS:
1780                 return 10;
1781         case SPI:
1782         default:
1783                 return 2;
1784         }
1785 }
1786
1787 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1788 /**
1789  *      mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant
1790  *      @SCpnt: Pointer to scsi_cmnd structure, IO to be aborted
1791  *
1792  *      (linux scsi_host_template.eh_abort_handler routine)
1793  *
1794  *      Returns SUCCESS or FAILED.
1795  **/
1796 int
1797 mptscsih_abort(struct scsi_cmnd * SCpnt)
1798 {
1799         MPT_SCSI_HOST   *hd;
1800         MPT_FRAME_HDR   *mf;
1801         u32              ctx2abort;
1802         int              scpnt_idx;
1803         int              retval;
1804         VirtDevice       *vdevice;
1805         ulong            sn = SCpnt->serial_number;
1806         MPT_ADAPTER     *ioc;
1807
1808         /* If we can't locate our host adapter structure, return FAILED status.
1809          */
1810         if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL) {
1811                 SCpnt->result = DID_RESET << 16;
1812                 SCpnt->scsi_done(SCpnt);
1813                 printk(KERN_ERR MYNAM ": task abort: "
1814                     "can't locate host! (sc=%p)\n", SCpnt);
1815                 return FAILED;
1816         }
1817
1818         ioc = hd->ioc;
1819         printk(MYIOC_s_INFO_FMT "attempting task abort! (sc=%p)\n",
1820                ioc->name, SCpnt);
1821         scsi_print_command(SCpnt);
1822
1823         vdevice = SCpnt->device->hostdata;
1824         if (!vdevice || !vdevice->vtarget) {
1825                 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1826                     "task abort: device has been deleted (sc=%p)\n",
1827                     ioc->name, SCpnt));
1828                 SCpnt->result = DID_NO_CONNECT << 16;
1829                 SCpnt->scsi_done(SCpnt);
1830                 retval = 0;
1831                 goto out;
1832         }
1833
1834         /* Task aborts are not supported for hidden raid components.
1835          */
1836         if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
1837                 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1838                     "task abort: hidden raid component (sc=%p)\n",
1839                     ioc->name, SCpnt));
1840                 SCpnt->result = DID_RESET << 16;
1841                 retval = FAILED;
1842                 goto out;
1843         }
1844
1845         /* Find this command
1846          */
1847         if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) {
1848                 /* Cmd not found in ScsiLookup.
1849                  * Do OS callback.
1850                  */
1851                 SCpnt->result = DID_RESET << 16;
1852                 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "task abort: "
1853                    "Command not in the active list! (sc=%p)\n", ioc->name,
1854                    SCpnt));
1855                 retval = 0;
1856                 goto out;
1857         }
1858
1859         if (hd->resetPending) {
1860                 retval = FAILED;
1861                 goto out;
1862         }
1863
1864         if (hd->timeouts < -1)
1865                 hd->timeouts++;
1866
1867         /* Most important!  Set TaskMsgContext to SCpnt's MsgContext!
1868          * (the IO to be ABORT'd)
1869          *
1870          * NOTE: Since we do not byteswap MsgContext, we do not
1871          *       swap it here either.  It is an opaque cookie to
1872          *       the controller, so it does not matter. -DaveM
1873          */
1874         mf = MPT_INDEX_2_MFPTR(ioc, scpnt_idx);
1875         ctx2abort = mf->u.frame.hwhdr.msgctxu.MsgContext;
1876
1877         hd->abortSCpnt = SCpnt;
1878
1879         retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
1880             vdevice->vtarget->channel, vdevice->vtarget->id, vdevice->lun,
1881             ctx2abort, mptscsih_get_tm_timeout(ioc));
1882
1883         if (SCPNT_TO_LOOKUP_IDX(SCpnt) == scpnt_idx &&
1884             SCpnt->serial_number == sn)
1885                 retval = FAILED;
1886
1887  out:
1888         printk(MYIOC_s_INFO_FMT "task abort: %s (sc=%p)\n",
1889             ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1890
1891         if (retval == 0)
1892                 return SUCCESS;
1893         else
1894                 return FAILED;
1895 }
1896
1897 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1898 /**
1899  *      mptscsih_dev_reset - Perform a SCSI TARGET_RESET!  new_eh variant
1900  *      @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1901  *
1902  *      (linux scsi_host_template.eh_dev_reset_handler routine)
1903  *
1904  *      Returns SUCCESS or FAILED.
1905  **/
1906 int
1907 mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
1908 {
1909         MPT_SCSI_HOST   *hd;
1910         int              retval;
1911         VirtDevice       *vdevice;
1912         MPT_ADAPTER     *ioc;
1913
1914         /* If we can't locate our host adapter structure, return FAILED status.
1915          */
1916         if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1917                 printk(KERN_ERR MYNAM ": target reset: "
1918                    "Can't locate host! (sc=%p)\n", SCpnt);
1919                 return FAILED;
1920         }
1921
1922         ioc = hd->ioc;
1923         printk(MYIOC_s_INFO_FMT "attempting target reset! (sc=%p)\n",
1924                ioc->name, SCpnt);
1925         scsi_print_command(SCpnt);
1926
1927         if (hd->resetPending) {
1928                 retval = FAILED;
1929                 goto out;
1930         }
1931
1932         vdevice = SCpnt->device->hostdata;
1933         if (!vdevice || !vdevice->vtarget) {
1934                 retval = 0;
1935                 goto out;
1936         }
1937
1938         /* Target reset to hidden raid component is not supported
1939          */
1940         if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
1941                 retval = FAILED;
1942                 goto out;
1943         }
1944
1945         retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
1946             vdevice->vtarget->channel, vdevice->vtarget->id, 0, 0,
1947             mptscsih_get_tm_timeout(ioc));
1948
1949  out:
1950         printk (MYIOC_s_INFO_FMT "target reset: %s (sc=%p)\n",
1951             ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1952
1953         if (retval == 0)
1954                 return SUCCESS;
1955         else
1956                 return FAILED;
1957 }
1958
1959
1960 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1961 /**
1962  *      mptscsih_bus_reset - Perform a SCSI BUS_RESET!  new_eh variant
1963  *      @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1964  *
1965  *      (linux scsi_host_template.eh_bus_reset_handler routine)
1966  *
1967  *      Returns SUCCESS or FAILED.
1968  **/
1969 int
1970 mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
1971 {
1972         MPT_SCSI_HOST   *hd;
1973         int              retval;
1974         VirtDevice       *vdevice;
1975         MPT_ADAPTER     *ioc;
1976
1977         /* If we can't locate our host adapter structure, return FAILED status.
1978          */
1979         if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1980                 printk(KERN_ERR MYNAM ": bus reset: "
1981                    "Can't locate host! (sc=%p)\n", SCpnt);
1982                 return FAILED;
1983         }
1984
1985         ioc = hd->ioc;
1986         printk(MYIOC_s_INFO_FMT "attempting bus reset! (sc=%p)\n",
1987                ioc->name, SCpnt);
1988         scsi_print_command(SCpnt);
1989
1990         if (hd->timeouts < -1)
1991                 hd->timeouts++;
1992
1993         vdevice = SCpnt->device->hostdata;
1994         retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
1995             vdevice->vtarget->channel, 0, 0, 0, mptscsih_get_tm_timeout(ioc));
1996
1997         printk(MYIOC_s_INFO_FMT "bus reset: %s (sc=%p)\n",
1998             ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1999
2000         if (retval == 0)
2001                 return SUCCESS;
2002         else
2003                 return FAILED;
2004 }
2005
2006 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2007 /**
2008  *      mptscsih_host_reset - Perform a SCSI host adapter RESET (new_eh variant)
2009  *      @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
2010  *
2011  *      (linux scsi_host_template.eh_host_reset_handler routine)
2012  *
2013  *      Returns SUCCESS or FAILED.
2014  */
2015 int
2016 mptscsih_host_reset(struct scsi_cmnd *SCpnt)
2017 {
2018         MPT_SCSI_HOST *  hd;
2019         int              retval;
2020         MPT_ADAPTER     *ioc;
2021
2022         /*  If we can't locate the host to reset, then we failed. */
2023         if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
2024                 printk(KERN_ERR MYNAM ": host reset: "
2025                     "Can't locate host! (sc=%p)\n", SCpnt);
2026                 return FAILED;
2027         }
2028
2029         ioc = hd->ioc;
2030         printk(MYIOC_s_INFO_FMT "attempting host reset! (sc=%p)\n",
2031             ioc->name, SCpnt);
2032
2033         /*  If our attempts to reset the host failed, then return a failed
2034          *  status.  The host will be taken off line by the SCSI mid-layer.
2035          */
2036         if (mpt_HardResetHandler(ioc, CAN_SLEEP) < 0) {
2037                 retval = FAILED;
2038         } else {
2039                 /*  Make sure TM pending is cleared and TM state is set to
2040                  *  NONE.
2041                  */
2042                 retval = 0;
2043                 hd->tmPending = 0;
2044                 hd->tmState = TM_STATE_NONE;
2045         }
2046
2047         printk(MYIOC_s_INFO_FMT "host reset: %s (sc=%p)\n",
2048             ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
2049
2050         return retval;
2051 }
2052
2053 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2054 /**
2055  *      mptscsih_tm_pending_wait - wait for pending task management request to complete
2056  *      @hd: Pointer to MPT host structure.
2057  *
2058  *      Returns {SUCCESS,FAILED}.
2059  */
2060 static int
2061 mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd)
2062 {
2063         unsigned long  flags;
2064         int            loop_count = 4 * 10;  /* Wait 10 seconds */
2065         int            status = FAILED;
2066         MPT_ADAPTER     *ioc = hd->ioc;
2067
2068         do {
2069                 spin_lock_irqsave(&ioc->FreeQlock, flags);
2070                 if (hd->tmState == TM_STATE_NONE) {
2071                         hd->tmState = TM_STATE_IN_PROGRESS;
2072                         hd->tmPending = 1;
2073                         spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2074                         status = SUCCESS;
2075                         break;
2076                 }
2077                 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2078                 msleep(250);
2079         } while (--loop_count);
2080
2081         return status;
2082 }
2083
2084 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2085 /**
2086  *      mptscsih_tm_wait_for_completion - wait for completion of TM task
2087  *      @hd: Pointer to MPT host structure.
2088  *      @timeout: timeout value
2089  *
2090  *      Returns {SUCCESS,FAILED}.
2091  */
2092 static int
2093 mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout )
2094 {
2095         unsigned long  flags;
2096         int            loop_count = 4 * timeout;
2097         int            status = FAILED;
2098         MPT_ADAPTER     *ioc = hd->ioc;
2099
2100         do {
2101                 spin_lock_irqsave(&ioc->FreeQlock, flags);
2102                 if(hd->tmPending == 0) {
2103                         status = SUCCESS;
2104                         spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2105                         break;
2106                 }
2107                 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2108                 msleep(250);
2109         } while (--loop_count);
2110
2111         return status;
2112 }
2113
2114 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2115 static void
2116 mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code)
2117 {
2118         char *desc;
2119
2120         switch (response_code) {
2121         case MPI_SCSITASKMGMT_RSP_TM_COMPLETE:
2122                 desc = "The task completed.";
2123                 break;
2124         case MPI_SCSITASKMGMT_RSP_INVALID_FRAME:
2125                 desc = "The IOC received an invalid frame status.";
2126                 break;
2127         case MPI_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED:
2128                 desc = "The task type is not supported.";
2129                 break;
2130         case MPI_SCSITASKMGMT_RSP_TM_FAILED:
2131                 desc = "The requested task failed.";
2132                 break;
2133         case MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED:
2134                 desc = "The task completed successfully.";
2135                 break;
2136         case MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN:
2137                 desc = "The LUN request is invalid.";
2138                 break;
2139         case MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC:
2140                 desc = "The task is in the IOC queue and has not been sent to target.";
2141                 break;
2142         default:
2143                 desc = "unknown";
2144                 break;
2145         }
2146         printk(MYIOC_s_INFO_FMT "Response Code(0x%08x): F/W: %s\n",
2147                 ioc->name, response_code, desc);
2148 }
2149
2150 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2151 /**
2152  *      mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
2153  *      @ioc: Pointer to MPT_ADAPTER structure
2154  *      @mf: Pointer to SCSI task mgmt request frame
2155  *      @mr: Pointer to SCSI task mgmt reply frame
2156  *
2157  *      This routine is called from mptbase.c::mpt_interrupt() at the completion
2158  *      of any SCSI task management request.
2159  *      This routine is registered with the MPT (base) driver at driver
2160  *      load/init time via the mpt_register() API call.
2161  *
2162  *      Returns 1 indicating alloc'd request frame ptr should be freed.
2163  **/
2164 int
2165 mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
2166 {
2167         SCSITaskMgmtReply_t     *pScsiTmReply;
2168         SCSITaskMgmt_t          *pScsiTmReq;
2169         MPT_SCSI_HOST           *hd;
2170         unsigned long            flags;
2171         u16                      iocstatus;
2172         u8                       tmType;
2173         u32                      termination_count;
2174
2175         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt completed (mf=%p,mr=%p)\n",
2176             ioc->name, mf, mr));
2177         if (!ioc->sh) {
2178                 dtmprintk(ioc, printk(MYIOC_s_WARN_FMT
2179                     "TaskMgmt Complete: NULL Scsi Host Ptr\n", ioc->name));
2180                 return 1;
2181         }
2182
2183         if (mr == NULL) {
2184                 dtmprintk(ioc, printk(MYIOC_s_WARN_FMT
2185                     "ERROR! TaskMgmt Reply: NULL Request %p\n", ioc->name, mf));
2186                 return 1;
2187         }
2188
2189         hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
2190         pScsiTmReply = (SCSITaskMgmtReply_t*)mr;
2191         pScsiTmReq = (SCSITaskMgmt_t*)mf;
2192         tmType = pScsiTmReq->TaskType;
2193         iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2194         termination_count = le32_to_cpu(pScsiTmReply->TerminationCount);
2195
2196         if (ioc->facts.MsgVersion >= MPI_VERSION_01_05 &&
2197             pScsiTmReply->ResponseCode)
2198                 mptscsih_taskmgmt_response_code(ioc,
2199                     pScsiTmReply->ResponseCode);
2200         DBG_DUMP_TM_REPLY_FRAME(ioc, (u32 *)pScsiTmReply);
2201
2202 #ifdef CONFIG_FUSION_LOGGING
2203         if ((ioc->debug_level & MPT_DEBUG_REPLY) ||
2204                                 (ioc->debug_level & MPT_DEBUG_TM ))
2205                 printk("%s: ha=%d [%d:%d:0] task_type=0x%02X "
2206                         "iocstatus=0x%04X\n\tloginfo=0x%08X response_code=0x%02X "
2207                         "term_cmnds=%d\n", __FUNCTION__, ioc->id, pScsiTmReply->Bus,
2208                          pScsiTmReply->TargetID, pScsiTmReq->TaskType,
2209                         le16_to_cpu(pScsiTmReply->IOCStatus),
2210                         le32_to_cpu(pScsiTmReply->IOCLogInfo),pScsiTmReply->ResponseCode,
2211                         le32_to_cpu(pScsiTmReply->TerminationCount));
2212 #endif
2213         if (!iocstatus) {
2214                 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT " TaskMgmt SUCCESS\n", ioc->name));
2215                         hd->abortSCpnt = NULL;
2216                 goto out;
2217         }
2218
2219         /* Error?  (anything non-zero?) */
2220
2221         /* clear flags and continue.
2222          */
2223         switch (tmType) {
2224
2225         case MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK:
2226                 if (termination_count == 1)
2227                         iocstatus = MPI_IOCSTATUS_SCSI_TASK_TERMINATED;
2228                 hd->abortSCpnt = NULL;
2229                 break;
2230
2231         case MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS:
2232
2233                 /* If an internal command is present
2234                  * or the TM failed - reload the FW.
2235                  * FC FW may respond FAILED to an ABORT
2236                  */
2237                 if (iocstatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED ||
2238                     hd->cmdPtr)
2239                         if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
2240                                 printk(MYIOC_s_WARN_FMT " Firmware Reload FAILED!!\n", ioc->name);
2241                 break;
2242
2243         case MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET:
2244         default:
2245                 break;
2246         }
2247
2248  out:
2249         spin_lock_irqsave(&ioc->FreeQlock, flags);
2250         hd->tmPending = 0;
2251         hd->tmState = TM_STATE_NONE;
2252         hd->tm_iocstatus = iocstatus;
2253         spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2254
2255         return 1;
2256 }
2257
2258 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2259 /*
2260  *      This is anyones guess quite frankly.
2261  */
2262 int
2263 mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
2264                 sector_t capacity, int geom[])
2265 {
2266         int             heads;
2267         int             sectors;
2268         sector_t        cylinders;
2269         ulong           dummy;
2270
2271         heads = 64;
2272         sectors = 32;
2273
2274         dummy = heads * sectors;
2275         cylinders = capacity;
2276         sector_div(cylinders,dummy);
2277
2278         /*
2279          * Handle extended translation size for logical drives
2280          * > 1Gb
2281          */
2282         if ((ulong)capacity >= 0x200000) {
2283                 heads = 255;
2284                 sectors = 63;
2285                 dummy = heads * sectors;
2286                 cylinders = capacity;
2287                 sector_div(cylinders,dummy);
2288         }
2289
2290         /* return result */
2291         geom[0] = heads;
2292         geom[1] = sectors;
2293         geom[2] = cylinders;
2294
2295         return 0;
2296 }
2297
2298 /* Search IOC page 3 to determine if this is hidden physical disk
2299  *
2300  */
2301 int
2302 mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id)
2303 {
2304         struct inactive_raid_component_info *component_info;
2305         int i;
2306         int rc = 0;
2307
2308         if (!ioc->raid_data.pIocPg3)
2309                 goto out;
2310         for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2311                 if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) &&
2312                     (channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) {
2313                         rc = 1;
2314                         goto out;
2315                 }
2316         }
2317
2318         /*
2319          * Check inactive list for matching phys disks
2320          */
2321         if (list_empty(&ioc->raid_data.inactive_list))
2322                 goto out;
2323
2324         down(&ioc->raid_data.inactive_list_mutex);
2325         list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
2326             list) {
2327                 if ((component_info->d.PhysDiskID == id) &&
2328                     (component_info->d.PhysDiskBus == channel))
2329                         rc = 1;
2330         }
2331         up(&ioc->raid_data.inactive_list_mutex);
2332
2333  out:
2334         return rc;
2335 }
2336 EXPORT_SYMBOL(mptscsih_is_phys_disk);
2337
2338 u8
2339 mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id)
2340 {
2341         struct inactive_raid_component_info *component_info;
2342         int i;
2343         int rc = -ENXIO;
2344
2345         if (!ioc->raid_data.pIocPg3)
2346                 goto out;
2347         for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2348                 if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) &&
2349                     (channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) {
2350                         rc = ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum;
2351                         goto out;
2352                 }
2353         }
2354
2355         /*
2356          * Check inactive list for matching phys disks
2357          */
2358         if (list_empty(&ioc->raid_data.inactive_list))
2359                 goto out;
2360
2361         down(&ioc->raid_data.inactive_list_mutex);
2362         list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
2363             list) {
2364                 if ((component_info->d.PhysDiskID == id) &&
2365                     (component_info->d.PhysDiskBus == channel))
2366                         rc = component_info->d.PhysDiskNum;
2367         }
2368         up(&ioc->raid_data.inactive_list_mutex);
2369
2370  out:
2371         return rc;
2372 }
2373 EXPORT_SYMBOL(mptscsih_raid_id_to_num);
2374
2375 /*
2376  *      OS entry point to allow for host driver to free allocated memory
2377  *      Called if no device present or device being unloaded
2378  */
2379 void
2380 mptscsih_slave_destroy(struct scsi_device *sdev)
2381 {
2382         struct Scsi_Host        *host = sdev->host;
2383         MPT_SCSI_HOST           *hd = (MPT_SCSI_HOST *)host->hostdata;
2384         VirtTarget              *vtarget;
2385         VirtDevice              *vdevice;
2386         struct scsi_target      *starget;
2387
2388         starget = scsi_target(sdev);
2389         vtarget = starget->hostdata;
2390         vdevice = sdev->hostdata;
2391
2392         mptscsih_search_running_cmds(hd, vdevice);
2393         vtarget->num_luns--;
2394         mptscsih_synchronize_cache(hd, vdevice);
2395         kfree(vdevice);
2396         sdev->hostdata = NULL;
2397 }
2398
2399 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2400 /*
2401  *      mptscsih_change_queue_depth - This function will set a devices queue depth
2402  *      @sdev: per scsi_device pointer
2403  *      @qdepth: requested queue depth
2404  *
2405  *      Adding support for new 'change_queue_depth' api.
2406 */
2407 int
2408 mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
2409 {
2410         MPT_SCSI_HOST           *hd = (MPT_SCSI_HOST *)sdev->host->hostdata;
2411         VirtTarget              *vtarget;
2412         struct scsi_target      *starget;
2413         int                     max_depth;
2414         int                     tagged;
2415         MPT_ADAPTER             *ioc = hd->ioc;
2416
2417         starget = scsi_target(sdev);
2418         vtarget = starget->hostdata;
2419
2420         if (ioc->bus_type == SPI) {
2421                 if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
2422                         max_depth = 1;
2423                 else if (sdev->type == TYPE_DISK &&
2424                          vtarget->minSyncFactor <= MPT_ULTRA160)
2425                         max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2426                 else
2427                         max_depth = MPT_SCSI_CMD_PER_DEV_LOW;
2428         } else
2429                 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2430
2431         if (qdepth > max_depth)
2432                 qdepth = max_depth;
2433         if (qdepth == 1)
2434                 tagged = 0;
2435         else
2436                 tagged = MSG_SIMPLE_TAG;
2437
2438         scsi_adjust_queue_depth(sdev, tagged, qdepth);
2439         return sdev->queue_depth;
2440 }
2441
2442 /*
2443  *      OS entry point to adjust the queue_depths on a per-device basis.
2444  *      Called once per device the bus scan. Use it to force the queue_depth
2445  *      member to 1 if a device does not support Q tags.
2446  *      Return non-zero if fails.
2447  */
2448 int
2449 mptscsih_slave_configure(struct scsi_device *sdev)
2450 {
2451         struct Scsi_Host        *sh = sdev->host;
2452         VirtTarget              *vtarget;
2453         VirtDevice              *vdevice;
2454         struct scsi_target      *starget;
2455         MPT_SCSI_HOST           *hd = (MPT_SCSI_HOST *)sh->hostdata;
2456         MPT_ADAPTER             *ioc = hd->ioc;
2457
2458         starget = scsi_target(sdev);
2459         vtarget = starget->hostdata;
2460         vdevice = sdev->hostdata;
2461
2462         dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2463                 "device @ %p, channel=%d, id=%d, lun=%d\n",
2464                 ioc->name, sdev, sdev->channel, sdev->id, sdev->lun));
2465         if (ioc->bus_type == SPI)
2466                 dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2467                     "sdtr %d wdtr %d ppr %d inq length=%d\n",
2468                     ioc->name, sdev->sdtr, sdev->wdtr,
2469                     sdev->ppr, sdev->inquiry_len));
2470
2471         if (sdev->id > sh->max_id) {
2472                 /* error case, should never happen */
2473                 scsi_adjust_queue_depth(sdev, 0, 1);
2474                 goto slave_configure_exit;
2475         }
2476
2477         vdevice->configured_lun = 1;
2478         mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH);
2479
2480         dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2481                 "Queue depth=%d, tflags=%x\n",
2482                 ioc->name, sdev->queue_depth, vtarget->tflags));
2483
2484         if (ioc->bus_type == SPI)
2485                 dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2486                     "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
2487                     ioc->name, vtarget->negoFlags, vtarget->maxOffset,
2488                     vtarget->minSyncFactor));
2489
2490 slave_configure_exit:
2491
2492         dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2493                 "tagged %d, simple %d, ordered %d\n",
2494                 ioc->name,sdev->tagged_supported, sdev->simple_tags,
2495                 sdev->ordered_tags));
2496
2497         return 0;
2498 }
2499
2500 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2501 /*
2502  *  Private routines...
2503  */
2504
2505 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2506 /* Utility function to copy sense data from the scsi_cmnd buffer
2507  * to the FC and SCSI target structures.
2508  *
2509  */
2510 static void
2511 mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
2512 {
2513         VirtDevice      *vdevice;
2514         SCSIIORequest_t *pReq;
2515         u32              sense_count = le32_to_cpu(pScsiReply->SenseCount);
2516         MPT_ADAPTER     *ioc = hd->ioc;
2517
2518         /* Get target structure
2519          */
2520         pReq = (SCSIIORequest_t *) mf;
2521         vdevice = sc->device->hostdata;
2522
2523         if (sense_count) {
2524                 u8 *sense_data;
2525                 int req_index;
2526
2527                 /* Copy the sense received into the scsi command block. */
2528                 req_index = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2529                 sense_data = ((u8 *)ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC));
2530                 memcpy(sc->sense_buffer, sense_data, SNS_LEN(sc));
2531
2532                 /* Log SMART data (asc = 0x5D, non-IM case only) if required.
2533                  */
2534                 if ((ioc->events) && (ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) {
2535                         if ((sense_data[12] == 0x5D) && (vdevice->vtarget->raidVolume == 0)) {
2536                                 int idx;
2537
2538                                 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
2539                                 ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
2540                                 ioc->events[idx].eventContext = ioc->eventContext;
2541
2542                                 ioc->events[idx].data[0] = (pReq->LUN[1] << 24) |
2543                                         (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) |
2544                                         (sc->device->channel << 8) | sc->device->id;
2545
2546                                 ioc->events[idx].data[1] = (sense_data[13] << 8) | sense_data[12];
2547
2548                                 ioc->eventContext++;
2549                                 if (ioc->pcidev->vendor ==
2550                                     PCI_VENDOR_ID_IBM) {
2551                                         mptscsih_issue_sep_command(ioc,
2552                                             vdevice->vtarget, MPI_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT);
2553                                         vdevice->vtarget->tflags |=
2554                                             MPT_TARGET_FLAGS_LED_ON;
2555                                 }
2556                         }
2557                 }
2558         } else {
2559                 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Hmmm... SenseData len=0! (?)\n",
2560                                 ioc->name));
2561         }
2562 }
2563
2564 static int
2565 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc)
2566 {
2567         MPT_SCSI_HOST *hd;
2568         int i;
2569
2570         hd = (MPT_SCSI_HOST *) sc->device->host->hostdata;
2571
2572         for (i = 0; i < hd->ioc->req_depth; i++) {
2573                 if (hd->ScsiLookup[i] == sc) {
2574                         return i;
2575                 }
2576         }
2577
2578         return -1;
2579 }
2580
2581 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2582 int
2583 mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2584 {
2585         MPT_SCSI_HOST   *hd;
2586         unsigned long    flags;
2587         int             ii;
2588
2589         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2590             ": IOC %s_reset routed to SCSI host driver!\n",
2591             ioc->name, reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
2592             reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
2593
2594         /* If a FW reload request arrives after base installed but
2595          * before all scsi hosts have been attached, then an alt_ioc
2596          * may have a NULL sh pointer.
2597          */
2598         if ((ioc->sh == NULL) || (ioc->sh->hostdata == NULL))
2599                 return 0;
2600         else
2601                 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2602
2603         if (reset_phase == MPT_IOC_SETUP_RESET) {
2604                 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Setup-Diag Reset\n", ioc->name));
2605
2606                 /* Clean Up:
2607                  * 1. Set Hard Reset Pending Flag
2608                  * All new commands go to doneQ
2609                  */
2610                 hd->resetPending = 1;
2611
2612         } else if (reset_phase == MPT_IOC_PRE_RESET) {
2613                 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Pre-Diag Reset\n", ioc->name));
2614
2615                 /* 2. Flush running commands
2616                  *      Clean ScsiLookup (and associated memory)
2617                  *      AND clean mytaskQ
2618                  */
2619
2620                 /* 2b. Reply to OS all known outstanding I/O commands.
2621                  */
2622                 mptscsih_flush_running_cmds(hd);
2623
2624                 /* 2c. If there was an internal command that
2625                  * has not completed, configuration or io request,
2626                  * free these resources.
2627                  */
2628                 if (hd->cmdPtr) {
2629                         del_timer(&hd->timer);
2630                         mpt_free_msg_frame(ioc, hd->cmdPtr);
2631                 }
2632
2633                 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Pre-Reset complete.\n", ioc->name));
2634
2635         } else {
2636                 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Post-Diag Reset\n", ioc->name));
2637
2638                 /* Once a FW reload begins, all new OS commands are
2639                  * redirected to the doneQ w/ a reset status.
2640                  * Init all control structures.
2641                  */
2642
2643                 /* ScsiLookup initialization
2644                  */
2645                 for (ii=0; ii < ioc->req_depth; ii++)
2646                         hd->ScsiLookup[ii] = NULL;
2647
2648                 /* 2. Chain Buffer initialization
2649                  */
2650
2651                 /* 4. Renegotiate to all devices, if SPI
2652                  */
2653
2654                 /* 5. Enable new commands to be posted
2655                  */
2656                 spin_lock_irqsave(&ioc->FreeQlock, flags);
2657                 hd->tmPending = 0;
2658                 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2659                 hd->resetPending = 0;
2660                 hd->tmState = TM_STATE_NONE;
2661
2662                 /* 6. If there was an internal command,
2663                  * wake this process up.
2664                  */
2665                 if (hd->cmdPtr) {
2666                         /*
2667                          * Wake up the original calling thread
2668                          */
2669                         hd->pLocal = &hd->localReply;
2670                         hd->pLocal->completion = MPT_SCANDV_DID_RESET;
2671                         hd->scandv_wait_done = 1;
2672                         wake_up(&hd->scandv_waitq);
2673                         hd->cmdPtr = NULL;
2674                 }
2675
2676                 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Post-Reset complete.\n", ioc->name));
2677
2678         }
2679
2680         return 1;               /* currently means nothing really */
2681 }
2682
2683 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2684 int
2685 mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2686 {
2687         MPT_SCSI_HOST *hd;
2688         u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
2689
2690         devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
2691                         ioc->name, event));
2692
2693         if (ioc->sh == NULL ||
2694                 ((hd = (MPT_SCSI_HOST *)ioc->sh->hostdata) == NULL))
2695                 return 1;
2696
2697         switch (event) {
2698         case MPI_EVENT_UNIT_ATTENTION:                  /* 03 */
2699                 /* FIXME! */
2700                 break;
2701         case MPI_EVENT_IOC_BUS_RESET:                   /* 04 */
2702         case MPI_EVENT_EXT_BUS_RESET:                   /* 05 */
2703                 if (hd && (ioc->bus_type == SPI) && (hd->soft_resets < -1))
2704                         hd->soft_resets++;
2705                 break;
2706         case MPI_EVENT_LOGOUT:                          /* 09 */
2707                 /* FIXME! */
2708                 break;
2709
2710         case MPI_EVENT_RESCAN:                          /* 06 */
2711                 break;
2712
2713                 /*
2714                  *  CHECKME! Don't think we need to do
2715                  *  anything for these, but...
2716                  */
2717         case MPI_EVENT_LINK_STATUS_CHANGE:              /* 07 */
2718         case MPI_EVENT_LOOP_STATE_CHANGE:               /* 08 */
2719                 /*
2720                  *  CHECKME!  Falling thru...
2721                  */
2722                 break;
2723
2724         case MPI_EVENT_INTEGRATED_RAID:                 /* 0B */
2725                 break;
2726
2727         case MPI_EVENT_NONE:                            /* 00 */
2728         case MPI_EVENT_LOG_DATA:                        /* 01 */
2729         case MPI_EVENT_STATE_CHANGE:                    /* 02 */
2730         case MPI_EVENT_EVENT_CHANGE:                    /* 0A */
2731         default:
2732                 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": Ignoring event (=%02Xh)\n",
2733                     ioc->name, event));
2734                 break;
2735         }
2736
2737         return 1;               /* currently means nothing really */
2738 }
2739
2740 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2741 /*
2742  *  Bus Scan and Domain Validation functionality ...
2743  */
2744
2745 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2746 /*
2747  *      mptscsih_scandv_complete - Scan and DV callback routine registered
2748  *      to Fustion MPT (base) driver.
2749  *
2750  *      @ioc: Pointer to MPT_ADAPTER structure
2751  *      @mf: Pointer to original MPT request frame
2752  *      @mr: Pointer to MPT reply frame (NULL if TurboReply)
2753  *
2754  *      This routine is called from mpt.c::mpt_interrupt() at the completion
2755  *      of any SCSI IO request.
2756  *      This routine is registered with the Fusion MPT (base) driver at driver
2757  *      load/init time via the mpt_register() API call.
2758  *
2759  *      Returns 1 indicating alloc'd request frame ptr should be freed.
2760  *
2761  *      Remark: Sets a completion code and (possibly) saves sense data
2762  *      in the IOC member localReply structure.
2763  *      Used ONLY for DV and other internal commands.
2764  */
2765 int
2766 mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
2767 {
2768         MPT_SCSI_HOST   *hd;
2769         SCSIIORequest_t *pReq;
2770         int              completionCode;
2771         u16              req_idx;
2772
2773         hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2774
2775         if ((mf == NULL) ||
2776             (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) {
2777                 printk(MYIOC_s_ERR_FMT
2778                         "ScanDvComplete, %s req frame ptr! (=%p)\n",
2779                                 ioc->name, mf?"BAD":"NULL", (void *) mf);
2780                 goto wakeup;
2781         }
2782
2783         del_timer(&hd->timer);
2784         req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2785         hd->ScsiLookup[req_idx] = NULL;
2786         pReq = (SCSIIORequest_t *) mf;
2787
2788         if (mf != hd->cmdPtr) {
2789                 printk(MYIOC_s_WARN_FMT "ScanDvComplete (mf=%p, cmdPtr=%p, idx=%d)\n",
2790                                 ioc->name, (void *)mf, (void *) hd->cmdPtr, req_idx);
2791         }
2792         hd->cmdPtr = NULL;
2793
2794         ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ScanDvComplete (mf=%p,mr=%p,idx=%d)\n",
2795                         ioc->name, mf, mr, req_idx));
2796
2797         hd->pLocal = &hd->localReply;
2798         hd->pLocal->scsiStatus = 0;
2799
2800         /* If target struct exists, clear sense valid flag.
2801          */
2802         if (mr == NULL) {
2803                 completionCode = MPT_SCANDV_GOOD;
2804         } else {
2805                 SCSIIOReply_t   *pReply;
2806                 u16              status;
2807                 u8               scsi_status;
2808
2809                 pReply = (SCSIIOReply_t *) mr;
2810
2811                 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2812                 scsi_status = pReply->SCSIStatus;
2813
2814
2815                 switch(status) {
2816
2817                 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE:       /* 0x0043 */
2818                         completionCode = MPT_SCANDV_SELECTION_TIMEOUT;
2819                         break;
2820
2821                 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR:          /* 0x0046 */
2822                 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED:        /* 0x0048 */
2823                 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED:         /* 0x004B */
2824                 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED:         /* 0x004C */
2825                         completionCode = MPT_SCANDV_DID_RESET;
2826                         break;
2827
2828                 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN:          /* 0x0045 */
2829                 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR:        /* 0x0040 */
2830                 case MPI_IOCSTATUS_SUCCESS:                     /* 0x0000 */
2831                         if (pReply->Function == MPI_FUNCTION_CONFIG) {
2832                                 ConfigReply_t *pr = (ConfigReply_t *)mr;
2833                                 completionCode = MPT_SCANDV_GOOD;
2834                                 hd->pLocal->header.PageVersion = pr->Header.PageVersion;
2835                                 hd->pLocal->header.PageLength = pr->Header.PageLength;
2836                                 hd->pLocal->header.PageNumber = pr->Header.PageNumber;
2837                                 hd->pLocal->header.PageType = pr->Header.PageType;
2838
2839                         } else if (pReply->Function == MPI_FUNCTION_RAID_ACTION) {
2840                                 /* If the RAID Volume request is successful,
2841                                  * return GOOD, else indicate that
2842                                  * some type of error occurred.
2843                                  */
2844                                 MpiRaidActionReply_t    *pr = (MpiRaidActionReply_t *)mr;
2845                                 if (le16_to_cpu(pr->ActionStatus) == MPI_RAID_ACTION_ASTATUS_SUCCESS)
2846                                         completionCode = MPT_SCANDV_GOOD;
2847                                 else
2848                                         completionCode = MPT_SCANDV_SOME_ERROR;
2849                                 memcpy(hd->pLocal->sense, pr, sizeof(hd->pLocal->sense));
2850
2851                         } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID) {
2852                                 u8              *sense_data;
2853                                 int              sz;
2854
2855                                 /* save sense data in global structure
2856                                  */
2857                                 completionCode = MPT_SCANDV_SENSE;
2858                                 hd->pLocal->scsiStatus = scsi_status;
2859                                 sense_data = ((u8 *)ioc->sense_buf_pool +
2860                                         (req_idx * MPT_SENSE_BUFFER_ALLOC));
2861
2862                                 sz = min_t(int, pReq->SenseBufferLength,
2863                                                         SCSI_STD_SENSE_BYTES);
2864                                 memcpy(hd->pLocal->sense, sense_data, sz);
2865
2866                                 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT "  Check Condition, sense ptr %p\n",
2867                                     ioc->name, sense_data));
2868                         } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_FAILED) {
2869                                 if (pReq->CDB[0] == INQUIRY)
2870                                         completionCode = MPT_SCANDV_ISSUE_SENSE;
2871                                 else
2872                                         completionCode = MPT_SCANDV_DID_RESET;
2873                         }
2874                         else if (pReply->SCSIState & MPI_SCSI_STATE_NO_SCSI_STATUS)
2875                                 completionCode = MPT_SCANDV_DID_RESET;
2876                         else if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
2877                                 completionCode = MPT_SCANDV_DID_RESET;
2878                         else {
2879                                 completionCode = MPT_SCANDV_GOOD;
2880                                 hd->pLocal->scsiStatus = scsi_status;
2881                         }
2882                         break;
2883
2884                 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR:         /* 0x0047 */
2885                         if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
2886                                 completionCode = MPT_SCANDV_DID_RESET;
2887                         else
2888                                 completionCode = MPT_SCANDV_SOME_ERROR;
2889                         break;
2890
2891                 default:
2892                         completionCode = MPT_SCANDV_SOME_ERROR;
2893                         break;
2894
2895                 }       /* switch(status) */
2896
2897         } /* end of address reply case */
2898
2899         hd->pLocal->completion = completionCode;
2900
2901         /* MF and RF are freed in mpt_interrupt
2902          */
2903 wakeup:
2904         /* Free Chain buffers (will never chain) in scan or dv */
2905         //mptscsih_freeChainBuffers(ioc, req_idx);
2906
2907         /*
2908          * Wake up the original calling thread
2909          */
2910         hd->scandv_wait_done = 1;
2911         wake_up(&hd->scandv_waitq);
2912
2913         return 1;
2914 }
2915
2916 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2917 /*      mptscsih_timer_expired - Call back for timer process.
2918  *      Used only for dv functionality.
2919  *      @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
2920  *
2921  */
2922 void
2923 mptscsih_timer_expired(unsigned long data)
2924 {
2925         MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) data;
2926         MPT_ADAPTER     *ioc = hd->ioc;
2927
2928         ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Timer Expired! Cmd %p\n", ioc->name, hd->cmdPtr));
2929
2930         if (hd->cmdPtr) {
2931                 MPIHeader_t *cmd = (MPIHeader_t *)hd->cmdPtr;
2932
2933                 if (cmd->Function == MPI_FUNCTION_SCSI_IO_REQUEST) {
2934                         /* Desire to issue a task management request here.
2935                          * TM requests MUST be single threaded.
2936                          * If old eh code and no TM current, issue request.
2937                          * If new eh code, do nothing. Wait for OS cmd timeout
2938                          *      for bus reset.
2939                          */
2940                 } else {
2941                         /* Perform a FW reload */
2942                         if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0) {
2943                                 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name);
2944                         }
2945                 }
2946         } else {
2947                 /* This should NEVER happen */
2948                 printk(MYIOC_s_WARN_FMT "Null cmdPtr!!!!\n", ioc->name);
2949         }
2950
2951         /* No more processing.
2952          * TM call will generate an interrupt for SCSI TM Management.
2953          * The FW will reply to all outstanding commands, callback will finish cleanup.
2954          * Hard reset clean-up will free all resources.
2955          */
2956         ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Timer Expired Complete!\n", ioc->name));
2957
2958         return;
2959 }
2960
2961
2962 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2963 /**
2964  *      mptscsih_do_cmd - Do internal command.
2965  *      @hd: MPT_SCSI_HOST pointer
2966  *      @io: INTERNAL_CMD pointer.
2967  *
2968  *      Issue the specified internally generated command and do command
2969  *      specific cleanup. For bus scan / DV only.
2970  *      NOTES: If command is Inquiry and status is good,
2971  *      initialize a target structure, save the data
2972  *
2973  *      Remark: Single threaded access only.
2974  *
2975  *      Return:
2976  *              < 0 if an illegal command or no resources
2977  *
2978  *                 0 if good
2979  *
2980  *               > 0 if command complete but some type of completion error.
2981  */
2982 static int
2983 mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
2984 {
2985         MPT_FRAME_HDR   *mf;
2986         SCSIIORequest_t *pScsiReq;
2987         SCSIIORequest_t  ReqCopy;
2988         int              my_idx, ii, dir;
2989         int              rc, cmdTimeout;
2990         int             in_isr;
2991         char             cmdLen;
2992         char             CDB[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
2993         char             cmd = io->cmd;
2994         MPT_ADAPTER     *ioc = hd->ioc;
2995
2996         in_isr = in_interrupt();
2997         if (in_isr) {
2998                 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Internal SCSI IO request not allowed in ISR context!\n",
2999                                         ioc->name));
3000                 return -EPERM;
3001         }
3002
3003
3004         /* Set command specific information
3005          */
3006         switch (cmd) {
3007         case INQUIRY:
3008                 cmdLen = 6;
3009                 dir = MPI_SCSIIO_CONTROL_READ;
3010                 CDB[0] = cmd;
3011                 CDB[4] = io->size;
3012                 cmdTimeout = 10;
3013                 break;
3014
3015         case TEST_UNIT_READY:
3016                 cmdLen = 6;
3017                 dir = MPI_SCSIIO_CONTROL_READ;
3018                 cmdTimeout = 10;
3019                 break;
3020
3021         case START_STOP:
3022                 cmdLen = 6;
3023                 dir = MPI_SCSIIO_CONTROL_READ;
3024                 CDB[0] = cmd;
3025                 CDB[4] = 1;     /*Spin up the disk */
3026                 cmdTimeout = 15;
3027                 break;
3028
3029         case REQUEST_SENSE:
3030                 cmdLen = 6;
3031                 CDB[0] = cmd;
3032                 CDB[4] = io->size;
3033                 dir = MPI_SCSIIO_CONTROL_READ;
3034                 cmdTimeout = 10;
3035                 break;
3036
3037         case READ_BUFFER:
3038                 cmdLen = 10;
3039                 dir = MPI_SCSIIO_CONTROL_READ;
3040                 CDB[0] = cmd;
3041                 if (io->flags & MPT_ICFLAG_ECHO) {
3042                         CDB[1] = 0x0A;
3043                 } else {
3044                         CDB[1] = 0x02;
3045                 }
3046
3047                 if (io->flags & MPT_ICFLAG_BUF_CAP) {
3048                         CDB[1] |= 0x01;
3049                 }
3050                 CDB[6] = (io->size >> 16) & 0xFF;
3051                 CDB[7] = (io->size >>  8) & 0xFF;
3052                 CDB[8] = io->size & 0xFF;
3053                 cmdTimeout = 10;
3054                 break;
3055
3056         case WRITE_BUFFER:
3057                 cmdLen = 10;
3058                 dir = MPI_SCSIIO_CONTROL_WRITE;
3059                 CDB[0] = cmd;
3060                 if (io->flags & MPT_ICFLAG_ECHO) {
3061                         CDB[1] = 0x0A;
3062                 } else {
3063                         CDB[1] = 0x02;
3064                 }
3065                 CDB[6] = (io->size >> 16) & 0xFF;
3066                 CDB[7] = (io->size >>  8) & 0xFF;
3067                 CDB[8] = io->size & 0xFF;
3068                 cmdTimeout = 10;
3069                 break;
3070
3071         case RESERVE:
3072                 cmdLen = 6;
3073                 dir = MPI_SCSIIO_CONTROL_READ;
3074                 CDB[0] = cmd;
3075                 cmdTimeout = 10;
3076                 break;
3077
3078         case RELEASE:
3079                 cmdLen = 6;
3080                 dir = MPI_SCSIIO_CONTROL_READ;
3081                 CDB[0] = cmd;
3082                 cmdTimeout = 10;
3083                 break;
3084
3085         case SYNCHRONIZE_CACHE:
3086                 cmdLen = 10;
3087                 dir = MPI_SCSIIO_CONTROL_READ;
3088                 CDB[0] = cmd;
3089 //              CDB[1] = 0x02;  /* set immediate bit */
3090                 cmdTimeout = 10;
3091                 break;
3092
3093         default:
3094                 /* Error Case */
3095                 return -EFAULT;
3096         }
3097
3098         /* Get and Populate a free Frame
3099          */
3100         if ((mf = mpt_get_msg_frame(ioc->InternalCtx, ioc)) == NULL) {
3101                 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "No msg frames!\n",
3102                     ioc->name));
3103                 return -EBUSY;
3104         }
3105
3106         pScsiReq = (SCSIIORequest_t *) mf;
3107
3108         /* Get the request index */
3109         my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3110         ADD_INDEX_LOG(my_idx); /* for debug */
3111
3112         if (io->flags & MPT_ICFLAG_PHYS_DISK) {
3113                 pScsiReq->TargetID = io->physDiskNum;
3114                 pScsiReq->Bus = 0;
3115                 pScsiReq->ChainOffset = 0;
3116                 pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
3117         } else {
3118                 pScsiReq->TargetID = io->id;
3119                 pScsiReq->Bus = io->channel;
3120                 pScsiReq->ChainOffset = 0;
3121                 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
3122         }
3123
3124         pScsiReq->CDBLength = cmdLen;
3125         pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
3126
3127         pScsiReq->Reserved = 0;
3128
3129         pScsiReq->MsgFlags = mpt_msg_flags();
3130         /* MsgContext set in mpt_get_msg_fram call  */
3131
3132         int_to_scsilun(io->lun, (struct scsi_lun *)pScsiReq->LUN);
3133
3134         if (io->flags & MPT_ICFLAG_TAGGED_CMD)
3135                 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ);
3136         else
3137                 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3138
3139         if (cmd == REQUEST_SENSE) {
3140                 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3141                 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Untagged! 0x%2x\n",
3142                         ioc->name, cmd));
3143         }
3144
3145         for (ii=0; ii < 16; ii++)
3146                 pScsiReq->CDB[ii] = CDB[ii];
3147
3148         pScsiReq->DataLength = cpu_to_le32(io->size);
3149         pScsiReq->SenseBufferLowAddr = cpu_to_le32(ioc->sense_buf_low_dma
3150                                            + (my_idx * MPT_SENSE_BUFFER_ALLOC));
3151
3152         ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Command 0x%x for (%d:%d:%d)\n",
3153                         ioc->name, cmd, io->channel, io->id, io->lun));
3154
3155         if (dir == MPI_SCSIIO_CONTROL_READ) {
3156                 mpt_add_sge((char *) &pScsiReq->SGL,
3157                         MPT_SGE_FLAGS_SSIMPLE_READ | io->size,
3158                         io->data_dma);
3159         } else {
3160                 mpt_add_sge((char *) &pScsiReq->SGL,
3161                         MPT_SGE_FLAGS_SSIMPLE_WRITE | io->size,
3162                         io->data_dma);
3163         }
3164
3165         /* The ISR will free the request frame, but we need
3166          * the information to initialize the target. Duplicate.
3167          */
3168         memcpy(&ReqCopy, pScsiReq, sizeof(SCSIIORequest_t));
3169
3170         /* Issue this command after:
3171          *      finish init
3172          *      add timer
3173          * Wait until the reply has been received
3174          *  ScsiScanDvCtx callback function will
3175          *      set hd->pLocal;
3176          *      set scandv_wait_done and call wake_up
3177          */
3178         hd->pLocal = NULL;
3179         hd->timer.expires = jiffies + HZ*cmdTimeout;
3180         hd->scandv_wait_done = 0;
3181
3182         /* Save cmd pointer, for resource free if timeout or
3183          * FW reload occurs
3184          */
3185         hd->cmdPtr = mf;
3186
3187         add_timer(&hd->timer);
3188         mpt_put_msg_frame(ioc->InternalCtx, ioc, mf);
3189         wait_event(hd->scandv_waitq, hd->scandv_wait_done);
3190
3191         if (hd->pLocal) {
3192                 rc = hd->pLocal->completion;
3193                 hd->pLocal->skip = 0;
3194
3195                 /* Always set fatal error codes in some cases.
3196                  */
3197                 if (rc == MPT_SCANDV_SELECTION_TIMEOUT)
3198                         rc = -ENXIO;
3199                 else if (rc == MPT_SCANDV_SOME_ERROR)
3200                         rc =  -rc;
3201         } else {
3202                 rc = -EFAULT;
3203                 /* This should never happen. */
3204                 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT "_do_cmd: Null pLocal!!!\n",
3205                                 ioc->name));
3206         }
3207
3208         return rc;
3209 }
3210
3211 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3212 /**
3213  *      mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
3214  *      @hd: Pointer to a SCSI HOST structure
3215  *      @vdevice: virtual target device
3216  *
3217  *      Uses the ISR, but with special processing.
3218  *      MUST be single-threaded.
3219  *
3220  */
3221 static void
3222 mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
3223 {
3224         INTERNAL_CMD             iocmd;
3225
3226         /* Ignore hidden raid components, this is handled when the command
3227          * is sent to the volume
3228          */
3229         if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
3230                 return;
3231
3232         if (vdevice->vtarget->type != TYPE_DISK || vdevice->vtarget->deleted ||
3233             !vdevice->configured_lun)
3234                 return;
3235
3236         /* Following parameters will not change
3237          * in this routine.
3238          */
3239         iocmd.cmd = SYNCHRONIZE_CACHE;
3240         iocmd.flags = 0;
3241         iocmd.physDiskNum = -1;
3242         iocmd.data = NULL;
3243         iocmd.data_dma = -1;
3244         iocmd.size = 0;
3245         iocmd.rsvd = iocmd.rsvd2 = 0;
3246         iocmd.channel = vdevice->vtarget->channel;
3247         iocmd.id = vdevice->vtarget->id;
3248         iocmd.lun = vdevice->lun;
3249
3250         mptscsih_do_cmd(hd, &iocmd);
3251 }
3252
3253 static ssize_t
3254 mptscsih_version_fw_show(struct class_device *cdev, char *buf)
3255 {
3256         struct Scsi_Host *host = class_to_shost(cdev);
3257         MPT_SCSI_HOST   *hd = (MPT_SCSI_HOST *)host->hostdata;
3258         MPT_ADAPTER *ioc = hd->ioc;
3259
3260         return snprintf(buf, PAGE_SIZE, "%02d.%02d.%02d.%02d\n",
3261             (ioc->facts.FWVersion.Word & 0xFF000000) >> 24,
3262             (ioc->facts.FWVersion.Word & 0x00FF0000) >> 16,
3263             (ioc->facts.FWVersion.Word & 0x0000FF00) >> 8,
3264             ioc->facts.FWVersion.Word & 0x000000FF);
3265 }
3266 static CLASS_DEVICE_ATTR(version_fw, S_IRUGO, mptscsih_version_fw_show, NULL);
3267
3268 static ssize_t
3269 mptscsih_version_bios_show(struct class_device *cdev, char *buf)
3270 {
3271         struct Scsi_Host *host = class_to_shost(cdev);
3272         MPT_SCSI_HOST   *hd = (MPT_SCSI_HOST *)host->hostdata;
3273         MPT_ADAPTER *ioc = hd->ioc;
3274
3275         return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x.%02x\n",
3276             (ioc->biosVersion & 0xFF000000) >> 24,
3277             (ioc->biosVersion & 0x00FF0000) >> 16,
3278             (ioc->biosVersion & 0x0000FF00) >> 8,
3279             ioc->biosVersion & 0x000000FF);
3280 }
3281 static CLASS_DEVICE_ATTR(version_bios, S_IRUGO, mptscsih_version_bios_show, NULL);
3282
3283 static ssize_t
3284 mptscsih_version_mpi_show(struct class_device *cdev, char *buf)
3285 {
3286         struct Scsi_Host *host = class_to_shost(cdev);
3287         MPT_SCSI_HOST   *hd = (MPT_SCSI_HOST *)host->hostdata;
3288         MPT_ADAPTER *ioc = hd->ioc;
3289
3290         return snprintf(buf, PAGE_SIZE, "%03x\n", ioc->facts.MsgVersion);
3291 }
3292 static CLASS_DEVICE_ATTR(version_mpi, S_IRUGO, mptscsih_version_mpi_show, NULL);
3293
3294 static ssize_t
3295 mptscsih_version_product_show(struct class_device *cdev, char *buf)
3296 {
3297         struct Scsi_Host *host = class_to_shost(cdev);
3298         MPT_SCSI_HOST   *hd = (MPT_SCSI_HOST *)host->hostdata;
3299         MPT_ADAPTER *ioc = hd->ioc;
3300
3301         return snprintf(buf, PAGE_SIZE, "%s\n", ioc->prod_name);
3302 }
3303 static CLASS_DEVICE_ATTR(version_product, S_IRUGO,
3304     mptscsih_version_product_show, NULL);
3305
3306 static ssize_t
3307 mptscsih_version_nvdata_persistent_show(struct class_device *cdev, char *buf)
3308 {
3309         struct Scsi_Host *host = class_to_shost(cdev);
3310         MPT_SCSI_HOST   *hd = (MPT_SCSI_HOST *)host->hostdata;
3311         MPT_ADAPTER *ioc = hd->ioc;
3312
3313         return snprintf(buf, PAGE_SIZE, "%02xh\n",
3314             ioc->nvdata_version_persistent);
3315 }
3316 static CLASS_DEVICE_ATTR(version_nvdata_persistent, S_IRUGO,
3317     mptscsih_version_nvdata_persistent_show, NULL);
3318
3319 static ssize_t
3320 mptscsih_version_nvdata_default_show(struct class_device *cdev, char *buf)
3321 {
3322         struct Scsi_Host *host = class_to_shost(cdev);
3323         MPT_SCSI_HOST   *hd = (MPT_SCSI_HOST *)host->hostdata;
3324         MPT_ADAPTER *ioc = hd->ioc;
3325
3326         return snprintf(buf, PAGE_SIZE, "%02xh\n",ioc->nvdata_version_default);
3327 }
3328 static CLASS_DEVICE_ATTR(version_nvdata_default, S_IRUGO,
3329     mptscsih_version_nvdata_default_show, NULL);
3330
3331 static ssize_t
3332 mptscsih_board_name_show(struct class_device *cdev, char *buf)
3333 {
3334         struct Scsi_Host *host = class_to_shost(cdev);
3335         MPT_SCSI_HOST   *hd = (MPT_SCSI_HOST *)host->hostdata;
3336         MPT_ADAPTER *ioc = hd->ioc;
3337
3338         return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_name);
3339 }
3340 static CLASS_DEVICE_ATTR(board_name, S_IRUGO, mptscsih_board_name_show, NULL);
3341
3342 static ssize_t
3343 mptscsih_board_assembly_show(struct class_device *cdev, char *buf)
3344 {
3345         struct Scsi_Host *host = class_to_shost(cdev);
3346         MPT_SCSI_HOST   *hd = (MPT_SCSI_HOST *)host->hostdata;
3347         MPT_ADAPTER *ioc = hd->ioc;
3348
3349         return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_assembly);
3350 }
3351 static CLASS_DEVICE_ATTR(board_assembly, S_IRUGO,
3352     mptscsih_board_assembly_show, NULL);
3353
3354 static ssize_t
3355 mptscsih_board_tracer_show(struct class_device *cdev, char *buf)
3356 {
3357         struct Scsi_Host *host = class_to_shost(cdev);
3358         MPT_SCSI_HOST   *hd = (MPT_SCSI_HOST *)host->hostdata;
3359         MPT_ADAPTER *ioc = hd->ioc;
3360
3361         return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_tracer);
3362 }
3363 static CLASS_DEVICE_ATTR(board_tracer, S_IRUGO,
3364     mptscsih_board_tracer_show, NULL);
3365
3366 static ssize_t
3367 mptscsih_io_delay_show(struct class_device *cdev, char *buf)
3368 {
3369         struct Scsi_Host *host = class_to_shost(cdev);
3370         MPT_SCSI_HOST   *hd = (MPT_SCSI_HOST *)host->hostdata;
3371         MPT_ADAPTER *ioc = hd->ioc;
3372
3373         return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->io_missing_delay);
3374 }
3375 static CLASS_DEVICE_ATTR(io_delay, S_IRUGO,
3376     mptscsih_io_delay_show, NULL);
3377
3378 static ssize_t
3379 mptscsih_device_delay_show(struct class_device *cdev, char *buf)
3380 {
3381         struct Scsi_Host *host = class_to_shost(cdev);
3382         MPT_SCSI_HOST   *hd = (MPT_SCSI_HOST *)host->hostdata;
3383         MPT_ADAPTER *ioc = hd->ioc;
3384
3385         return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->device_missing_delay);
3386 }
3387 static CLASS_DEVICE_ATTR(device_delay, S_IRUGO,
3388     mptscsih_device_delay_show, NULL);
3389
3390 static ssize_t
3391 mptscsih_debug_level_show(struct class_device *cdev, char *buf)
3392 {
3393         struct Scsi_Host *host = class_to_shost(cdev);
3394         MPT_SCSI_HOST   *hd = (MPT_SCSI_HOST *)host->hostdata;
3395         MPT_ADAPTER *ioc = hd->ioc;
3396
3397         return snprintf(buf, PAGE_SIZE, "%08xh\n", ioc->debug_level);
3398 }
3399 static ssize_t
3400 mptscsih_debug_level_store(struct class_device *cdev, const char *buf,
3401                                                                 size_t count)
3402 {
3403         struct Scsi_Host *host = class_to_shost(cdev);
3404         MPT_SCSI_HOST   *hd = (MPT_SCSI_HOST *)host->hostdata;
3405         MPT_ADAPTER *ioc = hd->ioc;
3406         int val = 0;
3407
3408         if (sscanf(buf, "%x", &val) != 1)
3409                 return -EINVAL;
3410
3411         ioc->debug_level = val;
3412         printk(MYIOC_s_INFO_FMT "debug_level=%08xh\n",
3413                                 ioc->name, ioc->debug_level);
3414         return strlen(buf);
3415 }
3416 static CLASS_DEVICE_ATTR(debug_level, S_IRUGO | S_IWUSR,
3417     mptscsih_debug_level_show, mptscsih_debug_level_store);
3418
3419 struct class_device_attribute *mptscsih_host_attrs[] = {
3420         &class_device_attr_version_fw,
3421         &class_device_attr_version_bios,
3422         &class_device_attr_version_mpi,
3423         &class_device_attr_version_product,
3424         &class_device_attr_version_nvdata_persistent,
3425         &class_device_attr_version_nvdata_default,
3426         &class_device_attr_board_name,
3427         &class_device_attr_board_assembly,
3428         &class_device_attr_board_tracer,
3429         &class_device_attr_io_delay,
3430         &class_device_attr_device_delay,
3431         &class_device_attr_debug_level,
3432         NULL,
3433 };
3434 EXPORT_SYMBOL(mptscsih_host_attrs);
3435
3436 EXPORT_SYMBOL(mptscsih_remove);
3437 EXPORT_SYMBOL(mptscsih_shutdown);
3438 #ifdef CONFIG_PM
3439 EXPORT_SYMBOL(mptscsih_suspend);
3440 EXPORT_SYMBOL(mptscsih_resume);
3441 #endif
3442 EXPORT_SYMBOL(mptscsih_proc_info);
3443 EXPORT_SYMBOL(mptscsih_info);
3444 EXPORT_SYMBOL(mptscsih_qcmd);
3445 EXPORT_SYMBOL(mptscsih_slave_destroy);
3446 EXPORT_SYMBOL(mptscsih_slave_configure);
3447 EXPORT_SYMBOL(mptscsih_abort);
3448 EXPORT_SYMBOL(mptscsih_dev_reset);
3449 EXPORT_SYMBOL(mptscsih_bus_reset);
3450 EXPORT_SYMBOL(mptscsih_host_reset);
3451 EXPORT_SYMBOL(mptscsih_bios_param);
3452 EXPORT_SYMBOL(mptscsih_io_done);
3453 EXPORT_SYMBOL(mptscsih_taskmgmt_complete);
3454 EXPORT_SYMBOL(mptscsih_scandv_complete);
3455 EXPORT_SYMBOL(mptscsih_event_process);
3456 EXPORT_SYMBOL(mptscsih_ioc_reset);
3457 EXPORT_SYMBOL(mptscsih_change_queue_depth);
3458 EXPORT_SYMBOL(mptscsih_timer_expired);
3459 EXPORT_SYMBOL(mptscsih_TMHandler);
3460
3461 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/