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.
6 * Copyright (c) 1999-2005 LSI Logic Corporation
7 * (mailto:mpt_linux_developer@lsil.com)
10 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
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.
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.
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.
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
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
45 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
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>
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>
70 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
71 #define my_NAME "Fusion MPT SCSI Host driver"
72 #define my_VERSION MPT_LINUX_VERSION_COMMON
73 #define MYNAM "mptscsih"
75 MODULE_AUTHOR(MODULEAUTHOR
);
76 MODULE_DESCRIPTION(my_NAME
);
77 MODULE_LICENSE("GPL");
79 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
81 typedef struct _BIG_SENSE_BUF
{
82 u8 data
[MPT_SENSE_BUFFER_ALLOC
];
85 #define MPT_SCANDV_GOOD (0x00000000) /* must be 0 */
86 #define MPT_SCANDV_DID_RESET (0x00000001)
87 #define MPT_SCANDV_SENSE (0x00000002)
88 #define MPT_SCANDV_SOME_ERROR (0x00000004)
89 #define MPT_SCANDV_SELECTION_TIMEOUT (0x00000008)
90 #define MPT_SCANDV_ISSUE_SENSE (0x00000010)
91 #define MPT_SCANDV_FALLBACK (0x00000020)
93 #define MPT_SCANDV_MAX_RETRIES (10)
95 #define MPT_ICFLAG_BUF_CAP 0x01 /* ReadBuffer Read Capacity format */
96 #define MPT_ICFLAG_ECHO 0x02 /* ReadBuffer Echo buffer format */
97 #define MPT_ICFLAG_EBOS 0x04 /* ReadBuffer Echo buffer has EBOS */
98 #define MPT_ICFLAG_PHYS_DISK 0x08 /* Any SCSI IO but do Phys Disk Format */
99 #define MPT_ICFLAG_TAGGED_CMD 0x10 /* Do tagged IO */
100 #define MPT_ICFLAG_DID_RESET 0x20 /* Bus Reset occurred with this command */
101 #define MPT_ICFLAG_RESERVED 0x40 /* Reserved has been issued */
103 typedef struct _internal_cmd
{
104 char *data
; /* data pointer */
105 dma_addr_t data_dma
; /* data dma address */
106 int size
; /* transfer size */
107 u8 cmd
; /* SCSI Op Code */
108 u8 bus
; /* bus number */
109 u8 id
; /* SCSI ID (virtual) */
111 u8 flags
; /* Bit Field - See above */
112 u8 physDiskNum
; /* Phys disk number, -1 else */
118 * Other private/forward protos...
120 int mptscsih_io_done(MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*mf
, MPT_FRAME_HDR
*r
);
121 static void mptscsih_report_queue_full(struct scsi_cmnd
*sc
, SCSIIOReply_t
*pScsiReply
, SCSIIORequest_t
*pScsiReq
);
122 int mptscsih_taskmgmt_complete(MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*mf
, MPT_FRAME_HDR
*r
);
124 static int mptscsih_AddSGE(MPT_ADAPTER
*ioc
, struct scsi_cmnd
*SCpnt
,
125 SCSIIORequest_t
*pReq
, int req_idx
);
126 static void mptscsih_freeChainBuffers(MPT_ADAPTER
*ioc
, int req_idx
);
127 static void mptscsih_copy_sense_data(struct scsi_cmnd
*sc
, MPT_SCSI_HOST
*hd
, MPT_FRAME_HDR
*mf
, SCSIIOReply_t
*pScsiReply
);
128 static int mptscsih_tm_pending_wait(MPT_SCSI_HOST
* hd
);
129 static int mptscsih_tm_wait_for_completion(MPT_SCSI_HOST
* hd
, ulong timeout
);
130 static u32
SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd
*sc
);
132 static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST
*hd
, u8 type
, u8 channel
, u8 target
, u8 lun
, int ctx2abort
, ulong timeout
);
134 int mptscsih_ioc_reset(MPT_ADAPTER
*ioc
, int post_reset
);
135 int mptscsih_event_process(MPT_ADAPTER
*ioc
, EventNotificationReply_t
*pEvReply
);
137 static void mptscsih_initTarget(MPT_SCSI_HOST
*hd
, VirtTarget
*vtarget
, struct scsi_device
*sdev
);
138 static void mptscsih_setTargetNegoParms(MPT_SCSI_HOST
*hd
, VirtTarget
*vtarget
, struct scsi_device
*sdev
);
139 static int mptscsih_writeIOCPage4(MPT_SCSI_HOST
*hd
, int target_id
, int bus
);
140 int mptscsih_scandv_complete(MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*mf
, MPT_FRAME_HDR
*r
);
141 static int mptscsih_do_cmd(MPT_SCSI_HOST
*hd
, INTERNAL_CMD
*iocmd
);
142 static void mptscsih_synchronize_cache(MPT_SCSI_HOST
*hd
, VirtDevice
*vdevice
);
144 void mptscsih_remove(struct pci_dev
*);
145 void mptscsih_shutdown(struct pci_dev
*);
147 int mptscsih_suspend(struct pci_dev
*pdev
, pm_message_t state
);
148 int mptscsih_resume(struct pci_dev
*pdev
);
151 #define SNS_LEN(scp) sizeof((scp)->sense_buffer)
153 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
155 * mptscsih_add_sge - Place a simple SGE at address pAddr.
156 * @pAddr: virtual address for SGE
157 * @flagslength: SGE flags and data transfer length
158 * @dma_addr: Physical address
160 * This routine places a MPT request frame back on the MPT adapter's
164 mptscsih_add_sge(char *pAddr
, u32 flagslength
, dma_addr_t dma_addr
)
166 if (sizeof(dma_addr_t
) == sizeof(u64
)) {
167 SGESimple64_t
*pSge
= (SGESimple64_t
*) pAddr
;
168 u32 tmp
= dma_addr
& 0xFFFFFFFF;
170 pSge
->FlagsLength
= cpu_to_le32(flagslength
);
171 pSge
->Address
.Low
= cpu_to_le32(tmp
);
172 tmp
= (u32
) ((u64
)dma_addr
>> 32);
173 pSge
->Address
.High
= cpu_to_le32(tmp
);
176 SGESimple32_t
*pSge
= (SGESimple32_t
*) pAddr
;
177 pSge
->FlagsLength
= cpu_to_le32(flagslength
);
178 pSge
->Address
= cpu_to_le32(dma_addr
);
180 } /* mptscsih_add_sge() */
182 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
184 * mptscsih_add_chain - Place a chain SGE at address pAddr.
185 * @pAddr: virtual address for SGE
186 * @next: nextChainOffset value (u32's)
187 * @length: length of next SGL segment
188 * @dma_addr: Physical address
190 * This routine places a MPT request frame back on the MPT adapter's
194 mptscsih_add_chain(char *pAddr
, u8 next
, u16 length
, dma_addr_t dma_addr
)
196 if (sizeof(dma_addr_t
) == sizeof(u64
)) {
197 SGEChain64_t
*pChain
= (SGEChain64_t
*) pAddr
;
198 u32 tmp
= dma_addr
& 0xFFFFFFFF;
200 pChain
->Length
= cpu_to_le16(length
);
201 pChain
->Flags
= MPI_SGE_FLAGS_CHAIN_ELEMENT
| mpt_addr_size();
203 pChain
->NextChainOffset
= next
;
205 pChain
->Address
.Low
= cpu_to_le32(tmp
);
206 tmp
= (u32
) ((u64
)dma_addr
>> 32);
207 pChain
->Address
.High
= cpu_to_le32(tmp
);
209 SGEChain32_t
*pChain
= (SGEChain32_t
*) pAddr
;
210 pChain
->Length
= cpu_to_le16(length
);
211 pChain
->Flags
= MPI_SGE_FLAGS_CHAIN_ELEMENT
| mpt_addr_size();
212 pChain
->NextChainOffset
= next
;
213 pChain
->Address
= cpu_to_le32(dma_addr
);
215 } /* mptscsih_add_chain() */
217 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
219 * mptscsih_getFreeChainBuffer - Function to get a free chain
220 * from the MPT_SCSI_HOST FreeChainQ.
221 * @ioc: Pointer to MPT_ADAPTER structure
222 * @req_idx: Index of the SCSI IO request frame. (output)
224 * return SUCCESS or FAILED
227 mptscsih_getFreeChainBuffer(MPT_ADAPTER
*ioc
, int *retIndex
)
229 MPT_FRAME_HDR
*chainBuf
;
234 dsgprintk((MYIOC_s_INFO_FMT
"getFreeChainBuffer called\n",
236 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
237 if (!list_empty(&ioc
->FreeChainQ
)) {
240 chainBuf
= list_entry(ioc
->FreeChainQ
.next
, MPT_FRAME_HDR
,
241 u
.frame
.linkage
.list
);
242 list_del(&chainBuf
->u
.frame
.linkage
.list
);
243 offset
= (u8
*)chainBuf
- (u8
*)ioc
->ChainBuffer
;
244 chain_idx
= offset
/ ioc
->req_sz
;
246 dsgprintk((MYIOC_s_ERR_FMT
"getFreeChainBuffer chainBuf=%p ChainBuffer=%p offset=%d chain_idx=%d\n",
247 ioc
->name
, chainBuf
, ioc
->ChainBuffer
, offset
, chain_idx
));
250 chain_idx
= MPT_HOST_NO_CHAIN
;
251 dfailprintk((MYIOC_s_INFO_FMT
"getFreeChainBuffer failed\n",
254 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
256 *retIndex
= chain_idx
;
258 } /* mptscsih_getFreeChainBuffer() */
260 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
262 * mptscsih_AddSGE - Add a SGE (plus chain buffers) to the
263 * SCSIIORequest_t Message Frame.
264 * @ioc: Pointer to MPT_ADAPTER structure
265 * @SCpnt: Pointer to scsi_cmnd structure
266 * @pReq: Pointer to SCSIIORequest_t structure
271 mptscsih_AddSGE(MPT_ADAPTER
*ioc
, struct scsi_cmnd
*SCpnt
,
272 SCSIIORequest_t
*pReq
, int req_idx
)
276 struct scatterlist
*sg
;
278 int sges_left
, sg_done
;
279 int chain_idx
= MPT_HOST_NO_CHAIN
;
281 int numSgeSlots
, numSgeThisFrame
;
282 u32 sgflags
, sgdir
, thisxfer
= 0;
283 int chain_dma_off
= 0;
289 sgdir
= le32_to_cpu(pReq
->Control
) & MPI_SCSIIO_CONTROL_DATADIRECTION_MASK
;
290 if (sgdir
== MPI_SCSIIO_CONTROL_WRITE
) {
291 sgdir
= MPT_TRANSFER_HOST_TO_IOC
;
293 sgdir
= MPT_TRANSFER_IOC_TO_HOST
;
296 psge
= (char *) &pReq
->SGL
;
297 frm_sz
= ioc
->req_sz
;
299 /* Map the data portion, if any.
300 * sges_left = 0 if no data transfer.
302 if ( (sges_left
= SCpnt
->use_sg
) ) {
303 sges_left
= pci_map_sg(ioc
->pcidev
,
304 (struct scatterlist
*) SCpnt
->request_buffer
,
306 SCpnt
->sc_data_direction
);
309 } else if (SCpnt
->request_bufflen
) {
310 SCpnt
->SCp
.dma_handle
= pci_map_single(ioc
->pcidev
,
311 SCpnt
->request_buffer
,
312 SCpnt
->request_bufflen
,
313 SCpnt
->sc_data_direction
);
314 dsgprintk((MYIOC_s_INFO_FMT
"SG: non-SG for %p, len=%d\n",
315 ioc
->name
, SCpnt
, SCpnt
->request_bufflen
));
316 mptscsih_add_sge((char *) &pReq
->SGL
,
317 0xD1000000|MPT_SGE_FLAGS_ADDRESSING
|sgdir
|SCpnt
->request_bufflen
,
318 SCpnt
->SCp
.dma_handle
);
323 /* Handle the SG case.
325 sg
= (struct scatterlist
*) SCpnt
->request_buffer
;
327 sgeOffset
= sizeof(SCSIIORequest_t
) - sizeof(SGE_IO_UNION
);
330 /* Prior to entering this loop - the following must be set
331 * current MF: sgeOffset (bytes)
332 * chainSge (Null if original MF is not a chain buffer)
333 * sg_done (num SGE done for this MF)
337 numSgeSlots
= ((frm_sz
- sgeOffset
) / (sizeof(u32
) + sizeof(dma_addr_t
)) );
338 numSgeThisFrame
= (sges_left
< numSgeSlots
) ? sges_left
: numSgeSlots
;
340 sgflags
= MPT_SGE_FLAGS_SIMPLE_ELEMENT
| MPT_SGE_FLAGS_ADDRESSING
| sgdir
;
342 /* Get first (num - 1) SG elements
343 * Skip any SG entries with a length of 0
344 * NOTE: at finish, sg and psge pointed to NEXT data/location positions
346 for (ii
=0; ii
< (numSgeThisFrame
-1); ii
++) {
347 thisxfer
= sg_dma_len(sg
);
349 sg
++; /* Get next SG element from the OS */
354 v2
= sg_dma_address(sg
);
355 mptscsih_add_sge(psge
, sgflags
| thisxfer
, v2
);
357 sg
++; /* Get next SG element from the OS */
358 psge
+= (sizeof(u32
) + sizeof(dma_addr_t
));
359 sgeOffset
+= (sizeof(u32
) + sizeof(dma_addr_t
));
363 if (numSgeThisFrame
== sges_left
) {
364 /* Add last element, end of buffer and end of list flags.
366 sgflags
|= MPT_SGE_FLAGS_LAST_ELEMENT
|
367 MPT_SGE_FLAGS_END_OF_BUFFER
|
368 MPT_SGE_FLAGS_END_OF_LIST
;
370 /* Add last SGE and set termination flags.
371 * Note: Last SGE may have a length of 0 - which should be ok.
373 thisxfer
= sg_dma_len(sg
);
375 v2
= sg_dma_address(sg
);
376 mptscsih_add_sge(psge
, sgflags
| thisxfer
, v2
);
379 psge += (sizeof(u32) + sizeof(dma_addr_t));
381 sgeOffset
+= (sizeof(u32
) + sizeof(dma_addr_t
));
385 /* The current buffer is a chain buffer,
386 * but there is not another one.
387 * Update the chain element
388 * Offset and Length fields.
390 mptscsih_add_chain((char *)chainSge
, 0, sgeOffset
, ioc
->ChainBufferDMA
+ chain_dma_off
);
392 /* The current buffer is the original MF
393 * and there is no Chain buffer.
395 pReq
->ChainOffset
= 0;
396 RequestNB
= (((sgeOffset
- 1) >> ioc
->NBShiftFactor
) + 1) & 0x03;
397 dsgprintk((MYIOC_s_INFO_FMT
398 "Single Buffer RequestNB=%x, sgeOffset=%d\n", ioc
->name
, RequestNB
, sgeOffset
));
399 ioc
->RequestNB
[req_idx
] = RequestNB
;
402 /* At least one chain buffer is needed.
403 * Complete the first MF
404 * - last SGE element, set the LastElement bit
405 * - set ChainOffset (words) for orig MF
406 * (OR finish previous MF chain buffer)
407 * - update MFStructPtr ChainIndex
408 * - Populate chain element
413 dsgprintk((MYIOC_s_INFO_FMT
"SG: Chain Required! sg done %d\n",
414 ioc
->name
, sg_done
));
416 /* Set LAST_ELEMENT flag for last non-chain element
417 * in the buffer. Since psge points at the NEXT
418 * SGE element, go back one SGE element, update the flags
419 * and reset the pointer. (Note: sgflags & thisxfer are already
423 u32
*ptmp
= (u32
*) (psge
- (sizeof(u32
) + sizeof(dma_addr_t
)));
424 sgflags
= le32_to_cpu(*ptmp
);
425 sgflags
|= MPT_SGE_FLAGS_LAST_ELEMENT
;
426 *ptmp
= cpu_to_le32(sgflags
);
430 /* The current buffer is a chain buffer.
431 * chainSge points to the previous Chain Element.
432 * Update its chain element Offset and Length (must
433 * include chain element size) fields.
434 * Old chain element is now complete.
436 u8 nextChain
= (u8
) (sgeOffset
>> 2);
437 sgeOffset
+= (sizeof(u32
) + sizeof(dma_addr_t
));
438 mptscsih_add_chain((char *)chainSge
, nextChain
, sgeOffset
, ioc
->ChainBufferDMA
+ chain_dma_off
);
440 /* The original MF buffer requires a chain buffer -
442 * Last element in this MF is a chain element.
444 pReq
->ChainOffset
= (u8
) (sgeOffset
>> 2);
445 RequestNB
= (((sgeOffset
- 1) >> ioc
->NBShiftFactor
) + 1) & 0x03;
446 dsgprintk((MYIOC_s_ERR_FMT
"Chain Buffer Needed, RequestNB=%x sgeOffset=%d\n", ioc
->name
, RequestNB
, sgeOffset
));
447 ioc
->RequestNB
[req_idx
] = RequestNB
;
450 sges_left
-= sg_done
;
453 /* NOTE: psge points to the beginning of the chain element
454 * in current buffer. Get a chain buffer.
456 if ((mptscsih_getFreeChainBuffer(ioc
, &newIndex
)) == FAILED
) {
457 dfailprintk((MYIOC_s_INFO_FMT
458 "getFreeChainBuffer FAILED SCSI cmd=%02x (%p)\n",
459 ioc
->name
, pReq
->CDB
[0], SCpnt
));
463 /* Update the tracking arrays.
464 * If chainSge == NULL, update ReqToChain, else ChainToChain
467 ioc
->ChainToChain
[chain_idx
] = newIndex
;
469 ioc
->ReqToChain
[req_idx
] = newIndex
;
471 chain_idx
= newIndex
;
472 chain_dma_off
= ioc
->req_sz
* chain_idx
;
474 /* Populate the chainSGE for the current buffer.
475 * - Set chain buffer pointer to psge and fill
476 * out the Address and Flags fields.
478 chainSge
= (char *) psge
;
479 dsgprintk((KERN_INFO
" Current buff @ %p (index 0x%x)",
482 /* Start the SGE for the next buffer
484 psge
= (char *) (ioc
->ChainBuffer
+ chain_dma_off
);
488 dsgprintk((KERN_INFO
" Chain buff @ %p (index 0x%x)\n",
491 /* Start the SGE for the next buffer
498 } /* mptscsih_AddSGE() */
500 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
502 * mptscsih_io_done - Main SCSI IO callback routine registered to
503 * Fusion MPT (base) driver
504 * @ioc: Pointer to MPT_ADAPTER structure
505 * @mf: Pointer to original MPT request frame
506 * @r: Pointer to MPT reply frame (NULL if TurboReply)
508 * This routine is called from mpt.c::mpt_interrupt() at the completion
509 * of any SCSI IO request.
510 * This routine is registered with the Fusion MPT (base) driver at driver
511 * load/init time via the mpt_register() API call.
513 * Returns 1 indicating alloc'd request frame ptr should be freed.
516 mptscsih_io_done(MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*mf
, MPT_FRAME_HDR
*mr
)
518 struct scsi_cmnd
*sc
;
520 SCSIIORequest_t
*pScsiReq
;
521 SCSIIOReply_t
*pScsiReply
;
522 u16 req_idx
, req_idx_MR
;
524 hd
= (MPT_SCSI_HOST
*) ioc
->sh
->hostdata
;
526 req_idx
= le16_to_cpu(mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
);
527 req_idx_MR
= (mr
!= NULL
) ?
528 le16_to_cpu(mr
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
) : req_idx
;
529 if ((req_idx
!= req_idx_MR
) ||
530 (mf
->u
.frame
.linkage
.arg1
== 0xdeadbeaf)) {
531 printk(MYIOC_s_ERR_FMT
"Received a mf that was already freed\n",
533 printk (MYIOC_s_ERR_FMT
534 "req_idx=%x req_idx_MR=%x mf=%p mr=%p sc=%p\n",
535 ioc
->name
, req_idx
, req_idx_MR
, mf
, mr
,
536 hd
->ScsiLookup
[req_idx_MR
]);
540 sc
= hd
->ScsiLookup
[req_idx
];
542 MPIHeader_t
*hdr
= (MPIHeader_t
*)mf
;
544 /* Remark: writeSDP1 will use the ScsiDoneCtx
545 * If a SCSI I/O cmd, device disabled by OS and
546 * completion done. Cannot touch sc struct. Just free mem.
548 if (hdr
->Function
== MPI_FUNCTION_SCSI_IO_REQUEST
)
549 printk(MYIOC_s_ERR_FMT
"NULL ScsiCmd ptr!\n",
552 mptscsih_freeChainBuffers(ioc
, req_idx
);
556 sc
->result
= DID_OK
<< 16; /* Set default reply as OK */
557 pScsiReq
= (SCSIIORequest_t
*) mf
;
558 pScsiReply
= (SCSIIOReply_t
*) mr
;
560 if((ioc
->facts
.MsgVersion
>= MPI_VERSION_01_05
) && pScsiReply
){
561 dmfprintk((MYIOC_s_INFO_FMT
562 "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d,task-tag=%d)\n",
563 ioc
->name
, mf
, mr
, sc
, req_idx
, pScsiReply
->TaskTag
));
565 dmfprintk((MYIOC_s_INFO_FMT
566 "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n",
567 ioc
->name
, mf
, mr
, sc
, req_idx
));
570 if (pScsiReply
== NULL
) {
571 /* special context reply handling */
576 u8 scsi_state
, scsi_status
;
578 status
= le16_to_cpu(pScsiReply
->IOCStatus
) & MPI_IOCSTATUS_MASK
;
579 scsi_state
= pScsiReply
->SCSIState
;
580 scsi_status
= pScsiReply
->SCSIStatus
;
581 xfer_cnt
= le32_to_cpu(pScsiReply
->TransferCount
);
582 sc
->resid
= sc
->request_bufflen
- xfer_cnt
;
585 * if we get a data underrun indication, yet no data was
586 * transferred and the SCSI status indicates that the
587 * command was never started, change the data underrun
590 if (status
== MPI_IOCSTATUS_SCSI_DATA_UNDERRUN
&& xfer_cnt
== 0 &&
591 (scsi_status
== MPI_SCSI_STATUS_BUSY
||
592 scsi_status
== MPI_SCSI_STATUS_RESERVATION_CONFLICT
||
593 scsi_status
== MPI_SCSI_STATUS_TASK_SET_FULL
)) {
594 status
= MPI_IOCSTATUS_SUCCESS
;
597 dreplyprintk((KERN_NOTICE
"Reply ha=%d id=%d lun=%d:\n"
598 "IOCStatus=%04xh SCSIState=%02xh SCSIStatus=%02xh\n"
599 "resid=%d bufflen=%d xfer_cnt=%d\n",
600 ioc
->id
, sc
->device
->id
, sc
->device
->lun
,
601 status
, scsi_state
, scsi_status
, sc
->resid
,
602 sc
->request_bufflen
, xfer_cnt
));
604 if (scsi_state
& MPI_SCSI_STATE_AUTOSENSE_VALID
)
605 mptscsih_copy_sense_data(sc
, hd
, mf
, pScsiReply
);
608 * Look for + dump FCP ResponseInfo[]!
610 if (scsi_state
& MPI_SCSI_STATE_RESPONSE_INFO_VALID
&&
611 pScsiReply
->ResponseInfo
) {
612 printk(KERN_NOTICE
"ha=%d id=%d lun=%d: "
613 "FCP_ResponseInfo=%08xh\n",
614 ioc
->id
, sc
->device
->id
, sc
->device
->lun
,
615 le32_to_cpu(pScsiReply
->ResponseInfo
));
619 case MPI_IOCSTATUS_BUSY
: /* 0x0002 */
621 * Maybe: DRIVER_BUSY | SUGGEST_RETRY | DID_SOFT_ERROR (retry)
622 * But not: DID_BUS_BUSY lest one risk
623 * killing interrupt handler:-(
625 sc
->result
= SAM_STAT_BUSY
;
628 case MPI_IOCSTATUS_SCSI_INVALID_BUS
: /* 0x0041 */
629 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID
: /* 0x0042 */
630 sc
->result
= DID_BAD_TARGET
<< 16;
633 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE
: /* 0x0043 */
634 /* Spoof to SCSI Selection Timeout! */
635 if (ioc
->bus_type
!= FC
)
636 sc
->result
= DID_NO_CONNECT
<< 16;
637 /* else fibre, just stall until rescan event */
639 sc
->result
= DID_REQUEUE
<< 16;
641 if (hd
->sel_timeout
[pScsiReq
->TargetID
] < 0xFFFF)
642 hd
->sel_timeout
[pScsiReq
->TargetID
]++;
645 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED
: /* 0x0048 */
646 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED
: /* 0x004B */
647 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED
: /* 0x004C */
648 /* Linux handles an unsolicited DID_RESET better
649 * than an unsolicited DID_ABORT.
651 sc
->result
= DID_RESET
<< 16;
655 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH
: /* 0x0049 */
656 sc
->resid
= sc
->request_bufflen
- xfer_cnt
;
657 if((xfer_cnt
==0)||(sc
->underflow
> xfer_cnt
))
658 sc
->result
=DID_SOFT_ERROR
<< 16;
659 else /* Sufficient data transfer occurred */
660 sc
->result
= (DID_OK
<< 16) | scsi_status
;
661 dreplyprintk((KERN_NOTICE
662 "RESIDUAL_MISMATCH: result=%x on id=%d\n", sc
->result
, sc
->device
->id
));
665 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN
: /* 0x0045 */
667 * Do upfront check for valid SenseData and give it
670 sc
->result
= (DID_OK
<< 16) | scsi_status
;
671 if (scsi_state
& MPI_SCSI_STATE_AUTOSENSE_VALID
) {
672 /* Have already saved the status and sense data
676 if (xfer_cnt
< sc
->underflow
) {
677 if (scsi_status
== SAM_STAT_BUSY
)
678 sc
->result
= SAM_STAT_BUSY
;
680 sc
->result
= DID_SOFT_ERROR
<< 16;
682 if (scsi_state
& (MPI_SCSI_STATE_AUTOSENSE_FAILED
| MPI_SCSI_STATE_NO_SCSI_STATUS
)) {
685 sc
->result
= DID_SOFT_ERROR
<< 16;
687 else if (scsi_state
& MPI_SCSI_STATE_TERMINATED
) {
688 /* Not real sure here either... */
689 sc
->result
= DID_RESET
<< 16;
693 dreplyprintk((KERN_NOTICE
" sc->underflow={report ERR if < %02xh bytes xfer'd}\n",
695 dreplyprintk((KERN_NOTICE
" ActBytesXferd=%02xh\n", xfer_cnt
));
698 if (scsi_status
== MPI_SCSI_STATUS_TASK_SET_FULL
)
699 mptscsih_report_queue_full(sc
, pScsiReply
, pScsiReq
);
703 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN
: /* 0x0044 */
705 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR
: /* 0x0040 */
706 case MPI_IOCSTATUS_SUCCESS
: /* 0x0000 */
707 if (scsi_status
== MPI_SCSI_STATUS_BUSY
)
708 sc
->result
= (DID_BUS_BUSY
<< 16) | scsi_status
;
710 sc
->result
= (DID_OK
<< 16) | scsi_status
;
711 if (scsi_state
== 0) {
713 } else if (scsi_state
& MPI_SCSI_STATE_AUTOSENSE_VALID
) {
715 * If running against circa 200003dd 909 MPT f/w,
716 * may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL
717 * (QUEUE_FULL) returned from device! --> get 0x0000?128
718 * and with SenseBytes set to 0.
720 if (pScsiReply
->SCSIStatus
== MPI_SCSI_STATUS_TASK_SET_FULL
)
721 mptscsih_report_queue_full(sc
, pScsiReply
, pScsiReq
);
724 else if (scsi_state
&
725 (MPI_SCSI_STATE_AUTOSENSE_FAILED
| MPI_SCSI_STATE_NO_SCSI_STATUS
)
730 sc
->result
= DID_SOFT_ERROR
<< 16;
732 else if (scsi_state
& MPI_SCSI_STATE_TERMINATED
) {
733 /* Not real sure here either... */
734 sc
->result
= DID_RESET
<< 16;
736 else if (scsi_state
& MPI_SCSI_STATE_QUEUE_TAG_REJECTED
) {
737 /* Device Inq. data indicates that it supports
738 * QTags, but rejects QTag messages.
739 * This command completed OK.
741 * Not real sure here either so do nothing... */
744 if (sc
->result
== MPI_SCSI_STATUS_TASK_SET_FULL
)
745 mptscsih_report_queue_full(sc
, pScsiReply
, pScsiReq
);
748 * Reservation Conflict, Busy,
749 * Command Terminated, CHECK
753 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR
: /* 0x0047 */
754 sc
->result
= DID_SOFT_ERROR
<< 16;
757 case MPI_IOCSTATUS_INVALID_FUNCTION
: /* 0x0001 */
758 case MPI_IOCSTATUS_INVALID_SGL
: /* 0x0003 */
759 case MPI_IOCSTATUS_INTERNAL_ERROR
: /* 0x0004 */
760 case MPI_IOCSTATUS_RESERVED
: /* 0x0005 */
761 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES
: /* 0x0006 */
762 case MPI_IOCSTATUS_INVALID_FIELD
: /* 0x0007 */
763 case MPI_IOCSTATUS_INVALID_STATE
: /* 0x0008 */
764 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR
: /* 0x0046 */
765 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED
: /* 0x004A */
770 sc
->result
= DID_SOFT_ERROR
<< 16;
773 } /* switch(status) */
775 dreplyprintk((KERN_NOTICE
" sc->result is %08xh\n", sc
->result
));
776 } /* end of address reply case */
778 /* Unmap the DMA buffers, if any. */
780 pci_unmap_sg(ioc
->pcidev
, (struct scatterlist
*) sc
->request_buffer
,
781 sc
->use_sg
, sc
->sc_data_direction
);
782 } else if (sc
->request_bufflen
) {
783 pci_unmap_single(ioc
->pcidev
, sc
->SCp
.dma_handle
,
784 sc
->request_bufflen
, sc
->sc_data_direction
);
787 hd
->ScsiLookup
[req_idx
] = NULL
;
789 sc
->scsi_done(sc
); /* Issue the command callback */
791 /* Free Chain buffers */
792 mptscsih_freeChainBuffers(ioc
, req_idx
);
797 * mptscsih_flush_running_cmds - For each command found, search
798 * Scsi_Host instance taskQ and reply to OS.
799 * Called only if recovering from a FW reload.
800 * @hd: Pointer to a SCSI HOST structure
804 * Must be called while new I/Os are being queued.
807 mptscsih_flush_running_cmds(MPT_SCSI_HOST
*hd
)
809 MPT_ADAPTER
*ioc
= hd
->ioc
;
810 struct scsi_cmnd
*SCpnt
;
813 int max
= ioc
->req_depth
;
815 dprintk((KERN_INFO MYNAM
": flush_ScsiLookup called\n"));
816 for (ii
= 0; ii
< max
; ii
++) {
817 if ((SCpnt
= hd
->ScsiLookup
[ii
]) != NULL
) {
822 /* Null ScsiLookup index
824 hd
->ScsiLookup
[ii
] = NULL
;
826 mf
= MPT_INDEX_2_MFPTR(ioc
, ii
);
827 dmfprintk(( "flush: ScsiDone (mf=%p,sc=%p)\n",
830 /* Set status, free OS resources (SG DMA buffers)
832 * Free driver resources (chain, msg buffers)
835 pci_unmap_sg(ioc
->pcidev
,
836 (struct scatterlist
*) SCpnt
->request_buffer
,
838 SCpnt
->sc_data_direction
);
839 } else if (SCpnt
->request_bufflen
) {
840 pci_unmap_single(ioc
->pcidev
,
841 SCpnt
->SCp
.dma_handle
,
842 SCpnt
->request_bufflen
,
843 SCpnt
->sc_data_direction
);
845 SCpnt
->result
= DID_RESET
<< 16;
846 SCpnt
->host_scribble
= NULL
;
848 /* Free Chain buffers */
849 mptscsih_freeChainBuffers(ioc
, ii
);
851 /* Free Message frames */
852 mpt_free_msg_frame(ioc
, mf
);
854 SCpnt
->scsi_done(SCpnt
); /* Issue the command callback */
862 * mptscsih_search_running_cmds - Delete any commands associated
863 * with the specified target and lun. Function called only
864 * when a lun is disable by mid-layer.
865 * Do NOT access the referenced scsi_cmnd structure or
866 * members. Will cause either a paging or NULL ptr error.
867 * (BUT, BUT, BUT, the code does reference it! - mdr)
868 * @hd: Pointer to a SCSI HOST structure
869 * @vdevice: per device private data
873 * Called from slave_destroy.
876 mptscsih_search_running_cmds(MPT_SCSI_HOST
*hd
, VirtDevice
*vdevice
)
878 SCSIIORequest_t
*mf
= NULL
;
880 int max
= hd
->ioc
->req_depth
;
881 struct scsi_cmnd
*sc
;
883 dsprintk((KERN_INFO MYNAM
": search_running target %d lun %d max %d\n",
884 vdevice
->vtarget
->target_id
, vdevice
->lun
, max
));
886 for (ii
=0; ii
< max
; ii
++) {
887 if ((sc
= hd
->ScsiLookup
[ii
]) != NULL
) {
889 mf
= (SCSIIORequest_t
*)MPT_INDEX_2_MFPTR(hd
->ioc
, ii
);
891 dsprintk(( "search_running: found (sc=%p, mf = %p) target %d, lun %d \n",
892 hd
->ScsiLookup
[ii
], mf
, mf
->TargetID
, mf
->LUN
[1]));
894 if ((mf
->TargetID
!= ((u8
)vdevice
->vtarget
->target_id
)) || (mf
->LUN
[1] != ((u8
) vdevice
->lun
)))
899 hd
->ScsiLookup
[ii
] = NULL
;
900 mptscsih_freeChainBuffers(hd
->ioc
, ii
);
901 mpt_free_msg_frame(hd
->ioc
, (MPT_FRAME_HDR
*)mf
);
903 pci_unmap_sg(hd
->ioc
->pcidev
,
904 (struct scatterlist
*) sc
->request_buffer
,
906 sc
->sc_data_direction
);
907 } else if (sc
->request_bufflen
) {
908 pci_unmap_single(hd
->ioc
->pcidev
,
911 sc
->sc_data_direction
);
913 sc
->host_scribble
= NULL
;
914 sc
->result
= DID_NO_CONNECT
<< 16;
921 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
923 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
925 * mptscsih_report_queue_full - Report QUEUE_FULL status returned
926 * from a SCSI target device.
927 * @sc: Pointer to scsi_cmnd structure
928 * @pScsiReply: Pointer to SCSIIOReply_t
929 * @pScsiReq: Pointer to original SCSI request
931 * This routine periodically reports QUEUE_FULL status returned from a
932 * SCSI target device. It reports this to the console via kernel
933 * printk() API call, not more than once every 10 seconds.
936 mptscsih_report_queue_full(struct scsi_cmnd
*sc
, SCSIIOReply_t
*pScsiReply
, SCSIIORequest_t
*pScsiReq
)
941 if (sc
->device
== NULL
)
943 if (sc
->device
->host
== NULL
)
945 if ((hd
= (MPT_SCSI_HOST
*)sc
->device
->host
->hostdata
) == NULL
)
948 if (time
- hd
->last_queue_full
> 10 * HZ
) {
949 dprintk((MYIOC_s_WARN_FMT
"Device (%d:%d:%d) reported QUEUE_FULL!\n",
950 hd
->ioc
->name
, 0, sc
->device
->id
, sc
->device
->lun
));
951 hd
->last_queue_full
= time
;
955 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
957 * mptscsih_remove - Removed scsi devices
958 * @pdev: Pointer to pci_dev structure
963 mptscsih_remove(struct pci_dev
*pdev
)
965 MPT_ADAPTER
*ioc
= pci_get_drvdata(pdev
);
966 struct Scsi_Host
*host
= ioc
->sh
;
975 scsi_remove_host(host
);
977 if((hd
= (MPT_SCSI_HOST
*)host
->hostdata
) == NULL
)
980 mptscsih_shutdown(pdev
);
984 if (hd
->ScsiLookup
!= NULL
) {
985 sz1
= hd
->ioc
->req_depth
* sizeof(void *);
986 kfree(hd
->ScsiLookup
);
987 hd
->ScsiLookup
= NULL
;
991 * Free pointer array.
996 dprintk((MYIOC_s_INFO_FMT
997 "Free'd ScsiLookup (%d) memory\n",
998 hd
->ioc
->name
, sz1
));
1000 kfree(hd
->info_kbuf
);
1002 /* NULL the Scsi_Host pointer
1006 scsi_host_put(host
);
1012 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1014 * mptscsih_shutdown - reboot notifier
1018 mptscsih_shutdown(struct pci_dev
*pdev
)
1020 MPT_ADAPTER
*ioc
= pci_get_drvdata(pdev
);
1021 struct Scsi_Host
*host
= ioc
->sh
;
1027 hd
= (MPT_SCSI_HOST
*)host
->hostdata
;
1032 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1034 * mptscsih_suspend - Fusion MPT scsi driver suspend routine.
1039 mptscsih_suspend(struct pci_dev
*pdev
, pm_message_t state
)
1041 mptscsih_shutdown(pdev
);
1042 return mpt_suspend(pdev
,state
);
1045 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1047 * mptscsih_resume - Fusion MPT scsi driver resume routine.
1052 mptscsih_resume(struct pci_dev
*pdev
)
1054 MPT_ADAPTER
*ioc
= pci_get_drvdata(pdev
);
1055 struct Scsi_Host
*host
= ioc
->sh
;
1063 hd
= (MPT_SCSI_HOST
*)host
->hostdata
;
1072 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1074 * mptscsih_info - Return information about MPT adapter
1075 * @SChost: Pointer to Scsi_Host structure
1077 * (linux scsi_host_template.info routine)
1079 * Returns pointer to buffer where information was written.
1082 mptscsih_info(struct Scsi_Host
*SChost
)
1087 h
= (MPT_SCSI_HOST
*)SChost
->hostdata
;
1090 if (h
->info_kbuf
== NULL
)
1091 if ((h
->info_kbuf
= kmalloc(0x1000 /* 4Kb */, GFP_KERNEL
)) == NULL
)
1092 return h
->info_kbuf
;
1093 h
->info_kbuf
[0] = '\0';
1095 mpt_print_ioc_summary(h
->ioc
, h
->info_kbuf
, &size
, 0, 0);
1096 h
->info_kbuf
[size
-1] = '\0';
1099 return h
->info_kbuf
;
1110 mptscsih_copy_mem_info(struct info_str
*info
, char *data
, int len
)
1112 if (info
->pos
+ len
> info
->length
)
1113 len
= info
->length
- info
->pos
;
1115 if (info
->pos
+ len
< info
->offset
) {
1120 if (info
->pos
< info
->offset
) {
1121 data
+= (info
->offset
- info
->pos
);
1122 len
-= (info
->offset
- info
->pos
);
1126 memcpy(info
->buffer
+ info
->pos
, data
, len
);
1132 mptscsih_copy_info(struct info_str
*info
, char *fmt
, ...)
1138 va_start(args
, fmt
);
1139 len
= vsprintf(buf
, fmt
, args
);
1142 mptscsih_copy_mem_info(info
, buf
, len
);
1147 mptscsih_host_info(MPT_ADAPTER
*ioc
, char *pbuf
, off_t offset
, int len
)
1149 struct info_str info
;
1153 info
.offset
= offset
;
1156 mptscsih_copy_info(&info
, "%s: %s, ", ioc
->name
, ioc
->prod_name
);
1157 mptscsih_copy_info(&info
, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING
, ioc
->facts
.FWVersion
.Word
);
1158 mptscsih_copy_info(&info
, "Ports=%d, ", ioc
->facts
.NumberOfPorts
);
1159 mptscsih_copy_info(&info
, "MaxQ=%d\n", ioc
->req_depth
);
1161 return ((info
.pos
> info
.offset
) ? info
.pos
- info
.offset
: 0);
1164 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1166 * mptscsih_proc_info - Return information about MPT adapter
1168 * (linux scsi_host_template.info routine)
1170 * buffer: if write, user data; if read, buffer for user
1171 * length: if write, return length;
1172 * offset: if write, 0; if read, the current offset into the buffer from
1173 * the previous read.
1174 * hostno: scsi host number
1175 * func: if write = 1; if read = 0
1178 mptscsih_proc_info(struct Scsi_Host
*host
, char *buffer
, char **start
, off_t offset
,
1179 int length
, int func
)
1181 MPT_SCSI_HOST
*hd
= (MPT_SCSI_HOST
*)host
->hostdata
;
1182 MPT_ADAPTER
*ioc
= hd
->ioc
;
1187 * write is not supported
1193 size
= mptscsih_host_info(ioc
, buffer
, offset
, length
);
1199 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1200 #define ADD_INDEX_LOG(req_ent) do { } while(0)
1202 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1204 * mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine.
1205 * @SCpnt: Pointer to scsi_cmnd structure
1206 * @done: Pointer SCSI mid-layer IO completion function
1208 * (linux scsi_host_template.queuecommand routine)
1209 * This is the primary SCSI IO start routine. Create a MPI SCSIIORequest
1210 * from a linux scsi_cmnd request and send it to the IOC.
1212 * Returns 0. (rtn value discarded by linux scsi mid-layer)
1215 mptscsih_qcmd(struct scsi_cmnd
*SCpnt
, void (*done
)(struct scsi_cmnd
*))
1219 SCSIIORequest_t
*pScsiReq
;
1220 VirtDevice
*vdev
= SCpnt
->device
->hostdata
;
1229 hd
= (MPT_SCSI_HOST
*) SCpnt
->device
->host
->hostdata
;
1230 lun
= SCpnt
->device
->lun
;
1231 SCpnt
->scsi_done
= done
;
1233 dmfprintk((MYIOC_s_INFO_FMT
"qcmd: SCpnt=%p, done()=%p\n",
1234 (hd
&& hd
->ioc
) ? hd
->ioc
->name
: "ioc?", SCpnt
, done
));
1236 if (hd
->resetPending
) {
1237 dtmprintk((MYIOC_s_WARN_FMT
"qcmd: SCpnt=%p timeout + 60HZ\n",
1238 (hd
&& hd
->ioc
) ? hd
->ioc
->name
: "ioc?", SCpnt
));
1239 return SCSI_MLQUEUE_HOST_BUSY
;
1242 if ((hd
->ioc
->bus_type
== SPI
) &&
1243 vdev
->vtarget
->tflags
& MPT_TARGET_FLAGS_RAID_COMPONENT
&&
1244 mptscsih_raid_id_to_num(hd
, SCpnt
->device
->id
) < 0) {
1245 SCpnt
->result
= DID_NO_CONNECT
<< 16;
1251 * Put together a MPT SCSI request...
1253 if ((mf
= mpt_get_msg_frame(hd
->ioc
->DoneCtx
, hd
->ioc
)) == NULL
) {
1254 dprintk((MYIOC_s_WARN_FMT
"QueueCmd, no msg frames!!\n",
1256 return SCSI_MLQUEUE_HOST_BUSY
;
1259 pScsiReq
= (SCSIIORequest_t
*) mf
;
1261 my_idx
= le16_to_cpu(mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
);
1263 ADD_INDEX_LOG(my_idx
);
1265 /* TUR's being issued with scsictl=0x02000000 (DATA_IN)!
1266 * Seems we may receive a buffer (datalen>0) even when there
1267 * will be no data transfer! GRRRRR...
1269 if (SCpnt
->sc_data_direction
== DMA_FROM_DEVICE
) {
1270 datalen
= SCpnt
->request_bufflen
;
1271 scsidir
= MPI_SCSIIO_CONTROL_READ
; /* DATA IN (host<--ioc<--dev) */
1272 } else if (SCpnt
->sc_data_direction
== DMA_TO_DEVICE
) {
1273 datalen
= SCpnt
->request_bufflen
;
1274 scsidir
= MPI_SCSIIO_CONTROL_WRITE
; /* DATA OUT (host-->ioc-->dev) */
1277 scsidir
= MPI_SCSIIO_CONTROL_NODATATRANSFER
;
1280 /* Default to untagged. Once a target structure has been allocated,
1281 * use the Inquiry data to determine if device supports tagged.
1284 && (vdev
->vtarget
->tflags
& MPT_TARGET_FLAGS_Q_YES
)
1285 && (SCpnt
->device
->tagged_supported
)) {
1286 scsictl
= scsidir
| MPI_SCSIIO_CONTROL_SIMPLEQ
;
1288 scsictl
= scsidir
| MPI_SCSIIO_CONTROL_UNTAGGED
;
1291 /* Use the above information to set up the message frame
1293 pScsiReq
->TargetID
= (u8
) vdev
->vtarget
->target_id
;
1294 pScsiReq
->Bus
= vdev
->vtarget
->bus_id
;
1295 pScsiReq
->ChainOffset
= 0;
1296 if (vdev
->vtarget
->tflags
& MPT_TARGET_FLAGS_RAID_COMPONENT
)
1297 pScsiReq
->Function
= MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH
;
1299 pScsiReq
->Function
= MPI_FUNCTION_SCSI_IO_REQUEST
;
1300 pScsiReq
->CDBLength
= SCpnt
->cmd_len
;
1301 pScsiReq
->SenseBufferLength
= MPT_SENSE_BUFFER_SIZE
;
1302 pScsiReq
->Reserved
= 0;
1303 pScsiReq
->MsgFlags
= mpt_msg_flags();
1304 pScsiReq
->LUN
[0] = 0;
1305 pScsiReq
->LUN
[1] = lun
;
1306 pScsiReq
->LUN
[2] = 0;
1307 pScsiReq
->LUN
[3] = 0;
1308 pScsiReq
->LUN
[4] = 0;
1309 pScsiReq
->LUN
[5] = 0;
1310 pScsiReq
->LUN
[6] = 0;
1311 pScsiReq
->LUN
[7] = 0;
1312 pScsiReq
->Control
= cpu_to_le32(scsictl
);
1315 * Write SCSI CDB into the message
1317 cmd_len
= SCpnt
->cmd_len
;
1318 for (ii
=0; ii
< cmd_len
; ii
++)
1319 pScsiReq
->CDB
[ii
] = SCpnt
->cmnd
[ii
];
1321 for (ii
=cmd_len
; ii
< 16; ii
++)
1322 pScsiReq
->CDB
[ii
] = 0;
1325 pScsiReq
->DataLength
= cpu_to_le32(datalen
);
1327 /* SenseBuffer low address */
1328 pScsiReq
->SenseBufferLowAddr
= cpu_to_le32(hd
->ioc
->sense_buf_low_dma
1329 + (my_idx
* MPT_SENSE_BUFFER_ALLOC
));
1331 /* Now add the SG list
1332 * Always have a SGE even if null length.
1335 /* Add a NULL SGE */
1336 mptscsih_add_sge((char *)&pScsiReq
->SGL
, MPT_SGE_FLAGS_SSIMPLE_READ
| 0,
1339 /* Add a 32 or 64 bit SGE */
1340 if (mptscsih_AddSGE(hd
->ioc
, SCpnt
, pScsiReq
, my_idx
) != SUCCESS
)
1344 hd
->ScsiLookup
[my_idx
] = SCpnt
;
1345 SCpnt
->host_scribble
= NULL
;
1347 mpt_put_msg_frame(hd
->ioc
->DoneCtx
, hd
->ioc
, mf
);
1348 dmfprintk((MYIOC_s_INFO_FMT
"Issued SCSI cmd (%p) mf=%p idx=%d\n",
1349 hd
->ioc
->name
, SCpnt
, mf
, my_idx
));
1350 DBG_DUMP_REQUEST_FRAME(mf
)
1354 hd
->ScsiLookup
[my_idx
] = NULL
;
1355 mptscsih_freeChainBuffers(hd
->ioc
, my_idx
);
1356 mpt_free_msg_frame(hd
->ioc
, mf
);
1357 return SCSI_MLQUEUE_HOST_BUSY
;
1360 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1362 * mptscsih_freeChainBuffers - Function to free chain buffers associated
1363 * with a SCSI IO request
1364 * @hd: Pointer to the MPT_SCSI_HOST instance
1365 * @req_idx: Index of the SCSI IO request frame.
1367 * Called if SG chain buffer allocation fails and mptscsih callbacks.
1371 mptscsih_freeChainBuffers(MPT_ADAPTER
*ioc
, int req_idx
)
1373 MPT_FRAME_HDR
*chain
;
1374 unsigned long flags
;
1378 /* Get the first chain index and reset
1381 chain_idx
= ioc
->ReqToChain
[req_idx
];
1382 ioc
->ReqToChain
[req_idx
] = MPT_HOST_NO_CHAIN
;
1384 while (chain_idx
!= MPT_HOST_NO_CHAIN
) {
1386 /* Save the next chain buffer index */
1387 next
= ioc
->ChainToChain
[chain_idx
];
1389 /* Free this chain buffer and reset
1392 ioc
->ChainToChain
[chain_idx
] = MPT_HOST_NO_CHAIN
;
1394 chain
= (MPT_FRAME_HDR
*) (ioc
->ChainBuffer
1395 + (chain_idx
* ioc
->req_sz
));
1397 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
1398 list_add_tail(&chain
->u
.frame
.linkage
.list
, &ioc
->FreeChainQ
);
1399 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
1401 dmfprintk((MYIOC_s_INFO_FMT
"FreeChainBuffers (index %d)\n",
1402 ioc
->name
, chain_idx
));
1410 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1415 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1417 * mptscsih_TMHandler - Generic handler for SCSI Task Management.
1418 * Fall through to mpt_HardResetHandler if: not operational, too many
1419 * failed TM requests or handshake failure.
1421 * @ioc: Pointer to MPT_ADAPTER structure
1422 * @type: Task Management type
1423 * @target: Logical Target ID for reset (if appropriate)
1424 * @lun: Logical Unit for reset (if appropriate)
1425 * @ctx2abort: Context for the task to be aborted (if appropriate)
1427 * Remark: Currently invoked from a non-interrupt thread (_bh).
1429 * Remark: With old EH code, at most 1 SCSI TaskMgmt function per IOC
1432 * Returns 0 for SUCCESS or -1 if FAILED.
1435 mptscsih_TMHandler(MPT_SCSI_HOST
*hd
, u8 type
, u8 channel
, u8 target
, u8 lun
, int ctx2abort
, ulong timeout
)
1441 unsigned long flags
;
1443 /* If FW is being reloaded currently, return success to
1444 * the calling function.
1451 printk(KERN_ERR MYNAM
" TMHandler" " NULL ioc!\n");
1454 dtmprintk((MYIOC_s_INFO_FMT
"TMHandler Entered!\n", ioc
->name
));
1456 // SJR - CHECKME - Can we avoid this here?
1457 // (mpt_HardResetHandler has this check...)
1458 spin_lock_irqsave(&ioc
->diagLock
, flags
);
1459 if ((ioc
->diagPending
) || (ioc
->alt_ioc
&& ioc
->alt_ioc
->diagPending
)) {
1460 spin_unlock_irqrestore(&ioc
->diagLock
, flags
);
1463 spin_unlock_irqrestore(&ioc
->diagLock
, flags
);
1465 /* Wait a fixed amount of time for the TM pending flag to be cleared.
1466 * If we time out and not bus reset, then we return a FAILED status to the caller.
1467 * The call to mptscsih_tm_pending_wait() will set the pending flag if we are
1468 * successful. Otherwise, reload the FW.
1470 if (mptscsih_tm_pending_wait(hd
) == FAILED
) {
1471 if (type
== MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK
) {
1472 dtmprintk((KERN_INFO MYNAM
": %s: TMHandler abort: "
1473 "Timed out waiting for last TM (%d) to complete! \n",
1474 hd
->ioc
->name
, hd
->tmPending
));
1476 } else if (type
== MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET
) {
1477 dtmprintk((KERN_INFO MYNAM
": %s: TMHandler target reset: "
1478 "Timed out waiting for last TM (%d) to complete! \n",
1479 hd
->ioc
->name
, hd
->tmPending
));
1481 } else if (type
== MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS
) {
1482 dtmprintk((KERN_INFO MYNAM
": %s: TMHandler bus reset: "
1483 "Timed out waiting for last TM (%d) to complete! \n",
1484 hd
->ioc
->name
, hd
->tmPending
));
1485 if (hd
->tmPending
& (1 << MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS
))
1491 spin_lock_irqsave(&hd
->ioc
->FreeQlock
, flags
);
1492 hd
->tmPending
|= (1 << type
);
1493 spin_unlock_irqrestore(&hd
->ioc
->FreeQlock
, flags
);
1498 ioc_raw_state
= mpt_GetIocState(hd
->ioc
, 0);
1500 #ifdef MPT_DEBUG_RESET
1501 if ((ioc_raw_state
& MPI_IOC_STATE_MASK
) != MPI_IOC_STATE_OPERATIONAL
) {
1502 printk(MYIOC_s_WARN_FMT
1503 "TM Handler: IOC Not operational(0x%x)!\n",
1504 hd
->ioc
->name
, ioc_raw_state
);
1508 if (doTask
&& ((ioc_raw_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_OPERATIONAL
)
1509 && !(ioc_raw_state
& MPI_DOORBELL_ACTIVE
)) {
1511 /* Isse the Task Mgmt request.
1513 if (hd
->hard_resets
< -1)
1515 rc
= mptscsih_IssueTaskMgmt(hd
, type
, channel
, target
, lun
, ctx2abort
, timeout
);
1517 printk(MYIOC_s_INFO_FMT
"Issue of TaskMgmt failed!\n", hd
->ioc
->name
);
1519 dtmprintk((MYIOC_s_INFO_FMT
"Issue of TaskMgmt Successful!\n", hd
->ioc
->name
));
1523 /* Only fall through to the HRH if this is a bus reset
1525 if ((type
== MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS
) && (rc
||
1526 ioc
->reload_fw
|| (ioc
->alt_ioc
&& ioc
->alt_ioc
->reload_fw
))) {
1527 dtmprintk((MYIOC_s_INFO_FMT
"Calling HardReset! \n",
1529 rc
= mpt_HardResetHandler(hd
->ioc
, CAN_SLEEP
);
1532 dtmprintk((MYIOC_s_INFO_FMT
"TMHandler rc = %d!\n", hd
->ioc
->name
, rc
));
1538 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1540 * mptscsih_IssueTaskMgmt - Generic send Task Management function.
1541 * @hd: Pointer to MPT_SCSI_HOST structure
1542 * @type: Task Management type
1543 * @target: Logical Target ID for reset (if appropriate)
1544 * @lun: Logical Unit for reset (if appropriate)
1545 * @ctx2abort: Context for the task to be aborted (if appropriate)
1547 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
1548 * or a non-interrupt thread. In the former, must not call schedule().
1550 * Not all fields are meaningfull for all task types.
1552 * Returns 0 for SUCCESS, -999 for "no msg frames",
1553 * else other non-zero value returned.
1556 mptscsih_IssueTaskMgmt(MPT_SCSI_HOST
*hd
, u8 type
, u8 channel
, u8 target
, u8 lun
, int ctx2abort
, ulong timeout
)
1559 SCSITaskMgmt_t
*pScsiTm
;
1563 /* Return Fail to calling function if no message frames available.
1565 if ((mf
= mpt_get_msg_frame(hd
->ioc
->TaskCtx
, hd
->ioc
)) == NULL
) {
1566 dfailprintk((MYIOC_s_ERR_FMT
"IssueTaskMgmt, no msg frames!!\n",
1570 dtmprintk((MYIOC_s_INFO_FMT
"IssueTaskMgmt request @ %p\n",
1571 hd
->ioc
->name
, mf
));
1573 /* Format the Request
1575 pScsiTm
= (SCSITaskMgmt_t
*) mf
;
1576 pScsiTm
->TargetID
= target
;
1577 pScsiTm
->Bus
= channel
;
1578 pScsiTm
->ChainOffset
= 0;
1579 pScsiTm
->Function
= MPI_FUNCTION_SCSI_TASK_MGMT
;
1581 pScsiTm
->Reserved
= 0;
1582 pScsiTm
->TaskType
= type
;
1583 pScsiTm
->Reserved1
= 0;
1584 pScsiTm
->MsgFlags
= (type
== MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS
)
1585 ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION
: 0;
1587 for (ii
= 0; ii
< 8; ii
++) {
1588 pScsiTm
->LUN
[ii
] = 0;
1590 pScsiTm
->LUN
[1] = lun
;
1592 for (ii
=0; ii
< 7; ii
++)
1593 pScsiTm
->Reserved2
[ii
] = 0;
1595 pScsiTm
->TaskMsgContext
= ctx2abort
;
1597 dtmprintk((MYIOC_s_INFO_FMT
"IssueTaskMgmt: ctx2abort (0x%08x) type=%d\n",
1598 hd
->ioc
->name
, ctx2abort
, type
));
1600 DBG_DUMP_TM_REQUEST_FRAME((u32
*)pScsiTm
);
1602 if ((retval
= mpt_send_handshake_request(hd
->ioc
->TaskCtx
, hd
->ioc
,
1603 sizeof(SCSITaskMgmt_t
), (u32
*)pScsiTm
,
1605 dfailprintk((MYIOC_s_ERR_FMT
"_send_handshake FAILED!"
1606 " (hd %p, ioc %p, mf %p) \n", hd
->ioc
->name
, hd
,
1608 mpt_free_msg_frame(hd
->ioc
, mf
);
1612 if(mptscsih_tm_wait_for_completion(hd
, timeout
) == FAILED
) {
1613 dfailprintk((MYIOC_s_ERR_FMT
"_wait_for_completion FAILED!"
1614 " (hd %p, ioc %p, mf %p) \n", hd
->ioc
->name
, hd
,
1616 mpt_free_msg_frame(hd
->ioc
, mf
);
1617 dtmprintk((MYIOC_s_INFO_FMT
"Calling HardReset! \n",
1619 retval
= mpt_HardResetHandler(hd
->ioc
, CAN_SLEEP
);
1626 mptscsih_get_tm_timeout(MPT_ADAPTER
*ioc
)
1628 switch (ioc
->bus_type
) {
1639 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1641 * mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant
1642 * @SCpnt: Pointer to scsi_cmnd structure, IO to be aborted
1644 * (linux scsi_host_template.eh_abort_handler routine)
1646 * Returns SUCCESS or FAILED.
1649 mptscsih_abort(struct scsi_cmnd
* SCpnt
)
1658 /* If we can't locate our host adapter structure, return FAILED status.
1660 if ((hd
= (MPT_SCSI_HOST
*) SCpnt
->device
->host
->hostdata
) == NULL
) {
1661 SCpnt
->result
= DID_RESET
<< 16;
1662 SCpnt
->scsi_done(SCpnt
);
1663 dfailprintk((KERN_INFO MYNAM
": mptscsih_abort: "
1664 "Can't locate host! (sc=%p)\n",
1669 /* Find this command
1671 if ((scpnt_idx
= SCPNT_TO_LOOKUP_IDX(SCpnt
)) < 0) {
1672 /* Cmd not found in ScsiLookup.
1675 SCpnt
->result
= DID_RESET
<< 16;
1676 dtmprintk((KERN_INFO MYNAM
": %s: mptscsih_abort: "
1677 "Command not in the active list! (sc=%p)\n",
1678 hd
->ioc
->name
, SCpnt
));
1682 if (hd
->resetPending
) {
1686 if (hd
->timeouts
< -1)
1689 printk(KERN_WARNING MYNAM
": %s: attempting task abort! (sc=%p)\n",
1690 hd
->ioc
->name
, SCpnt
);
1691 scsi_print_command(SCpnt
);
1693 /* Most important! Set TaskMsgContext to SCpnt's MsgContext!
1694 * (the IO to be ABORT'd)
1696 * NOTE: Since we do not byteswap MsgContext, we do not
1697 * swap it here either. It is an opaque cookie to
1698 * the controller, so it does not matter. -DaveM
1700 mf
= MPT_INDEX_2_MFPTR(hd
->ioc
, scpnt_idx
);
1701 ctx2abort
= mf
->u
.frame
.hwhdr
.msgctxu
.MsgContext
;
1703 hd
->abortSCpnt
= SCpnt
;
1705 vdev
= SCpnt
->device
->hostdata
;
1706 retval
= mptscsih_TMHandler(hd
, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK
,
1707 vdev
->vtarget
->bus_id
, vdev
->vtarget
->target_id
, vdev
->lun
,
1708 ctx2abort
, mptscsih_get_tm_timeout(hd
->ioc
));
1710 printk (KERN_WARNING MYNAM
": %s: task abort: %s (sc=%p)\n",
1712 ((retval
== 0) ? "SUCCESS" : "FAILED" ), SCpnt
);
1717 if(retval
!= FAILED
) {
1719 hd
->tmState
= TM_STATE_NONE
;
1724 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1726 * mptscsih_dev_reset - Perform a SCSI TARGET_RESET! new_eh variant
1727 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1729 * (linux scsi_host_template.eh_dev_reset_handler routine)
1731 * Returns SUCCESS or FAILED.
1734 mptscsih_dev_reset(struct scsi_cmnd
* SCpnt
)
1740 /* If we can't locate our host adapter structure, return FAILED status.
1742 if ((hd
= (MPT_SCSI_HOST
*) SCpnt
->device
->host
->hostdata
) == NULL
){
1743 dtmprintk((KERN_INFO MYNAM
": mptscsih_dev_reset: "
1744 "Can't locate host! (sc=%p)\n",
1749 if (hd
->resetPending
)
1752 printk(KERN_WARNING MYNAM
": %s: attempting target reset! (sc=%p)\n",
1753 hd
->ioc
->name
, SCpnt
);
1754 scsi_print_command(SCpnt
);
1756 vdev
= SCpnt
->device
->hostdata
;
1757 retval
= mptscsih_TMHandler(hd
, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET
,
1758 vdev
->vtarget
->bus_id
, vdev
->vtarget
->target_id
,
1759 0, 0, mptscsih_get_tm_timeout(hd
->ioc
));
1761 printk (KERN_WARNING MYNAM
": %s: target reset: %s (sc=%p)\n",
1763 ((retval
== 0) ? "SUCCESS" : "FAILED" ), SCpnt
);
1768 if(retval
!= FAILED
) {
1770 hd
->tmState
= TM_STATE_NONE
;
1775 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1777 * mptscsih_bus_reset - Perform a SCSI BUS_RESET! new_eh variant
1778 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1780 * (linux scsi_host_template.eh_bus_reset_handler routine)
1782 * Returns SUCCESS or FAILED.
1785 mptscsih_bus_reset(struct scsi_cmnd
* SCpnt
)
1791 /* If we can't locate our host adapter structure, return FAILED status.
1793 if ((hd
= (MPT_SCSI_HOST
*) SCpnt
->device
->host
->hostdata
) == NULL
){
1794 dtmprintk((KERN_INFO MYNAM
": mptscsih_bus_reset: "
1795 "Can't locate host! (sc=%p)\n",
1800 printk(KERN_WARNING MYNAM
": %s: attempting bus reset! (sc=%p)\n",
1801 hd
->ioc
->name
, SCpnt
);
1802 scsi_print_command(SCpnt
);
1804 if (hd
->timeouts
< -1)
1807 vdev
= SCpnt
->device
->hostdata
;
1808 retval
= mptscsih_TMHandler(hd
, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS
,
1809 vdev
->vtarget
->bus_id
, 0, 0, 0, mptscsih_get_tm_timeout(hd
->ioc
));
1811 printk (KERN_WARNING MYNAM
": %s: bus reset: %s (sc=%p)\n",
1813 ((retval
== 0) ? "SUCCESS" : "FAILED" ), SCpnt
);
1818 if(retval
!= FAILED
) {
1820 hd
->tmState
= TM_STATE_NONE
;
1825 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1827 * mptscsih_host_reset - Perform a SCSI host adapter RESET!
1829 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1831 * (linux scsi_host_template.eh_host_reset_handler routine)
1833 * Returns SUCCESS or FAILED.
1836 mptscsih_host_reset(struct scsi_cmnd
*SCpnt
)
1839 int status
= SUCCESS
;
1841 /* If we can't locate the host to reset, then we failed. */
1842 if ((hd
= (MPT_SCSI_HOST
*) SCpnt
->device
->host
->hostdata
) == NULL
){
1843 dtmprintk( ( KERN_INFO MYNAM
": mptscsih_host_reset: "
1844 "Can't locate host! (sc=%p)\n",
1849 printk(KERN_WARNING MYNAM
": %s: Attempting host reset! (sc=%p)\n",
1850 hd
->ioc
->name
, SCpnt
);
1852 /* If our attempts to reset the host failed, then return a failed
1853 * status. The host will be taken off line by the SCSI mid-layer.
1855 if (mpt_HardResetHandler(hd
->ioc
, CAN_SLEEP
) < 0){
1858 /* Make sure TM pending is cleared and TM state is set to
1862 hd
->tmState
= TM_STATE_NONE
;
1865 dtmprintk( ( KERN_INFO MYNAM
": mptscsih_host_reset: "
1867 (status
== SUCCESS
) ? "SUCCESS" : "FAILED" ) );
1872 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1874 * mptscsih_tm_pending_wait - wait for pending task management request to
1876 * @hd: Pointer to MPT host structure.
1878 * Returns {SUCCESS,FAILED}.
1881 mptscsih_tm_pending_wait(MPT_SCSI_HOST
* hd
)
1883 unsigned long flags
;
1884 int loop_count
= 4 * 10; /* Wait 10 seconds */
1885 int status
= FAILED
;
1888 spin_lock_irqsave(&hd
->ioc
->FreeQlock
, flags
);
1889 if (hd
->tmState
== TM_STATE_NONE
) {
1890 hd
->tmState
= TM_STATE_IN_PROGRESS
;
1892 spin_unlock_irqrestore(&hd
->ioc
->FreeQlock
, flags
);
1896 spin_unlock_irqrestore(&hd
->ioc
->FreeQlock
, flags
);
1898 } while (--loop_count
);
1903 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1905 * mptscsih_tm_wait_for_completion - wait for completion of TM task
1906 * @hd: Pointer to MPT host structure.
1908 * Returns {SUCCESS,FAILED}.
1911 mptscsih_tm_wait_for_completion(MPT_SCSI_HOST
* hd
, ulong timeout
)
1913 unsigned long flags
;
1914 int loop_count
= 4 * timeout
;
1915 int status
= FAILED
;
1918 spin_lock_irqsave(&hd
->ioc
->FreeQlock
, flags
);
1919 if(hd
->tmPending
== 0) {
1921 spin_unlock_irqrestore(&hd
->ioc
->FreeQlock
, flags
);
1924 spin_unlock_irqrestore(&hd
->ioc
->FreeQlock
, flags
);
1925 msleep_interruptible(250);
1926 } while (--loop_count
);
1931 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1933 mptscsih_taskmgmt_response_code(MPT_ADAPTER
*ioc
, u8 response_code
)
1937 switch (response_code
) {
1938 case MPI_SCSITASKMGMT_RSP_TM_COMPLETE
:
1939 desc
= "The task completed.";
1941 case MPI_SCSITASKMGMT_RSP_INVALID_FRAME
:
1942 desc
= "The IOC received an invalid frame status.";
1944 case MPI_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED
:
1945 desc
= "The task type is not supported.";
1947 case MPI_SCSITASKMGMT_RSP_TM_FAILED
:
1948 desc
= "The requested task failed.";
1950 case MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED
:
1951 desc
= "The task completed successfully.";
1953 case MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN
:
1954 desc
= "The LUN request is invalid.";
1956 case MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC
:
1957 desc
= "The task is in the IOC queue and has not been sent to target.";
1963 printk(MYIOC_s_INFO_FMT
"Response Code(0x%08x): F/W: %s\n",
1964 ioc
->name
, response_code
, desc
);
1967 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1969 * mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
1970 * @ioc: Pointer to MPT_ADAPTER structure
1971 * @mf: Pointer to SCSI task mgmt request frame
1972 * @mr: Pointer to SCSI task mgmt reply frame
1974 * This routine is called from mptbase.c::mpt_interrupt() at the completion
1975 * of any SCSI task management request.
1976 * This routine is registered with the MPT (base) driver at driver
1977 * load/init time via the mpt_register() API call.
1979 * Returns 1 indicating alloc'd request frame ptr should be freed.
1982 mptscsih_taskmgmt_complete(MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*mf
, MPT_FRAME_HDR
*mr
)
1984 SCSITaskMgmtReply_t
*pScsiTmReply
;
1985 SCSITaskMgmt_t
*pScsiTmReq
;
1987 unsigned long flags
;
1991 dtmprintk((MYIOC_s_WARN_FMT
"TaskMgmt completed (mf=%p,mr=%p)\n",
1992 ioc
->name
, mf
, mr
));
1994 /* Depending on the thread, a timer is activated for
1995 * the TM request. Delete this timer on completion of TM.
1996 * Decrement count of outstanding TM requests.
1998 hd
= (MPT_SCSI_HOST
*)ioc
->sh
->hostdata
;
2000 dtmprintk((MYIOC_s_WARN_FMT
"TaskMgmt Complete: NULL Scsi Host Ptr\n",
2006 dtmprintk((MYIOC_s_WARN_FMT
"ERROR! TaskMgmt Reply: NULL Request %p\n",
2010 pScsiTmReply
= (SCSITaskMgmtReply_t
*)mr
;
2011 pScsiTmReq
= (SCSITaskMgmt_t
*)mf
;
2013 /* Figure out if this was ABORT_TASK, TARGET_RESET, or BUS_RESET! */
2014 tmType
= pScsiTmReq
->TaskType
;
2016 if (ioc
->facts
.MsgVersion
>= MPI_VERSION_01_05
&&
2017 pScsiTmReply
->ResponseCode
)
2018 mptscsih_taskmgmt_response_code(ioc
,
2019 pScsiTmReply
->ResponseCode
);
2021 dtmprintk((MYIOC_s_WARN_FMT
" TaskType = %d, TerminationCount=%d\n",
2022 ioc
->name
, tmType
, le32_to_cpu(pScsiTmReply
->TerminationCount
)));
2023 DBG_DUMP_TM_REPLY_FRAME((u32
*)pScsiTmReply
);
2025 iocstatus
= le16_to_cpu(pScsiTmReply
->IOCStatus
) & MPI_IOCSTATUS_MASK
;
2026 dtmprintk((MYIOC_s_WARN_FMT
" SCSI TaskMgmt (%d) IOCStatus=%04x IOCLogInfo=%08x\n",
2027 ioc
->name
, tmType
, iocstatus
, le32_to_cpu(pScsiTmReply
->IOCLogInfo
)));
2028 /* Error? (anything non-zero?) */
2031 /* clear flags and continue.
2033 if (tmType
== MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK
)
2034 hd
->abortSCpnt
= NULL
;
2036 /* If an internal command is present
2037 * or the TM failed - reload the FW.
2038 * FC FW may respond FAILED to an ABORT
2040 if (tmType
== MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS
) {
2042 (iocstatus
== MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED
)) {
2043 if (mpt_HardResetHandler(ioc
, NO_SLEEP
) < 0) {
2044 printk((KERN_WARNING
2045 " Firmware Reload FAILED!!\n"));
2050 dtmprintk((MYIOC_s_WARN_FMT
" TaskMgmt SUCCESS\n", ioc
->name
));
2052 hd
->abortSCpnt
= NULL
;
2057 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
2059 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
2060 hd
->tmState
= TM_STATE_NONE
;
2065 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2067 * This is anyones guess quite frankly.
2070 mptscsih_bios_param(struct scsi_device
* sdev
, struct block_device
*bdev
,
2071 sector_t capacity
, int geom
[])
2081 dummy
= heads
* sectors
;
2082 cylinders
= capacity
;
2083 sector_div(cylinders
,dummy
);
2086 * Handle extended translation size for logical drives
2089 if ((ulong
)capacity
>= 0x200000) {
2092 dummy
= heads
* sectors
;
2093 cylinders
= capacity
;
2094 sector_div(cylinders
,dummy
);
2100 geom
[2] = cylinders
;
2102 dprintk((KERN_NOTICE
2103 ": bios_param: Id=%i Lun=%i Channel=%i CHS=%i/%i/%i\n",
2104 sdev
->id
, sdev
->lun
,sdev
->channel
,(int)cylinders
,heads
,sectors
));
2109 /* Search IOC page 3 to determine if this is hidden physical disk
2113 mptscsih_is_phys_disk(MPT_ADAPTER
*ioc
, int id
)
2117 if (!ioc
->raid_data
.isRaid
|| !ioc
->raid_data
.pIocPg3
)
2119 for (i
= 0; i
< ioc
->raid_data
.pIocPg3
->NumPhysDisks
; i
++) {
2120 if (id
== ioc
->raid_data
.pIocPg3
->PhysDisk
[i
].PhysDiskID
)
2125 EXPORT_SYMBOL(mptscsih_is_phys_disk
);
2128 mptscsih_raid_id_to_num(MPT_SCSI_HOST
*hd
, uint physdiskid
)
2132 if (!hd
->ioc
->raid_data
.isRaid
|| !hd
->ioc
->raid_data
.pIocPg3
)
2135 for (i
= 0; i
< hd
->ioc
->raid_data
.pIocPg3
->NumPhysDisks
; i
++) {
2137 hd
->ioc
->raid_data
.pIocPg3
->PhysDisk
[i
].PhysDiskID
)
2138 return hd
->ioc
->raid_data
.pIocPg3
->PhysDisk
[i
].PhysDiskNum
;
2143 EXPORT_SYMBOL(mptscsih_raid_id_to_num
);
2145 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2147 * OS entry point to allow host driver to alloc memory
2148 * for each scsi target. Called once per device the bus scan.
2149 * Return non-zero if allocation fails.
2152 mptscsih_target_alloc(struct scsi_target
*starget
)
2154 VirtTarget
*vtarget
;
2156 vtarget
= kzalloc(sizeof(VirtTarget
), GFP_KERNEL
);
2159 starget
->hostdata
= vtarget
;
2160 vtarget
->starget
= starget
;
2164 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2166 * OS entry point to allow host driver to alloc memory
2167 * for each scsi device. Called once per device the bus scan.
2168 * Return non-zero if allocation fails.
2171 mptscsih_slave_alloc(struct scsi_device
*sdev
)
2173 struct Scsi_Host
*host
= sdev
->host
;
2174 MPT_SCSI_HOST
*hd
= (MPT_SCSI_HOST
*)host
->hostdata
;
2175 VirtTarget
*vtarget
;
2177 struct scsi_target
*starget
;
2179 vdev
= kzalloc(sizeof(VirtDevice
), GFP_KERNEL
);
2181 printk(MYIOC_s_ERR_FMT
"slave_alloc kmalloc(%zd) FAILED!\n",
2182 hd
->ioc
->name
, sizeof(VirtDevice
));
2186 vdev
->lun
= sdev
->lun
;
2187 sdev
->hostdata
= vdev
;
2189 starget
= scsi_target(sdev
);
2190 vtarget
= starget
->hostdata
;
2192 vdev
->vtarget
= vtarget
;
2194 if (vtarget
->num_luns
== 0) {
2195 hd
->Targets
[sdev
->id
] = vtarget
;
2196 vtarget
->ioc_id
= hd
->ioc
->id
;
2197 vtarget
->tflags
= MPT_TARGET_FLAGS_Q_YES
;
2198 vtarget
->target_id
= sdev
->id
;
2199 vtarget
->bus_id
= sdev
->channel
;
2200 if (hd
->ioc
->bus_type
== SPI
&& sdev
->channel
== 0 &&
2201 hd
->ioc
->raid_data
.isRaid
& (1 << sdev
->id
)) {
2202 vtarget
->raidVolume
= 1;
2203 ddvtprintk((KERN_INFO
2204 "RAID Volume @ id %d\n", sdev
->id
));
2207 vtarget
->num_luns
++;
2212 * OS entry point to allow for host driver to free allocated memory
2213 * Called if no device present or device being unloaded
2216 mptscsih_target_destroy(struct scsi_target
*starget
)
2218 if (starget
->hostdata
)
2219 kfree(starget
->hostdata
);
2220 starget
->hostdata
= NULL
;
2224 * OS entry point to allow for host driver to free allocated memory
2225 * Called if no device present or device being unloaded
2228 mptscsih_slave_destroy(struct scsi_device
*sdev
)
2230 struct Scsi_Host
*host
= sdev
->host
;
2231 MPT_SCSI_HOST
*hd
= (MPT_SCSI_HOST
*)host
->hostdata
;
2232 VirtTarget
*vtarget
;
2233 VirtDevice
*vdevice
;
2234 struct scsi_target
*starget
;
2236 starget
= scsi_target(sdev
);
2237 vtarget
= starget
->hostdata
;
2238 vdevice
= sdev
->hostdata
;
2240 mptscsih_search_running_cmds(hd
, vdevice
);
2241 vtarget
->luns
[0] &= ~(1 << vdevice
->lun
);
2242 vtarget
->num_luns
--;
2243 if (vtarget
->num_luns
== 0) {
2244 hd
->Targets
[sdev
->id
] = NULL
;
2246 mptscsih_synchronize_cache(hd
, vdevice
);
2248 sdev
->hostdata
= NULL
;
2251 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2253 * mptscsih_change_queue_depth - This function will set a devices queue depth
2254 * @sdev: per scsi_device pointer
2255 * @qdepth: requested queue depth
2257 * Adding support for new 'change_queue_depth' api.
2260 mptscsih_change_queue_depth(struct scsi_device
*sdev
, int qdepth
)
2262 MPT_SCSI_HOST
*hd
= (MPT_SCSI_HOST
*)sdev
->host
->hostdata
;
2263 VirtTarget
*vtarget
;
2264 struct scsi_target
*starget
;
2268 starget
= scsi_target(sdev
);
2269 vtarget
= starget
->hostdata
;
2271 if (hd
->ioc
->bus_type
== SPI
) {
2272 if (!(vtarget
->tflags
& MPT_TARGET_FLAGS_Q_YES
))
2274 else if (sdev
->type
== TYPE_DISK
&&
2275 vtarget
->minSyncFactor
<= MPT_ULTRA160
)
2276 max_depth
= MPT_SCSI_CMD_PER_DEV_HIGH
;
2278 max_depth
= MPT_SCSI_CMD_PER_DEV_LOW
;
2280 max_depth
= MPT_SCSI_CMD_PER_DEV_HIGH
;
2282 if (qdepth
> max_depth
)
2287 tagged
= MSG_SIMPLE_TAG
;
2289 scsi_adjust_queue_depth(sdev
, tagged
, qdepth
);
2290 return sdev
->queue_depth
;
2294 * OS entry point to adjust the queue_depths on a per-device basis.
2295 * Called once per device the bus scan. Use it to force the queue_depth
2296 * member to 1 if a device does not support Q tags.
2297 * Return non-zero if fails.
2300 mptscsih_slave_configure(struct scsi_device
*sdev
)
2302 struct Scsi_Host
*sh
= sdev
->host
;
2303 VirtTarget
*vtarget
;
2304 VirtDevice
*vdevice
;
2305 struct scsi_target
*starget
;
2306 MPT_SCSI_HOST
*hd
= (MPT_SCSI_HOST
*)sh
->hostdata
;
2307 int indexed_lun
, lun_index
;
2309 starget
= scsi_target(sdev
);
2310 vtarget
= starget
->hostdata
;
2311 vdevice
= sdev
->hostdata
;
2313 dsprintk((MYIOC_s_INFO_FMT
2314 "device @ %p, id=%d, LUN=%d, channel=%d\n",
2315 hd
->ioc
->name
, sdev
, sdev
->id
, sdev
->lun
, sdev
->channel
));
2316 if (hd
->ioc
->bus_type
== SPI
)
2317 dsprintk((MYIOC_s_INFO_FMT
2318 "sdtr %d wdtr %d ppr %d inq length=%d\n",
2319 hd
->ioc
->name
, sdev
->sdtr
, sdev
->wdtr
,
2320 sdev
->ppr
, sdev
->inquiry_len
));
2322 if (sdev
->id
> sh
->max_id
) {
2323 /* error case, should never happen */
2324 scsi_adjust_queue_depth(sdev
, 0, 1);
2325 goto slave_configure_exit
;
2328 vdevice
->configured_lun
=1;
2329 lun_index
= (vdevice
->lun
>> 5); /* 32 luns per lun_index */
2330 indexed_lun
= (vdevice
->lun
% 32);
2331 vtarget
->luns
[lun_index
] |= (1 << indexed_lun
);
2332 mptscsih_initTarget(hd
, vtarget
, sdev
);
2333 mptscsih_change_queue_depth(sdev
, MPT_SCSI_CMD_PER_DEV_HIGH
);
2335 dsprintk((MYIOC_s_INFO_FMT
2336 "Queue depth=%d, tflags=%x\n",
2337 hd
->ioc
->name
, sdev
->queue_depth
, vtarget
->tflags
));
2339 if (hd
->ioc
->bus_type
== SPI
)
2340 dsprintk((MYIOC_s_INFO_FMT
2341 "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
2342 hd
->ioc
->name
, vtarget
->negoFlags
, vtarget
->maxOffset
,
2343 vtarget
->minSyncFactor
));
2345 slave_configure_exit
:
2347 dsprintk((MYIOC_s_INFO_FMT
2348 "tagged %d, simple %d, ordered %d\n",
2349 hd
->ioc
->name
,sdev
->tagged_supported
, sdev
->simple_tags
,
2350 sdev
->ordered_tags
));
2355 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2357 * Private routines...
2360 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2361 /* Utility function to copy sense data from the scsi_cmnd buffer
2362 * to the FC and SCSI target structures.
2366 mptscsih_copy_sense_data(struct scsi_cmnd
*sc
, MPT_SCSI_HOST
*hd
, MPT_FRAME_HDR
*mf
, SCSIIOReply_t
*pScsiReply
)
2369 SCSIIORequest_t
*pReq
;
2370 u32 sense_count
= le32_to_cpu(pScsiReply
->SenseCount
);
2372 /* Get target structure
2374 pReq
= (SCSIIORequest_t
*) mf
;
2375 vdev
= sc
->device
->hostdata
;
2381 /* Copy the sense received into the scsi command block. */
2382 req_index
= le16_to_cpu(mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
);
2383 sense_data
= ((u8
*)hd
->ioc
->sense_buf_pool
+ (req_index
* MPT_SENSE_BUFFER_ALLOC
));
2384 memcpy(sc
->sense_buffer
, sense_data
, SNS_LEN(sc
));
2386 /* Log SMART data (asc = 0x5D, non-IM case only) if required.
2388 if ((hd
->ioc
->events
) && (hd
->ioc
->eventTypes
& (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE
))) {
2389 if ((sense_data
[12] == 0x5D) && (vdev
->vtarget
->raidVolume
== 0)) {
2391 MPT_ADAPTER
*ioc
= hd
->ioc
;
2393 idx
= ioc
->eventContext
% MPTCTL_EVENT_LOG_SIZE
;
2394 ioc
->events
[idx
].event
= MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE
;
2395 ioc
->events
[idx
].eventContext
= ioc
->eventContext
;
2397 ioc
->events
[idx
].data
[0] = (pReq
->LUN
[1] << 24) ||
2398 (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA
<< 16) ||
2399 (sc
->device
->channel
<< 8) || sc
->device
->id
;
2401 ioc
->events
[idx
].data
[1] = (sense_data
[13] << 8) || sense_data
[12];
2403 ioc
->eventContext
++;
2407 dprintk((MYIOC_s_INFO_FMT
"Hmmm... SenseData len=0! (?)\n",
2413 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd
*sc
)
2418 hd
= (MPT_SCSI_HOST
*) sc
->device
->host
->hostdata
;
2420 for (i
= 0; i
< hd
->ioc
->req_depth
; i
++) {
2421 if (hd
->ScsiLookup
[i
] == sc
) {
2429 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2431 mptscsih_ioc_reset(MPT_ADAPTER
*ioc
, int reset_phase
)
2434 unsigned long flags
;
2437 dtmprintk((KERN_WARNING MYNAM
2438 ": IOC %s_reset routed to SCSI host driver!\n",
2439 reset_phase
==MPT_IOC_SETUP_RESET
? "setup" : (
2440 reset_phase
==MPT_IOC_PRE_RESET
? "pre" : "post")));
2442 /* If a FW reload request arrives after base installed but
2443 * before all scsi hosts have been attached, then an alt_ioc
2444 * may have a NULL sh pointer.
2446 if ((ioc
->sh
== NULL
) || (ioc
->sh
->hostdata
== NULL
))
2449 hd
= (MPT_SCSI_HOST
*) ioc
->sh
->hostdata
;
2451 if (reset_phase
== MPT_IOC_SETUP_RESET
) {
2452 dtmprintk((MYIOC_s_WARN_FMT
"Setup-Diag Reset\n", ioc
->name
));
2455 * 1. Set Hard Reset Pending Flag
2456 * All new commands go to doneQ
2458 hd
->resetPending
= 1;
2460 } else if (reset_phase
== MPT_IOC_PRE_RESET
) {
2461 dtmprintk((MYIOC_s_WARN_FMT
"Pre-Diag Reset\n", ioc
->name
));
2463 /* 2. Flush running commands
2464 * Clean ScsiLookup (and associated memory)
2468 /* 2b. Reply to OS all known outstanding I/O commands.
2470 mptscsih_flush_running_cmds(hd
);
2472 /* 2c. If there was an internal command that
2473 * has not completed, configuration or io request,
2474 * free these resources.
2477 del_timer(&hd
->timer
);
2478 mpt_free_msg_frame(ioc
, hd
->cmdPtr
);
2481 dtmprintk((MYIOC_s_WARN_FMT
"Pre-Reset complete.\n", ioc
->name
));
2484 dtmprintk((MYIOC_s_WARN_FMT
"Post-Diag Reset\n", ioc
->name
));
2486 /* Once a FW reload begins, all new OS commands are
2487 * redirected to the doneQ w/ a reset status.
2488 * Init all control structures.
2491 /* ScsiLookup initialization
2493 for (ii
=0; ii
< hd
->ioc
->req_depth
; ii
++)
2494 hd
->ScsiLookup
[ii
] = NULL
;
2496 /* 2. Chain Buffer initialization
2499 /* 4. Renegotiate to all devices, if SPI
2502 /* 5. Enable new commands to be posted
2504 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
2506 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
2507 hd
->resetPending
= 0;
2508 hd
->tmState
= TM_STATE_NONE
;
2510 /* 6. If there was an internal command,
2511 * wake this process up.
2515 * Wake up the original calling thread
2517 hd
->pLocal
= &hd
->localReply
;
2518 hd
->pLocal
->completion
= MPT_SCANDV_DID_RESET
;
2519 hd
->scandv_wait_done
= 1;
2520 wake_up(&hd
->scandv_waitq
);
2524 /* 7. FC: Rescan for blocked rports which might have returned.
2526 if (ioc
->bus_type
== FC
) {
2527 spin_lock_irqsave(&ioc
->fc_rescan_work_lock
, flags
);
2528 if (ioc
->fc_rescan_work_q
) {
2529 if (ioc
->fc_rescan_work_count
++ == 0) {
2530 queue_work(ioc
->fc_rescan_work_q
,
2531 &ioc
->fc_rescan_work
);
2534 spin_unlock_irqrestore(&ioc
->fc_rescan_work_lock
, flags
);
2536 dtmprintk((MYIOC_s_WARN_FMT
"Post-Reset complete.\n", ioc
->name
));
2540 return 1; /* currently means nothing really */
2543 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2545 mptscsih_event_process(MPT_ADAPTER
*ioc
, EventNotificationReply_t
*pEvReply
)
2548 u8 event
= le32_to_cpu(pEvReply
->Event
) & 0xFF;
2549 unsigned long flags
;
2551 devtverboseprintk((MYIOC_s_INFO_FMT
"MPT event (=%02Xh) routed to SCSI host driver!\n",
2554 if (ioc
->sh
== NULL
||
2555 ((hd
= (MPT_SCSI_HOST
*)ioc
->sh
->hostdata
) == NULL
))
2559 case MPI_EVENT_UNIT_ATTENTION
: /* 03 */
2562 case MPI_EVENT_IOC_BUS_RESET
: /* 04 */
2563 case MPI_EVENT_EXT_BUS_RESET
: /* 05 */
2564 if (hd
&& (ioc
->bus_type
== SPI
) && (hd
->soft_resets
< -1))
2567 case MPI_EVENT_LOGOUT
: /* 09 */
2571 case MPI_EVENT_RESCAN
: /* 06 */
2572 spin_lock_irqsave(&ioc
->fc_rescan_work_lock
, flags
);
2573 if (ioc
->fc_rescan_work_q
) {
2574 if (ioc
->fc_rescan_work_count
++ == 0) {
2575 queue_work(ioc
->fc_rescan_work_q
,
2576 &ioc
->fc_rescan_work
);
2579 spin_unlock_irqrestore(&ioc
->fc_rescan_work_lock
, flags
);
2583 * CHECKME! Don't think we need to do
2584 * anything for these, but...
2586 case MPI_EVENT_LINK_STATUS_CHANGE
: /* 07 */
2587 case MPI_EVENT_LOOP_STATE_CHANGE
: /* 08 */
2589 * CHECKME! Falling thru...
2593 case MPI_EVENT_INTEGRATED_RAID
: /* 0B */
2596 case MPI_EVENT_NONE
: /* 00 */
2597 case MPI_EVENT_LOG_DATA
: /* 01 */
2598 case MPI_EVENT_STATE_CHANGE
: /* 02 */
2599 case MPI_EVENT_EVENT_CHANGE
: /* 0A */
2601 dprintk((KERN_INFO
" Ignoring event (=%02Xh)\n", event
));
2605 return 1; /* currently means nothing really */
2608 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2610 * mptscsih_initTarget - Target, LUN alloc/free functionality.
2611 * @hd: Pointer to MPT_SCSI_HOST structure
2612 * @vtarget: per target private data
2613 * @sdev: SCSI device
2615 * NOTE: It's only SAFE to call this routine if data points to
2616 * sane & valid STANDARD INQUIRY data!
2618 * Allocate and initialize memory for this target.
2619 * Save inquiry data.
2623 mptscsih_initTarget(MPT_SCSI_HOST
*hd
, VirtTarget
*vtarget
,
2624 struct scsi_device
*sdev
)
2626 dinitprintk((MYIOC_s_INFO_FMT
"initTarget bus=%d id=%d lun=%d hd=%p\n",
2627 hd
->ioc
->name
, vtarget
->bus_id
, vtarget
->target_id
, lun
, hd
));
2629 /* Is LUN supported? If so, upper 2 bits will be 0
2630 * in first byte of inquiry data.
2632 if (sdev
->inq_periph_qual
!= 0)
2635 if (vtarget
== NULL
)
2638 vtarget
->type
= sdev
->type
;
2640 if (hd
->ioc
->bus_type
!= SPI
)
2643 if ((sdev
->type
== TYPE_PROCESSOR
) && (hd
->ioc
->spi_data
.Saf_Te
)) {
2644 /* Treat all Processors as SAF-TE if
2645 * command line option is set */
2646 vtarget
->tflags
|= MPT_TARGET_FLAGS_SAF_TE_ISSUED
;
2647 mptscsih_writeIOCPage4(hd
, vtarget
->target_id
, vtarget
->bus_id
);
2648 }else if ((sdev
->type
== TYPE_PROCESSOR
) &&
2649 !(vtarget
->tflags
& MPT_TARGET_FLAGS_SAF_TE_ISSUED
)) {
2650 if (sdev
->inquiry_len
> 49 ) {
2651 if (sdev
->inquiry
[44] == 'S' &&
2652 sdev
->inquiry
[45] == 'A' &&
2653 sdev
->inquiry
[46] == 'F' &&
2654 sdev
->inquiry
[47] == '-' &&
2655 sdev
->inquiry
[48] == 'T' &&
2656 sdev
->inquiry
[49] == 'E' ) {
2657 vtarget
->tflags
|= MPT_TARGET_FLAGS_SAF_TE_ISSUED
;
2658 mptscsih_writeIOCPage4(hd
, vtarget
->target_id
, vtarget
->bus_id
);
2662 mptscsih_setTargetNegoParms(hd
, vtarget
, sdev
);
2665 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2667 * Update the target negotiation parameters based on the
2668 * the Inquiry data, adapter capabilities, and NVRAM settings.
2672 mptscsih_setTargetNegoParms(MPT_SCSI_HOST
*hd
, VirtTarget
*target
,
2673 struct scsi_device
*sdev
)
2675 SpiCfgData
*pspi_data
= &hd
->ioc
->spi_data
;
2676 int id
= (int) target
->target_id
;
2678 u8 width
= MPT_NARROW
;
2679 u8 factor
= MPT_ASYNC
;
2684 target
->negoFlags
= pspi_data
->noQas
;
2686 /* noQas == 0 => device supports QAS. */
2688 if (sdev
->scsi_level
< SCSI_2
) {
2690 factor
= MPT_ULTRA2
;
2691 offset
= pspi_data
->maxSyncOffset
;
2692 target
->tflags
&= ~MPT_TARGET_FLAGS_Q_YES
;
2694 if (scsi_device_wide(sdev
)) {
2698 if (scsi_device_sync(sdev
)) {
2699 factor
= pspi_data
->minSyncFactor
;
2700 if (!scsi_device_dt(sdev
))
2701 factor
= MPT_ULTRA2
;
2703 if (!scsi_device_ius(sdev
) &&
2704 !scsi_device_qas(sdev
))
2705 factor
= MPT_ULTRA160
;
2707 factor
= MPT_ULTRA320
;
2708 if (scsi_device_qas(sdev
)) {
2709 ddvtprintk((KERN_INFO
"Enabling QAS due to byte56=%02x on id=%d!\n", byte56
, id
));
2712 if (sdev
->type
== TYPE_TAPE
&&
2713 scsi_device_ius(sdev
))
2714 target
->negoFlags
|= MPT_TAPE_NEGO_IDP
;
2717 offset
= pspi_data
->maxSyncOffset
;
2719 /* If RAID, never disable QAS
2720 * else if non RAID, do not disable
2721 * QAS if bit 1 is set
2722 * bit 1 QAS support, non-raid only
2725 if (target
->raidVolume
== 1) {
2734 if (!sdev
->tagged_supported
) {
2735 target
->tflags
&= ~MPT_TARGET_FLAGS_Q_YES
;
2738 /* Update tflags based on NVRAM settings. (SCSI only)
2740 if (pspi_data
->nvram
&& (pspi_data
->nvram
[id
] != MPT_HOST_NVRAM_INVALID
)) {
2741 nvram
= pspi_data
->nvram
[id
];
2742 nfactor
= (nvram
& MPT_NVRAM_SYNC_MASK
) >> 8;
2745 width
= nvram
& MPT_NVRAM_WIDE_DISABLE
? 0 : 1;
2748 /* Ensure factor is set to the
2749 * maximum of: adapter, nvram, inquiry
2752 if (nfactor
< pspi_data
->minSyncFactor
)
2753 nfactor
= pspi_data
->minSyncFactor
;
2755 factor
= max(factor
, nfactor
);
2756 if (factor
== MPT_ASYNC
)
2767 /* Make sure data is consistent
2769 if ((!width
) && (factor
< MPT_ULTRA2
)) {
2770 factor
= MPT_ULTRA2
;
2773 /* Save the data to the target structure.
2775 target
->minSyncFactor
= factor
;
2776 target
->maxOffset
= offset
;
2777 target
->maxWidth
= width
;
2779 target
->tflags
|= MPT_TARGET_FLAGS_VALID_NEGO
;
2781 /* Disable unused features.
2784 target
->negoFlags
|= MPT_TARGET_NO_NEGO_WIDE
;
2787 target
->negoFlags
|= MPT_TARGET_NO_NEGO_SYNC
;
2789 if ( factor
> MPT_ULTRA320
)
2792 if (noQas
&& (pspi_data
->noQas
== 0)) {
2793 pspi_data
->noQas
|= MPT_TARGET_NO_NEGO_QAS
;
2794 target
->negoFlags
|= MPT_TARGET_NO_NEGO_QAS
;
2796 /* Disable QAS in a mixed configuration case
2799 ddvtprintk((KERN_INFO
"Disabling QAS due to noQas=%02x on id=%d!\n", noQas
, id
));
2803 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2805 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2807 * SCSI Config Page functionality ...
2810 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2811 /* mptscsih_writeIOCPage4 - write IOC Page 4
2812 * @hd: Pointer to a SCSI Host Structure
2813 * @target_id: write IOC Page4 for this ID & Bus
2815 * Return: -EAGAIN if unable to obtain a Message Frame
2818 * Remark: We do not wait for a return, write pages sequentially.
2821 mptscsih_writeIOCPage4(MPT_SCSI_HOST
*hd
, int target_id
, int bus
)
2823 MPT_ADAPTER
*ioc
= hd
->ioc
;
2825 IOCPage4_t
*IOCPage4Ptr
;
2833 /* Get a MF for this command.
2835 if ((mf
= mpt_get_msg_frame(ioc
->DoneCtx
, ioc
)) == NULL
) {
2836 dfailprintk((MYIOC_s_WARN_FMT
"writeIOCPage4 : no msg frames!\n",
2841 /* Set the request and the data pointers.
2842 * Place data at end of MF.
2844 pReq
= (Config_t
*)mf
;
2846 req_idx
= le16_to_cpu(mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
);
2847 frameOffset
= ioc
->req_sz
- sizeof(IOCPage4_t
);
2849 /* Complete the request frame (same for all requests).
2851 pReq
->Action
= MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT
;
2853 pReq
->ChainOffset
= 0;
2854 pReq
->Function
= MPI_FUNCTION_CONFIG
;
2855 pReq
->ExtPageLength
= 0;
2856 pReq
->ExtPageType
= 0;
2858 for (ii
=0; ii
< 8; ii
++) {
2859 pReq
->Reserved2
[ii
] = 0;
2862 IOCPage4Ptr
= ioc
->spi_data
.pIocPg4
;
2863 dataDma
= ioc
->spi_data
.IocPg4_dma
;
2864 ii
= IOCPage4Ptr
->ActiveSEP
++;
2865 IOCPage4Ptr
->SEP
[ii
].SEPTargetID
= target_id
;
2866 IOCPage4Ptr
->SEP
[ii
].SEPBus
= bus
;
2867 pReq
->Header
= IOCPage4Ptr
->Header
;
2868 pReq
->PageAddress
= cpu_to_le32(target_id
| (bus
<< 8 ));
2870 /* Add a SGE to the config request.
2872 flagsLength
= MPT_SGE_FLAGS_SSIMPLE_WRITE
|
2873 (IOCPage4Ptr
->Header
.PageLength
+ ii
) * 4;
2875 mpt_add_sge((char *)&pReq
->PageBufferSGE
, flagsLength
, dataDma
);
2877 dinitprintk((MYIOC_s_INFO_FMT
2878 "writeIOCPage4: MaxSEP=%d ActiveSEP=%d id=%d bus=%d\n",
2879 ioc
->name
, IOCPage4Ptr
->MaxSEP
, IOCPage4Ptr
->ActiveSEP
, target_id
, bus
));
2881 mpt_put_msg_frame(ioc
->DoneCtx
, ioc
, mf
);
2886 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2888 * Bus Scan and Domain Validation functionality ...
2891 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2893 * mptscsih_scandv_complete - Scan and DV callback routine registered
2894 * to Fustion MPT (base) driver.
2896 * @ioc: Pointer to MPT_ADAPTER structure
2897 * @mf: Pointer to original MPT request frame
2898 * @mr: Pointer to MPT reply frame (NULL if TurboReply)
2900 * This routine is called from mpt.c::mpt_interrupt() at the completion
2901 * of any SCSI IO request.
2902 * This routine is registered with the Fusion MPT (base) driver at driver
2903 * load/init time via the mpt_register() API call.
2905 * Returns 1 indicating alloc'd request frame ptr should be freed.
2907 * Remark: Sets a completion code and (possibly) saves sense data
2908 * in the IOC member localReply structure.
2909 * Used ONLY for DV and other internal commands.
2912 mptscsih_scandv_complete(MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*mf
, MPT_FRAME_HDR
*mr
)
2915 SCSIIORequest_t
*pReq
;
2919 hd
= (MPT_SCSI_HOST
*) ioc
->sh
->hostdata
;
2922 (mf
>= MPT_INDEX_2_MFPTR(ioc
, ioc
->req_depth
))) {
2923 printk(MYIOC_s_ERR_FMT
2924 "ScanDvComplete, %s req frame ptr! (=%p)\n",
2925 ioc
->name
, mf
?"BAD":"NULL", (void *) mf
);
2929 del_timer(&hd
->timer
);
2930 req_idx
= le16_to_cpu(mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
);
2931 hd
->ScsiLookup
[req_idx
] = NULL
;
2932 pReq
= (SCSIIORequest_t
*) mf
;
2934 if (mf
!= hd
->cmdPtr
) {
2935 printk(MYIOC_s_WARN_FMT
"ScanDvComplete (mf=%p, cmdPtr=%p, idx=%d)\n",
2936 hd
->ioc
->name
, (void *)mf
, (void *) hd
->cmdPtr
, req_idx
);
2940 ddvprintk((MYIOC_s_INFO_FMT
"ScanDvComplete (mf=%p,mr=%p,idx=%d)\n",
2941 hd
->ioc
->name
, mf
, mr
, req_idx
));
2943 hd
->pLocal
= &hd
->localReply
;
2944 hd
->pLocal
->scsiStatus
= 0;
2946 /* If target struct exists, clear sense valid flag.
2949 completionCode
= MPT_SCANDV_GOOD
;
2951 SCSIIOReply_t
*pReply
;
2955 pReply
= (SCSIIOReply_t
*) mr
;
2957 status
= le16_to_cpu(pReply
->IOCStatus
) & MPI_IOCSTATUS_MASK
;
2958 scsi_status
= pReply
->SCSIStatus
;
2960 ddvtprintk((KERN_NOTICE
" IOCStatus=%04xh, SCSIState=%02xh, SCSIStatus=%02xh, IOCLogInfo=%08xh\n",
2961 status
, pReply
->SCSIState
, scsi_status
,
2962 le32_to_cpu(pReply
->IOCLogInfo
)));
2966 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE
: /* 0x0043 */
2967 completionCode
= MPT_SCANDV_SELECTION_TIMEOUT
;
2970 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR
: /* 0x0046 */
2971 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED
: /* 0x0048 */
2972 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED
: /* 0x004B */
2973 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED
: /* 0x004C */
2974 completionCode
= MPT_SCANDV_DID_RESET
;
2977 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN
: /* 0x0045 */
2978 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR
: /* 0x0040 */
2979 case MPI_IOCSTATUS_SUCCESS
: /* 0x0000 */
2980 if (pReply
->Function
== MPI_FUNCTION_CONFIG
) {
2981 ConfigReply_t
*pr
= (ConfigReply_t
*)mr
;
2982 completionCode
= MPT_SCANDV_GOOD
;
2983 hd
->pLocal
->header
.PageVersion
= pr
->Header
.PageVersion
;
2984 hd
->pLocal
->header
.PageLength
= pr
->Header
.PageLength
;
2985 hd
->pLocal
->header
.PageNumber
= pr
->Header
.PageNumber
;
2986 hd
->pLocal
->header
.PageType
= pr
->Header
.PageType
;
2988 } else if (pReply
->Function
== MPI_FUNCTION_RAID_ACTION
) {
2989 /* If the RAID Volume request is successful,
2990 * return GOOD, else indicate that
2991 * some type of error occurred.
2993 MpiRaidActionReply_t
*pr
= (MpiRaidActionReply_t
*)mr
;
2994 if (le16_to_cpu(pr
->ActionStatus
) == MPI_RAID_ACTION_ASTATUS_SUCCESS
)
2995 completionCode
= MPT_SCANDV_GOOD
;
2997 completionCode
= MPT_SCANDV_SOME_ERROR
;
2998 memcpy(hd
->pLocal
->sense
, pr
, sizeof(hd
->pLocal
->sense
));
3000 } else if (pReply
->SCSIState
& MPI_SCSI_STATE_AUTOSENSE_VALID
) {
3004 /* save sense data in global structure
3006 completionCode
= MPT_SCANDV_SENSE
;
3007 hd
->pLocal
->scsiStatus
= scsi_status
;
3008 sense_data
= ((u8
*)hd
->ioc
->sense_buf_pool
+
3009 (req_idx
* MPT_SENSE_BUFFER_ALLOC
));
3011 sz
= min_t(int, pReq
->SenseBufferLength
,
3012 SCSI_STD_SENSE_BYTES
);
3013 memcpy(hd
->pLocal
->sense
, sense_data
, sz
);
3015 ddvprintk((KERN_NOTICE
" Check Condition, sense ptr %p\n",
3017 } else if (pReply
->SCSIState
& MPI_SCSI_STATE_AUTOSENSE_FAILED
) {
3018 if (pReq
->CDB
[0] == INQUIRY
)
3019 completionCode
= MPT_SCANDV_ISSUE_SENSE
;
3021 completionCode
= MPT_SCANDV_DID_RESET
;
3023 else if (pReply
->SCSIState
& MPI_SCSI_STATE_NO_SCSI_STATUS
)
3024 completionCode
= MPT_SCANDV_DID_RESET
;
3025 else if (pReply
->SCSIState
& MPI_SCSI_STATE_TERMINATED
)
3026 completionCode
= MPT_SCANDV_DID_RESET
;
3028 completionCode
= MPT_SCANDV_GOOD
;
3029 hd
->pLocal
->scsiStatus
= scsi_status
;
3033 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR
: /* 0x0047 */
3034 if (pReply
->SCSIState
& MPI_SCSI_STATE_TERMINATED
)
3035 completionCode
= MPT_SCANDV_DID_RESET
;
3037 completionCode
= MPT_SCANDV_SOME_ERROR
;
3041 completionCode
= MPT_SCANDV_SOME_ERROR
;
3044 } /* switch(status) */
3046 ddvtprintk((KERN_NOTICE
" completionCode set to %08xh\n",
3048 } /* end of address reply case */
3050 hd
->pLocal
->completion
= completionCode
;
3052 /* MF and RF are freed in mpt_interrupt
3055 /* Free Chain buffers (will never chain) in scan or dv */
3056 //mptscsih_freeChainBuffers(ioc, req_idx);
3059 * Wake up the original calling thread
3061 hd
->scandv_wait_done
= 1;
3062 wake_up(&hd
->scandv_waitq
);
3067 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3068 /* mptscsih_timer_expired - Call back for timer process.
3069 * Used only for dv functionality.
3070 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
3074 mptscsih_timer_expired(unsigned long data
)
3076 MPT_SCSI_HOST
*hd
= (MPT_SCSI_HOST
*) data
;
3078 ddvprintk((MYIOC_s_WARN_FMT
"Timer Expired! Cmd %p\n", hd
->ioc
->name
, hd
->cmdPtr
));
3081 MPIHeader_t
*cmd
= (MPIHeader_t
*)hd
->cmdPtr
;
3083 if (cmd
->Function
== MPI_FUNCTION_SCSI_IO_REQUEST
) {
3084 /* Desire to issue a task management request here.
3085 * TM requests MUST be single threaded.
3086 * If old eh code and no TM current, issue request.
3087 * If new eh code, do nothing. Wait for OS cmd timeout
3090 ddvtprintk((MYIOC_s_NOTE_FMT
"DV Cmd Timeout: NoOp\n", hd
->ioc
->name
));
3092 /* Perform a FW reload */
3093 if (mpt_HardResetHandler(hd
->ioc
, NO_SLEEP
) < 0) {
3094 printk(MYIOC_s_WARN_FMT
"Firmware Reload FAILED!\n", hd
->ioc
->name
);
3098 /* This should NEVER happen */
3099 printk(MYIOC_s_WARN_FMT
"Null cmdPtr!!!!\n", hd
->ioc
->name
);
3102 /* No more processing.
3103 * TM call will generate an interrupt for SCSI TM Management.
3104 * The FW will reply to all outstanding commands, callback will finish cleanup.
3105 * Hard reset clean-up will free all resources.
3107 ddvprintk((MYIOC_s_WARN_FMT
"Timer Expired Complete!\n", hd
->ioc
->name
));
3113 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3115 * mptscsih_do_cmd - Do internal command.
3116 * @hd: MPT_SCSI_HOST pointer
3117 * @io: INTERNAL_CMD pointer.
3119 * Issue the specified internally generated command and do command
3120 * specific cleanup. For bus scan / DV only.
3121 * NOTES: If command is Inquiry and status is good,
3122 * initialize a target structure, save the data
3124 * Remark: Single threaded access only.
3127 * < 0 if an illegal command or no resources
3131 * > 0 if command complete but some type of completion error.
3134 mptscsih_do_cmd(MPT_SCSI_HOST
*hd
, INTERNAL_CMD
*io
)
3137 SCSIIORequest_t
*pScsiReq
;
3138 SCSIIORequest_t ReqCopy
;
3139 int my_idx
, ii
, dir
;
3143 char CDB
[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
3146 in_isr
= in_interrupt();
3148 dprintk((MYIOC_s_WARN_FMT
"Internal SCSI IO request not allowed in ISR context!\n",
3154 /* Set command specific information
3159 dir
= MPI_SCSIIO_CONTROL_READ
;
3165 case TEST_UNIT_READY
:
3167 dir
= MPI_SCSIIO_CONTROL_READ
;
3173 dir
= MPI_SCSIIO_CONTROL_READ
;
3175 CDB
[4] = 1; /*Spin up the disk */
3183 dir
= MPI_SCSIIO_CONTROL_READ
;
3189 dir
= MPI_SCSIIO_CONTROL_READ
;
3191 if (io
->flags
& MPT_ICFLAG_ECHO
) {
3197 if (io
->flags
& MPT_ICFLAG_BUF_CAP
) {
3200 CDB
[6] = (io
->size
>> 16) & 0xFF;
3201 CDB
[7] = (io
->size
>> 8) & 0xFF;
3202 CDB
[8] = io
->size
& 0xFF;
3208 dir
= MPI_SCSIIO_CONTROL_WRITE
;
3210 if (io
->flags
& MPT_ICFLAG_ECHO
) {
3215 CDB
[6] = (io
->size
>> 16) & 0xFF;
3216 CDB
[7] = (io
->size
>> 8) & 0xFF;
3217 CDB
[8] = io
->size
& 0xFF;
3223 dir
= MPI_SCSIIO_CONTROL_READ
;
3230 dir
= MPI_SCSIIO_CONTROL_READ
;
3235 case SYNCHRONIZE_CACHE
:
3237 dir
= MPI_SCSIIO_CONTROL_READ
;
3239 // CDB[1] = 0x02; /* set immediate bit */
3248 /* Get and Populate a free Frame
3250 if ((mf
= mpt_get_msg_frame(hd
->ioc
->InternalCtx
, hd
->ioc
)) == NULL
) {
3251 ddvprintk((MYIOC_s_WARN_FMT
"No msg frames!\n",
3256 pScsiReq
= (SCSIIORequest_t
*) mf
;
3258 /* Get the request index */
3259 my_idx
= le16_to_cpu(mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
);
3260 ADD_INDEX_LOG(my_idx
); /* for debug */
3262 if (io
->flags
& MPT_ICFLAG_PHYS_DISK
) {
3263 pScsiReq
->TargetID
= io
->physDiskNum
;
3265 pScsiReq
->ChainOffset
= 0;
3266 pScsiReq
->Function
= MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH
;
3268 pScsiReq
->TargetID
= io
->id
;
3269 pScsiReq
->Bus
= io
->bus
;
3270 pScsiReq
->ChainOffset
= 0;
3271 pScsiReq
->Function
= MPI_FUNCTION_SCSI_IO_REQUEST
;
3274 pScsiReq
->CDBLength
= cmdLen
;
3275 pScsiReq
->SenseBufferLength
= MPT_SENSE_BUFFER_SIZE
;
3277 pScsiReq
->Reserved
= 0;
3279 pScsiReq
->MsgFlags
= mpt_msg_flags();
3280 /* MsgContext set in mpt_get_msg_fram call */
3282 for (ii
=0; ii
< 8; ii
++)
3283 pScsiReq
->LUN
[ii
] = 0;
3284 pScsiReq
->LUN
[1] = io
->lun
;
3286 if (io
->flags
& MPT_ICFLAG_TAGGED_CMD
)
3287 pScsiReq
->Control
= cpu_to_le32(dir
| MPI_SCSIIO_CONTROL_SIMPLEQ
);
3289 pScsiReq
->Control
= cpu_to_le32(dir
| MPI_SCSIIO_CONTROL_UNTAGGED
);
3291 if (cmd
== REQUEST_SENSE
) {
3292 pScsiReq
->Control
= cpu_to_le32(dir
| MPI_SCSIIO_CONTROL_UNTAGGED
);
3293 ddvprintk((MYIOC_s_INFO_FMT
"Untagged! 0x%2x\n",
3294 hd
->ioc
->name
, cmd
));
3297 for (ii
=0; ii
< 16; ii
++)
3298 pScsiReq
->CDB
[ii
] = CDB
[ii
];
3300 pScsiReq
->DataLength
= cpu_to_le32(io
->size
);
3301 pScsiReq
->SenseBufferLowAddr
= cpu_to_le32(hd
->ioc
->sense_buf_low_dma
3302 + (my_idx
* MPT_SENSE_BUFFER_ALLOC
));
3304 ddvprintk((MYIOC_s_INFO_FMT
"Sending Command 0x%x for (%d:%d:%d)\n",
3305 hd
->ioc
->name
, cmd
, io
->bus
, io
->id
, io
->lun
));
3307 if (dir
== MPI_SCSIIO_CONTROL_READ
) {
3308 mpt_add_sge((char *) &pScsiReq
->SGL
,
3309 MPT_SGE_FLAGS_SSIMPLE_READ
| io
->size
,
3312 mpt_add_sge((char *) &pScsiReq
->SGL
,
3313 MPT_SGE_FLAGS_SSIMPLE_WRITE
| io
->size
,
3317 /* The ISR will free the request frame, but we need
3318 * the information to initialize the target. Duplicate.
3320 memcpy(&ReqCopy
, pScsiReq
, sizeof(SCSIIORequest_t
));
3322 /* Issue this command after:
3325 * Wait until the reply has been received
3326 * ScsiScanDvCtx callback function will
3328 * set scandv_wait_done and call wake_up
3331 hd
->timer
.expires
= jiffies
+ HZ
*cmdTimeout
;
3332 hd
->scandv_wait_done
= 0;
3334 /* Save cmd pointer, for resource free if timeout or
3339 add_timer(&hd
->timer
);
3340 mpt_put_msg_frame(hd
->ioc
->InternalCtx
, hd
->ioc
, mf
);
3341 wait_event(hd
->scandv_waitq
, hd
->scandv_wait_done
);
3344 rc
= hd
->pLocal
->completion
;
3345 hd
->pLocal
->skip
= 0;
3347 /* Always set fatal error codes in some cases.
3349 if (rc
== MPT_SCANDV_SELECTION_TIMEOUT
)
3351 else if (rc
== MPT_SCANDV_SOME_ERROR
)
3355 /* This should never happen. */
3356 ddvprintk((MYIOC_s_INFO_FMT
"_do_cmd: Null pLocal!!!\n",
3363 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3365 * mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
3366 * @hd: Pointer to a SCSI HOST structure
3367 * @vtarget: per device private data
3370 * Uses the ISR, but with special processing.
3371 * MUST be single-threaded.
3375 mptscsih_synchronize_cache(MPT_SCSI_HOST
*hd
, VirtDevice
*vdevice
)
3379 /* Following parameters will not change
3382 iocmd
.cmd
= SYNCHRONIZE_CACHE
;
3384 iocmd
.physDiskNum
= -1;
3386 iocmd
.data_dma
= -1;
3388 iocmd
.rsvd
= iocmd
.rsvd2
= 0;
3389 iocmd
.bus
= vdevice
->vtarget
->bus_id
;
3390 iocmd
.id
= vdevice
->vtarget
->target_id
;
3391 iocmd
.lun
= (u8
)vdevice
->lun
;
3393 if ((vdevice
->vtarget
->type
== TYPE_DISK
) &&
3394 (vdevice
->configured_lun
))
3395 mptscsih_do_cmd(hd
, &iocmd
);
3398 EXPORT_SYMBOL(mptscsih_remove
);
3399 EXPORT_SYMBOL(mptscsih_shutdown
);
3401 EXPORT_SYMBOL(mptscsih_suspend
);
3402 EXPORT_SYMBOL(mptscsih_resume
);
3404 EXPORT_SYMBOL(mptscsih_proc_info
);
3405 EXPORT_SYMBOL(mptscsih_info
);
3406 EXPORT_SYMBOL(mptscsih_qcmd
);
3407 EXPORT_SYMBOL(mptscsih_target_alloc
);
3408 EXPORT_SYMBOL(mptscsih_slave_alloc
);
3409 EXPORT_SYMBOL(mptscsih_target_destroy
);
3410 EXPORT_SYMBOL(mptscsih_slave_destroy
);
3411 EXPORT_SYMBOL(mptscsih_slave_configure
);
3412 EXPORT_SYMBOL(mptscsih_abort
);
3413 EXPORT_SYMBOL(mptscsih_dev_reset
);
3414 EXPORT_SYMBOL(mptscsih_bus_reset
);
3415 EXPORT_SYMBOL(mptscsih_host_reset
);
3416 EXPORT_SYMBOL(mptscsih_bios_param
);
3417 EXPORT_SYMBOL(mptscsih_io_done
);
3418 EXPORT_SYMBOL(mptscsih_taskmgmt_complete
);
3419 EXPORT_SYMBOL(mptscsih_scandv_complete
);
3420 EXPORT_SYMBOL(mptscsih_event_process
);
3421 EXPORT_SYMBOL(mptscsih_ioc_reset
);
3422 EXPORT_SYMBOL(mptscsih_change_queue_depth
);
3423 EXPORT_SYMBOL(mptscsih_timer_expired
);
3424 EXPORT_SYMBOL(mptscsih_TMHandler
);
3426 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/