3918ebf01e8d14942bd0f3639d691e5947908e7c
[sfrench/cifs-2.6.git] / drivers / message / fusion / mptscsih.c
1 /*
2  *  linux/drivers/message/fusion/mptscsih.c
3  *      For use with LSI PCI chip/adapter(s)
4  *      running LSI Fusion MPT (Message Passing Technology) firmware.
5  *
6  *  Copyright (c) 1999-2007 LSI Corporation
7  *  (mailto:DL-MPTFusionLinux@lsi.com)
8  *
9  */
10 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
11 /*
12     This program is free software; you can redistribute it and/or modify
13     it under the terms of the GNU General Public License as published by
14     the Free Software Foundation; version 2 of the License.
15
16     This program is distributed in the hope that it will be useful,
17     but WITHOUT ANY WARRANTY; without even the implied warranty of
18     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19     GNU General Public License for more details.
20
21     NO WARRANTY
22     THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
23     CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
24     LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
25     MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
26     solely responsible for determining the appropriateness of using and
27     distributing the Program and assumes all risks associated with its
28     exercise of rights under this Agreement, including but not limited to
29     the risks and costs of program errors, damage to or loss of data,
30     programs or equipment, and unavailability or interruption of operations.
31
32     DISCLAIMER OF LIABILITY
33     NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
34     DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
35     DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
36     ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
37     TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
38     USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
39     HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
40
41     You should have received a copy of the GNU General Public License
42     along with this program; if not, write to the Free Software
43     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
44 */
45 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
46
47 #include <linux/module.h>
48 #include <linux/kernel.h>
49 #include <linux/init.h>
50 #include <linux/errno.h>
51 #include <linux/kdev_t.h>
52 #include <linux/blkdev.h>
53 #include <linux/delay.h>        /* for mdelay */
54 #include <linux/interrupt.h>    /* needed for in_interrupt() proto */
55 #include <linux/reboot.h>       /* notifier code */
56 #include <linux/workqueue.h>
57
58 #include <scsi/scsi.h>
59 #include <scsi/scsi_cmnd.h>
60 #include <scsi/scsi_device.h>
61 #include <scsi/scsi_host.h>
62 #include <scsi/scsi_tcq.h>
63 #include <scsi/scsi_dbg.h>
64
65 #include "mptbase.h"
66 #include "mptscsih.h"
67 #include "lsi/mpi_log_sas.h"
68
69 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
70 #define my_NAME         "Fusion MPT SCSI Host driver"
71 #define my_VERSION      MPT_LINUX_VERSION_COMMON
72 #define MYNAM           "mptscsih"
73
74 MODULE_AUTHOR(MODULEAUTHOR);
75 MODULE_DESCRIPTION(my_NAME);
76 MODULE_LICENSE("GPL");
77 MODULE_VERSION(my_VERSION);
78
79 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
80 /*
81  *  Other private/forward protos...
82  */
83 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)    sizeof((scp)->sense_buffer)
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
2609  *
2610  * search's for a given scmd in the ScsiLookup[] array list
2611  *
2612  * @ioc: Pointer to MPT_ADAPTER structure
2613  * @scmd: scsi_cmnd pointer
2614  *
2615  **/
2616 static int
2617 SCPNT_TO_LOOKUP_IDX(MPT_ADAPTER *ioc, struct scsi_cmnd *sc)
2618 {
2619         unsigned long   flags;
2620         int i, index=-1;
2621
2622         spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
2623         for (i = 0; i < ioc->req_depth; i++) {
2624                 if (ioc->ScsiLookup[i] == sc) {
2625                         index = i;
2626                         goto out;
2627                 }
2628         }
2629
2630  out:
2631         spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
2632         return index;
2633 }
2634
2635 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2636 int
2637 mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2638 {
2639         MPT_SCSI_HOST   *hd;
2640         unsigned long    flags;
2641
2642         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2643             ": IOC %s_reset routed to SCSI host driver!\n",
2644             ioc->name, reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
2645             reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
2646
2647         /* If a FW reload request arrives after base installed but
2648          * before all scsi hosts have been attached, then an alt_ioc
2649          * may have a NULL sh pointer.
2650          */
2651         if (ioc->sh == NULL || shost_priv(ioc->sh) == NULL)
2652                 return 0;
2653         else
2654                 hd = shost_priv(ioc->sh);
2655
2656         if (reset_phase == MPT_IOC_SETUP_RESET) {
2657                 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Setup-Diag Reset\n", ioc->name));
2658
2659                 /* Clean Up:
2660                  * 1. Set Hard Reset Pending Flag
2661                  * All new commands go to doneQ
2662                  */
2663                 hd->resetPending = 1;
2664
2665         } else if (reset_phase == MPT_IOC_PRE_RESET) {
2666                 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Pre-Diag Reset\n", ioc->name));
2667
2668                 /* 2. Flush running commands
2669                  *      Clean ScsiLookup (and associated memory)
2670                  *      AND clean mytaskQ
2671                  */
2672
2673                 /* 2b. Reply to OS all known outstanding I/O commands.
2674                  */
2675                 mptscsih_flush_running_cmds(hd);
2676
2677                 /* 2c. If there was an internal command that
2678                  * has not completed, configuration or io request,
2679                  * free these resources.
2680                  */
2681                 if (hd->cmdPtr) {
2682                         del_timer(&hd->timer);
2683                         mpt_free_msg_frame(ioc, hd->cmdPtr);
2684                 }
2685
2686                 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Pre-Reset complete.\n", ioc->name));
2687
2688         } else {
2689                 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Post-Diag Reset\n", ioc->name));
2690
2691                 /* Once a FW reload begins, all new OS commands are
2692                  * redirected to the doneQ w/ a reset status.
2693                  * Init all control structures.
2694                  */
2695
2696                 /* 2. Chain Buffer initialization
2697                  */
2698
2699                 /* 4. Renegotiate to all devices, if SPI
2700                  */
2701
2702                 /* 5. Enable new commands to be posted
2703                  */
2704                 spin_lock_irqsave(&ioc->FreeQlock, flags);
2705                 hd->tmPending = 0;
2706                 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2707                 hd->resetPending = 0;
2708                 hd->tmState = TM_STATE_NONE;
2709
2710                 /* 6. If there was an internal command,
2711                  * wake this process up.
2712                  */
2713                 if (hd->cmdPtr) {
2714                         /*
2715                          * Wake up the original calling thread
2716                          */
2717                         hd->pLocal = &hd->localReply;
2718                         hd->pLocal->completion = MPT_SCANDV_DID_RESET;
2719                         hd->scandv_wait_done = 1;
2720                         wake_up(&hd->scandv_waitq);
2721                         hd->cmdPtr = NULL;
2722                 }
2723
2724                 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Post-Reset complete.\n", ioc->name));
2725
2726         }
2727
2728         return 1;               /* currently means nothing really */
2729 }
2730
2731 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2732 int
2733 mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2734 {
2735         MPT_SCSI_HOST *hd;
2736         u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
2737
2738         devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
2739                         ioc->name, event));
2740
2741         if (ioc->sh == NULL ||
2742                 ((hd = shost_priv(ioc->sh)) == NULL))
2743                 return 1;
2744
2745         switch (event) {
2746         case MPI_EVENT_UNIT_ATTENTION:                  /* 03 */
2747                 /* FIXME! */
2748                 break;
2749         case MPI_EVENT_IOC_BUS_RESET:                   /* 04 */
2750         case MPI_EVENT_EXT_BUS_RESET:                   /* 05 */
2751                 if (hd && (ioc->bus_type == SPI) && (hd->soft_resets < -1))
2752                         hd->soft_resets++;
2753                 break;
2754         case MPI_EVENT_LOGOUT:                          /* 09 */
2755                 /* FIXME! */
2756                 break;
2757
2758         case MPI_EVENT_RESCAN:                          /* 06 */
2759                 break;
2760
2761                 /*
2762                  *  CHECKME! Don't think we need to do
2763                  *  anything for these, but...
2764                  */
2765         case MPI_EVENT_LINK_STATUS_CHANGE:              /* 07 */
2766         case MPI_EVENT_LOOP_STATE_CHANGE:               /* 08 */
2767                 /*
2768                  *  CHECKME!  Falling thru...
2769                  */
2770                 break;
2771
2772         case MPI_EVENT_INTEGRATED_RAID:                 /* 0B */
2773                 break;
2774
2775         case MPI_EVENT_NONE:                            /* 00 */
2776         case MPI_EVENT_LOG_DATA:                        /* 01 */
2777         case MPI_EVENT_STATE_CHANGE:                    /* 02 */
2778         case MPI_EVENT_EVENT_CHANGE:                    /* 0A */
2779         default:
2780                 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": Ignoring event (=%02Xh)\n",
2781                     ioc->name, event));
2782                 break;
2783         }
2784
2785         return 1;               /* currently means nothing really */
2786 }
2787
2788 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2789 /*
2790  *  Bus Scan and Domain Validation functionality ...
2791  */
2792
2793 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2794 /*
2795  *      mptscsih_scandv_complete - Scan and DV callback routine registered
2796  *      to Fustion MPT (base) driver.
2797  *
2798  *      @ioc: Pointer to MPT_ADAPTER structure
2799  *      @mf: Pointer to original MPT request frame
2800  *      @mr: Pointer to MPT reply frame (NULL if TurboReply)
2801  *
2802  *      This routine is called from mpt.c::mpt_interrupt() at the completion
2803  *      of any SCSI IO request.
2804  *      This routine is registered with the Fusion MPT (base) driver at driver
2805  *      load/init time via the mpt_register() API call.
2806  *
2807  *      Returns 1 indicating alloc'd request frame ptr should be freed.
2808  *
2809  *      Remark: Sets a completion code and (possibly) saves sense data
2810  *      in the IOC member localReply structure.
2811  *      Used ONLY for DV and other internal commands.
2812  */
2813 int
2814 mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
2815 {
2816         MPT_SCSI_HOST   *hd;
2817         SCSIIORequest_t *pReq;
2818         int              completionCode;
2819         u16              req_idx;
2820
2821         hd = shost_priv(ioc->sh);
2822
2823         if ((mf == NULL) ||
2824             (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) {
2825                 printk(MYIOC_s_ERR_FMT
2826                         "ScanDvComplete, %s req frame ptr! (=%p)\n",
2827                                 ioc->name, mf?"BAD":"NULL", (void *) mf);
2828                 goto wakeup;
2829         }
2830
2831         del_timer(&hd->timer);
2832         req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2833         mptscsih_set_scsi_lookup(ioc, req_idx, NULL);
2834         pReq = (SCSIIORequest_t *) mf;
2835
2836         if (mf != hd->cmdPtr) {
2837                 printk(MYIOC_s_WARN_FMT "ScanDvComplete (mf=%p, cmdPtr=%p, idx=%d)\n",
2838                                 ioc->name, (void *)mf, (void *) hd->cmdPtr, req_idx);
2839         }
2840         hd->cmdPtr = NULL;
2841
2842         ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ScanDvComplete (mf=%p,mr=%p,idx=%d)\n",
2843                         ioc->name, mf, mr, req_idx));
2844
2845         hd->pLocal = &hd->localReply;
2846         hd->pLocal->scsiStatus = 0;
2847
2848         /* If target struct exists, clear sense valid flag.
2849          */
2850         if (mr == NULL) {
2851                 completionCode = MPT_SCANDV_GOOD;
2852         } else {
2853                 SCSIIOReply_t   *pReply;
2854                 u16              status;
2855                 u8               scsi_status;
2856
2857                 pReply = (SCSIIOReply_t *) mr;
2858
2859                 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2860                 scsi_status = pReply->SCSIStatus;
2861
2862
2863                 switch(status) {
2864
2865                 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE:       /* 0x0043 */
2866                         completionCode = MPT_SCANDV_SELECTION_TIMEOUT;
2867                         break;
2868
2869                 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR:          /* 0x0046 */
2870                 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED:        /* 0x0048 */
2871                 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED:         /* 0x004B */
2872                 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED:         /* 0x004C */
2873                         completionCode = MPT_SCANDV_DID_RESET;
2874                         break;
2875
2876                 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN:          /* 0x0045 */
2877                 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR:        /* 0x0040 */
2878                 case MPI_IOCSTATUS_SUCCESS:                     /* 0x0000 */
2879                         if (pReply->Function == MPI_FUNCTION_CONFIG) {
2880                                 ConfigReply_t *pr = (ConfigReply_t *)mr;
2881                                 completionCode = MPT_SCANDV_GOOD;
2882                                 hd->pLocal->header.PageVersion = pr->Header.PageVersion;
2883                                 hd->pLocal->header.PageLength = pr->Header.PageLength;
2884                                 hd->pLocal->header.PageNumber = pr->Header.PageNumber;
2885                                 hd->pLocal->header.PageType = pr->Header.PageType;
2886
2887                         } else if (pReply->Function == MPI_FUNCTION_RAID_ACTION) {
2888                                 /* If the RAID Volume request is successful,
2889                                  * return GOOD, else indicate that
2890                                  * some type of error occurred.
2891                                  */
2892                                 MpiRaidActionReply_t    *pr = (MpiRaidActionReply_t *)mr;
2893                                 if (le16_to_cpu(pr->ActionStatus) == MPI_RAID_ACTION_ASTATUS_SUCCESS)
2894                                         completionCode = MPT_SCANDV_GOOD;
2895                                 else
2896                                         completionCode = MPT_SCANDV_SOME_ERROR;
2897                                 memcpy(hd->pLocal->sense, pr, sizeof(hd->pLocal->sense));
2898
2899                         } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID) {
2900                                 u8              *sense_data;
2901                                 int              sz;
2902
2903                                 /* save sense data in global structure
2904                                  */
2905                                 completionCode = MPT_SCANDV_SENSE;
2906                                 hd->pLocal->scsiStatus = scsi_status;
2907                                 sense_data = ((u8 *)ioc->sense_buf_pool +
2908                                         (req_idx * MPT_SENSE_BUFFER_ALLOC));
2909
2910                                 sz = min_t(int, pReq->SenseBufferLength,
2911                                                         SCSI_STD_SENSE_BYTES);
2912                                 memcpy(hd->pLocal->sense, sense_data, sz);
2913
2914                                 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT "  Check Condition, sense ptr %p\n",
2915                                     ioc->name, sense_data));
2916                         } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_FAILED) {
2917                                 if (pReq->CDB[0] == INQUIRY)
2918                                         completionCode = MPT_SCANDV_ISSUE_SENSE;
2919                                 else
2920                                         completionCode = MPT_SCANDV_DID_RESET;
2921                         }
2922                         else if (pReply->SCSIState & MPI_SCSI_STATE_NO_SCSI_STATUS)
2923                                 completionCode = MPT_SCANDV_DID_RESET;
2924                         else if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
2925                                 completionCode = MPT_SCANDV_DID_RESET;
2926                         else {
2927                                 completionCode = MPT_SCANDV_GOOD;
2928                                 hd->pLocal->scsiStatus = scsi_status;
2929                         }
2930                         break;
2931
2932                 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR:         /* 0x0047 */
2933                         if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
2934                                 completionCode = MPT_SCANDV_DID_RESET;
2935                         else
2936                                 completionCode = MPT_SCANDV_SOME_ERROR;
2937                         break;
2938
2939                 default:
2940                         completionCode = MPT_SCANDV_SOME_ERROR;
2941                         break;
2942
2943                 }       /* switch(status) */
2944
2945         } /* end of address reply case */
2946
2947         hd->pLocal->completion = completionCode;
2948
2949         /* MF and RF are freed in mpt_interrupt
2950          */
2951 wakeup:
2952         /* Free Chain buffers (will never chain) in scan or dv */
2953         //mptscsih_freeChainBuffers(ioc, req_idx);
2954
2955         /*
2956          * Wake up the original calling thread
2957          */
2958         hd->scandv_wait_done = 1;
2959         wake_up(&hd->scandv_waitq);
2960
2961         return 1;
2962 }
2963
2964 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2965 /*      mptscsih_timer_expired - Call back for timer process.
2966  *      Used only for dv functionality.
2967  *      @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
2968  *
2969  */
2970 void
2971 mptscsih_timer_expired(unsigned long data)
2972 {
2973         MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) data;
2974         MPT_ADAPTER     *ioc = hd->ioc;
2975
2976         ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Timer Expired! Cmd %p\n", ioc->name, hd->cmdPtr));
2977
2978         if (hd->cmdPtr) {
2979                 MPIHeader_t *cmd = (MPIHeader_t *)hd->cmdPtr;
2980
2981                 if (cmd->Function == MPI_FUNCTION_SCSI_IO_REQUEST) {
2982                         /* Desire to issue a task management request here.
2983                          * TM requests MUST be single threaded.
2984                          * If old eh code and no TM current, issue request.
2985                          * If new eh code, do nothing. Wait for OS cmd timeout
2986                          *      for bus reset.
2987                          */
2988                 } else {
2989                         /* Perform a FW reload */
2990                         if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0) {
2991                                 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name);
2992                         }
2993                 }
2994         } else {
2995                 /* This should NEVER happen */
2996                 printk(MYIOC_s_WARN_FMT "Null cmdPtr!!!!\n", ioc->name);
2997         }
2998
2999         /* No more processing.
3000          * TM call will generate an interrupt for SCSI TM Management.
3001          * The FW will reply to all outstanding commands, callback will finish cleanup.
3002          * Hard reset clean-up will free all resources.
3003          */
3004         ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Timer Expired Complete!\n", ioc->name));
3005
3006         return;
3007 }
3008
3009
3010 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3011 /**
3012  *      mptscsih_do_cmd - Do internal command.
3013  *      @hd: MPT_SCSI_HOST pointer
3014  *      @io: INTERNAL_CMD pointer.
3015  *
3016  *      Issue the specified internally generated command and do command
3017  *      specific cleanup. For bus scan / DV only.
3018  *      NOTES: If command is Inquiry and status is good,
3019  *      initialize a target structure, save the data
3020  *
3021  *      Remark: Single threaded access only.
3022  *
3023  *      Return:
3024  *              < 0 if an illegal command or no resources
3025  *
3026  *                 0 if good
3027  *
3028  *               > 0 if command complete but some type of completion error.
3029  */
3030 static int
3031 mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
3032 {
3033         MPT_FRAME_HDR   *mf;
3034         SCSIIORequest_t *pScsiReq;
3035         SCSIIORequest_t  ReqCopy;
3036         int              my_idx, ii, dir;
3037         int              rc, cmdTimeout;
3038         int             in_isr;
3039         char             cmdLen;
3040         char             CDB[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
3041         char             cmd = io->cmd;
3042         MPT_ADAPTER     *ioc = hd->ioc;
3043
3044         in_isr = in_interrupt();
3045         if (in_isr) {
3046                 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Internal SCSI IO request not allowed in ISR context!\n",
3047                                         ioc->name));
3048                 return -EPERM;
3049         }
3050
3051
3052         /* Set command specific information
3053          */
3054         switch (cmd) {
3055         case INQUIRY:
3056                 cmdLen = 6;
3057                 dir = MPI_SCSIIO_CONTROL_READ;
3058                 CDB[0] = cmd;
3059                 CDB[4] = io->size;
3060                 cmdTimeout = 10;
3061                 break;
3062
3063         case TEST_UNIT_READY:
3064                 cmdLen = 6;
3065                 dir = MPI_SCSIIO_CONTROL_READ;
3066                 cmdTimeout = 10;
3067                 break;
3068
3069         case START_STOP:
3070                 cmdLen = 6;
3071                 dir = MPI_SCSIIO_CONTROL_READ;
3072                 CDB[0] = cmd;
3073                 CDB[4] = 1;     /*Spin up the disk */
3074                 cmdTimeout = 15;
3075                 break;
3076
3077         case REQUEST_SENSE:
3078                 cmdLen = 6;
3079                 CDB[0] = cmd;
3080                 CDB[4] = io->size;
3081                 dir = MPI_SCSIIO_CONTROL_READ;
3082                 cmdTimeout = 10;
3083                 break;
3084
3085         case READ_BUFFER:
3086                 cmdLen = 10;
3087                 dir = MPI_SCSIIO_CONTROL_READ;
3088                 CDB[0] = cmd;
3089                 if (io->flags & MPT_ICFLAG_ECHO) {
3090                         CDB[1] = 0x0A;
3091                 } else {
3092                         CDB[1] = 0x02;
3093                 }
3094
3095                 if (io->flags & MPT_ICFLAG_BUF_CAP) {
3096                         CDB[1] |= 0x01;
3097                 }
3098                 CDB[6] = (io->size >> 16) & 0xFF;
3099                 CDB[7] = (io->size >>  8) & 0xFF;
3100                 CDB[8] = io->size & 0xFF;
3101                 cmdTimeout = 10;
3102                 break;
3103
3104         case WRITE_BUFFER:
3105                 cmdLen = 10;
3106                 dir = MPI_SCSIIO_CONTROL_WRITE;
3107                 CDB[0] = cmd;
3108                 if (io->flags & MPT_ICFLAG_ECHO) {
3109                         CDB[1] = 0x0A;
3110                 } else {
3111                         CDB[1] = 0x02;
3112                 }
3113                 CDB[6] = (io->size >> 16) & 0xFF;
3114                 CDB[7] = (io->size >>  8) & 0xFF;
3115                 CDB[8] = io->size & 0xFF;
3116                 cmdTimeout = 10;
3117                 break;
3118
3119         case RESERVE:
3120                 cmdLen = 6;
3121                 dir = MPI_SCSIIO_CONTROL_READ;
3122                 CDB[0] = cmd;
3123                 cmdTimeout = 10;
3124                 break;
3125
3126         case RELEASE:
3127                 cmdLen = 6;
3128                 dir = MPI_SCSIIO_CONTROL_READ;
3129                 CDB[0] = cmd;
3130                 cmdTimeout = 10;
3131                 break;
3132
3133         case SYNCHRONIZE_CACHE:
3134                 cmdLen = 10;
3135                 dir = MPI_SCSIIO_CONTROL_READ;
3136                 CDB[0] = cmd;
3137 //              CDB[1] = 0x02;  /* set immediate bit */
3138                 cmdTimeout = 10;
3139                 break;
3140
3141         default:
3142                 /* Error Case */
3143                 return -EFAULT;
3144         }
3145
3146         /* Get and Populate a free Frame
3147          */
3148         if ((mf = mpt_get_msg_frame(ioc->InternalCtx, ioc)) == NULL) {
3149                 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "No msg frames!\n",
3150                     ioc->name));
3151                 return -EBUSY;
3152         }
3153
3154         pScsiReq = (SCSIIORequest_t *) mf;
3155
3156         /* Get the request index */
3157         my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3158         ADD_INDEX_LOG(my_idx); /* for debug */
3159
3160         if (io->flags & MPT_ICFLAG_PHYS_DISK) {
3161                 pScsiReq->TargetID = io->physDiskNum;
3162                 pScsiReq->Bus = 0;
3163                 pScsiReq->ChainOffset = 0;
3164                 pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
3165         } else {
3166                 pScsiReq->TargetID = io->id;
3167                 pScsiReq->Bus = io->channel;
3168                 pScsiReq->ChainOffset = 0;
3169                 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
3170         }
3171
3172         pScsiReq->CDBLength = cmdLen;
3173         pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
3174
3175         pScsiReq->Reserved = 0;
3176
3177         pScsiReq->MsgFlags = mpt_msg_flags();
3178         /* MsgContext set in mpt_get_msg_fram call  */
3179
3180         int_to_scsilun(io->lun, (struct scsi_lun *)pScsiReq->LUN);
3181
3182         if (io->flags & MPT_ICFLAG_TAGGED_CMD)
3183                 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ);
3184         else
3185                 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3186
3187         if (cmd == REQUEST_SENSE) {
3188                 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3189                 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Untagged! 0x%2x\n",
3190                         ioc->name, cmd));
3191         }
3192
3193         for (ii=0; ii < 16; ii++)
3194                 pScsiReq->CDB[ii] = CDB[ii];
3195
3196         pScsiReq->DataLength = cpu_to_le32(io->size);
3197         pScsiReq->SenseBufferLowAddr = cpu_to_le32(ioc->sense_buf_low_dma
3198                                            + (my_idx * MPT_SENSE_BUFFER_ALLOC));
3199
3200         ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Command 0x%x for (%d:%d:%d)\n",
3201                         ioc->name, cmd, io->channel, io->id, io->lun));
3202
3203         if (dir == MPI_SCSIIO_CONTROL_READ) {
3204                 mpt_add_sge((char *) &pScsiReq->SGL,
3205                         MPT_SGE_FLAGS_SSIMPLE_READ | io->size,
3206                         io->data_dma);
3207         } else {
3208                 mpt_add_sge((char *) &pScsiReq->SGL,
3209                         MPT_SGE_FLAGS_SSIMPLE_WRITE | io->size,
3210                         io->data_dma);
3211         }
3212
3213         /* The ISR will free the request frame, but we need
3214          * the information to initialize the target. Duplicate.
3215          */
3216         memcpy(&ReqCopy, pScsiReq, sizeof(SCSIIORequest_t));
3217
3218         /* Issue this command after:
3219          *      finish init
3220          *      add timer
3221          * Wait until the reply has been received
3222          *  ScsiScanDvCtx callback function will
3223          *      set hd->pLocal;
3224          *      set scandv_wait_done and call wake_up
3225          */
3226         hd->pLocal = NULL;
3227         hd->timer.expires = jiffies + HZ*cmdTimeout;
3228         hd->scandv_wait_done = 0;
3229
3230         /* Save cmd pointer, for resource free if timeout or
3231          * FW reload occurs
3232          */
3233         hd->cmdPtr = mf;
3234
3235         add_timer(&hd->timer);
3236         mpt_put_msg_frame(ioc->InternalCtx, ioc, mf);
3237         wait_event(hd->scandv_waitq, hd->scandv_wait_done);
3238
3239         if (hd->pLocal) {
3240                 rc = hd->pLocal->completion;
3241                 hd->pLocal->skip = 0;
3242
3243                 /* Always set fatal error codes in some cases.
3244                  */
3245                 if (rc == MPT_SCANDV_SELECTION_TIMEOUT)
3246                         rc = -ENXIO;
3247                 else if (rc == MPT_SCANDV_SOME_ERROR)
3248                         rc =  -rc;
3249         } else {
3250                 rc = -EFAULT;
3251                 /* This should never happen. */
3252                 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT "_do_cmd: Null pLocal!!!\n",
3253                                 ioc->name));
3254         }
3255
3256         return rc;
3257 }
3258
3259 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3260 /**
3261  *      mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
3262  *      @hd: Pointer to a SCSI HOST structure
3263  *      @vdevice: virtual target device
3264  *
3265  *      Uses the ISR, but with special processing.
3266  *      MUST be single-threaded.
3267  *
3268  */
3269 static void
3270 mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
3271 {
3272         INTERNAL_CMD             iocmd;
3273
3274         /* Ignore hidden raid components, this is handled when the command
3275          * is sent to the volume
3276          */
3277         if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
3278                 return;
3279
3280         if (vdevice->vtarget->type != TYPE_DISK || vdevice->vtarget->deleted ||
3281             !vdevice->configured_lun)
3282                 return;
3283
3284         /* Following parameters will not change
3285          * in this routine.
3286          */
3287         iocmd.cmd = SYNCHRONIZE_CACHE;
3288         iocmd.flags = 0;
3289         iocmd.physDiskNum = -1;
3290         iocmd.data = NULL;
3291         iocmd.data_dma = -1;
3292         iocmd.size = 0;
3293         iocmd.rsvd = iocmd.rsvd2 = 0;
3294         iocmd.channel = vdevice->vtarget->channel;
3295         iocmd.id = vdevice->vtarget->id;
3296         iocmd.lun = vdevice->lun;
3297
3298         mptscsih_do_cmd(hd, &iocmd);
3299 }
3300
3301 static ssize_t
3302 mptscsih_version_fw_show(struct class_device *cdev, char *buf)
3303 {
3304         struct Scsi_Host *host = class_to_shost(cdev);
3305         MPT_SCSI_HOST   *hd = shost_priv(host);
3306         MPT_ADAPTER *ioc = hd->ioc;
3307
3308         return snprintf(buf, PAGE_SIZE, "%02d.%02d.%02d.%02d\n",
3309             (ioc->facts.FWVersion.Word & 0xFF000000) >> 24,
3310             (ioc->facts.FWVersion.Word & 0x00FF0000) >> 16,
3311             (ioc->facts.FWVersion.Word & 0x0000FF00) >> 8,
3312             ioc->facts.FWVersion.Word & 0x000000FF);
3313 }
3314 static CLASS_DEVICE_ATTR(version_fw, S_IRUGO, mptscsih_version_fw_show, NULL);
3315
3316 static ssize_t
3317 mptscsih_version_bios_show(struct class_device *cdev, char *buf)
3318 {
3319         struct Scsi_Host *host = class_to_shost(cdev);
3320         MPT_SCSI_HOST   *hd = shost_priv(host);
3321         MPT_ADAPTER *ioc = hd->ioc;
3322
3323         return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x.%02x\n",
3324             (ioc->biosVersion & 0xFF000000) >> 24,
3325             (ioc->biosVersion & 0x00FF0000) >> 16,
3326             (ioc->biosVersion & 0x0000FF00) >> 8,
3327             ioc->biosVersion & 0x000000FF);
3328 }
3329 static CLASS_DEVICE_ATTR(version_bios, S_IRUGO, mptscsih_version_bios_show, NULL);
3330
3331 static ssize_t
3332 mptscsih_version_mpi_show(struct class_device *cdev, char *buf)
3333 {
3334         struct Scsi_Host *host = class_to_shost(cdev);
3335         MPT_SCSI_HOST   *hd = shost_priv(host);
3336         MPT_ADAPTER *ioc = hd->ioc;
3337
3338         return snprintf(buf, PAGE_SIZE, "%03x\n", ioc->facts.MsgVersion);
3339 }
3340 static CLASS_DEVICE_ATTR(version_mpi, S_IRUGO, mptscsih_version_mpi_show, NULL);
3341
3342 static ssize_t
3343 mptscsih_version_product_show(struct class_device *cdev, char *buf)
3344 {
3345         struct Scsi_Host *host = class_to_shost(cdev);
3346         MPT_SCSI_HOST   *hd = shost_priv(host);
3347         MPT_ADAPTER *ioc = hd->ioc;
3348
3349         return snprintf(buf, PAGE_SIZE, "%s\n", ioc->prod_name);
3350 }
3351 static CLASS_DEVICE_ATTR(version_product, S_IRUGO,
3352     mptscsih_version_product_show, NULL);
3353
3354 static ssize_t
3355 mptscsih_version_nvdata_persistent_show(struct class_device *cdev, char *buf)
3356 {
3357         struct Scsi_Host *host = class_to_shost(cdev);
3358         MPT_SCSI_HOST   *hd = shost_priv(host);
3359         MPT_ADAPTER *ioc = hd->ioc;
3360
3361         return snprintf(buf, PAGE_SIZE, "%02xh\n",
3362             ioc->nvdata_version_persistent);
3363 }
3364 static CLASS_DEVICE_ATTR(version_nvdata_persistent, S_IRUGO,
3365     mptscsih_version_nvdata_persistent_show, NULL);
3366
3367 static ssize_t
3368 mptscsih_version_nvdata_default_show(struct class_device *cdev, char *buf)
3369 {
3370         struct Scsi_Host *host = class_to_shost(cdev);
3371         MPT_SCSI_HOST   *hd = shost_priv(host);
3372         MPT_ADAPTER *ioc = hd->ioc;
3373
3374         return snprintf(buf, PAGE_SIZE, "%02xh\n",ioc->nvdata_version_default);
3375 }
3376 static CLASS_DEVICE_ATTR(version_nvdata_default, S_IRUGO,
3377     mptscsih_version_nvdata_default_show, NULL);
3378
3379 static ssize_t
3380 mptscsih_board_name_show(struct class_device *cdev, char *buf)
3381 {
3382         struct Scsi_Host *host = class_to_shost(cdev);
3383         MPT_SCSI_HOST   *hd = shost_priv(host);
3384         MPT_ADAPTER *ioc = hd->ioc;
3385
3386         return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_name);
3387 }
3388 static CLASS_DEVICE_ATTR(board_name, S_IRUGO, mptscsih_board_name_show, NULL);
3389
3390 static ssize_t
3391 mptscsih_board_assembly_show(struct class_device *cdev, char *buf)
3392 {
3393         struct Scsi_Host *host = class_to_shost(cdev);
3394         MPT_SCSI_HOST   *hd = shost_priv(host);
3395         MPT_ADAPTER *ioc = hd->ioc;
3396
3397         return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_assembly);
3398 }
3399 static CLASS_DEVICE_ATTR(board_assembly, S_IRUGO,
3400     mptscsih_board_assembly_show, NULL);
3401
3402 static ssize_t
3403 mptscsih_board_tracer_show(struct class_device *cdev, char *buf)
3404 {
3405         struct Scsi_Host *host = class_to_shost(cdev);
3406         MPT_SCSI_HOST   *hd = shost_priv(host);
3407         MPT_ADAPTER *ioc = hd->ioc;
3408
3409         return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_tracer);
3410 }
3411 static CLASS_DEVICE_ATTR(board_tracer, S_IRUGO,
3412     mptscsih_board_tracer_show, NULL);
3413
3414 static ssize_t
3415 mptscsih_io_delay_show(struct class_device *cdev, char *buf)
3416 {
3417         struct Scsi_Host *host = class_to_shost(cdev);
3418         MPT_SCSI_HOST   *hd = shost_priv(host);
3419         MPT_ADAPTER *ioc = hd->ioc;
3420
3421         return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->io_missing_delay);
3422 }
3423 static CLASS_DEVICE_ATTR(io_delay, S_IRUGO,
3424     mptscsih_io_delay_show, NULL);
3425
3426 static ssize_t
3427 mptscsih_device_delay_show(struct class_device *cdev, char *buf)
3428 {
3429         struct Scsi_Host *host = class_to_shost(cdev);
3430         MPT_SCSI_HOST   *hd = shost_priv(host);
3431         MPT_ADAPTER *ioc = hd->ioc;
3432
3433         return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->device_missing_delay);
3434 }
3435 static CLASS_DEVICE_ATTR(device_delay, S_IRUGO,
3436     mptscsih_device_delay_show, NULL);
3437
3438 static ssize_t
3439 mptscsih_debug_level_show(struct class_device *cdev, char *buf)
3440 {
3441         struct Scsi_Host *host = class_to_shost(cdev);
3442         MPT_SCSI_HOST   *hd = shost_priv(host);
3443         MPT_ADAPTER *ioc = hd->ioc;
3444
3445         return snprintf(buf, PAGE_SIZE, "%08xh\n", ioc->debug_level);
3446 }
3447 static ssize_t
3448 mptscsih_debug_level_store(struct class_device *cdev, const char *buf,
3449                                                                 size_t count)
3450 {
3451         struct Scsi_Host *host = class_to_shost(cdev);
3452         MPT_SCSI_HOST   *hd = shost_priv(host);
3453         MPT_ADAPTER *ioc = hd->ioc;
3454         int val = 0;
3455
3456         if (sscanf(buf, "%x", &val) != 1)
3457                 return -EINVAL;
3458
3459         ioc->debug_level = val;
3460         printk(MYIOC_s_INFO_FMT "debug_level=%08xh\n",
3461                                 ioc->name, ioc->debug_level);
3462         return strlen(buf);
3463 }
3464 static CLASS_DEVICE_ATTR(debug_level, S_IRUGO | S_IWUSR,
3465     mptscsih_debug_level_show, mptscsih_debug_level_store);
3466
3467 struct class_device_attribute *mptscsih_host_attrs[] = {
3468         &class_device_attr_version_fw,
3469         &class_device_attr_version_bios,
3470         &class_device_attr_version_mpi,
3471         &class_device_attr_version_product,
3472         &class_device_attr_version_nvdata_persistent,
3473         &class_device_attr_version_nvdata_default,
3474         &class_device_attr_board_name,
3475         &class_device_attr_board_assembly,
3476         &class_device_attr_board_tracer,
3477         &class_device_attr_io_delay,
3478         &class_device_attr_device_delay,
3479         &class_device_attr_debug_level,
3480         NULL,
3481 };
3482 EXPORT_SYMBOL(mptscsih_host_attrs);
3483
3484 EXPORT_SYMBOL(mptscsih_remove);
3485 EXPORT_SYMBOL(mptscsih_shutdown);
3486 #ifdef CONFIG_PM
3487 EXPORT_SYMBOL(mptscsih_suspend);
3488 EXPORT_SYMBOL(mptscsih_resume);
3489 #endif
3490 EXPORT_SYMBOL(mptscsih_proc_info);
3491 EXPORT_SYMBOL(mptscsih_info);
3492 EXPORT_SYMBOL(mptscsih_qcmd);
3493 EXPORT_SYMBOL(mptscsih_slave_destroy);
3494 EXPORT_SYMBOL(mptscsih_slave_configure);
3495 EXPORT_SYMBOL(mptscsih_abort);
3496 EXPORT_SYMBOL(mptscsih_dev_reset);
3497 EXPORT_SYMBOL(mptscsih_bus_reset);
3498 EXPORT_SYMBOL(mptscsih_host_reset);
3499 EXPORT_SYMBOL(mptscsih_bios_param);
3500 EXPORT_SYMBOL(mptscsih_io_done);
3501 EXPORT_SYMBOL(mptscsih_taskmgmt_complete);
3502 EXPORT_SYMBOL(mptscsih_scandv_complete);
3503 EXPORT_SYMBOL(mptscsih_event_process);
3504 EXPORT_SYMBOL(mptscsih_ioc_reset);
3505 EXPORT_SYMBOL(mptscsih_change_queue_depth);
3506 EXPORT_SYMBOL(mptscsih_timer_expired);
3507 EXPORT_SYMBOL(mptscsih_TMHandler);
3508
3509 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/