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