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