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