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