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