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