[SCSI] mptscsih: remove unused page 1 setting function
[linux-2.6] / drivers / message / fusion / mptscsih.c
1 /*
2  *  linux/drivers/message/fusion/mptscsih.c
3  *      For use with LSI Logic PCI chip/adapter(s)
4  *      running LSI Logic Fusion MPT (Message Passing Technology) firmware.
5  *
6  *  Copyright (c) 1999-2005 LSI Logic Corporation
7  *  (mailto:mpt_linux_developer@lsil.com)
8  *
9  */
10 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
11 /*
12     This program is free software; you can redistribute it and/or modify
13     it under the terms of the GNU General Public License as published by
14     the Free Software Foundation; version 2 of the License.
15
16     This program is distributed in the hope that it will be useful,
17     but WITHOUT ANY WARRANTY; without even the implied warranty of
18     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19     GNU General Public License for more details.
20
21     NO WARRANTY
22     THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
23     CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
24     LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
25     MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
26     solely responsible for determining the appropriateness of using and
27     distributing the Program and assumes all risks associated with its
28     exercise of rights under this Agreement, including but not limited to
29     the risks and costs of program errors, damage to or loss of data,
30     programs or equipment, and unavailability or interruption of operations.
31
32     DISCLAIMER OF LIABILITY
33     NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
34     DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
35     DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
36     ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
37     TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
38     USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
39     HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
40
41     You should have received a copy of the GNU General Public License
42     along with this program; if not, write to the Free Software
43     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
44 */
45 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
46
47 #include "linux_compat.h"       /* linux-2.6 tweaks */
48 #include <linux/module.h>
49 #include <linux/kernel.h>
50 #include <linux/init.h>
51 #include <linux/errno.h>
52 #include <linux/kdev_t.h>
53 #include <linux/blkdev.h>
54 #include <linux/delay.h>        /* for mdelay */
55 #include <linux/interrupt.h>    /* needed for in_interrupt() proto */
56 #include <linux/reboot.h>       /* notifier code */
57 #include <linux/sched.h>
58 #include <linux/workqueue.h>
59
60 #include <scsi/scsi.h>
61 #include <scsi/scsi_cmnd.h>
62 #include <scsi/scsi_device.h>
63 #include <scsi/scsi_host.h>
64 #include <scsi/scsi_tcq.h>
65 #include <scsi/scsi_dbg.h>
66
67 #include "mptbase.h"
68 #include "mptscsih.h"
69
70 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
71 #define my_NAME         "Fusion MPT SCSI Host driver"
72 #define my_VERSION      MPT_LINUX_VERSION_COMMON
73 #define MYNAM           "mptscsih"
74
75 MODULE_AUTHOR(MODULEAUTHOR);
76 MODULE_DESCRIPTION(my_NAME);
77 MODULE_LICENSE("GPL");
78
79 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
80
81 typedef struct _BIG_SENSE_BUF {
82         u8              data[MPT_SENSE_BUFFER_ALLOC];
83 } BIG_SENSE_BUF;
84
85 #define MPT_SCANDV_GOOD                 (0x00000000) /* must be 0 */
86 #define MPT_SCANDV_DID_RESET            (0x00000001)
87 #define MPT_SCANDV_SENSE                (0x00000002)
88 #define MPT_SCANDV_SOME_ERROR           (0x00000004)
89 #define MPT_SCANDV_SELECTION_TIMEOUT    (0x00000008)
90 #define MPT_SCANDV_ISSUE_SENSE          (0x00000010)
91 #define MPT_SCANDV_FALLBACK             (0x00000020)
92
93 #define MPT_SCANDV_MAX_RETRIES          (10)
94
95 #define MPT_ICFLAG_BUF_CAP      0x01    /* ReadBuffer Read Capacity format */
96 #define MPT_ICFLAG_ECHO         0x02    /* ReadBuffer Echo buffer format */
97 #define MPT_ICFLAG_EBOS         0x04    /* ReadBuffer Echo buffer has EBOS */
98 #define MPT_ICFLAG_PHYS_DISK    0x08    /* Any SCSI IO but do Phys Disk Format */
99 #define MPT_ICFLAG_TAGGED_CMD   0x10    /* Do tagged IO */
100 #define MPT_ICFLAG_DID_RESET    0x20    /* Bus Reset occurred with this command */
101 #define MPT_ICFLAG_RESERVED     0x40    /* Reserved has been issued */
102
103 typedef struct _internal_cmd {
104         char            *data;          /* data pointer */
105         dma_addr_t      data_dma;       /* data dma address */
106         int             size;           /* transfer size */
107         u8              cmd;            /* SCSI Op Code */
108         u8              bus;            /* bus number */
109         u8              id;             /* SCSI ID (virtual) */
110         u8              lun;
111         u8              flags;          /* Bit Field - See above */
112         u8              physDiskNum;    /* Phys disk number, -1 else */
113         u8              rsvd2;
114         u8              rsvd;
115 } INTERNAL_CMD;
116
117 /*
118  *  Other private/forward protos...
119  */
120 int             mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
121 static void     mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq);
122 int             mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
123
124 static int      mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
125                                  SCSIIORequest_t *pReq, int req_idx);
126 static void     mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx);
127 static void     mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply);
128 static int      mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd);
129 static int      mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout );
130 static u32      SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc);
131
132 static int      mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout);
133
134 int             mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
135 int             mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
136
137 static void     mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, struct scsi_device *sdev);
138 static void     mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *vtarget, struct scsi_device *sdev);
139 static int      mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus);
140 int             mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
141 static int      mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
142 static void     mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice);
143
144 void            mptscsih_remove(struct pci_dev *);
145 void            mptscsih_shutdown(struct pci_dev *);
146 #ifdef CONFIG_PM
147 int             mptscsih_suspend(struct pci_dev *pdev, pm_message_t state);
148 int             mptscsih_resume(struct pci_dev *pdev);
149 #endif
150
151 #define SNS_LEN(scp)    sizeof((scp)->sense_buffer)
152
153 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
154 /**
155  *      mptscsih_add_sge - Place a simple SGE at address pAddr.
156  *      @pAddr: virtual address for SGE
157  *      @flagslength: SGE flags and data transfer length
158  *      @dma_addr: Physical address
159  *
160  *      This routine places a MPT request frame back on the MPT adapter's
161  *      FreeQ.
162  */
163 static inline void
164 mptscsih_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
165 {
166         if (sizeof(dma_addr_t) == sizeof(u64)) {
167                 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
168                 u32 tmp = dma_addr & 0xFFFFFFFF;
169
170                 pSge->FlagsLength = cpu_to_le32(flagslength);
171                 pSge->Address.Low = cpu_to_le32(tmp);
172                 tmp = (u32) ((u64)dma_addr >> 32);
173                 pSge->Address.High = cpu_to_le32(tmp);
174
175         } else {
176                 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
177                 pSge->FlagsLength = cpu_to_le32(flagslength);
178                 pSge->Address = cpu_to_le32(dma_addr);
179         }
180 } /* mptscsih_add_sge() */
181
182 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
183 /**
184  *      mptscsih_add_chain - Place a chain SGE at address pAddr.
185  *      @pAddr: virtual address for SGE
186  *      @next: nextChainOffset value (u32's)
187  *      @length: length of next SGL segment
188  *      @dma_addr: Physical address
189  *
190  *      This routine places a MPT request frame back on the MPT adapter's
191  *      FreeQ.
192  */
193 static inline void
194 mptscsih_add_chain(char *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
195 {
196         if (sizeof(dma_addr_t) == sizeof(u64)) {
197                 SGEChain64_t *pChain = (SGEChain64_t *) pAddr;
198                 u32 tmp = dma_addr & 0xFFFFFFFF;
199
200                 pChain->Length = cpu_to_le16(length);
201                 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size();
202
203                 pChain->NextChainOffset = next;
204
205                 pChain->Address.Low = cpu_to_le32(tmp);
206                 tmp = (u32) ((u64)dma_addr >> 32);
207                 pChain->Address.High = cpu_to_le32(tmp);
208         } else {
209                 SGEChain32_t *pChain = (SGEChain32_t *) pAddr;
210                 pChain->Length = cpu_to_le16(length);
211                 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size();
212                 pChain->NextChainOffset = next;
213                 pChain->Address = cpu_to_le32(dma_addr);
214         }
215 } /* mptscsih_add_chain() */
216
217 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
218 /*
219  *      mptscsih_getFreeChainBuffer - Function to get a free chain
220  *      from the MPT_SCSI_HOST FreeChainQ.
221  *      @ioc: Pointer to MPT_ADAPTER structure
222  *      @req_idx: Index of the SCSI IO request frame. (output)
223  *
224  *      return SUCCESS or FAILED
225  */
226 static inline int
227 mptscsih_getFreeChainBuffer(MPT_ADAPTER *ioc, int *retIndex)
228 {
229         MPT_FRAME_HDR *chainBuf;
230         unsigned long flags;
231         int rc;
232         int chain_idx;
233
234         dsgprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer called\n",
235                         ioc->name));
236         spin_lock_irqsave(&ioc->FreeQlock, flags);
237         if (!list_empty(&ioc->FreeChainQ)) {
238                 int offset;
239
240                 chainBuf = list_entry(ioc->FreeChainQ.next, MPT_FRAME_HDR,
241                                 u.frame.linkage.list);
242                 list_del(&chainBuf->u.frame.linkage.list);
243                 offset = (u8 *)chainBuf - (u8 *)ioc->ChainBuffer;
244                 chain_idx = offset / ioc->req_sz;
245                 rc = SUCCESS;
246                 dsgprintk((MYIOC_s_ERR_FMT "getFreeChainBuffer chainBuf=%p ChainBuffer=%p offset=%d chain_idx=%d\n",
247                         ioc->name, chainBuf, ioc->ChainBuffer, offset, chain_idx));
248         } else {
249                 rc = FAILED;
250                 chain_idx = MPT_HOST_NO_CHAIN;
251                 dfailprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer failed\n",
252                         ioc->name));
253         }
254         spin_unlock_irqrestore(&ioc->FreeQlock, flags);
255
256         *retIndex = chain_idx;
257         return rc;
258 } /* mptscsih_getFreeChainBuffer() */
259
260 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
261 /*
262  *      mptscsih_AddSGE - Add a SGE (plus chain buffers) to the
263  *      SCSIIORequest_t Message Frame.
264  *      @ioc: Pointer to MPT_ADAPTER structure
265  *      @SCpnt: Pointer to scsi_cmnd structure
266  *      @pReq: Pointer to SCSIIORequest_t structure
267  *
268  *      Returns ...
269  */
270 static int
271 mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
272                 SCSIIORequest_t *pReq, int req_idx)
273 {
274         char    *psge;
275         char    *chainSge;
276         struct scatterlist *sg;
277         int      frm_sz;
278         int      sges_left, sg_done;
279         int      chain_idx = MPT_HOST_NO_CHAIN;
280         int      sgeOffset;
281         int      numSgeSlots, numSgeThisFrame;
282         u32      sgflags, sgdir, thisxfer = 0;
283         int      chain_dma_off = 0;
284         int      newIndex;
285         int      ii;
286         dma_addr_t v2;
287         u32     RequestNB;
288
289         sgdir = le32_to_cpu(pReq->Control) & MPI_SCSIIO_CONTROL_DATADIRECTION_MASK;
290         if (sgdir == MPI_SCSIIO_CONTROL_WRITE)  {
291                 sgdir = MPT_TRANSFER_HOST_TO_IOC;
292         } else {
293                 sgdir = MPT_TRANSFER_IOC_TO_HOST;
294         }
295
296         psge = (char *) &pReq->SGL;
297         frm_sz = ioc->req_sz;
298
299         /* Map the data portion, if any.
300          * sges_left  = 0 if no data transfer.
301          */
302         if ( (sges_left = SCpnt->use_sg) ) {
303                 sges_left = pci_map_sg(ioc->pcidev,
304                                (struct scatterlist *) SCpnt->request_buffer,
305                                SCpnt->use_sg,
306                                SCpnt->sc_data_direction);
307                 if (sges_left == 0)
308                         return FAILED;
309         } else if (SCpnt->request_bufflen) {
310                 SCpnt->SCp.dma_handle = pci_map_single(ioc->pcidev,
311                                       SCpnt->request_buffer,
312                                       SCpnt->request_bufflen,
313                                       SCpnt->sc_data_direction);
314                 dsgprintk((MYIOC_s_INFO_FMT "SG: non-SG for %p, len=%d\n",
315                                 ioc->name, SCpnt, SCpnt->request_bufflen));
316                 mptscsih_add_sge((char *) &pReq->SGL,
317                         0xD1000000|MPT_SGE_FLAGS_ADDRESSING|sgdir|SCpnt->request_bufflen,
318                         SCpnt->SCp.dma_handle);
319
320                 return SUCCESS;
321         }
322
323         /* Handle the SG case.
324          */
325         sg = (struct scatterlist *) SCpnt->request_buffer;
326         sg_done  = 0;
327         sgeOffset = sizeof(SCSIIORequest_t) - sizeof(SGE_IO_UNION);
328         chainSge = NULL;
329
330         /* Prior to entering this loop - the following must be set
331          * current MF:  sgeOffset (bytes)
332          *              chainSge (Null if original MF is not a chain buffer)
333          *              sg_done (num SGE done for this MF)
334          */
335
336 nextSGEset:
337         numSgeSlots = ((frm_sz - sgeOffset) / (sizeof(u32) + sizeof(dma_addr_t)) );
338         numSgeThisFrame = (sges_left < numSgeSlots) ? sges_left : numSgeSlots;
339
340         sgflags = MPT_SGE_FLAGS_SIMPLE_ELEMENT | MPT_SGE_FLAGS_ADDRESSING | sgdir;
341
342         /* Get first (num - 1) SG elements
343          * Skip any SG entries with a length of 0
344          * NOTE: at finish, sg and psge pointed to NEXT data/location positions
345          */
346         for (ii=0; ii < (numSgeThisFrame-1); ii++) {
347                 thisxfer = sg_dma_len(sg);
348                 if (thisxfer == 0) {
349                         sg ++; /* Get next SG element from the OS */
350                         sg_done++;
351                         continue;
352                 }
353
354                 v2 = sg_dma_address(sg);
355                 mptscsih_add_sge(psge, sgflags | thisxfer, v2);
356
357                 sg++;           /* Get next SG element from the OS */
358                 psge += (sizeof(u32) + sizeof(dma_addr_t));
359                 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
360                 sg_done++;
361         }
362
363         if (numSgeThisFrame == sges_left) {
364                 /* Add last element, end of buffer and end of list flags.
365                  */
366                 sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT |
367                                 MPT_SGE_FLAGS_END_OF_BUFFER |
368                                 MPT_SGE_FLAGS_END_OF_LIST;
369
370                 /* Add last SGE and set termination flags.
371                  * Note: Last SGE may have a length of 0 - which should be ok.
372                  */
373                 thisxfer = sg_dma_len(sg);
374
375                 v2 = sg_dma_address(sg);
376                 mptscsih_add_sge(psge, sgflags | thisxfer, v2);
377                 /*
378                 sg++;
379                 psge += (sizeof(u32) + sizeof(dma_addr_t));
380                 */
381                 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
382                 sg_done++;
383
384                 if (chainSge) {
385                         /* The current buffer is a chain buffer,
386                          * but there is not another one.
387                          * Update the chain element
388                          * Offset and Length fields.
389                          */
390                         mptscsih_add_chain((char *)chainSge, 0, sgeOffset, ioc->ChainBufferDMA + chain_dma_off);
391                 } else {
392                         /* The current buffer is the original MF
393                          * and there is no Chain buffer.
394                          */
395                         pReq->ChainOffset = 0;
396                         RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor)  + 1) & 0x03;
397                         dsgprintk((MYIOC_s_INFO_FMT
398                             "Single Buffer RequestNB=%x, sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
399                         ioc->RequestNB[req_idx] = RequestNB;
400                 }
401         } else {
402                 /* At least one chain buffer is needed.
403                  * Complete the first MF
404                  *  - last SGE element, set the LastElement bit
405                  *  - set ChainOffset (words) for orig MF
406                  *             (OR finish previous MF chain buffer)
407                  *  - update MFStructPtr ChainIndex
408                  *  - Populate chain element
409                  * Also
410                  * Loop until done.
411                  */
412
413                 dsgprintk((MYIOC_s_INFO_FMT "SG: Chain Required! sg done %d\n",
414                                 ioc->name, sg_done));
415
416                 /* Set LAST_ELEMENT flag for last non-chain element
417                  * in the buffer. Since psge points at the NEXT
418                  * SGE element, go back one SGE element, update the flags
419                  * and reset the pointer. (Note: sgflags & thisxfer are already
420                  * set properly).
421                  */
422                 if (sg_done) {
423                         u32 *ptmp = (u32 *) (psge - (sizeof(u32) + sizeof(dma_addr_t)));
424                         sgflags = le32_to_cpu(*ptmp);
425                         sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT;
426                         *ptmp = cpu_to_le32(sgflags);
427                 }
428
429                 if (chainSge) {
430                         /* The current buffer is a chain buffer.
431                          * chainSge points to the previous Chain Element.
432                          * Update its chain element Offset and Length (must
433                          * include chain element size) fields.
434                          * Old chain element is now complete.
435                          */
436                         u8 nextChain = (u8) (sgeOffset >> 2);
437                         sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
438                         mptscsih_add_chain((char *)chainSge, nextChain, sgeOffset, ioc->ChainBufferDMA + chain_dma_off);
439                 } else {
440                         /* The original MF buffer requires a chain buffer -
441                          * set the offset.
442                          * Last element in this MF is a chain element.
443                          */
444                         pReq->ChainOffset = (u8) (sgeOffset >> 2);
445                         RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor)  + 1) & 0x03;
446                         dsgprintk((MYIOC_s_ERR_FMT "Chain Buffer Needed, RequestNB=%x sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
447                         ioc->RequestNB[req_idx] = RequestNB;
448                 }
449
450                 sges_left -= sg_done;
451
452
453                 /* NOTE: psge points to the beginning of the chain element
454                  * in current buffer. Get a chain buffer.
455                  */
456                 if ((mptscsih_getFreeChainBuffer(ioc, &newIndex)) == FAILED) {
457                         dfailprintk((MYIOC_s_INFO_FMT
458                             "getFreeChainBuffer FAILED SCSI cmd=%02x (%p)\n",
459                             ioc->name, pReq->CDB[0], SCpnt));
460                         return FAILED;
461                 }
462
463                 /* Update the tracking arrays.
464                  * If chainSge == NULL, update ReqToChain, else ChainToChain
465                  */
466                 if (chainSge) {
467                         ioc->ChainToChain[chain_idx] = newIndex;
468                 } else {
469                         ioc->ReqToChain[req_idx] = newIndex;
470                 }
471                 chain_idx = newIndex;
472                 chain_dma_off = ioc->req_sz * chain_idx;
473
474                 /* Populate the chainSGE for the current buffer.
475                  * - Set chain buffer pointer to psge and fill
476                  *   out the Address and Flags fields.
477                  */
478                 chainSge = (char *) psge;
479                 dsgprintk((KERN_INFO "  Current buff @ %p (index 0x%x)",
480                                 psge, req_idx));
481
482                 /* Start the SGE for the next buffer
483                  */
484                 psge = (char *) (ioc->ChainBuffer + chain_dma_off);
485                 sgeOffset = 0;
486                 sg_done = 0;
487
488                 dsgprintk((KERN_INFO "  Chain buff @ %p (index 0x%x)\n",
489                                 psge, chain_idx));
490
491                 /* Start the SGE for the next buffer
492                  */
493
494                 goto nextSGEset;
495         }
496
497         return SUCCESS;
498 } /* mptscsih_AddSGE() */
499
500 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
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->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 (vdev->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT &&
1239             mptscsih_raid_id_to_num(hd, SCpnt->device->id) < 0) {
1240                 SCpnt->result = DID_NO_CONNECT << 16;
1241                 done(SCpnt);
1242                 return 0;
1243         }
1244
1245         /*
1246          *  Put together a MPT SCSI request...
1247          */
1248         if ((mf = mpt_get_msg_frame(hd->ioc->DoneCtx, hd->ioc)) == NULL) {
1249                 dprintk((MYIOC_s_WARN_FMT "QueueCmd, no msg frames!!\n",
1250                                 hd->ioc->name));
1251                 return SCSI_MLQUEUE_HOST_BUSY;
1252         }
1253
1254         pScsiReq = (SCSIIORequest_t *) mf;
1255
1256         my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
1257
1258         ADD_INDEX_LOG(my_idx);
1259
1260         /*    TUR's being issued with scsictl=0x02000000 (DATA_IN)!
1261          *    Seems we may receive a buffer (datalen>0) even when there
1262          *    will be no data transfer!  GRRRRR...
1263          */
1264         if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
1265                 datalen = SCpnt->request_bufflen;
1266                 scsidir = MPI_SCSIIO_CONTROL_READ;      /* DATA IN  (host<--ioc<--dev) */
1267         } else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
1268                 datalen = SCpnt->request_bufflen;
1269                 scsidir = MPI_SCSIIO_CONTROL_WRITE;     /* DATA OUT (host-->ioc-->dev) */
1270         } else {
1271                 datalen = 0;
1272                 scsidir = MPI_SCSIIO_CONTROL_NODATATRANSFER;
1273         }
1274
1275         /* Default to untagged. Once a target structure has been allocated,
1276          * use the Inquiry data to determine if device supports tagged.
1277          */
1278         if (vdev
1279             && (vdev->vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)
1280             && (SCpnt->device->tagged_supported)) {
1281                 scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
1282         } else {
1283                 scsictl = scsidir | MPI_SCSIIO_CONTROL_UNTAGGED;
1284         }
1285
1286         /* Use the above information to set up the message frame
1287          */
1288         pScsiReq->TargetID = (u8) vdev->target_id;
1289         pScsiReq->Bus = vdev->bus_id;
1290         pScsiReq->ChainOffset = 0;
1291         if (vdev->vtarget->tflags &  MPT_TARGET_FLAGS_RAID_COMPONENT)
1292                 pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
1293         else
1294                 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
1295         pScsiReq->CDBLength = SCpnt->cmd_len;
1296         pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
1297         pScsiReq->Reserved = 0;
1298         pScsiReq->MsgFlags = mpt_msg_flags();
1299         pScsiReq->LUN[0] = 0;
1300         pScsiReq->LUN[1] = lun;
1301         pScsiReq->LUN[2] = 0;
1302         pScsiReq->LUN[3] = 0;
1303         pScsiReq->LUN[4] = 0;
1304         pScsiReq->LUN[5] = 0;
1305         pScsiReq->LUN[6] = 0;
1306         pScsiReq->LUN[7] = 0;
1307         pScsiReq->Control = cpu_to_le32(scsictl);
1308
1309         /*
1310          *  Write SCSI CDB into the message
1311          */
1312         cmd_len = SCpnt->cmd_len;
1313         for (ii=0; ii < cmd_len; ii++)
1314                 pScsiReq->CDB[ii] = SCpnt->cmnd[ii];
1315
1316         for (ii=cmd_len; ii < 16; ii++)
1317                 pScsiReq->CDB[ii] = 0;
1318
1319         /* DataLength */
1320         pScsiReq->DataLength = cpu_to_le32(datalen);
1321
1322         /* SenseBuffer low address */
1323         pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
1324                                            + (my_idx * MPT_SENSE_BUFFER_ALLOC));
1325
1326         /* Now add the SG list
1327          * Always have a SGE even if null length.
1328          */
1329         if (datalen == 0) {
1330                 /* Add a NULL SGE */
1331                 mptscsih_add_sge((char *)&pScsiReq->SGL, MPT_SGE_FLAGS_SSIMPLE_READ | 0,
1332                         (dma_addr_t) -1);
1333         } else {
1334                 /* Add a 32 or 64 bit SGE */
1335                 if (mptscsih_AddSGE(hd->ioc, SCpnt, pScsiReq, my_idx) != SUCCESS)
1336                         goto fail;
1337         }
1338
1339         hd->ScsiLookup[my_idx] = SCpnt;
1340         SCpnt->host_scribble = NULL;
1341
1342         mpt_put_msg_frame(hd->ioc->DoneCtx, hd->ioc, mf);
1343         dmfprintk((MYIOC_s_INFO_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n",
1344                         hd->ioc->name, SCpnt, mf, my_idx));
1345         DBG_DUMP_REQUEST_FRAME(mf)
1346         return 0;
1347
1348  fail:
1349         hd->ScsiLookup[my_idx] = NULL;
1350         mptscsih_freeChainBuffers(hd->ioc, my_idx);
1351         mpt_free_msg_frame(hd->ioc, mf);
1352         return SCSI_MLQUEUE_HOST_BUSY;
1353 }
1354
1355 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1356 /*
1357  *      mptscsih_freeChainBuffers - Function to free chain buffers associated
1358  *      with a SCSI IO request
1359  *      @hd: Pointer to the MPT_SCSI_HOST instance
1360  *      @req_idx: Index of the SCSI IO request frame.
1361  *
1362  *      Called if SG chain buffer allocation fails and mptscsih callbacks.
1363  *      No return.
1364  */
1365 static void
1366 mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
1367 {
1368         MPT_FRAME_HDR *chain;
1369         unsigned long flags;
1370         int chain_idx;
1371         int next;
1372
1373         /* Get the first chain index and reset
1374          * tracker state.
1375          */
1376         chain_idx = ioc->ReqToChain[req_idx];
1377         ioc->ReqToChain[req_idx] = MPT_HOST_NO_CHAIN;
1378
1379         while (chain_idx != MPT_HOST_NO_CHAIN) {
1380
1381                 /* Save the next chain buffer index */
1382                 next = ioc->ChainToChain[chain_idx];
1383
1384                 /* Free this chain buffer and reset
1385                  * tracker
1386                  */
1387                 ioc->ChainToChain[chain_idx] = MPT_HOST_NO_CHAIN;
1388
1389                 chain = (MPT_FRAME_HDR *) (ioc->ChainBuffer
1390                                         + (chain_idx * ioc->req_sz));
1391
1392                 spin_lock_irqsave(&ioc->FreeQlock, flags);
1393                 list_add_tail(&chain->u.frame.linkage.list, &ioc->FreeChainQ);
1394                 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1395
1396                 dmfprintk((MYIOC_s_INFO_FMT "FreeChainBuffers (index %d)\n",
1397                                 ioc->name, chain_idx));
1398
1399                 /* handle next */
1400                 chain_idx = next;
1401         }
1402         return;
1403 }
1404
1405 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1406 /*
1407  *      Reset Handling
1408  */
1409
1410 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1411 /*
1412  *      mptscsih_TMHandler - Generic handler for SCSI Task Management.
1413  *      Fall through to mpt_HardResetHandler if: not operational, too many
1414  *      failed TM requests or handshake failure.
1415  *
1416  *      @ioc: Pointer to MPT_ADAPTER structure
1417  *      @type: Task Management type
1418  *      @target: Logical Target ID for reset (if appropriate)
1419  *      @lun: Logical Unit for reset (if appropriate)
1420  *      @ctx2abort: Context for the task to be aborted (if appropriate)
1421  *
1422  *      Remark: Currently invoked from a non-interrupt thread (_bh).
1423  *
1424  *      Remark: With old EH code, at most 1 SCSI TaskMgmt function per IOC
1425  *      will be active.
1426  *
1427  *      Returns 0 for SUCCESS or -1 if FAILED.
1428  */
1429 int
1430 mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout)
1431 {
1432         MPT_ADAPTER     *ioc;
1433         int              rc = -1;
1434         int              doTask = 1;
1435         u32              ioc_raw_state;
1436         unsigned long    flags;
1437
1438         /* If FW is being reloaded currently, return success to
1439          * the calling function.
1440          */
1441         if (hd == NULL)
1442                 return 0;
1443
1444         ioc = hd->ioc;
1445         if (ioc == NULL) {
1446                 printk(KERN_ERR MYNAM " TMHandler" " NULL ioc!\n");
1447                 return FAILED;
1448         }
1449         dtmprintk((MYIOC_s_INFO_FMT "TMHandler Entered!\n", ioc->name));
1450
1451         // SJR - CHECKME - Can we avoid this here?
1452         // (mpt_HardResetHandler has this check...)
1453         spin_lock_irqsave(&ioc->diagLock, flags);
1454         if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)) {
1455                 spin_unlock_irqrestore(&ioc->diagLock, flags);
1456                 return FAILED;
1457         }
1458         spin_unlock_irqrestore(&ioc->diagLock, flags);
1459
1460         /*  Wait a fixed amount of time for the TM pending flag to be cleared.
1461          *  If we time out and not bus reset, then we return a FAILED status to the caller.
1462          *  The call to mptscsih_tm_pending_wait() will set the pending flag if we are
1463          *  successful. Otherwise, reload the FW.
1464          */
1465         if (mptscsih_tm_pending_wait(hd) == FAILED) {
1466                 if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
1467                         dtmprintk((KERN_INFO MYNAM ": %s: TMHandler abort: "
1468                            "Timed out waiting for last TM (%d) to complete! \n",
1469                            hd->ioc->name, hd->tmPending));
1470                         return FAILED;
1471                 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) {
1472                         dtmprintk((KERN_INFO MYNAM ": %s: TMHandler target reset: "
1473                            "Timed out waiting for last TM (%d) to complete! \n",
1474                            hd->ioc->name, hd->tmPending));
1475                         return FAILED;
1476                 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
1477                         dtmprintk((KERN_INFO MYNAM ": %s: TMHandler bus reset: "
1478                            "Timed out waiting for last TM (%d) to complete! \n",
1479                            hd->ioc->name, hd->tmPending));
1480                         if (hd->tmPending & (1 << MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS))
1481                                 return FAILED;
1482
1483                         doTask = 0;
1484                 }
1485         } else {
1486                 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
1487                 hd->tmPending |=  (1 << type);
1488                 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1489         }
1490
1491         /* Is operational?
1492          */
1493         ioc_raw_state = mpt_GetIocState(hd->ioc, 0);
1494
1495 #ifdef MPT_DEBUG_RESET
1496         if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) {
1497                 printk(MYIOC_s_WARN_FMT
1498                         "TM Handler: IOC Not operational(0x%x)!\n",
1499                         hd->ioc->name, ioc_raw_state);
1500         }
1501 #endif
1502
1503         if (doTask && ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL)
1504                                 && !(ioc_raw_state & MPI_DOORBELL_ACTIVE)) {
1505
1506                 /* Isse the Task Mgmt request.
1507                  */
1508                 if (hd->hard_resets < -1)
1509                         hd->hard_resets++;
1510                 rc = mptscsih_IssueTaskMgmt(hd, type, channel, target, lun, ctx2abort, timeout);
1511                 if (rc) {
1512                         printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n", hd->ioc->name);
1513                 } else {
1514                         dtmprintk((MYIOC_s_INFO_FMT "Issue of TaskMgmt Successful!\n", hd->ioc->name));
1515                 }
1516         }
1517
1518         /* Only fall through to the HRH if this is a bus reset
1519          */
1520         if ((type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) && (rc ||
1521                 ioc->reload_fw || (ioc->alt_ioc && ioc->alt_ioc->reload_fw))) {
1522                 dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
1523                          hd->ioc->name));
1524                 rc = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
1525         }
1526
1527         dtmprintk((MYIOC_s_INFO_FMT "TMHandler rc = %d!\n", hd->ioc->name, rc));
1528
1529         return rc;
1530 }
1531
1532
1533 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1534 /*
1535  *      mptscsih_IssueTaskMgmt - Generic send Task Management function.
1536  *      @hd: Pointer to MPT_SCSI_HOST structure
1537  *      @type: Task Management type
1538  *      @target: Logical Target ID for reset (if appropriate)
1539  *      @lun: Logical Unit for reset (if appropriate)
1540  *      @ctx2abort: Context for the task to be aborted (if appropriate)
1541  *
1542  *      Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
1543  *      or a non-interrupt thread.  In the former, must not call schedule().
1544  *
1545  *      Not all fields are meaningfull for all task types.
1546  *
1547  *      Returns 0 for SUCCESS, -999 for "no msg frames",
1548  *      else other non-zero value returned.
1549  */
1550 static int
1551 mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout)
1552 {
1553         MPT_FRAME_HDR   *mf;
1554         SCSITaskMgmt_t  *pScsiTm;
1555         int              ii;
1556         int              retval;
1557
1558         /* Return Fail to calling function if no message frames available.
1559          */
1560         if ((mf = mpt_get_msg_frame(hd->ioc->TaskCtx, hd->ioc)) == NULL) {
1561                 dfailprintk((MYIOC_s_ERR_FMT "IssueTaskMgmt, no msg frames!!\n",
1562                                 hd->ioc->name));
1563                 return FAILED;
1564         }
1565         dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt request @ %p\n",
1566                         hd->ioc->name, mf));
1567
1568         /* Format the Request
1569          */
1570         pScsiTm = (SCSITaskMgmt_t *) mf;
1571         pScsiTm->TargetID = target;
1572         pScsiTm->Bus = channel;
1573         pScsiTm->ChainOffset = 0;
1574         pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
1575
1576         pScsiTm->Reserved = 0;
1577         pScsiTm->TaskType = type;
1578         pScsiTm->Reserved1 = 0;
1579         pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)
1580                     ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0;
1581
1582         for (ii= 0; ii < 8; ii++) {
1583                 pScsiTm->LUN[ii] = 0;
1584         }
1585         pScsiTm->LUN[1] = lun;
1586
1587         for (ii=0; ii < 7; ii++)
1588                 pScsiTm->Reserved2[ii] = 0;
1589
1590         pScsiTm->TaskMsgContext = ctx2abort;
1591
1592         dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt: ctx2abort (0x%08x) type=%d\n",
1593                         hd->ioc->name, ctx2abort, type));
1594
1595         DBG_DUMP_TM_REQUEST_FRAME((u32 *)pScsiTm);
1596
1597         if ((retval = mpt_send_handshake_request(hd->ioc->TaskCtx, hd->ioc,
1598                 sizeof(SCSITaskMgmt_t), (u32*)pScsiTm,
1599                 CAN_SLEEP)) != 0) {
1600                 dfailprintk((MYIOC_s_ERR_FMT "_send_handshake FAILED!"
1601                         " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
1602                         hd->ioc, mf));
1603                 mpt_free_msg_frame(hd->ioc, mf);
1604                 return retval;
1605         }
1606
1607         if(mptscsih_tm_wait_for_completion(hd, timeout) == FAILED) {
1608                 dfailprintk((MYIOC_s_ERR_FMT "_wait_for_completion FAILED!"
1609                         " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
1610                         hd->ioc, mf));
1611                 mpt_free_msg_frame(hd->ioc, mf);
1612                 dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
1613                          hd->ioc->name));
1614                 retval = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
1615         }
1616
1617         return retval;
1618 }
1619
1620 static int
1621 mptscsih_get_tm_timeout(MPT_ADAPTER *ioc)
1622 {
1623         switch (ioc->bus_type) {
1624         case FC:
1625                 return 40;
1626         case SAS:
1627                 return 10;
1628         case SPI:
1629         default:
1630                 return 2;
1631         }
1632 }
1633
1634 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1635 /**
1636  *      mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant
1637  *      @SCpnt: Pointer to scsi_cmnd structure, IO to be aborted
1638  *
1639  *      (linux scsi_host_template.eh_abort_handler routine)
1640  *
1641  *      Returns SUCCESS or FAILED.
1642  */
1643 int
1644 mptscsih_abort(struct scsi_cmnd * SCpnt)
1645 {
1646         MPT_SCSI_HOST   *hd;
1647         MPT_ADAPTER     *ioc;
1648         MPT_FRAME_HDR   *mf;
1649         u32              ctx2abort;
1650         int              scpnt_idx;
1651         int              retval;
1652         VirtDevice       *vdev;
1653
1654         /* If we can't locate our host adapter structure, return FAILED status.
1655          */
1656         if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL) {
1657                 SCpnt->result = DID_RESET << 16;
1658                 SCpnt->scsi_done(SCpnt);
1659                 dfailprintk((KERN_INFO MYNAM ": mptscsih_abort: "
1660                            "Can't locate host! (sc=%p)\n",
1661                            SCpnt));
1662                 return FAILED;
1663         }
1664
1665         ioc = hd->ioc;
1666         if (hd->resetPending) {
1667                 return FAILED;
1668         }
1669
1670         if (hd->timeouts < -1)
1671                 hd->timeouts++;
1672
1673         /* Find this command
1674          */
1675         if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) {
1676                 /* Cmd not found in ScsiLookup.
1677                  * Do OS callback.
1678                  */
1679                 SCpnt->result = DID_RESET << 16;
1680                 dtmprintk((KERN_INFO MYNAM ": %s: mptscsih_abort: "
1681                            "Command not in the active list! (sc=%p)\n",
1682                            hd->ioc->name, SCpnt));
1683                 return SUCCESS;
1684         }
1685
1686         printk(KERN_WARNING MYNAM ": %s: attempting task abort! (sc=%p)\n",
1687                hd->ioc->name, SCpnt);
1688         scsi_print_command(SCpnt);
1689
1690         /* Most important!  Set TaskMsgContext to SCpnt's MsgContext!
1691          * (the IO to be ABORT'd)
1692          *
1693          * NOTE: Since we do not byteswap MsgContext, we do not
1694          *       swap it here either.  It is an opaque cookie to
1695          *       the controller, so it does not matter. -DaveM
1696          */
1697         mf = MPT_INDEX_2_MFPTR(hd->ioc, scpnt_idx);
1698         ctx2abort = mf->u.frame.hwhdr.msgctxu.MsgContext;
1699
1700         hd->abortSCpnt = SCpnt;
1701
1702         vdev = SCpnt->device->hostdata;
1703         retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
1704                 vdev->bus_id, vdev->target_id, vdev->lun,
1705                 ctx2abort, mptscsih_get_tm_timeout(ioc));
1706
1707         printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n",
1708                 hd->ioc->name,
1709                 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1710
1711         if (retval == 0)
1712                 return SUCCESS;
1713
1714         if(retval != FAILED ) {
1715                 hd->tmPending = 0;
1716                 hd->tmState = TM_STATE_NONE;
1717         }
1718         return FAILED;
1719 }
1720
1721 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1722 /**
1723  *      mptscsih_dev_reset - Perform a SCSI TARGET_RESET!  new_eh variant
1724  *      @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1725  *
1726  *      (linux scsi_host_template.eh_dev_reset_handler routine)
1727  *
1728  *      Returns SUCCESS or FAILED.
1729  */
1730 int
1731 mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
1732 {
1733         MPT_SCSI_HOST   *hd;
1734         int              retval;
1735         VirtDevice       *vdev;
1736
1737         /* If we can't locate our host adapter structure, return FAILED status.
1738          */
1739         if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1740                 dtmprintk((KERN_INFO MYNAM ": mptscsih_dev_reset: "
1741                            "Can't locate host! (sc=%p)\n",
1742                            SCpnt));
1743                 return FAILED;
1744         }
1745
1746         if (hd->resetPending)
1747                 return FAILED;
1748
1749         printk(KERN_WARNING MYNAM ": %s: attempting target reset! (sc=%p)\n",
1750                hd->ioc->name, SCpnt);
1751         scsi_print_command(SCpnt);
1752
1753         vdev = SCpnt->device->hostdata;
1754         retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
1755                 vdev->bus_id, vdev->target_id,
1756                 0, 0, mptscsih_get_tm_timeout(hd->ioc));
1757
1758         printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n",
1759                 hd->ioc->name,
1760                 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1761
1762         if (retval == 0)
1763                 return SUCCESS;
1764
1765         if(retval != FAILED ) {
1766                 hd->tmPending = 0;
1767                 hd->tmState = TM_STATE_NONE;
1768         }
1769         return FAILED;
1770 }
1771
1772 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1773 /**
1774  *      mptscsih_bus_reset - Perform a SCSI BUS_RESET!  new_eh variant
1775  *      @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1776  *
1777  *      (linux scsi_host_template.eh_bus_reset_handler routine)
1778  *
1779  *      Returns SUCCESS or FAILED.
1780  */
1781 int
1782 mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
1783 {
1784         MPT_SCSI_HOST   *hd;
1785         int              retval;
1786         VirtDevice       *vdev;
1787
1788         /* If we can't locate our host adapter structure, return FAILED status.
1789          */
1790         if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1791                 dtmprintk((KERN_INFO MYNAM ": mptscsih_bus_reset: "
1792                            "Can't locate host! (sc=%p)\n",
1793                            SCpnt ) );
1794                 return FAILED;
1795         }
1796
1797         printk(KERN_WARNING MYNAM ": %s: attempting bus reset! (sc=%p)\n",
1798                hd->ioc->name, SCpnt);
1799         scsi_print_command(SCpnt);
1800
1801         if (hd->timeouts < -1)
1802                 hd->timeouts++;
1803
1804         vdev = SCpnt->device->hostdata;
1805         retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
1806                 vdev->bus_id, 0, 0, 0, mptscsih_get_tm_timeout(hd->ioc));
1807
1808         printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n",
1809                 hd->ioc->name,
1810                 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1811
1812         if (retval == 0)
1813                 return SUCCESS;
1814
1815         if(retval != FAILED ) {
1816                 hd->tmPending = 0;
1817                 hd->tmState = TM_STATE_NONE;
1818         }
1819         return FAILED;
1820 }
1821
1822 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1823 /**
1824  *      mptscsih_host_reset - Perform a SCSI host adapter RESET!
1825  *      new_eh variant
1826  *      @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1827  *
1828  *      (linux scsi_host_template.eh_host_reset_handler routine)
1829  *
1830  *      Returns SUCCESS or FAILED.
1831  */
1832 int
1833 mptscsih_host_reset(struct scsi_cmnd *SCpnt)
1834 {
1835         MPT_SCSI_HOST *  hd;
1836         int              status = SUCCESS;
1837
1838         /*  If we can't locate the host to reset, then we failed. */
1839         if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1840                 dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
1841                              "Can't locate host! (sc=%p)\n",
1842                              SCpnt ) );
1843                 return FAILED;
1844         }
1845
1846         printk(KERN_WARNING MYNAM ": %s: Attempting host reset! (sc=%p)\n",
1847                hd->ioc->name, SCpnt);
1848
1849         /*  If our attempts to reset the host failed, then return a failed
1850          *  status.  The host will be taken off line by the SCSI mid-layer.
1851          */
1852         if (mpt_HardResetHandler(hd->ioc, CAN_SLEEP) < 0){
1853                 status = FAILED;
1854         } else {
1855                 /*  Make sure TM pending is cleared and TM state is set to
1856                  *  NONE.
1857                  */
1858                 hd->tmPending = 0;
1859                 hd->tmState = TM_STATE_NONE;
1860         }
1861
1862         dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
1863                      "Status = %s\n",
1864                      (status == SUCCESS) ? "SUCCESS" : "FAILED" ) );
1865
1866         return status;
1867 }
1868
1869 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1870 /**
1871  *      mptscsih_tm_pending_wait - wait for pending task management request to
1872  *              complete.
1873  *      @hd: Pointer to MPT host structure.
1874  *
1875  *      Returns {SUCCESS,FAILED}.
1876  */
1877 static int
1878 mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd)
1879 {
1880         unsigned long  flags;
1881         int            loop_count = 4 * 10;  /* Wait 10 seconds */
1882         int            status = FAILED;
1883
1884         do {
1885                 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
1886                 if (hd->tmState == TM_STATE_NONE) {
1887                         hd->tmState = TM_STATE_IN_PROGRESS;
1888                         hd->tmPending = 1;
1889                         spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1890                         status = SUCCESS;
1891                         break;
1892                 }
1893                 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1894                 msleep(250);
1895         } while (--loop_count);
1896
1897         return status;
1898 }
1899
1900 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1901 /**
1902  *      mptscsih_tm_wait_for_completion - wait for completion of TM task
1903  *      @hd: Pointer to MPT host structure.
1904  *
1905  *      Returns {SUCCESS,FAILED}.
1906  */
1907 static int
1908 mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout )
1909 {
1910         unsigned long  flags;
1911         int            loop_count = 4 * timeout;
1912         int            status = FAILED;
1913
1914         do {
1915                 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
1916                 if(hd->tmPending == 0) {
1917                         status = SUCCESS;
1918                         spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1919                         break;
1920                 }
1921                 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1922                 msleep_interruptible(250);
1923         } while (--loop_count);
1924
1925         return status;
1926 }
1927
1928 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1929 static void
1930 mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code)
1931 {
1932         char *desc;
1933
1934         switch (response_code) {
1935         case MPI_SCSITASKMGMT_RSP_TM_COMPLETE:
1936                 desc = "The task completed.";
1937                 break;
1938         case MPI_SCSITASKMGMT_RSP_INVALID_FRAME:
1939                 desc = "The IOC received an invalid frame status.";
1940                 break;
1941         case MPI_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED:
1942                 desc = "The task type is not supported.";
1943                 break;
1944         case MPI_SCSITASKMGMT_RSP_TM_FAILED:
1945                 desc = "The requested task failed.";
1946                 break;
1947         case MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED:
1948                 desc = "The task completed successfully.";
1949                 break;
1950         case MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN:
1951                 desc = "The LUN request is invalid.";
1952                 break;
1953         case MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC:
1954                 desc = "The task is in the IOC queue and has not been sent to target.";
1955                 break;
1956         default:
1957                 desc = "unknown";
1958                 break;
1959         }
1960         printk(MYIOC_s_INFO_FMT "Response Code(0x%08x): F/W: %s\n",
1961                 ioc->name, response_code, desc);
1962 }
1963
1964 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1965 /**
1966  *      mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
1967  *      @ioc: Pointer to MPT_ADAPTER structure
1968  *      @mf: Pointer to SCSI task mgmt request frame
1969  *      @mr: Pointer to SCSI task mgmt reply frame
1970  *
1971  *      This routine is called from mptbase.c::mpt_interrupt() at the completion
1972  *      of any SCSI task management request.
1973  *      This routine is registered with the MPT (base) driver at driver
1974  *      load/init time via the mpt_register() API call.
1975  *
1976  *      Returns 1 indicating alloc'd request frame ptr should be freed.
1977  */
1978 int
1979 mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
1980 {
1981         SCSITaskMgmtReply_t     *pScsiTmReply;
1982         SCSITaskMgmt_t          *pScsiTmReq;
1983         MPT_SCSI_HOST           *hd;
1984         unsigned long            flags;
1985         u16                      iocstatus;
1986         u8                       tmType;
1987
1988         dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt completed (mf=%p,mr=%p)\n",
1989                         ioc->name, mf, mr));
1990         if (ioc->sh) {
1991                 /* Depending on the thread, a timer is activated for
1992                  * the TM request.  Delete this timer on completion of TM.
1993                  * Decrement count of outstanding TM requests.
1994                  */
1995                 hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
1996         } else {
1997                 dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt Complete: NULL Scsi Host Ptr\n",
1998                         ioc->name));
1999                 return 1;
2000         }
2001
2002         if (mr == NULL) {
2003                 dtmprintk((MYIOC_s_WARN_FMT "ERROR! TaskMgmt Reply: NULL Request %p\n",
2004                         ioc->name, mf));
2005                 return 1;
2006         } else {
2007                 pScsiTmReply = (SCSITaskMgmtReply_t*)mr;
2008                 pScsiTmReq = (SCSITaskMgmt_t*)mf;
2009
2010                 /* Figure out if this was ABORT_TASK, TARGET_RESET, or BUS_RESET! */
2011                 tmType = pScsiTmReq->TaskType;
2012
2013                 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05 &&
2014                     pScsiTmReply->ResponseCode)
2015                         mptscsih_taskmgmt_response_code(ioc,
2016                             pScsiTmReply->ResponseCode);
2017
2018                 dtmprintk((MYIOC_s_WARN_FMT "  TaskType = %d, TerminationCount=%d\n",
2019                                 ioc->name, tmType, le32_to_cpu(pScsiTmReply->TerminationCount)));
2020                 DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply);
2021
2022                 iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2023                 dtmprintk((MYIOC_s_WARN_FMT "  SCSI TaskMgmt (%d) IOCStatus=%04x IOCLogInfo=%08x\n",
2024                         ioc->name, tmType, iocstatus, le32_to_cpu(pScsiTmReply->IOCLogInfo)));
2025                 /* Error?  (anything non-zero?) */
2026                 if (iocstatus) {
2027
2028                         /* clear flags and continue.
2029                          */
2030                         if (tmType == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK)
2031                                 hd->abortSCpnt = NULL;
2032
2033                         /* If an internal command is present
2034                          * or the TM failed - reload the FW.
2035                          * FC FW may respond FAILED to an ABORT
2036                          */
2037                         if (tmType == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
2038                                 if ((hd->cmdPtr) ||
2039                                     (iocstatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED)) {
2040                                         if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0) {
2041                                                 printk((KERN_WARNING
2042                                                         " Firmware Reload FAILED!!\n"));
2043                                         }
2044                                 }
2045                         }
2046                 } else {
2047                         dtmprintk((MYIOC_s_WARN_FMT " TaskMgmt SUCCESS\n", ioc->name));
2048
2049                         hd->abortSCpnt = NULL;
2050
2051                 }
2052         }
2053
2054         spin_lock_irqsave(&ioc->FreeQlock, flags);
2055         hd->tmPending = 0;
2056         spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2057         hd->tmState = TM_STATE_NONE;
2058
2059         return 1;
2060 }
2061
2062 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2063 /*
2064  *      This is anyones guess quite frankly.
2065  */
2066 int
2067 mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
2068                 sector_t capacity, int geom[])
2069 {
2070         int             heads;
2071         int             sectors;
2072         sector_t        cylinders;
2073         ulong           dummy;
2074
2075         heads = 64;
2076         sectors = 32;
2077
2078         dummy = heads * sectors;
2079         cylinders = capacity;
2080         sector_div(cylinders,dummy);
2081
2082         /*
2083          * Handle extended translation size for logical drives
2084          * > 1Gb
2085          */
2086         if ((ulong)capacity >= 0x200000) {
2087                 heads = 255;
2088                 sectors = 63;
2089                 dummy = heads * sectors;
2090                 cylinders = capacity;
2091                 sector_div(cylinders,dummy);
2092         }
2093
2094         /* return result */
2095         geom[0] = heads;
2096         geom[1] = sectors;
2097         geom[2] = cylinders;
2098
2099         dprintk((KERN_NOTICE
2100                 ": bios_param: Id=%i Lun=%i Channel=%i CHS=%i/%i/%i\n",
2101                 sdev->id, sdev->lun,sdev->channel,(int)cylinders,heads,sectors));
2102
2103         return 0;
2104 }
2105
2106 int
2107 mptscsih_raid_id_to_num(MPT_SCSI_HOST *hd, uint physdiskid)
2108 {
2109         int i;
2110
2111         if (!hd->ioc->raid_data.isRaid || !hd->ioc->raid_data.pIocPg3)
2112                 return -ENXIO;
2113
2114         for (i = 0; i < hd->ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2115                 if (physdiskid ==
2116                     hd->ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID)
2117                         return hd->ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum;
2118         }
2119
2120         return -ENXIO;
2121 }
2122 EXPORT_SYMBOL(mptscsih_raid_id_to_num);
2123
2124 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2125 /*
2126  *      OS entry point to allow host driver to alloc memory
2127  *      for each scsi target. Called once per device the bus scan.
2128  *      Return non-zero if allocation fails.
2129  */
2130 int
2131 mptscsih_target_alloc(struct scsi_target *starget)
2132 {
2133         VirtTarget              *vtarget;
2134
2135         vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
2136         if (!vtarget)
2137                 return -ENOMEM;
2138         starget->hostdata = vtarget;
2139         vtarget->starget = starget;
2140         return 0;
2141 }
2142
2143 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2144 /*
2145  *      OS entry point to allow host driver to alloc memory
2146  *      for each scsi device. Called once per device the bus scan.
2147  *      Return non-zero if allocation fails.
2148  */
2149 int
2150 mptscsih_slave_alloc(struct scsi_device *sdev)
2151 {
2152         struct Scsi_Host        *host = sdev->host;
2153         MPT_SCSI_HOST           *hd = (MPT_SCSI_HOST *)host->hostdata;
2154         VirtTarget              *vtarget;
2155         VirtDevice              *vdev;
2156         struct scsi_target      *starget;
2157
2158         vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
2159         if (!vdev) {
2160                 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
2161                                 hd->ioc->name, sizeof(VirtDevice));
2162                 return -ENOMEM;
2163         }
2164
2165         vdev->ioc_id = hd->ioc->id;
2166         vdev->target_id = sdev->id;
2167         vdev->bus_id = sdev->channel;
2168         vdev->lun = sdev->lun;
2169         sdev->hostdata = vdev;
2170
2171         starget = scsi_target(sdev);
2172         vtarget = starget->hostdata;
2173
2174         vdev->vtarget = vtarget;
2175
2176         if (vtarget->num_luns == 0) {
2177                 hd->Targets[sdev->id] = vtarget;
2178                 vtarget->ioc_id = hd->ioc->id;
2179                 vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
2180                 vtarget->target_id = sdev->id;
2181                 vtarget->bus_id = sdev->channel;
2182                 if (hd->ioc->bus_type == SPI && sdev->channel == 0 &&
2183                     hd->ioc->raid_data.isRaid & (1 << sdev->id)) {
2184                         vtarget->raidVolume = 1;
2185                         ddvtprintk((KERN_INFO
2186                                     "RAID Volume @ id %d\n", sdev->id));
2187                 }
2188         }
2189         vtarget->num_luns++;
2190         return 0;
2191 }
2192
2193 /*
2194  *      OS entry point to allow for host driver to free allocated memory
2195  *      Called if no device present or device being unloaded
2196  */
2197 void
2198 mptscsih_target_destroy(struct scsi_target *starget)
2199 {
2200         if (starget->hostdata)
2201                 kfree(starget->hostdata);
2202         starget->hostdata = NULL;
2203 }
2204
2205 /*
2206  *      OS entry point to allow for host driver to free allocated memory
2207  *      Called if no device present or device being unloaded
2208  */
2209 void
2210 mptscsih_slave_destroy(struct scsi_device *sdev)
2211 {
2212         struct Scsi_Host        *host = sdev->host;
2213         MPT_SCSI_HOST           *hd = (MPT_SCSI_HOST *)host->hostdata;
2214         VirtTarget              *vtarget;
2215         VirtDevice              *vdevice;
2216         struct scsi_target      *starget;
2217
2218         starget = scsi_target(sdev);
2219         vtarget = starget->hostdata;
2220         vdevice = sdev->hostdata;
2221
2222         mptscsih_search_running_cmds(hd, vdevice);
2223         vtarget->luns[0] &= ~(1 << vdevice->lun);
2224         vtarget->num_luns--;
2225         if (vtarget->num_luns == 0) {
2226                 hd->Targets[sdev->id] = NULL;
2227         }
2228         mptscsih_synchronize_cache(hd, vdevice);
2229         kfree(vdevice);
2230         sdev->hostdata = NULL;
2231 }
2232
2233 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2234 /*
2235  *      mptscsih_change_queue_depth - This function will set a devices queue depth
2236  *      @sdev: per scsi_device pointer
2237  *      @qdepth: requested queue depth
2238  *
2239  *      Adding support for new 'change_queue_depth' api.
2240 */
2241 int
2242 mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
2243 {
2244         MPT_SCSI_HOST           *hd = (MPT_SCSI_HOST *)sdev->host->hostdata;
2245         VirtTarget              *vtarget;
2246         struct scsi_target      *starget;
2247         int                     max_depth;
2248         int                     tagged;
2249
2250         starget = scsi_target(sdev);
2251         vtarget = starget->hostdata;
2252
2253         if (hd->ioc->bus_type == SPI) {
2254                 if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
2255                         max_depth = 1;
2256                 else if (sdev->type == TYPE_DISK &&
2257                          vtarget->minSyncFactor <= MPT_ULTRA160)
2258                         max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2259                 else
2260                         max_depth = MPT_SCSI_CMD_PER_DEV_LOW;
2261         } else
2262                 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2263
2264         if (qdepth > max_depth)
2265                 qdepth = max_depth;
2266         if (qdepth == 1)
2267                 tagged = 0;
2268         else
2269                 tagged = MSG_SIMPLE_TAG;
2270
2271         scsi_adjust_queue_depth(sdev, tagged, qdepth);
2272         return sdev->queue_depth;
2273 }
2274
2275 /*
2276  *      OS entry point to adjust the queue_depths on a per-device basis.
2277  *      Called once per device the bus scan. Use it to force the queue_depth
2278  *      member to 1 if a device does not support Q tags.
2279  *      Return non-zero if fails.
2280  */
2281 int
2282 mptscsih_slave_configure(struct scsi_device *sdev)
2283 {
2284         struct Scsi_Host        *sh = sdev->host;
2285         VirtTarget              *vtarget;
2286         VirtDevice              *vdevice;
2287         struct scsi_target      *starget;
2288         MPT_SCSI_HOST           *hd = (MPT_SCSI_HOST *)sh->hostdata;
2289         int                     indexed_lun, lun_index;
2290
2291         starget = scsi_target(sdev);
2292         vtarget = starget->hostdata;
2293         vdevice = sdev->hostdata;
2294
2295         dsprintk((MYIOC_s_INFO_FMT
2296                 "device @ %p, id=%d, LUN=%d, channel=%d\n",
2297                 hd->ioc->name, sdev, sdev->id, sdev->lun, sdev->channel));
2298         if (hd->ioc->bus_type == SPI)
2299                 dsprintk((MYIOC_s_INFO_FMT
2300                     "sdtr %d wdtr %d ppr %d inq length=%d\n",
2301                     hd->ioc->name, sdev->sdtr, sdev->wdtr,
2302                     sdev->ppr, sdev->inquiry_len));
2303
2304         if (sdev->id > sh->max_id) {
2305                 /* error case, should never happen */
2306                 scsi_adjust_queue_depth(sdev, 0, 1);
2307                 goto slave_configure_exit;
2308         }
2309
2310         vdevice->configured_lun=1;
2311         lun_index = (vdevice->lun >> 5);  /* 32 luns per lun_index */
2312         indexed_lun = (vdevice->lun % 32);
2313         vtarget->luns[lun_index] |= (1 << indexed_lun);
2314         mptscsih_initTarget(hd, vtarget, sdev);
2315         mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH);
2316
2317         dsprintk((MYIOC_s_INFO_FMT
2318                 "Queue depth=%d, tflags=%x\n",
2319                 hd->ioc->name, sdev->queue_depth, vtarget->tflags));
2320
2321         if (hd->ioc->bus_type == SPI)
2322                 dsprintk((MYIOC_s_INFO_FMT
2323                     "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
2324                     hd->ioc->name, vtarget->negoFlags, vtarget->maxOffset,
2325                     vtarget->minSyncFactor));
2326
2327 slave_configure_exit:
2328
2329         dsprintk((MYIOC_s_INFO_FMT
2330                 "tagged %d, simple %d, ordered %d\n",
2331                 hd->ioc->name,sdev->tagged_supported, sdev->simple_tags,
2332                 sdev->ordered_tags));
2333
2334         return 0;
2335 }
2336
2337 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2338 /*
2339  *  Private routines...
2340  */
2341
2342 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2343 /* Utility function to copy sense data from the scsi_cmnd buffer
2344  * to the FC and SCSI target structures.
2345  *
2346  */
2347 static void
2348 mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
2349 {
2350         VirtDevice      *vdev;
2351         SCSIIORequest_t *pReq;
2352         u32              sense_count = le32_to_cpu(pScsiReply->SenseCount);
2353
2354         /* Get target structure
2355          */
2356         pReq = (SCSIIORequest_t *) mf;
2357         vdev = sc->device->hostdata;
2358
2359         if (sense_count) {
2360                 u8 *sense_data;
2361                 int req_index;
2362
2363                 /* Copy the sense received into the scsi command block. */
2364                 req_index = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2365                 sense_data = ((u8 *)hd->ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC));
2366                 memcpy(sc->sense_buffer, sense_data, SNS_LEN(sc));
2367
2368                 /* Log SMART data (asc = 0x5D, non-IM case only) if required.
2369                  */
2370                 if ((hd->ioc->events) && (hd->ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) {
2371                         if ((sense_data[12] == 0x5D) && (vdev->vtarget->raidVolume == 0)) {
2372                                 int idx;
2373                                 MPT_ADAPTER *ioc = hd->ioc;
2374
2375                                 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
2376                                 ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
2377                                 ioc->events[idx].eventContext = ioc->eventContext;
2378
2379                                 ioc->events[idx].data[0] = (pReq->LUN[1] << 24) ||
2380                                         (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) ||
2381                                         (sc->device->channel << 8) || sc->device->id;
2382
2383                                 ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12];
2384
2385                                 ioc->eventContext++;
2386                         }
2387                 }
2388         } else {
2389                 dprintk((MYIOC_s_INFO_FMT "Hmmm... SenseData len=0! (?)\n",
2390                                 hd->ioc->name));
2391         }
2392 }
2393
2394 static u32
2395 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc)
2396 {
2397         MPT_SCSI_HOST *hd;
2398         int i;
2399
2400         hd = (MPT_SCSI_HOST *) sc->device->host->hostdata;
2401
2402         for (i = 0; i < hd->ioc->req_depth; i++) {
2403                 if (hd->ScsiLookup[i] == sc) {
2404                         return i;
2405                 }
2406         }
2407
2408         return -1;
2409 }
2410
2411 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2412 int
2413 mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2414 {
2415         MPT_SCSI_HOST   *hd;
2416         unsigned long    flags;
2417         int             ii;
2418
2419         dtmprintk((KERN_WARNING MYNAM
2420                         ": IOC %s_reset routed to SCSI host driver!\n",
2421                         reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
2422                         reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
2423
2424         /* If a FW reload request arrives after base installed but
2425          * before all scsi hosts have been attached, then an alt_ioc
2426          * may have a NULL sh pointer.
2427          */
2428         if ((ioc->sh == NULL) || (ioc->sh->hostdata == NULL))
2429                 return 0;
2430         else
2431                 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2432
2433         if (reset_phase == MPT_IOC_SETUP_RESET) {
2434                 dtmprintk((MYIOC_s_WARN_FMT "Setup-Diag Reset\n", ioc->name));
2435
2436                 /* Clean Up:
2437                  * 1. Set Hard Reset Pending Flag
2438                  * All new commands go to doneQ
2439                  */
2440                 hd->resetPending = 1;
2441
2442         } else if (reset_phase == MPT_IOC_PRE_RESET) {
2443                 dtmprintk((MYIOC_s_WARN_FMT "Pre-Diag Reset\n", ioc->name));
2444
2445                 /* 2. Flush running commands
2446                  *      Clean ScsiLookup (and associated memory)
2447                  *      AND clean mytaskQ
2448                  */
2449
2450                 /* 2b. Reply to OS all known outstanding I/O commands.
2451                  */
2452                 mptscsih_flush_running_cmds(hd);
2453
2454                 /* 2c. If there was an internal command that
2455                  * has not completed, configuration or io request,
2456                  * free these resources.
2457                  */
2458                 if (hd->cmdPtr) {
2459                         del_timer(&hd->timer);
2460                         mpt_free_msg_frame(ioc, hd->cmdPtr);
2461                 }
2462
2463                 dtmprintk((MYIOC_s_WARN_FMT "Pre-Reset complete.\n", ioc->name));
2464
2465         } else {
2466                 dtmprintk((MYIOC_s_WARN_FMT "Post-Diag Reset\n", ioc->name));
2467
2468                 /* Once a FW reload begins, all new OS commands are
2469                  * redirected to the doneQ w/ a reset status.
2470                  * Init all control structures.
2471                  */
2472
2473                 /* ScsiLookup initialization
2474                  */
2475                 for (ii=0; ii < hd->ioc->req_depth; ii++)
2476                         hd->ScsiLookup[ii] = NULL;
2477
2478                 /* 2. Chain Buffer initialization
2479                  */
2480
2481                 /* 4. Renegotiate to all devices, if SPI
2482                  */
2483
2484                 /* 5. Enable new commands to be posted
2485                  */
2486                 spin_lock_irqsave(&ioc->FreeQlock, flags);
2487                 hd->tmPending = 0;
2488                 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2489                 hd->resetPending = 0;
2490                 hd->tmState = TM_STATE_NONE;
2491
2492                 /* 6. If there was an internal command,
2493                  * wake this process up.
2494                  */
2495                 if (hd->cmdPtr) {
2496                         /*
2497                          * Wake up the original calling thread
2498                          */
2499                         hd->pLocal = &hd->localReply;
2500                         hd->pLocal->completion = MPT_SCANDV_DID_RESET;
2501                         hd->scandv_wait_done = 1;
2502                         wake_up(&hd->scandv_waitq);
2503                         hd->cmdPtr = NULL;
2504                 }
2505
2506                 /* 7. FC: Rescan for blocked rports which might have returned.
2507                  */
2508                 else if (ioc->bus_type == FC) {
2509                         int work_count;
2510                         unsigned long flags;
2511
2512                         spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
2513                         work_count = ++ioc->fc_rescan_work_count;
2514                         spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
2515                         if (work_count == 1)
2516                                 schedule_work(&ioc->fc_rescan_work);
2517                 }
2518                 dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name));
2519
2520         }
2521
2522         return 1;               /* currently means nothing really */
2523 }
2524
2525 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2526 int
2527 mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2528 {
2529         MPT_SCSI_HOST *hd;
2530         u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
2531         int work_count;
2532         unsigned long flags;
2533
2534         devtprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
2535                         ioc->name, event));
2536
2537         if (ioc->sh == NULL ||
2538                 ((hd = (MPT_SCSI_HOST *)ioc->sh->hostdata) == NULL))
2539                 return 1;
2540
2541         switch (event) {
2542         case MPI_EVENT_UNIT_ATTENTION:                  /* 03 */
2543                 /* FIXME! */
2544                 break;
2545         case MPI_EVENT_IOC_BUS_RESET:                   /* 04 */
2546         case MPI_EVENT_EXT_BUS_RESET:                   /* 05 */
2547                 if (hd && (ioc->bus_type == SPI) && (hd->soft_resets < -1))
2548                         hd->soft_resets++;
2549                 break;
2550         case MPI_EVENT_LOGOUT:                          /* 09 */
2551                 /* FIXME! */
2552                 break;
2553
2554         case MPI_EVENT_RESCAN:                          /* 06 */
2555                 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
2556                 work_count = ++ioc->fc_rescan_work_count;
2557                 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
2558                 if (work_count == 1)
2559                         schedule_work(&ioc->fc_rescan_work);
2560                 break;
2561
2562                 /*
2563                  *  CHECKME! Don't think we need to do
2564                  *  anything for these, but...
2565                  */
2566         case MPI_EVENT_LINK_STATUS_CHANGE:              /* 07 */
2567         case MPI_EVENT_LOOP_STATE_CHANGE:               /* 08 */
2568                 /*
2569                  *  CHECKME!  Falling thru...
2570                  */
2571                 break;
2572
2573         case MPI_EVENT_INTEGRATED_RAID:                 /* 0B */
2574                 break;
2575
2576         case MPI_EVENT_NONE:                            /* 00 */
2577         case MPI_EVENT_LOG_DATA:                        /* 01 */
2578         case MPI_EVENT_STATE_CHANGE:                    /* 02 */
2579         case MPI_EVENT_EVENT_CHANGE:                    /* 0A */
2580         default:
2581                 dprintk((KERN_INFO "  Ignoring event (=%02Xh)\n", event));
2582                 break;
2583         }
2584
2585         return 1;               /* currently means nothing really */
2586 }
2587
2588 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2589 /*
2590  *      mptscsih_initTarget - Target, LUN alloc/free functionality.
2591  *      @hd: Pointer to MPT_SCSI_HOST structure
2592  *      @vtarget: per target private data
2593  *      @sdev: SCSI device
2594  *
2595  *      NOTE: It's only SAFE to call this routine if data points to
2596  *      sane & valid STANDARD INQUIRY data!
2597  *
2598  *      Allocate and initialize memory for this target.
2599  *      Save inquiry data.
2600  *
2601  */
2602 static void
2603 mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget,
2604                     struct scsi_device *sdev)
2605 {
2606         dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n",
2607                 hd->ioc->name, vtarget->bus_id, vtarget->target_id, lun, hd));
2608
2609         /* Is LUN supported? If so, upper 2 bits will be 0
2610         * in first byte of inquiry data.
2611         */
2612         if (sdev->inq_periph_qual != 0)
2613                 return;
2614
2615         if (vtarget == NULL)
2616                 return;
2617
2618         vtarget->type = sdev->type;
2619
2620         if (hd->ioc->bus_type != SPI)
2621                 return;
2622
2623         if ((sdev->type == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) {
2624                 /* Treat all Processors as SAF-TE if
2625                  * command line option is set */
2626                 vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
2627                 mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id);
2628         }else if ((sdev->type == TYPE_PROCESSOR) &&
2629                 !(vtarget->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) {
2630                 if (sdev->inquiry_len > 49 ) {
2631                         if (sdev->inquiry[44] == 'S' &&
2632                             sdev->inquiry[45] == 'A' &&
2633                             sdev->inquiry[46] == 'F' &&
2634                             sdev->inquiry[47] == '-' &&
2635                             sdev->inquiry[48] == 'T' &&
2636                             sdev->inquiry[49] == 'E' ) {
2637                                 vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
2638                                 mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id);
2639                         }
2640                 }
2641         }
2642         mptscsih_setTargetNegoParms(hd, vtarget, sdev);
2643 }
2644
2645 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2646 /*
2647  *  Update the target negotiation parameters based on the
2648  *  the Inquiry data, adapter capabilities, and NVRAM settings.
2649  *
2650  */
2651 static void
2652 mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target,
2653                             struct scsi_device *sdev)
2654 {
2655         SpiCfgData *pspi_data = &hd->ioc->spi_data;
2656         int  id = (int) target->target_id;
2657         int  nvram;
2658         u8 width = MPT_NARROW;
2659         u8 factor = MPT_ASYNC;
2660         u8 offset = 0;
2661         u8 nfactor;
2662         u8 noQas = 1;
2663
2664         target->negoFlags = pspi_data->noQas;
2665
2666         /* noQas == 0 => device supports QAS. */
2667
2668         if (sdev->scsi_level < SCSI_2) {
2669                 width = 0;
2670                 factor = MPT_ULTRA2;
2671                 offset = pspi_data->maxSyncOffset;
2672                 target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
2673         } else {
2674                 if (scsi_device_wide(sdev)) {
2675                         width = 1;
2676                 }
2677
2678                 if (scsi_device_sync(sdev)) {
2679                         factor = pspi_data->minSyncFactor;
2680                         if (!scsi_device_dt(sdev))
2681                                         factor = MPT_ULTRA2;
2682                         else {
2683                                 if (!scsi_device_ius(sdev) &&
2684                                     !scsi_device_qas(sdev))
2685                                         factor = MPT_ULTRA160;
2686                                 else {
2687                                         factor = MPT_ULTRA320;
2688                                         if (scsi_device_qas(sdev)) {
2689                                                 ddvtprintk((KERN_INFO "Enabling QAS due to byte56=%02x on id=%d!\n", byte56, id));
2690                                                 noQas = 0;
2691                                         }
2692                                         if (sdev->type == TYPE_TAPE &&
2693                                             scsi_device_ius(sdev))
2694                                                 target->negoFlags |= MPT_TAPE_NEGO_IDP;
2695                                 }
2696                         }
2697                         offset = pspi_data->maxSyncOffset;
2698
2699                         /* If RAID, never disable QAS
2700                          * else if non RAID, do not disable
2701                          *   QAS if bit 1 is set
2702                          * bit 1 QAS support, non-raid only
2703                          * bit 0 IU support
2704                          */
2705                         if (target->raidVolume == 1) {
2706                                 noQas = 0;
2707                         }
2708                 } else {
2709                         factor = MPT_ASYNC;
2710                         offset = 0;
2711                 }
2712         }
2713
2714         if (!sdev->tagged_supported) {
2715                 target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
2716         }
2717
2718         /* Update tflags based on NVRAM settings. (SCSI only)
2719          */
2720         if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
2721                 nvram = pspi_data->nvram[id];
2722                 nfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
2723
2724                 if (width)
2725                         width = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
2726
2727                 if (offset > 0) {
2728                         /* Ensure factor is set to the
2729                          * maximum of: adapter, nvram, inquiry
2730                          */
2731                         if (nfactor) {
2732                                 if (nfactor < pspi_data->minSyncFactor )
2733                                         nfactor = pspi_data->minSyncFactor;
2734
2735                                 factor = max(factor, nfactor);
2736                                 if (factor == MPT_ASYNC)
2737                                         offset = 0;
2738                         } else {
2739                                 offset = 0;
2740                                 factor = MPT_ASYNC;
2741                 }
2742                 } else {
2743                         factor = MPT_ASYNC;
2744                 }
2745         }
2746
2747         /* Make sure data is consistent
2748          */
2749         if ((!width) && (factor < MPT_ULTRA2)) {
2750                 factor = MPT_ULTRA2;
2751         }
2752
2753         /* Save the data to the target structure.
2754          */
2755         target->minSyncFactor = factor;
2756         target->maxOffset = offset;
2757         target->maxWidth = width;
2758
2759         target->tflags |= MPT_TARGET_FLAGS_VALID_NEGO;
2760
2761         /* Disable unused features.
2762          */
2763         if (!width)
2764                 target->negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
2765
2766         if (!offset)
2767                 target->negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
2768
2769         if ( factor > MPT_ULTRA320 )
2770                 noQas = 0;
2771
2772         if (noQas && (pspi_data->noQas == 0)) {
2773                 pspi_data->noQas |= MPT_TARGET_NO_NEGO_QAS;
2774                 target->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
2775
2776                 /* Disable QAS in a mixed configuration case
2777                  */
2778
2779                 ddvtprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id));
2780         }
2781 }
2782
2783 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2784
2785 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2786 /*
2787  *  SCSI Config Page functionality ...
2788  */
2789
2790 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2791 /*      mptscsih_writeIOCPage4  - write IOC Page 4
2792  *      @hd: Pointer to a SCSI Host Structure
2793  *      @target_id: write IOC Page4 for this ID & Bus
2794  *
2795  *      Return: -EAGAIN if unable to obtain a Message Frame
2796  *              or 0 if success.
2797  *
2798  *      Remark: We do not wait for a return, write pages sequentially.
2799  */
2800 static int
2801 mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus)
2802 {
2803         MPT_ADAPTER             *ioc = hd->ioc;
2804         Config_t                *pReq;
2805         IOCPage4_t              *IOCPage4Ptr;
2806         MPT_FRAME_HDR           *mf;
2807         dma_addr_t               dataDma;
2808         u16                      req_idx;
2809         u32                      frameOffset;
2810         u32                      flagsLength;
2811         int                      ii;
2812
2813         /* Get a MF for this command.
2814          */
2815         if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
2816                 dfailprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n",
2817                                         ioc->name));
2818                 return -EAGAIN;
2819         }
2820
2821         /* Set the request and the data pointers.
2822          * Place data at end of MF.
2823          */
2824         pReq = (Config_t *)mf;
2825
2826         req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2827         frameOffset = ioc->req_sz - sizeof(IOCPage4_t);
2828
2829         /* Complete the request frame (same for all requests).
2830          */
2831         pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
2832         pReq->Reserved = 0;
2833         pReq->ChainOffset = 0;
2834         pReq->Function = MPI_FUNCTION_CONFIG;
2835         pReq->ExtPageLength = 0;
2836         pReq->ExtPageType = 0;
2837         pReq->MsgFlags = 0;
2838         for (ii=0; ii < 8; ii++) {
2839                 pReq->Reserved2[ii] = 0;
2840         }
2841
2842         IOCPage4Ptr = ioc->spi_data.pIocPg4;
2843         dataDma = ioc->spi_data.IocPg4_dma;
2844         ii = IOCPage4Ptr->ActiveSEP++;
2845         IOCPage4Ptr->SEP[ii].SEPTargetID = target_id;
2846         IOCPage4Ptr->SEP[ii].SEPBus = bus;
2847         pReq->Header = IOCPage4Ptr->Header;
2848         pReq->PageAddress = cpu_to_le32(target_id | (bus << 8 ));
2849
2850         /* Add a SGE to the config request.
2851          */
2852         flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE |
2853                 (IOCPage4Ptr->Header.PageLength + ii) * 4;
2854
2855         mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma);
2856
2857         dinitprintk((MYIOC_s_INFO_FMT
2858                 "writeIOCPage4: MaxSEP=%d ActiveSEP=%d id=%d bus=%d\n",
2859                         ioc->name, IOCPage4Ptr->MaxSEP, IOCPage4Ptr->ActiveSEP, target_id, bus));
2860
2861         mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
2862
2863         return 0;
2864 }
2865
2866 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2867 /*
2868  *  Bus Scan and Domain Validation functionality ...
2869  */
2870
2871 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2872 /*
2873  *      mptscsih_scandv_complete - Scan and DV callback routine registered
2874  *      to Fustion MPT (base) driver.
2875  *
2876  *      @ioc: Pointer to MPT_ADAPTER structure
2877  *      @mf: Pointer to original MPT request frame
2878  *      @mr: Pointer to MPT reply frame (NULL if TurboReply)
2879  *
2880  *      This routine is called from mpt.c::mpt_interrupt() at the completion
2881  *      of any SCSI IO request.
2882  *      This routine is registered with the Fusion MPT (base) driver at driver
2883  *      load/init time via the mpt_register() API call.
2884  *
2885  *      Returns 1 indicating alloc'd request frame ptr should be freed.
2886  *
2887  *      Remark: Sets a completion code and (possibly) saves sense data
2888  *      in the IOC member localReply structure.
2889  *      Used ONLY for DV and other internal commands.
2890  */
2891 int
2892 mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
2893 {
2894         MPT_SCSI_HOST   *hd;
2895         SCSIIORequest_t *pReq;
2896         int              completionCode;
2897         u16              req_idx;
2898
2899         hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2900
2901         if ((mf == NULL) ||
2902             (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) {
2903                 printk(MYIOC_s_ERR_FMT
2904                         "ScanDvComplete, %s req frame ptr! (=%p)\n",
2905                                 ioc->name, mf?"BAD":"NULL", (void *) mf);
2906                 goto wakeup;
2907         }
2908
2909         del_timer(&hd->timer);
2910         req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2911         hd->ScsiLookup[req_idx] = NULL;
2912         pReq = (SCSIIORequest_t *) mf;
2913
2914         if (mf != hd->cmdPtr) {
2915                 printk(MYIOC_s_WARN_FMT "ScanDvComplete (mf=%p, cmdPtr=%p, idx=%d)\n",
2916                                 hd->ioc->name, (void *)mf, (void *) hd->cmdPtr, req_idx);
2917         }
2918         hd->cmdPtr = NULL;
2919
2920         ddvprintk((MYIOC_s_INFO_FMT "ScanDvComplete (mf=%p,mr=%p,idx=%d)\n",
2921                         hd->ioc->name, mf, mr, req_idx));
2922
2923         hd->pLocal = &hd->localReply;
2924         hd->pLocal->scsiStatus = 0;
2925
2926         /* If target struct exists, clear sense valid flag.
2927          */
2928         if (mr == NULL) {
2929                 completionCode = MPT_SCANDV_GOOD;
2930         } else {
2931                 SCSIIOReply_t   *pReply;
2932                 u16              status;
2933                 u8               scsi_status;
2934
2935                 pReply = (SCSIIOReply_t *) mr;
2936
2937                 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2938                 scsi_status = pReply->SCSIStatus;
2939
2940                 ddvtprintk((KERN_NOTICE "  IOCStatus=%04xh, SCSIState=%02xh, SCSIStatus=%02xh, IOCLogInfo=%08xh\n",
2941                              status, pReply->SCSIState, scsi_status,
2942                              le32_to_cpu(pReply->IOCLogInfo)));
2943
2944                 switch(status) {
2945
2946                 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE:       /* 0x0043 */
2947                         completionCode = MPT_SCANDV_SELECTION_TIMEOUT;
2948                         break;
2949
2950                 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR:          /* 0x0046 */
2951                 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED:        /* 0x0048 */
2952                 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED:         /* 0x004B */
2953                 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED:         /* 0x004C */
2954                         completionCode = MPT_SCANDV_DID_RESET;
2955                         break;
2956
2957                 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN:          /* 0x0045 */
2958                 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR:        /* 0x0040 */
2959                 case MPI_IOCSTATUS_SUCCESS:                     /* 0x0000 */
2960                         if (pReply->Function == MPI_FUNCTION_CONFIG) {
2961                                 ConfigReply_t *pr = (ConfigReply_t *)mr;
2962                                 completionCode = MPT_SCANDV_GOOD;
2963                                 hd->pLocal->header.PageVersion = pr->Header.PageVersion;
2964                                 hd->pLocal->header.PageLength = pr->Header.PageLength;
2965                                 hd->pLocal->header.PageNumber = pr->Header.PageNumber;
2966                                 hd->pLocal->header.PageType = pr->Header.PageType;
2967
2968                         } else if (pReply->Function == MPI_FUNCTION_RAID_ACTION) {
2969                                 /* If the RAID Volume request is successful,
2970                                  * return GOOD, else indicate that
2971                                  * some type of error occurred.
2972                                  */
2973                                 MpiRaidActionReply_t    *pr = (MpiRaidActionReply_t *)mr;
2974                                 if (le16_to_cpu(pr->ActionStatus) == MPI_RAID_ACTION_ASTATUS_SUCCESS)
2975                                         completionCode = MPT_SCANDV_GOOD;
2976                                 else
2977                                         completionCode = MPT_SCANDV_SOME_ERROR;
2978                                 memcpy(hd->pLocal->sense, pr, sizeof(hd->pLocal->sense));
2979
2980                         } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID) {
2981                                 u8              *sense_data;
2982                                 int              sz;
2983
2984                                 /* save sense data in global structure
2985                                  */
2986                                 completionCode = MPT_SCANDV_SENSE;
2987                                 hd->pLocal->scsiStatus = scsi_status;
2988                                 sense_data = ((u8 *)hd->ioc->sense_buf_pool +
2989                                         (req_idx * MPT_SENSE_BUFFER_ALLOC));
2990
2991                                 sz = min_t(int, pReq->SenseBufferLength,
2992                                                         SCSI_STD_SENSE_BYTES);
2993                                 memcpy(hd->pLocal->sense, sense_data, sz);
2994
2995                                 ddvprintk((KERN_NOTICE "  Check Condition, sense ptr %p\n",
2996                                                 sense_data));
2997                         } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_FAILED) {
2998                                 if (pReq->CDB[0] == INQUIRY)
2999                                         completionCode = MPT_SCANDV_ISSUE_SENSE;
3000                                 else
3001                                         completionCode = MPT_SCANDV_DID_RESET;
3002                         }
3003                         else if (pReply->SCSIState & MPI_SCSI_STATE_NO_SCSI_STATUS)
3004                                 completionCode = MPT_SCANDV_DID_RESET;
3005                         else if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
3006                                 completionCode = MPT_SCANDV_DID_RESET;
3007                         else {
3008                                 completionCode = MPT_SCANDV_GOOD;
3009                                 hd->pLocal->scsiStatus = scsi_status;
3010                         }
3011                         break;
3012
3013                 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR:         /* 0x0047 */
3014                         if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
3015                                 completionCode = MPT_SCANDV_DID_RESET;
3016                         else
3017                                 completionCode = MPT_SCANDV_SOME_ERROR;
3018                         break;
3019
3020                 default:
3021                         completionCode = MPT_SCANDV_SOME_ERROR;
3022                         break;
3023
3024                 }       /* switch(status) */
3025
3026                 ddvtprintk((KERN_NOTICE "  completionCode set to %08xh\n",
3027                                 completionCode));
3028         } /* end of address reply case */
3029
3030         hd->pLocal->completion = completionCode;
3031
3032         /* MF and RF are freed in mpt_interrupt
3033          */
3034 wakeup:
3035         /* Free Chain buffers (will never chain) in scan or dv */
3036         //mptscsih_freeChainBuffers(ioc, req_idx);
3037
3038         /*
3039          * Wake up the original calling thread
3040          */
3041         hd->scandv_wait_done = 1;
3042         wake_up(&hd->scandv_waitq);
3043
3044         return 1;
3045 }
3046
3047 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3048 /*      mptscsih_timer_expired - Call back for timer process.
3049  *      Used only for dv functionality.
3050  *      @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
3051  *
3052  */
3053 void
3054 mptscsih_timer_expired(unsigned long data)
3055 {
3056         MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) data;
3057
3058         ddvprintk((MYIOC_s_WARN_FMT "Timer Expired! Cmd %p\n", hd->ioc->name, hd->cmdPtr));
3059
3060         if (hd->cmdPtr) {
3061                 MPIHeader_t *cmd = (MPIHeader_t *)hd->cmdPtr;
3062
3063                 if (cmd->Function == MPI_FUNCTION_SCSI_IO_REQUEST) {
3064                         /* Desire to issue a task management request here.
3065                          * TM requests MUST be single threaded.
3066                          * If old eh code and no TM current, issue request.
3067                          * If new eh code, do nothing. Wait for OS cmd timeout
3068                          *      for bus reset.
3069                          */
3070                         ddvtprintk((MYIOC_s_NOTE_FMT "DV Cmd Timeout: NoOp\n", hd->ioc->name));
3071                 } else {
3072                         /* Perform a FW reload */
3073                         if (mpt_HardResetHandler(hd->ioc, NO_SLEEP) < 0) {
3074                                 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", hd->ioc->name);
3075                         }
3076                 }
3077         } else {
3078                 /* This should NEVER happen */
3079                 printk(MYIOC_s_WARN_FMT "Null cmdPtr!!!!\n", hd->ioc->name);
3080         }
3081
3082         /* No more processing.
3083          * TM call will generate an interrupt for SCSI TM Management.
3084          * The FW will reply to all outstanding commands, callback will finish cleanup.
3085          * Hard reset clean-up will free all resources.
3086          */
3087         ddvprintk((MYIOC_s_WARN_FMT "Timer Expired Complete!\n", hd->ioc->name));
3088
3089         return;
3090 }
3091
3092
3093 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3094 /**
3095  *      mptscsih_do_cmd - Do internal command.
3096  *      @hd: MPT_SCSI_HOST pointer
3097  *      @io: INTERNAL_CMD pointer.
3098  *
3099  *      Issue the specified internally generated command and do command
3100  *      specific cleanup. For bus scan / DV only.
3101  *      NOTES: If command is Inquiry and status is good,
3102  *      initialize a target structure, save the data
3103  *
3104  *      Remark: Single threaded access only.
3105  *
3106  *      Return:
3107  *              < 0 if an illegal command or no resources
3108  *
3109  *                 0 if good
3110  *
3111  *               > 0 if command complete but some type of completion error.
3112  */
3113 static int
3114 mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
3115 {
3116         MPT_FRAME_HDR   *mf;
3117         SCSIIORequest_t *pScsiReq;
3118         SCSIIORequest_t  ReqCopy;
3119         int              my_idx, ii, dir;
3120         int              rc, cmdTimeout;
3121         int             in_isr;
3122         char             cmdLen;
3123         char             CDB[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
3124         char             cmd = io->cmd;
3125
3126         in_isr = in_interrupt();
3127         if (in_isr) {
3128                 dprintk((MYIOC_s_WARN_FMT "Internal SCSI IO request not allowed in ISR context!\n",
3129                                 hd->ioc->name));
3130                 return -EPERM;
3131         }
3132
3133
3134         /* Set command specific information
3135          */
3136         switch (cmd) {
3137         case INQUIRY:
3138                 cmdLen = 6;
3139                 dir = MPI_SCSIIO_CONTROL_READ;
3140                 CDB[0] = cmd;
3141                 CDB[4] = io->size;
3142                 cmdTimeout = 10;
3143                 break;
3144
3145         case TEST_UNIT_READY:
3146                 cmdLen = 6;
3147                 dir = MPI_SCSIIO_CONTROL_READ;
3148                 cmdTimeout = 10;
3149                 break;
3150
3151         case START_STOP:
3152                 cmdLen = 6;
3153                 dir = MPI_SCSIIO_CONTROL_READ;
3154                 CDB[0] = cmd;
3155                 CDB[4] = 1;     /*Spin up the disk */
3156                 cmdTimeout = 15;
3157                 break;
3158
3159         case REQUEST_SENSE:
3160                 cmdLen = 6;
3161                 CDB[0] = cmd;
3162                 CDB[4] = io->size;
3163                 dir = MPI_SCSIIO_CONTROL_READ;
3164                 cmdTimeout = 10;
3165                 break;
3166
3167         case READ_BUFFER:
3168                 cmdLen = 10;
3169                 dir = MPI_SCSIIO_CONTROL_READ;
3170                 CDB[0] = cmd;
3171                 if (io->flags & MPT_ICFLAG_ECHO) {
3172                         CDB[1] = 0x0A;
3173                 } else {
3174                         CDB[1] = 0x02;
3175                 }
3176
3177                 if (io->flags & MPT_ICFLAG_BUF_CAP) {
3178                         CDB[1] |= 0x01;
3179                 }
3180                 CDB[6] = (io->size >> 16) & 0xFF;
3181                 CDB[7] = (io->size >>  8) & 0xFF;
3182                 CDB[8] = io->size & 0xFF;
3183                 cmdTimeout = 10;
3184                 break;
3185
3186         case WRITE_BUFFER:
3187                 cmdLen = 10;
3188                 dir = MPI_SCSIIO_CONTROL_WRITE;
3189                 CDB[0] = cmd;
3190                 if (io->flags & MPT_ICFLAG_ECHO) {
3191                         CDB[1] = 0x0A;
3192                 } else {
3193                         CDB[1] = 0x02;
3194                 }
3195                 CDB[6] = (io->size >> 16) & 0xFF;
3196                 CDB[7] = (io->size >>  8) & 0xFF;
3197                 CDB[8] = io->size & 0xFF;
3198                 cmdTimeout = 10;
3199                 break;
3200
3201         case RESERVE:
3202                 cmdLen = 6;
3203                 dir = MPI_SCSIIO_CONTROL_READ;
3204                 CDB[0] = cmd;
3205                 cmdTimeout = 10;
3206                 break;
3207
3208         case RELEASE:
3209                 cmdLen = 6;
3210                 dir = MPI_SCSIIO_CONTROL_READ;
3211                 CDB[0] = cmd;
3212                 cmdTimeout = 10;
3213                 break;
3214
3215         case SYNCHRONIZE_CACHE:
3216                 cmdLen = 10;
3217                 dir = MPI_SCSIIO_CONTROL_READ;
3218                 CDB[0] = cmd;
3219 //              CDB[1] = 0x02;  /* set immediate bit */
3220                 cmdTimeout = 10;
3221                 break;
3222
3223         default:
3224                 /* Error Case */
3225                 return -EFAULT;
3226         }
3227
3228         /* Get and Populate a free Frame
3229          */
3230         if ((mf = mpt_get_msg_frame(hd->ioc->InternalCtx, hd->ioc)) == NULL) {
3231                 ddvprintk((MYIOC_s_WARN_FMT "No msg frames!\n",
3232                                         hd->ioc->name));
3233                 return -EBUSY;
3234         }
3235
3236         pScsiReq = (SCSIIORequest_t *) mf;
3237
3238         /* Get the request index */
3239         my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3240         ADD_INDEX_LOG(my_idx); /* for debug */
3241
3242         if (io->flags & MPT_ICFLAG_PHYS_DISK) {
3243                 pScsiReq->TargetID = io->physDiskNum;
3244                 pScsiReq->Bus = 0;
3245                 pScsiReq->ChainOffset = 0;
3246                 pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
3247         } else {
3248                 pScsiReq->TargetID = io->id;
3249                 pScsiReq->Bus = io->bus;
3250                 pScsiReq->ChainOffset = 0;
3251                 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
3252         }
3253
3254         pScsiReq->CDBLength = cmdLen;
3255         pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
3256
3257         pScsiReq->Reserved = 0;
3258
3259         pScsiReq->MsgFlags = mpt_msg_flags();
3260         /* MsgContext set in mpt_get_msg_fram call  */
3261
3262         for (ii=0; ii < 8; ii++)
3263                 pScsiReq->LUN[ii] = 0;
3264         pScsiReq->LUN[1] = io->lun;
3265
3266         if (io->flags & MPT_ICFLAG_TAGGED_CMD)
3267                 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ);
3268         else
3269                 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3270
3271         if (cmd == REQUEST_SENSE) {
3272                 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3273                 ddvprintk((MYIOC_s_INFO_FMT "Untagged! 0x%2x\n",
3274                         hd->ioc->name, cmd));
3275         }
3276
3277         for (ii=0; ii < 16; ii++)
3278                 pScsiReq->CDB[ii] = CDB[ii];
3279
3280         pScsiReq->DataLength = cpu_to_le32(io->size);
3281         pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
3282                                            + (my_idx * MPT_SENSE_BUFFER_ALLOC));
3283
3284         ddvprintk((MYIOC_s_INFO_FMT "Sending Command 0x%x for (%d:%d:%d)\n",
3285                         hd->ioc->name, cmd, io->bus, io->id, io->lun));
3286
3287         if (dir == MPI_SCSIIO_CONTROL_READ) {
3288                 mpt_add_sge((char *) &pScsiReq->SGL,
3289                         MPT_SGE_FLAGS_SSIMPLE_READ | io->size,
3290                         io->data_dma);
3291         } else {
3292                 mpt_add_sge((char *) &pScsiReq->SGL,
3293                         MPT_SGE_FLAGS_SSIMPLE_WRITE | io->size,
3294                         io->data_dma);
3295         }
3296
3297         /* The ISR will free the request frame, but we need
3298          * the information to initialize the target. Duplicate.
3299          */
3300         memcpy(&ReqCopy, pScsiReq, sizeof(SCSIIORequest_t));
3301
3302         /* Issue this command after:
3303          *      finish init
3304          *      add timer
3305          * Wait until the reply has been received
3306          *  ScsiScanDvCtx callback function will
3307          *      set hd->pLocal;
3308          *      set scandv_wait_done and call wake_up
3309          */
3310         hd->pLocal = NULL;
3311         hd->timer.expires = jiffies + HZ*cmdTimeout;
3312         hd->scandv_wait_done = 0;
3313
3314         /* Save cmd pointer, for resource free if timeout or
3315          * FW reload occurs
3316          */
3317         hd->cmdPtr = mf;
3318
3319         add_timer(&hd->timer);
3320         mpt_put_msg_frame(hd->ioc->InternalCtx, hd->ioc, mf);
3321         wait_event(hd->scandv_waitq, hd->scandv_wait_done);
3322
3323         if (hd->pLocal) {
3324                 rc = hd->pLocal->completion;
3325                 hd->pLocal->skip = 0;
3326
3327                 /* Always set fatal error codes in some cases.
3328                  */
3329                 if (rc == MPT_SCANDV_SELECTION_TIMEOUT)
3330                         rc = -ENXIO;
3331                 else if (rc == MPT_SCANDV_SOME_ERROR)
3332                         rc =  -rc;
3333         } else {
3334                 rc = -EFAULT;
3335                 /* This should never happen. */
3336                 ddvprintk((MYIOC_s_INFO_FMT "_do_cmd: Null pLocal!!!\n",
3337                                 hd->ioc->name));
3338         }
3339
3340         return rc;
3341 }
3342
3343 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3344 /**
3345  *      mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
3346  *      @hd: Pointer to a SCSI HOST structure
3347  *      @vtarget: per device private data
3348  *      @lun: lun
3349  *
3350  *      Uses the ISR, but with special processing.
3351  *      MUST be single-threaded.
3352  *
3353  */
3354 static void
3355 mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
3356 {
3357         INTERNAL_CMD             iocmd;
3358
3359         /* Following parameters will not change
3360          * in this routine.
3361          */
3362         iocmd.cmd = SYNCHRONIZE_CACHE;
3363         iocmd.flags = 0;
3364         iocmd.physDiskNum = -1;
3365         iocmd.data = NULL;
3366         iocmd.data_dma = -1;
3367         iocmd.size = 0;
3368         iocmd.rsvd = iocmd.rsvd2 = 0;
3369         iocmd.bus = vdevice->bus_id;
3370         iocmd.id = vdevice->target_id;
3371         iocmd.lun = (u8)vdevice->lun;
3372
3373         if ((vdevice->vtarget->type == TYPE_DISK) &&
3374             (vdevice->configured_lun))
3375                 mptscsih_do_cmd(hd, &iocmd);
3376 }
3377
3378 EXPORT_SYMBOL(mptscsih_remove);
3379 EXPORT_SYMBOL(mptscsih_shutdown);
3380 #ifdef CONFIG_PM
3381 EXPORT_SYMBOL(mptscsih_suspend);
3382 EXPORT_SYMBOL(mptscsih_resume);
3383 #endif
3384 EXPORT_SYMBOL(mptscsih_proc_info);
3385 EXPORT_SYMBOL(mptscsih_info);
3386 EXPORT_SYMBOL(mptscsih_qcmd);
3387 EXPORT_SYMBOL(mptscsih_target_alloc);
3388 EXPORT_SYMBOL(mptscsih_slave_alloc);
3389 EXPORT_SYMBOL(mptscsih_target_destroy);
3390 EXPORT_SYMBOL(mptscsih_slave_destroy);
3391 EXPORT_SYMBOL(mptscsih_slave_configure);
3392 EXPORT_SYMBOL(mptscsih_abort);
3393 EXPORT_SYMBOL(mptscsih_dev_reset);
3394 EXPORT_SYMBOL(mptscsih_bus_reset);
3395 EXPORT_SYMBOL(mptscsih_host_reset);
3396 EXPORT_SYMBOL(mptscsih_bios_param);
3397 EXPORT_SYMBOL(mptscsih_io_done);
3398 EXPORT_SYMBOL(mptscsih_taskmgmt_complete);
3399 EXPORT_SYMBOL(mptscsih_scandv_complete);
3400 EXPORT_SYMBOL(mptscsih_event_process);
3401 EXPORT_SYMBOL(mptscsih_ioc_reset);
3402 EXPORT_SYMBOL(mptscsih_change_queue_depth);
3403 EXPORT_SYMBOL(mptscsih_timer_expired);
3404 EXPORT_SYMBOL(mptscsih_TMHandler);
3405
3406 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/