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