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