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