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>
69 #include "lsi/mpi_log_sas.h"
71 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
72 #define my_NAME "Fusion MPT SCSI Host driver"
73 #define my_VERSION MPT_LINUX_VERSION_COMMON
74 #define MYNAM "mptscsih"
76 MODULE_AUTHOR(MODULEAUTHOR
);
77 MODULE_DESCRIPTION(my_NAME
);
78 MODULE_LICENSE("GPL");
80 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
82 typedef struct _BIG_SENSE_BUF
{
83 u8 data
[MPT_SENSE_BUFFER_ALLOC
];
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)
94 #define MPT_SCANDV_MAX_RETRIES (10)
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 */
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) */
112 u8 flags
; /* Bit Field - See above */
113 u8 physDiskNum
; /* Phys disk number, -1 else */
119 * Other private/forward protos...
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
);
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 u32
SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd
*sc
);
133 static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST
*hd
, u8 type
, u8 channel
, u8 target
, u8 lun
, int ctx2abort
, ulong timeout
);
135 int mptscsih_ioc_reset(MPT_ADAPTER
*ioc
, int post_reset
);
136 int mptscsih_event_process(MPT_ADAPTER
*ioc
, EventNotificationReply_t
*pEvReply
);
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
);
145 void mptscsih_remove(struct pci_dev
*);
146 void mptscsih_shutdown(struct pci_dev
*);
148 int mptscsih_suspend(struct pci_dev
*pdev
, pm_message_t state
);
149 int mptscsih_resume(struct pci_dev
*pdev
);
152 #define SNS_LEN(scp) sizeof((scp)->sense_buffer)
154 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
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
161 * This routine places a MPT request frame back on the MPT adapter's
165 mptscsih_add_sge(char *pAddr
, u32 flagslength
, dma_addr_t dma_addr
)
167 if (sizeof(dma_addr_t
) == sizeof(u64
)) {
168 SGESimple64_t
*pSge
= (SGESimple64_t
*) pAddr
;
169 u32 tmp
= dma_addr
& 0xFFFFFFFF;
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
);
177 SGESimple32_t
*pSge
= (SGESimple32_t
*) pAddr
;
178 pSge
->FlagsLength
= cpu_to_le32(flagslength
);
179 pSge
->Address
= cpu_to_le32(dma_addr
);
181 } /* mptscsih_add_sge() */
183 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
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
191 * This routine places a MPT request frame back on the MPT adapter's
195 mptscsih_add_chain(char *pAddr
, u8 next
, u16 length
, dma_addr_t dma_addr
)
197 if (sizeof(dma_addr_t
) == sizeof(u64
)) {
198 SGEChain64_t
*pChain
= (SGEChain64_t
*) pAddr
;
199 u32 tmp
= dma_addr
& 0xFFFFFFFF;
201 pChain
->Length
= cpu_to_le16(length
);
202 pChain
->Flags
= MPI_SGE_FLAGS_CHAIN_ELEMENT
| mpt_addr_size();
204 pChain
->NextChainOffset
= next
;
206 pChain
->Address
.Low
= cpu_to_le32(tmp
);
207 tmp
= (u32
) ((u64
)dma_addr
>> 32);
208 pChain
->Address
.High
= cpu_to_le32(tmp
);
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
);
216 } /* mptscsih_add_chain() */
218 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
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)
225 * return SUCCESS or FAILED
228 mptscsih_getFreeChainBuffer(MPT_ADAPTER
*ioc
, int *retIndex
)
230 MPT_FRAME_HDR
*chainBuf
;
235 dsgprintk((MYIOC_s_INFO_FMT
"getFreeChainBuffer called\n",
237 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
238 if (!list_empty(&ioc
->FreeChainQ
)) {
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
;
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
));
251 chain_idx
= MPT_HOST_NO_CHAIN
;
252 dfailprintk((MYIOC_s_INFO_FMT
"getFreeChainBuffer failed\n",
255 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
257 *retIndex
= chain_idx
;
259 } /* mptscsih_getFreeChainBuffer() */
261 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
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
272 mptscsih_AddSGE(MPT_ADAPTER
*ioc
, struct scsi_cmnd
*SCpnt
,
273 SCSIIORequest_t
*pReq
, int req_idx
)
277 struct scatterlist
*sg
;
279 int sges_left
, sg_done
;
280 int chain_idx
= MPT_HOST_NO_CHAIN
;
282 int numSgeSlots
, numSgeThisFrame
;
283 u32 sgflags
, sgdir
, thisxfer
= 0;
284 int chain_dma_off
= 0;
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
;
294 sgdir
= MPT_TRANSFER_IOC_TO_HOST
;
297 psge
= (char *) &pReq
->SGL
;
298 frm_sz
= ioc
->req_sz
;
300 /* Map the data portion, if any.
301 * sges_left = 0 if no data transfer.
303 if ( (sges_left
= SCpnt
->use_sg
) ) {
304 sges_left
= pci_map_sg(ioc
->pcidev
,
305 (struct scatterlist
*) SCpnt
->request_buffer
,
307 SCpnt
->sc_data_direction
);
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
);
324 /* Handle the SG case.
326 sg
= (struct scatterlist
*) SCpnt
->request_buffer
;
328 sgeOffset
= sizeof(SCSIIORequest_t
) - sizeof(SGE_IO_UNION
);
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)
338 numSgeSlots
= ((frm_sz
- sgeOffset
) / (sizeof(u32
) + sizeof(dma_addr_t
)) );
339 numSgeThisFrame
= (sges_left
< numSgeSlots
) ? sges_left
: numSgeSlots
;
341 sgflags
= MPT_SGE_FLAGS_SIMPLE_ELEMENT
| MPT_SGE_FLAGS_ADDRESSING
| sgdir
;
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
347 for (ii
=0; ii
< (numSgeThisFrame
-1); ii
++) {
348 thisxfer
= sg_dma_len(sg
);
350 sg
++; /* Get next SG element from the OS */
355 v2
= sg_dma_address(sg
);
356 mptscsih_add_sge(psge
, sgflags
| thisxfer
, v2
);
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
));
364 if (numSgeThisFrame
== sges_left
) {
365 /* Add last element, end of buffer and end of list flags.
367 sgflags
|= MPT_SGE_FLAGS_LAST_ELEMENT
|
368 MPT_SGE_FLAGS_END_OF_BUFFER
|
369 MPT_SGE_FLAGS_END_OF_LIST
;
371 /* Add last SGE and set termination flags.
372 * Note: Last SGE may have a length of 0 - which should be ok.
374 thisxfer
= sg_dma_len(sg
);
376 v2
= sg_dma_address(sg
);
377 mptscsih_add_sge(psge
, sgflags
| thisxfer
, v2
);
380 psge += (sizeof(u32) + sizeof(dma_addr_t));
382 sgeOffset
+= (sizeof(u32
) + sizeof(dma_addr_t
));
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.
391 mptscsih_add_chain((char *)chainSge
, 0, sgeOffset
, ioc
->ChainBufferDMA
+ chain_dma_off
);
393 /* The current buffer is the original MF
394 * and there is no Chain buffer.
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
;
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
414 dsgprintk((MYIOC_s_INFO_FMT
"SG: Chain Required! sg done %d\n",
415 ioc
->name
, sg_done
));
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
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
);
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.
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
);
441 /* The original MF buffer requires a chain buffer -
443 * Last element in this MF is a chain element.
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
;
451 sges_left
-= sg_done
;
454 /* NOTE: psge points to the beginning of the chain element
455 * in current buffer. Get a chain buffer.
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
));
464 /* Update the tracking arrays.
465 * If chainSge == NULL, update ReqToChain, else ChainToChain
468 ioc
->ChainToChain
[chain_idx
] = newIndex
;
470 ioc
->ReqToChain
[req_idx
] = newIndex
;
472 chain_idx
= newIndex
;
473 chain_dma_off
= ioc
->req_sz
* chain_idx
;
475 /* Populate the chainSGE for the current buffer.
476 * - Set chain buffer pointer to psge and fill
477 * out the Address and Flags fields.
479 chainSge
= (char *) psge
;
480 dsgprintk((KERN_INFO
" Current buff @ %p (index 0x%x)",
483 /* Start the SGE for the next buffer
485 psge
= (char *) (ioc
->ChainBuffer
+ chain_dma_off
);
489 dsgprintk((KERN_INFO
" Chain buff @ %p (index 0x%x)\n",
492 /* Start the SGE for the next buffer
499 } /* mptscsih_AddSGE() */
502 mptscsih_issue_sep_command(MPT_ADAPTER
*ioc
, VirtTarget
*vtarget
,
506 SEPRequest_t
*SEPMsg
;
508 if (ioc
->bus_type
== FC
)
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__
));
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
);
529 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
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)
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.
542 * Returns 1 indicating alloc'd request frame ptr should be freed.
545 mptscsih_io_done(MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*mf
, MPT_FRAME_HDR
*mr
)
547 struct scsi_cmnd
*sc
;
549 SCSIIORequest_t
*pScsiReq
;
550 SCSIIOReply_t
*pScsiReply
;
551 u16 req_idx
, req_idx_MR
;
555 hd
= (MPT_SCSI_HOST
*) ioc
->sh
->hostdata
;
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",
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
]);
571 sc
= hd
->ScsiLookup
[req_idx
];
573 MPIHeader_t
*hdr
= (MPIHeader_t
*)mf
;
575 /* Remark: writeSDP1 will use the ScsiDoneCtx
576 * If a SCSI I/O cmd, device disabled by OS and
577 * completion done. Cannot touch sc struct. Just free mem.
579 if (hdr
->Function
== MPI_FUNCTION_SCSI_IO_REQUEST
)
580 printk(MYIOC_s_ERR_FMT
"NULL ScsiCmd ptr!\n",
583 mptscsih_freeChainBuffers(ioc
, req_idx
);
587 sc
->result
= DID_OK
<< 16; /* Set default reply as OK */
588 pScsiReq
= (SCSIIORequest_t
*) mf
;
589 pScsiReply
= (SCSIIOReply_t
*) mr
;
591 if((ioc
->facts
.MsgVersion
>= MPI_VERSION_01_05
) && pScsiReply
){
592 dmfprintk((MYIOC_s_INFO_FMT
593 "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d,task-tag=%d)\n",
594 ioc
->name
, mf
, mr
, sc
, req_idx
, pScsiReply
->TaskTag
));
596 dmfprintk((MYIOC_s_INFO_FMT
597 "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n",
598 ioc
->name
, mf
, mr
, sc
, req_idx
));
601 if (pScsiReply
== NULL
) {
602 /* special context reply handling */
607 u8 scsi_state
, scsi_status
;
609 status
= le16_to_cpu(pScsiReply
->IOCStatus
) & MPI_IOCSTATUS_MASK
;
610 scsi_state
= pScsiReply
->SCSIState
;
611 scsi_status
= pScsiReply
->SCSIStatus
;
612 xfer_cnt
= le32_to_cpu(pScsiReply
->TransferCount
);
613 sc
->resid
= sc
->request_bufflen
- xfer_cnt
;
616 * if we get a data underrun indication, yet no data was
617 * transferred and the SCSI status indicates that the
618 * command was never started, change the data underrun
621 if (status
== MPI_IOCSTATUS_SCSI_DATA_UNDERRUN
&& xfer_cnt
== 0 &&
622 (scsi_status
== MPI_SCSI_STATUS_BUSY
||
623 scsi_status
== MPI_SCSI_STATUS_RESERVATION_CONFLICT
||
624 scsi_status
== MPI_SCSI_STATUS_TASK_SET_FULL
)) {
625 status
= MPI_IOCSTATUS_SUCCESS
;
628 dreplyprintk((KERN_NOTICE
"Reply ha=%d id=%d lun=%d:\n"
629 "IOCStatus=%04xh SCSIState=%02xh SCSIStatus=%02xh\n"
630 "resid=%d bufflen=%d xfer_cnt=%d\n",
631 ioc
->id
, sc
->device
->id
, sc
->device
->lun
,
632 status
, scsi_state
, scsi_status
, sc
->resid
,
633 sc
->request_bufflen
, xfer_cnt
));
635 if (scsi_state
& MPI_SCSI_STATE_AUTOSENSE_VALID
)
636 mptscsih_copy_sense_data(sc
, hd
, mf
, pScsiReply
);
639 * Look for + dump FCP ResponseInfo[]!
641 if (scsi_state
& MPI_SCSI_STATE_RESPONSE_INFO_VALID
&&
642 pScsiReply
->ResponseInfo
) {
643 printk(KERN_NOTICE
"ha=%d id=%d lun=%d: "
644 "FCP_ResponseInfo=%08xh\n",
645 ioc
->id
, sc
->device
->id
, sc
->device
->lun
,
646 le32_to_cpu(pScsiReply
->ResponseInfo
));
650 case MPI_IOCSTATUS_BUSY
: /* 0x0002 */
652 * Maybe: DRIVER_BUSY | SUGGEST_RETRY | DID_SOFT_ERROR (retry)
653 * But not: DID_BUS_BUSY lest one risk
654 * killing interrupt handler:-(
656 sc
->result
= SAM_STAT_BUSY
;
659 case MPI_IOCSTATUS_SCSI_INVALID_BUS
: /* 0x0041 */
660 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID
: /* 0x0042 */
661 sc
->result
= DID_BAD_TARGET
<< 16;
664 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE
: /* 0x0043 */
665 /* Spoof to SCSI Selection Timeout! */
666 if (ioc
->bus_type
!= FC
)
667 sc
->result
= DID_NO_CONNECT
<< 16;
668 /* else fibre, just stall until rescan event */
670 sc
->result
= DID_REQUEUE
<< 16;
672 if (hd
->sel_timeout
[pScsiReq
->TargetID
] < 0xFFFF)
673 hd
->sel_timeout
[pScsiReq
->TargetID
]++;
675 vdev
= sc
->device
->hostdata
;
678 vtarget
= vdev
->vtarget
;
679 if (vtarget
->tflags
& MPT_TARGET_FLAGS_LED_ON
) {
680 mptscsih_issue_sep_command(ioc
, vtarget
,
681 MPI_SEP_REQ_SLOTSTATUS_UNCONFIGURED
);
682 vtarget
->tflags
&= ~MPT_TARGET_FLAGS_LED_ON
;
686 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED
: /* 0x004B */
687 if ( ioc
->bus_type
== SAS
) {
688 u16 ioc_status
= le16_to_cpu(pScsiReply
->IOCStatus
);
689 if (ioc_status
& MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE
) {
690 u32 log_info
= le32_to_cpu(mr
->u
.reply
.IOCLogInfo
);
691 log_info
&=SAS_LOGINFO_MASK
;
692 if (log_info
== SAS_LOGINFO_NEXUS_LOSS
) {
693 sc
->result
= (DID_BUS_BUSY
<< 16);
700 * Allow non-SAS & non-NEXUS_LOSS to drop into below code
703 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED
: /* 0x0048 */
704 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED
: /* 0x004C */
705 /* Linux handles an unsolicited DID_RESET better
706 * than an unsolicited DID_ABORT.
708 sc
->result
= DID_RESET
<< 16;
712 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH
: /* 0x0049 */
713 sc
->resid
= sc
->request_bufflen
- xfer_cnt
;
714 if((xfer_cnt
==0)||(sc
->underflow
> xfer_cnt
))
715 sc
->result
=DID_SOFT_ERROR
<< 16;
716 else /* Sufficient data transfer occurred */
717 sc
->result
= (DID_OK
<< 16) | scsi_status
;
718 dreplyprintk((KERN_NOTICE
719 "RESIDUAL_MISMATCH: result=%x on id=%d\n", sc
->result
, sc
->device
->id
));
722 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN
: /* 0x0045 */
724 * Do upfront check for valid SenseData and give it
727 sc
->result
= (DID_OK
<< 16) | scsi_status
;
728 if (scsi_state
& MPI_SCSI_STATE_AUTOSENSE_VALID
) {
729 /* Have already saved the status and sense data
733 if (xfer_cnt
< sc
->underflow
) {
734 if (scsi_status
== SAM_STAT_BUSY
)
735 sc
->result
= SAM_STAT_BUSY
;
737 sc
->result
= DID_SOFT_ERROR
<< 16;
739 if (scsi_state
& (MPI_SCSI_STATE_AUTOSENSE_FAILED
| MPI_SCSI_STATE_NO_SCSI_STATUS
)) {
742 sc
->result
= DID_SOFT_ERROR
<< 16;
744 else if (scsi_state
& MPI_SCSI_STATE_TERMINATED
) {
745 /* Not real sure here either... */
746 sc
->result
= DID_RESET
<< 16;
750 dreplyprintk((KERN_NOTICE
" sc->underflow={report ERR if < %02xh bytes xfer'd}\n",
752 dreplyprintk((KERN_NOTICE
" ActBytesXferd=%02xh\n", xfer_cnt
));
755 if (scsi_status
== MPI_SCSI_STATUS_TASK_SET_FULL
)
756 mptscsih_report_queue_full(sc
, pScsiReply
, pScsiReq
);
760 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN
: /* 0x0044 */
762 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR
: /* 0x0040 */
763 case MPI_IOCSTATUS_SUCCESS
: /* 0x0000 */
764 if (scsi_status
== MPI_SCSI_STATUS_BUSY
)
765 sc
->result
= (DID_BUS_BUSY
<< 16) | scsi_status
;
767 sc
->result
= (DID_OK
<< 16) | scsi_status
;
768 if (scsi_state
== 0) {
770 } else if (scsi_state
& MPI_SCSI_STATE_AUTOSENSE_VALID
) {
772 * If running against circa 200003dd 909 MPT f/w,
773 * may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL
774 * (QUEUE_FULL) returned from device! --> get 0x0000?128
775 * and with SenseBytes set to 0.
777 if (pScsiReply
->SCSIStatus
== MPI_SCSI_STATUS_TASK_SET_FULL
)
778 mptscsih_report_queue_full(sc
, pScsiReply
, pScsiReq
);
781 else if (scsi_state
&
782 (MPI_SCSI_STATE_AUTOSENSE_FAILED
| MPI_SCSI_STATE_NO_SCSI_STATUS
)
787 sc
->result
= DID_SOFT_ERROR
<< 16;
789 else if (scsi_state
& MPI_SCSI_STATE_TERMINATED
) {
790 /* Not real sure here either... */
791 sc
->result
= DID_RESET
<< 16;
793 else if (scsi_state
& MPI_SCSI_STATE_QUEUE_TAG_REJECTED
) {
794 /* Device Inq. data indicates that it supports
795 * QTags, but rejects QTag messages.
796 * This command completed OK.
798 * Not real sure here either so do nothing... */
801 if (sc
->result
== MPI_SCSI_STATUS_TASK_SET_FULL
)
802 mptscsih_report_queue_full(sc
, pScsiReply
, pScsiReq
);
805 * Reservation Conflict, Busy,
806 * Command Terminated, CHECK
810 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR
: /* 0x0047 */
811 sc
->result
= DID_SOFT_ERROR
<< 16;
814 case MPI_IOCSTATUS_INVALID_FUNCTION
: /* 0x0001 */
815 case MPI_IOCSTATUS_INVALID_SGL
: /* 0x0003 */
816 case MPI_IOCSTATUS_INTERNAL_ERROR
: /* 0x0004 */
817 case MPI_IOCSTATUS_RESERVED
: /* 0x0005 */
818 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES
: /* 0x0006 */
819 case MPI_IOCSTATUS_INVALID_FIELD
: /* 0x0007 */
820 case MPI_IOCSTATUS_INVALID_STATE
: /* 0x0008 */
821 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR
: /* 0x0046 */
822 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED
: /* 0x004A */
827 sc
->result
= DID_SOFT_ERROR
<< 16;
830 } /* switch(status) */
832 dreplyprintk((KERN_NOTICE
" sc->result is %08xh\n", sc
->result
));
833 } /* end of address reply case */
835 /* Unmap the DMA buffers, if any. */
837 pci_unmap_sg(ioc
->pcidev
, (struct scatterlist
*) sc
->request_buffer
,
838 sc
->use_sg
, sc
->sc_data_direction
);
839 } else if (sc
->request_bufflen
) {
840 pci_unmap_single(ioc
->pcidev
, sc
->SCp
.dma_handle
,
841 sc
->request_bufflen
, sc
->sc_data_direction
);
844 hd
->ScsiLookup
[req_idx
] = NULL
;
846 sc
->scsi_done(sc
); /* Issue the command callback */
848 /* Free Chain buffers */
849 mptscsih_freeChainBuffers(ioc
, req_idx
);
854 * mptscsih_flush_running_cmds - For each command found, search
855 * Scsi_Host instance taskQ and reply to OS.
856 * Called only if recovering from a FW reload.
857 * @hd: Pointer to a SCSI HOST structure
861 * Must be called while new I/Os are being queued.
864 mptscsih_flush_running_cmds(MPT_SCSI_HOST
*hd
)
866 MPT_ADAPTER
*ioc
= hd
->ioc
;
867 struct scsi_cmnd
*SCpnt
;
870 int max
= ioc
->req_depth
;
872 dprintk((KERN_INFO MYNAM
": flush_ScsiLookup called\n"));
873 for (ii
= 0; ii
< max
; ii
++) {
874 if ((SCpnt
= hd
->ScsiLookup
[ii
]) != NULL
) {
879 /* Null ScsiLookup index
881 hd
->ScsiLookup
[ii
] = NULL
;
883 mf
= MPT_INDEX_2_MFPTR(ioc
, ii
);
884 dmfprintk(( "flush: ScsiDone (mf=%p,sc=%p)\n",
887 /* Set status, free OS resources (SG DMA buffers)
889 * Free driver resources (chain, msg buffers)
892 pci_unmap_sg(ioc
->pcidev
,
893 (struct scatterlist
*) SCpnt
->request_buffer
,
895 SCpnt
->sc_data_direction
);
896 } else if (SCpnt
->request_bufflen
) {
897 pci_unmap_single(ioc
->pcidev
,
898 SCpnt
->SCp
.dma_handle
,
899 SCpnt
->request_bufflen
,
900 SCpnt
->sc_data_direction
);
902 SCpnt
->result
= DID_RESET
<< 16;
903 SCpnt
->host_scribble
= NULL
;
905 /* Free Chain buffers */
906 mptscsih_freeChainBuffers(ioc
, ii
);
908 /* Free Message frames */
909 mpt_free_msg_frame(ioc
, mf
);
911 SCpnt
->scsi_done(SCpnt
); /* Issue the command callback */
919 * mptscsih_search_running_cmds - Delete any commands associated
920 * with the specified target and lun. Function called only
921 * when a lun is disable by mid-layer.
922 * Do NOT access the referenced scsi_cmnd structure or
923 * members. Will cause either a paging or NULL ptr error.
924 * (BUT, BUT, BUT, the code does reference it! - mdr)
925 * @hd: Pointer to a SCSI HOST structure
926 * @vdevice: per device private data
930 * Called from slave_destroy.
933 mptscsih_search_running_cmds(MPT_SCSI_HOST
*hd
, VirtDevice
*vdevice
)
935 SCSIIORequest_t
*mf
= NULL
;
937 int max
= hd
->ioc
->req_depth
;
938 struct scsi_cmnd
*sc
;
940 dsprintk((KERN_INFO MYNAM
": search_running target %d lun %d max %d\n",
941 vdevice
->vtarget
->target_id
, vdevice
->lun
, max
));
943 for (ii
=0; ii
< max
; ii
++) {
944 if ((sc
= hd
->ScsiLookup
[ii
]) != NULL
) {
946 mf
= (SCSIIORequest_t
*)MPT_INDEX_2_MFPTR(hd
->ioc
, ii
);
948 dsprintk(( "search_running: found (sc=%p, mf = %p) target %d, lun %d \n",
949 hd
->ScsiLookup
[ii
], mf
, mf
->TargetID
, mf
->LUN
[1]));
951 if ((mf
->TargetID
!= ((u8
)vdevice
->vtarget
->target_id
)) || (mf
->LUN
[1] != ((u8
) vdevice
->lun
)))
956 hd
->ScsiLookup
[ii
] = NULL
;
957 mptscsih_freeChainBuffers(hd
->ioc
, ii
);
958 mpt_free_msg_frame(hd
->ioc
, (MPT_FRAME_HDR
*)mf
);
960 pci_unmap_sg(hd
->ioc
->pcidev
,
961 (struct scatterlist
*) sc
->request_buffer
,
963 sc
->sc_data_direction
);
964 } else if (sc
->request_bufflen
) {
965 pci_unmap_single(hd
->ioc
->pcidev
,
968 sc
->sc_data_direction
);
970 sc
->host_scribble
= NULL
;
971 sc
->result
= DID_NO_CONNECT
<< 16;
978 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
980 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
982 * mptscsih_report_queue_full - Report QUEUE_FULL status returned
983 * from a SCSI target device.
984 * @sc: Pointer to scsi_cmnd structure
985 * @pScsiReply: Pointer to SCSIIOReply_t
986 * @pScsiReq: Pointer to original SCSI request
988 * This routine periodically reports QUEUE_FULL status returned from a
989 * SCSI target device. It reports this to the console via kernel
990 * printk() API call, not more than once every 10 seconds.
993 mptscsih_report_queue_full(struct scsi_cmnd
*sc
, SCSIIOReply_t
*pScsiReply
, SCSIIORequest_t
*pScsiReq
)
998 if (sc
->device
== NULL
)
1000 if (sc
->device
->host
== NULL
)
1002 if ((hd
= (MPT_SCSI_HOST
*)sc
->device
->host
->hostdata
) == NULL
)
1005 if (time
- hd
->last_queue_full
> 10 * HZ
) {
1006 dprintk((MYIOC_s_WARN_FMT
"Device (%d:%d:%d) reported QUEUE_FULL!\n",
1007 hd
->ioc
->name
, 0, sc
->device
->id
, sc
->device
->lun
));
1008 hd
->last_queue_full
= time
;
1012 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1014 * mptscsih_remove - Removed scsi devices
1015 * @pdev: Pointer to pci_dev structure
1020 mptscsih_remove(struct pci_dev
*pdev
)
1022 MPT_ADAPTER
*ioc
= pci_get_drvdata(pdev
);
1023 struct Scsi_Host
*host
= ioc
->sh
;
1032 scsi_remove_host(host
);
1034 if((hd
= (MPT_SCSI_HOST
*)host
->hostdata
) == NULL
)
1037 mptscsih_shutdown(pdev
);
1041 if (hd
->ScsiLookup
!= NULL
) {
1042 sz1
= hd
->ioc
->req_depth
* sizeof(void *);
1043 kfree(hd
->ScsiLookup
);
1044 hd
->ScsiLookup
= NULL
;
1048 * Free pointer array.
1053 dprintk((MYIOC_s_INFO_FMT
1054 "Free'd ScsiLookup (%d) memory\n",
1055 hd
->ioc
->name
, sz1
));
1057 kfree(hd
->info_kbuf
);
1059 /* NULL the Scsi_Host pointer
1063 scsi_host_put(host
);
1069 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1071 * mptscsih_shutdown - reboot notifier
1075 mptscsih_shutdown(struct pci_dev
*pdev
)
1077 MPT_ADAPTER
*ioc
= pci_get_drvdata(pdev
);
1078 struct Scsi_Host
*host
= ioc
->sh
;
1084 hd
= (MPT_SCSI_HOST
*)host
->hostdata
;
1089 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1091 * mptscsih_suspend - Fusion MPT scsi driver suspend routine.
1096 mptscsih_suspend(struct pci_dev
*pdev
, pm_message_t state
)
1098 mptscsih_shutdown(pdev
);
1099 return mpt_suspend(pdev
,state
);
1102 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1104 * mptscsih_resume - Fusion MPT scsi driver resume routine.
1109 mptscsih_resume(struct pci_dev
*pdev
)
1111 MPT_ADAPTER
*ioc
= pci_get_drvdata(pdev
);
1112 struct Scsi_Host
*host
= ioc
->sh
;
1120 hd
= (MPT_SCSI_HOST
*)host
->hostdata
;
1129 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1131 * mptscsih_info - Return information about MPT adapter
1132 * @SChost: Pointer to Scsi_Host structure
1134 * (linux scsi_host_template.info routine)
1136 * Returns pointer to buffer where information was written.
1139 mptscsih_info(struct Scsi_Host
*SChost
)
1144 h
= (MPT_SCSI_HOST
*)SChost
->hostdata
;
1147 if (h
->info_kbuf
== NULL
)
1148 if ((h
->info_kbuf
= kmalloc(0x1000 /* 4Kb */, GFP_KERNEL
)) == NULL
)
1149 return h
->info_kbuf
;
1150 h
->info_kbuf
[0] = '\0';
1152 mpt_print_ioc_summary(h
->ioc
, h
->info_kbuf
, &size
, 0, 0);
1153 h
->info_kbuf
[size
-1] = '\0';
1156 return h
->info_kbuf
;
1167 mptscsih_copy_mem_info(struct info_str
*info
, char *data
, int len
)
1169 if (info
->pos
+ len
> info
->length
)
1170 len
= info
->length
- info
->pos
;
1172 if (info
->pos
+ len
< info
->offset
) {
1177 if (info
->pos
< info
->offset
) {
1178 data
+= (info
->offset
- info
->pos
);
1179 len
-= (info
->offset
- info
->pos
);
1183 memcpy(info
->buffer
+ info
->pos
, data
, len
);
1189 mptscsih_copy_info(struct info_str
*info
, char *fmt
, ...)
1195 va_start(args
, fmt
);
1196 len
= vsprintf(buf
, fmt
, args
);
1199 mptscsih_copy_mem_info(info
, buf
, len
);
1204 mptscsih_host_info(MPT_ADAPTER
*ioc
, char *pbuf
, off_t offset
, int len
)
1206 struct info_str info
;
1210 info
.offset
= offset
;
1213 mptscsih_copy_info(&info
, "%s: %s, ", ioc
->name
, ioc
->prod_name
);
1214 mptscsih_copy_info(&info
, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING
, ioc
->facts
.FWVersion
.Word
);
1215 mptscsih_copy_info(&info
, "Ports=%d, ", ioc
->facts
.NumberOfPorts
);
1216 mptscsih_copy_info(&info
, "MaxQ=%d\n", ioc
->req_depth
);
1218 return ((info
.pos
> info
.offset
) ? info
.pos
- info
.offset
: 0);
1221 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1223 * mptscsih_proc_info - Return information about MPT adapter
1225 * (linux scsi_host_template.info routine)
1227 * buffer: if write, user data; if read, buffer for user
1228 * length: if write, return length;
1229 * offset: if write, 0; if read, the current offset into the buffer from
1230 * the previous read.
1231 * hostno: scsi host number
1232 * func: if write = 1; if read = 0
1235 mptscsih_proc_info(struct Scsi_Host
*host
, char *buffer
, char **start
, off_t offset
,
1236 int length
, int func
)
1238 MPT_SCSI_HOST
*hd
= (MPT_SCSI_HOST
*)host
->hostdata
;
1239 MPT_ADAPTER
*ioc
= hd
->ioc
;
1244 * write is not supported
1250 size
= mptscsih_host_info(ioc
, buffer
, offset
, length
);
1256 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1257 #define ADD_INDEX_LOG(req_ent) do { } while(0)
1259 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1261 * mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine.
1262 * @SCpnt: Pointer to scsi_cmnd structure
1263 * @done: Pointer SCSI mid-layer IO completion function
1265 * (linux scsi_host_template.queuecommand routine)
1266 * This is the primary SCSI IO start routine. Create a MPI SCSIIORequest
1267 * from a linux scsi_cmnd request and send it to the IOC.
1269 * Returns 0. (rtn value discarded by linux scsi mid-layer)
1272 mptscsih_qcmd(struct scsi_cmnd
*SCpnt
, void (*done
)(struct scsi_cmnd
*))
1276 SCSIIORequest_t
*pScsiReq
;
1277 VirtDevice
*vdev
= SCpnt
->device
->hostdata
;
1286 hd
= (MPT_SCSI_HOST
*) SCpnt
->device
->host
->hostdata
;
1287 lun
= SCpnt
->device
->lun
;
1288 SCpnt
->scsi_done
= done
;
1290 dmfprintk((MYIOC_s_INFO_FMT
"qcmd: SCpnt=%p, done()=%p\n",
1291 (hd
&& hd
->ioc
) ? hd
->ioc
->name
: "ioc?", SCpnt
, done
));
1293 if (hd
->resetPending
) {
1294 dtmprintk((MYIOC_s_WARN_FMT
"qcmd: SCpnt=%p timeout + 60HZ\n",
1295 (hd
&& hd
->ioc
) ? hd
->ioc
->name
: "ioc?", SCpnt
));
1296 return SCSI_MLQUEUE_HOST_BUSY
;
1299 if ((hd
->ioc
->bus_type
== SPI
) &&
1300 vdev
->vtarget
->tflags
& MPT_TARGET_FLAGS_RAID_COMPONENT
&&
1301 mptscsih_raid_id_to_num(hd
, SCpnt
->device
->id
) < 0) {
1302 SCpnt
->result
= DID_NO_CONNECT
<< 16;
1308 * Put together a MPT SCSI request...
1310 if ((mf
= mpt_get_msg_frame(hd
->ioc
->DoneCtx
, hd
->ioc
)) == NULL
) {
1311 dprintk((MYIOC_s_WARN_FMT
"QueueCmd, no msg frames!!\n",
1313 return SCSI_MLQUEUE_HOST_BUSY
;
1316 pScsiReq
= (SCSIIORequest_t
*) mf
;
1318 my_idx
= le16_to_cpu(mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
);
1320 ADD_INDEX_LOG(my_idx
);
1322 /* TUR's being issued with scsictl=0x02000000 (DATA_IN)!
1323 * Seems we may receive a buffer (datalen>0) even when there
1324 * will be no data transfer! GRRRRR...
1326 if (SCpnt
->sc_data_direction
== DMA_FROM_DEVICE
) {
1327 datalen
= SCpnt
->request_bufflen
;
1328 scsidir
= MPI_SCSIIO_CONTROL_READ
; /* DATA IN (host<--ioc<--dev) */
1329 } else if (SCpnt
->sc_data_direction
== DMA_TO_DEVICE
) {
1330 datalen
= SCpnt
->request_bufflen
;
1331 scsidir
= MPI_SCSIIO_CONTROL_WRITE
; /* DATA OUT (host-->ioc-->dev) */
1334 scsidir
= MPI_SCSIIO_CONTROL_NODATATRANSFER
;
1337 /* Default to untagged. Once a target structure has been allocated,
1338 * use the Inquiry data to determine if device supports tagged.
1341 && (vdev
->vtarget
->tflags
& MPT_TARGET_FLAGS_Q_YES
)
1342 && (SCpnt
->device
->tagged_supported
)) {
1343 scsictl
= scsidir
| MPI_SCSIIO_CONTROL_SIMPLEQ
;
1345 scsictl
= scsidir
| MPI_SCSIIO_CONTROL_UNTAGGED
;
1348 /* Use the above information to set up the message frame
1350 pScsiReq
->TargetID
= (u8
) vdev
->vtarget
->target_id
;
1351 pScsiReq
->Bus
= vdev
->vtarget
->bus_id
;
1352 pScsiReq
->ChainOffset
= 0;
1353 if (vdev
->vtarget
->tflags
& MPT_TARGET_FLAGS_RAID_COMPONENT
)
1354 pScsiReq
->Function
= MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH
;
1356 pScsiReq
->Function
= MPI_FUNCTION_SCSI_IO_REQUEST
;
1357 pScsiReq
->CDBLength
= SCpnt
->cmd_len
;
1358 pScsiReq
->SenseBufferLength
= MPT_SENSE_BUFFER_SIZE
;
1359 pScsiReq
->Reserved
= 0;
1360 pScsiReq
->MsgFlags
= mpt_msg_flags();
1361 pScsiReq
->LUN
[0] = 0;
1362 pScsiReq
->LUN
[1] = lun
;
1363 pScsiReq
->LUN
[2] = 0;
1364 pScsiReq
->LUN
[3] = 0;
1365 pScsiReq
->LUN
[4] = 0;
1366 pScsiReq
->LUN
[5] = 0;
1367 pScsiReq
->LUN
[6] = 0;
1368 pScsiReq
->LUN
[7] = 0;
1369 pScsiReq
->Control
= cpu_to_le32(scsictl
);
1372 * Write SCSI CDB into the message
1374 cmd_len
= SCpnt
->cmd_len
;
1375 for (ii
=0; ii
< cmd_len
; ii
++)
1376 pScsiReq
->CDB
[ii
] = SCpnt
->cmnd
[ii
];
1378 for (ii
=cmd_len
; ii
< 16; ii
++)
1379 pScsiReq
->CDB
[ii
] = 0;
1382 pScsiReq
->DataLength
= cpu_to_le32(datalen
);
1384 /* SenseBuffer low address */
1385 pScsiReq
->SenseBufferLowAddr
= cpu_to_le32(hd
->ioc
->sense_buf_low_dma
1386 + (my_idx
* MPT_SENSE_BUFFER_ALLOC
));
1388 /* Now add the SG list
1389 * Always have a SGE even if null length.
1392 /* Add a NULL SGE */
1393 mptscsih_add_sge((char *)&pScsiReq
->SGL
, MPT_SGE_FLAGS_SSIMPLE_READ
| 0,
1396 /* Add a 32 or 64 bit SGE */
1397 if (mptscsih_AddSGE(hd
->ioc
, SCpnt
, pScsiReq
, my_idx
) != SUCCESS
)
1401 hd
->ScsiLookup
[my_idx
] = SCpnt
;
1402 SCpnt
->host_scribble
= NULL
;
1404 mpt_put_msg_frame(hd
->ioc
->DoneCtx
, hd
->ioc
, mf
);
1405 dmfprintk((MYIOC_s_INFO_FMT
"Issued SCSI cmd (%p) mf=%p idx=%d\n",
1406 hd
->ioc
->name
, SCpnt
, mf
, my_idx
));
1407 DBG_DUMP_REQUEST_FRAME(mf
)
1411 hd
->ScsiLookup
[my_idx
] = NULL
;
1412 mptscsih_freeChainBuffers(hd
->ioc
, my_idx
);
1413 mpt_free_msg_frame(hd
->ioc
, mf
);
1414 return SCSI_MLQUEUE_HOST_BUSY
;
1417 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1419 * mptscsih_freeChainBuffers - Function to free chain buffers associated
1420 * with a SCSI IO request
1421 * @hd: Pointer to the MPT_SCSI_HOST instance
1422 * @req_idx: Index of the SCSI IO request frame.
1424 * Called if SG chain buffer allocation fails and mptscsih callbacks.
1428 mptscsih_freeChainBuffers(MPT_ADAPTER
*ioc
, int req_idx
)
1430 MPT_FRAME_HDR
*chain
;
1431 unsigned long flags
;
1435 /* Get the first chain index and reset
1438 chain_idx
= ioc
->ReqToChain
[req_idx
];
1439 ioc
->ReqToChain
[req_idx
] = MPT_HOST_NO_CHAIN
;
1441 while (chain_idx
!= MPT_HOST_NO_CHAIN
) {
1443 /* Save the next chain buffer index */
1444 next
= ioc
->ChainToChain
[chain_idx
];
1446 /* Free this chain buffer and reset
1449 ioc
->ChainToChain
[chain_idx
] = MPT_HOST_NO_CHAIN
;
1451 chain
= (MPT_FRAME_HDR
*) (ioc
->ChainBuffer
1452 + (chain_idx
* ioc
->req_sz
));
1454 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
1455 list_add_tail(&chain
->u
.frame
.linkage
.list
, &ioc
->FreeChainQ
);
1456 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
1458 dmfprintk((MYIOC_s_INFO_FMT
"FreeChainBuffers (index %d)\n",
1459 ioc
->name
, chain_idx
));
1467 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1472 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1474 * mptscsih_TMHandler - Generic handler for SCSI Task Management.
1475 * Fall through to mpt_HardResetHandler if: not operational, too many
1476 * failed TM requests or handshake failure.
1478 * @ioc: Pointer to MPT_ADAPTER structure
1479 * @type: Task Management type
1480 * @target: Logical Target ID for reset (if appropriate)
1481 * @lun: Logical Unit for reset (if appropriate)
1482 * @ctx2abort: Context for the task to be aborted (if appropriate)
1484 * Remark: Currently invoked from a non-interrupt thread (_bh).
1486 * Remark: With old EH code, at most 1 SCSI TaskMgmt function per IOC
1489 * Returns 0 for SUCCESS or -1 if FAILED.
1492 mptscsih_TMHandler(MPT_SCSI_HOST
*hd
, u8 type
, u8 channel
, u8 target
, u8 lun
, int ctx2abort
, ulong timeout
)
1498 unsigned long flags
;
1500 /* If FW is being reloaded currently, return success to
1501 * the calling function.
1508 printk(KERN_ERR MYNAM
" TMHandler" " NULL ioc!\n");
1511 dtmprintk((MYIOC_s_INFO_FMT
"TMHandler Entered!\n", ioc
->name
));
1513 // SJR - CHECKME - Can we avoid this here?
1514 // (mpt_HardResetHandler has this check...)
1515 spin_lock_irqsave(&ioc
->diagLock
, flags
);
1516 if ((ioc
->diagPending
) || (ioc
->alt_ioc
&& ioc
->alt_ioc
->diagPending
)) {
1517 spin_unlock_irqrestore(&ioc
->diagLock
, flags
);
1520 spin_unlock_irqrestore(&ioc
->diagLock
, flags
);
1522 /* Wait a fixed amount of time for the TM pending flag to be cleared.
1523 * If we time out and not bus reset, then we return a FAILED status to the caller.
1524 * The call to mptscsih_tm_pending_wait() will set the pending flag if we are
1525 * successful. Otherwise, reload the FW.
1527 if (mptscsih_tm_pending_wait(hd
) == FAILED
) {
1528 if (type
== MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK
) {
1529 dtmprintk((KERN_INFO MYNAM
": %s: TMHandler abort: "
1530 "Timed out waiting for last TM (%d) to complete! \n",
1531 hd
->ioc
->name
, hd
->tmPending
));
1533 } else if (type
== MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET
) {
1534 dtmprintk((KERN_INFO MYNAM
": %s: TMHandler target reset: "
1535 "Timed out waiting for last TM (%d) to complete! \n",
1536 hd
->ioc
->name
, hd
->tmPending
));
1538 } else if (type
== MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS
) {
1539 dtmprintk((KERN_INFO MYNAM
": %s: TMHandler bus reset: "
1540 "Timed out waiting for last TM (%d) to complete! \n",
1541 hd
->ioc
->name
, hd
->tmPending
));
1542 if (hd
->tmPending
& (1 << MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS
))
1548 spin_lock_irqsave(&hd
->ioc
->FreeQlock
, flags
);
1549 hd
->tmPending
|= (1 << type
);
1550 spin_unlock_irqrestore(&hd
->ioc
->FreeQlock
, flags
);
1555 ioc_raw_state
= mpt_GetIocState(hd
->ioc
, 0);
1557 #ifdef MPT_DEBUG_RESET
1558 if ((ioc_raw_state
& MPI_IOC_STATE_MASK
) != MPI_IOC_STATE_OPERATIONAL
) {
1559 printk(MYIOC_s_WARN_FMT
1560 "TM Handler: IOC Not operational(0x%x)!\n",
1561 hd
->ioc
->name
, ioc_raw_state
);
1565 if (doTask
&& ((ioc_raw_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_OPERATIONAL
)
1566 && !(ioc_raw_state
& MPI_DOORBELL_ACTIVE
)) {
1568 /* Isse the Task Mgmt request.
1570 if (hd
->hard_resets
< -1)
1572 rc
= mptscsih_IssueTaskMgmt(hd
, type
, channel
, target
, lun
, ctx2abort
, timeout
);
1574 printk(MYIOC_s_INFO_FMT
"Issue of TaskMgmt failed!\n", hd
->ioc
->name
);
1576 dtmprintk((MYIOC_s_INFO_FMT
"Issue of TaskMgmt Successful!\n", hd
->ioc
->name
));
1580 /* Only fall through to the HRH if this is a bus reset
1582 if ((type
== MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS
) && (rc
||
1583 ioc
->reload_fw
|| (ioc
->alt_ioc
&& ioc
->alt_ioc
->reload_fw
))) {
1584 dtmprintk((MYIOC_s_INFO_FMT
"Calling HardReset! \n",
1586 rc
= mpt_HardResetHandler(hd
->ioc
, CAN_SLEEP
);
1589 dtmprintk((MYIOC_s_INFO_FMT
"TMHandler rc = %d!\n", hd
->ioc
->name
, rc
));
1595 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1597 * mptscsih_IssueTaskMgmt - Generic send Task Management function.
1598 * @hd: Pointer to MPT_SCSI_HOST structure
1599 * @type: Task Management type
1600 * @target: Logical Target ID for reset (if appropriate)
1601 * @lun: Logical Unit for reset (if appropriate)
1602 * @ctx2abort: Context for the task to be aborted (if appropriate)
1604 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
1605 * or a non-interrupt thread. In the former, must not call schedule().
1607 * Not all fields are meaningfull for all task types.
1609 * Returns 0 for SUCCESS, -999 for "no msg frames",
1610 * else other non-zero value returned.
1613 mptscsih_IssueTaskMgmt(MPT_SCSI_HOST
*hd
, u8 type
, u8 channel
, u8 target
, u8 lun
, int ctx2abort
, ulong timeout
)
1616 SCSITaskMgmt_t
*pScsiTm
;
1620 /* Return Fail to calling function if no message frames available.
1622 if ((mf
= mpt_get_msg_frame(hd
->ioc
->TaskCtx
, hd
->ioc
)) == NULL
) {
1623 dfailprintk((MYIOC_s_ERR_FMT
"IssueTaskMgmt, no msg frames!!\n",
1627 dtmprintk((MYIOC_s_INFO_FMT
"IssueTaskMgmt request @ %p\n",
1628 hd
->ioc
->name
, mf
));
1630 /* Format the Request
1632 pScsiTm
= (SCSITaskMgmt_t
*) mf
;
1633 pScsiTm
->TargetID
= target
;
1634 pScsiTm
->Bus
= channel
;
1635 pScsiTm
->ChainOffset
= 0;
1636 pScsiTm
->Function
= MPI_FUNCTION_SCSI_TASK_MGMT
;
1638 pScsiTm
->Reserved
= 0;
1639 pScsiTm
->TaskType
= type
;
1640 pScsiTm
->Reserved1
= 0;
1641 pScsiTm
->MsgFlags
= (type
== MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS
)
1642 ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION
: 0;
1644 for (ii
= 0; ii
< 8; ii
++) {
1645 pScsiTm
->LUN
[ii
] = 0;
1647 pScsiTm
->LUN
[1] = lun
;
1649 for (ii
=0; ii
< 7; ii
++)
1650 pScsiTm
->Reserved2
[ii
] = 0;
1652 pScsiTm
->TaskMsgContext
= ctx2abort
;
1654 dtmprintk((MYIOC_s_INFO_FMT
"IssueTaskMgmt: ctx2abort (0x%08x) type=%d\n",
1655 hd
->ioc
->name
, ctx2abort
, type
));
1657 DBG_DUMP_TM_REQUEST_FRAME((u32
*)pScsiTm
);
1659 if ((retval
= mpt_send_handshake_request(hd
->ioc
->TaskCtx
, hd
->ioc
,
1660 sizeof(SCSITaskMgmt_t
), (u32
*)pScsiTm
,
1662 dfailprintk((MYIOC_s_ERR_FMT
"_send_handshake FAILED!"
1663 " (hd %p, ioc %p, mf %p) \n", hd
->ioc
->name
, hd
,
1665 mpt_free_msg_frame(hd
->ioc
, mf
);
1669 if(mptscsih_tm_wait_for_completion(hd
, timeout
) == FAILED
) {
1670 dfailprintk((MYIOC_s_ERR_FMT
"_wait_for_completion FAILED!"
1671 " (hd %p, ioc %p, mf %p) \n", hd
->ioc
->name
, hd
,
1673 mpt_free_msg_frame(hd
->ioc
, mf
);
1674 dtmprintk((MYIOC_s_INFO_FMT
"Calling HardReset! \n",
1676 retval
= mpt_HardResetHandler(hd
->ioc
, CAN_SLEEP
);
1683 mptscsih_get_tm_timeout(MPT_ADAPTER
*ioc
)
1685 switch (ioc
->bus_type
) {
1696 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1698 * mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant
1699 * @SCpnt: Pointer to scsi_cmnd structure, IO to be aborted
1701 * (linux scsi_host_template.eh_abort_handler routine)
1703 * Returns SUCCESS or FAILED.
1706 mptscsih_abort(struct scsi_cmnd
* SCpnt
)
1715 /* If we can't locate our host adapter structure, return FAILED status.
1717 if ((hd
= (MPT_SCSI_HOST
*) SCpnt
->device
->host
->hostdata
) == NULL
) {
1718 SCpnt
->result
= DID_RESET
<< 16;
1719 SCpnt
->scsi_done(SCpnt
);
1720 dfailprintk((KERN_INFO MYNAM
": mptscsih_abort: "
1721 "Can't locate host! (sc=%p)\n",
1726 /* Find this command
1728 if ((scpnt_idx
= SCPNT_TO_LOOKUP_IDX(SCpnt
)) < 0) {
1729 /* Cmd not found in ScsiLookup.
1732 SCpnt
->result
= DID_RESET
<< 16;
1733 dtmprintk((KERN_INFO MYNAM
": %s: mptscsih_abort: "
1734 "Command not in the active list! (sc=%p)\n",
1735 hd
->ioc
->name
, SCpnt
));
1739 if (hd
->resetPending
) {
1743 if (hd
->timeouts
< -1)
1746 printk(KERN_WARNING MYNAM
": %s: attempting task abort! (sc=%p)\n",
1747 hd
->ioc
->name
, SCpnt
);
1748 scsi_print_command(SCpnt
);
1750 /* Most important! Set TaskMsgContext to SCpnt's MsgContext!
1751 * (the IO to be ABORT'd)
1753 * NOTE: Since we do not byteswap MsgContext, we do not
1754 * swap it here either. It is an opaque cookie to
1755 * the controller, so it does not matter. -DaveM
1757 mf
= MPT_INDEX_2_MFPTR(hd
->ioc
, scpnt_idx
);
1758 ctx2abort
= mf
->u
.frame
.hwhdr
.msgctxu
.MsgContext
;
1760 hd
->abortSCpnt
= SCpnt
;
1762 vdev
= SCpnt
->device
->hostdata
;
1763 retval
= mptscsih_TMHandler(hd
, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK
,
1764 vdev
->vtarget
->bus_id
, vdev
->vtarget
->target_id
, vdev
->lun
,
1765 ctx2abort
, mptscsih_get_tm_timeout(hd
->ioc
));
1767 printk (KERN_WARNING MYNAM
": %s: task abort: %s (sc=%p)\n",
1769 ((retval
== 0) ? "SUCCESS" : "FAILED" ), SCpnt
);
1774 if(retval
!= FAILED
) {
1776 hd
->tmState
= TM_STATE_NONE
;
1781 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1783 * mptscsih_dev_reset - Perform a SCSI TARGET_RESET! new_eh variant
1784 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1786 * (linux scsi_host_template.eh_dev_reset_handler routine)
1788 * Returns SUCCESS or FAILED.
1791 mptscsih_dev_reset(struct scsi_cmnd
* SCpnt
)
1797 /* If we can't locate our host adapter structure, return FAILED status.
1799 if ((hd
= (MPT_SCSI_HOST
*) SCpnt
->device
->host
->hostdata
) == NULL
){
1800 dtmprintk((KERN_INFO MYNAM
": mptscsih_dev_reset: "
1801 "Can't locate host! (sc=%p)\n",
1806 if (hd
->resetPending
)
1809 printk(KERN_WARNING MYNAM
": %s: attempting target reset! (sc=%p)\n",
1810 hd
->ioc
->name
, SCpnt
);
1811 scsi_print_command(SCpnt
);
1813 vdev
= SCpnt
->device
->hostdata
;
1814 retval
= mptscsih_TMHandler(hd
, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET
,
1815 vdev
->vtarget
->bus_id
, vdev
->vtarget
->target_id
,
1816 0, 0, mptscsih_get_tm_timeout(hd
->ioc
));
1818 printk (KERN_WARNING MYNAM
": %s: target reset: %s (sc=%p)\n",
1820 ((retval
== 0) ? "SUCCESS" : "FAILED" ), SCpnt
);
1825 if(retval
!= FAILED
) {
1827 hd
->tmState
= TM_STATE_NONE
;
1832 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1834 * mptscsih_bus_reset - Perform a SCSI BUS_RESET! new_eh variant
1835 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1837 * (linux scsi_host_template.eh_bus_reset_handler routine)
1839 * Returns SUCCESS or FAILED.
1842 mptscsih_bus_reset(struct scsi_cmnd
* SCpnt
)
1848 /* If we can't locate our host adapter structure, return FAILED status.
1850 if ((hd
= (MPT_SCSI_HOST
*) SCpnt
->device
->host
->hostdata
) == NULL
){
1851 dtmprintk((KERN_INFO MYNAM
": mptscsih_bus_reset: "
1852 "Can't locate host! (sc=%p)\n",
1857 printk(KERN_WARNING MYNAM
": %s: attempting bus reset! (sc=%p)\n",
1858 hd
->ioc
->name
, SCpnt
);
1859 scsi_print_command(SCpnt
);
1861 if (hd
->timeouts
< -1)
1864 vdev
= SCpnt
->device
->hostdata
;
1865 retval
= mptscsih_TMHandler(hd
, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS
,
1866 vdev
->vtarget
->bus_id
, 0, 0, 0, mptscsih_get_tm_timeout(hd
->ioc
));
1868 printk (KERN_WARNING MYNAM
": %s: bus reset: %s (sc=%p)\n",
1870 ((retval
== 0) ? "SUCCESS" : "FAILED" ), SCpnt
);
1875 if(retval
!= FAILED
) {
1877 hd
->tmState
= TM_STATE_NONE
;
1882 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1884 * mptscsih_host_reset - Perform a SCSI host adapter RESET!
1886 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1888 * (linux scsi_host_template.eh_host_reset_handler routine)
1890 * Returns SUCCESS or FAILED.
1893 mptscsih_host_reset(struct scsi_cmnd
*SCpnt
)
1896 int status
= SUCCESS
;
1898 /* If we can't locate the host to reset, then we failed. */
1899 if ((hd
= (MPT_SCSI_HOST
*) SCpnt
->device
->host
->hostdata
) == NULL
){
1900 dtmprintk( ( KERN_INFO MYNAM
": mptscsih_host_reset: "
1901 "Can't locate host! (sc=%p)\n",
1906 printk(KERN_WARNING MYNAM
": %s: Attempting host reset! (sc=%p)\n",
1907 hd
->ioc
->name
, SCpnt
);
1909 /* If our attempts to reset the host failed, then return a failed
1910 * status. The host will be taken off line by the SCSI mid-layer.
1912 if (mpt_HardResetHandler(hd
->ioc
, CAN_SLEEP
) < 0){
1915 /* Make sure TM pending is cleared and TM state is set to
1919 hd
->tmState
= TM_STATE_NONE
;
1922 dtmprintk( ( KERN_INFO MYNAM
": mptscsih_host_reset: "
1924 (status
== SUCCESS
) ? "SUCCESS" : "FAILED" ) );
1929 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1931 * mptscsih_tm_pending_wait - wait for pending task management request to
1933 * @hd: Pointer to MPT host structure.
1935 * Returns {SUCCESS,FAILED}.
1938 mptscsih_tm_pending_wait(MPT_SCSI_HOST
* hd
)
1940 unsigned long flags
;
1941 int loop_count
= 4 * 10; /* Wait 10 seconds */
1942 int status
= FAILED
;
1945 spin_lock_irqsave(&hd
->ioc
->FreeQlock
, flags
);
1946 if (hd
->tmState
== TM_STATE_NONE
) {
1947 hd
->tmState
= TM_STATE_IN_PROGRESS
;
1949 spin_unlock_irqrestore(&hd
->ioc
->FreeQlock
, flags
);
1953 spin_unlock_irqrestore(&hd
->ioc
->FreeQlock
, flags
);
1955 } while (--loop_count
);
1960 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1962 * mptscsih_tm_wait_for_completion - wait for completion of TM task
1963 * @hd: Pointer to MPT host structure.
1965 * Returns {SUCCESS,FAILED}.
1968 mptscsih_tm_wait_for_completion(MPT_SCSI_HOST
* hd
, ulong timeout
)
1970 unsigned long flags
;
1971 int loop_count
= 4 * timeout
;
1972 int status
= FAILED
;
1975 spin_lock_irqsave(&hd
->ioc
->FreeQlock
, flags
);
1976 if(hd
->tmPending
== 0) {
1978 spin_unlock_irqrestore(&hd
->ioc
->FreeQlock
, flags
);
1981 spin_unlock_irqrestore(&hd
->ioc
->FreeQlock
, flags
);
1983 } while (--loop_count
);
1988 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1990 mptscsih_taskmgmt_response_code(MPT_ADAPTER
*ioc
, u8 response_code
)
1994 switch (response_code
) {
1995 case MPI_SCSITASKMGMT_RSP_TM_COMPLETE
:
1996 desc
= "The task completed.";
1998 case MPI_SCSITASKMGMT_RSP_INVALID_FRAME
:
1999 desc
= "The IOC received an invalid frame status.";
2001 case MPI_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED
:
2002 desc
= "The task type is not supported.";
2004 case MPI_SCSITASKMGMT_RSP_TM_FAILED
:
2005 desc
= "The requested task failed.";
2007 case MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED
:
2008 desc
= "The task completed successfully.";
2010 case MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN
:
2011 desc
= "The LUN request is invalid.";
2013 case MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC
:
2014 desc
= "The task is in the IOC queue and has not been sent to target.";
2020 printk(MYIOC_s_INFO_FMT
"Response Code(0x%08x): F/W: %s\n",
2021 ioc
->name
, response_code
, desc
);
2024 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2026 * mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
2027 * @ioc: Pointer to MPT_ADAPTER structure
2028 * @mf: Pointer to SCSI task mgmt request frame
2029 * @mr: Pointer to SCSI task mgmt reply frame
2031 * This routine is called from mptbase.c::mpt_interrupt() at the completion
2032 * of any SCSI task management request.
2033 * This routine is registered with the MPT (base) driver at driver
2034 * load/init time via the mpt_register() API call.
2036 * Returns 1 indicating alloc'd request frame ptr should be freed.
2039 mptscsih_taskmgmt_complete(MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*mf
, MPT_FRAME_HDR
*mr
)
2041 SCSITaskMgmtReply_t
*pScsiTmReply
;
2042 SCSITaskMgmt_t
*pScsiTmReq
;
2044 unsigned long flags
;
2048 dtmprintk((MYIOC_s_WARN_FMT
"TaskMgmt completed (mf=%p,mr=%p)\n",
2049 ioc
->name
, mf
, mr
));
2051 /* Depending on the thread, a timer is activated for
2052 * the TM request. Delete this timer on completion of TM.
2053 * Decrement count of outstanding TM requests.
2055 hd
= (MPT_SCSI_HOST
*)ioc
->sh
->hostdata
;
2057 dtmprintk((MYIOC_s_WARN_FMT
"TaskMgmt Complete: NULL Scsi Host Ptr\n",
2063 dtmprintk((MYIOC_s_WARN_FMT
"ERROR! TaskMgmt Reply: NULL Request %p\n",
2067 pScsiTmReply
= (SCSITaskMgmtReply_t
*)mr
;
2068 pScsiTmReq
= (SCSITaskMgmt_t
*)mf
;
2070 /* Figure out if this was ABORT_TASK, TARGET_RESET, or BUS_RESET! */
2071 tmType
= pScsiTmReq
->TaskType
;
2073 if (ioc
->facts
.MsgVersion
>= MPI_VERSION_01_05
&&
2074 pScsiTmReply
->ResponseCode
)
2075 mptscsih_taskmgmt_response_code(ioc
,
2076 pScsiTmReply
->ResponseCode
);
2078 dtmprintk((MYIOC_s_WARN_FMT
" TaskType = %d, TerminationCount=%d\n",
2079 ioc
->name
, tmType
, le32_to_cpu(pScsiTmReply
->TerminationCount
)));
2080 DBG_DUMP_TM_REPLY_FRAME((u32
*)pScsiTmReply
);
2082 iocstatus
= le16_to_cpu(pScsiTmReply
->IOCStatus
) & MPI_IOCSTATUS_MASK
;
2083 dtmprintk((MYIOC_s_WARN_FMT
" SCSI TaskMgmt (%d) IOCStatus=%04x IOCLogInfo=%08x\n",
2084 ioc
->name
, tmType
, iocstatus
, le32_to_cpu(pScsiTmReply
->IOCLogInfo
)));
2085 /* Error? (anything non-zero?) */
2088 /* clear flags and continue.
2090 if (tmType
== MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK
)
2091 hd
->abortSCpnt
= NULL
;
2093 /* If an internal command is present
2094 * or the TM failed - reload the FW.
2095 * FC FW may respond FAILED to an ABORT
2097 if (tmType
== MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS
) {
2099 (iocstatus
== MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED
)) {
2100 if (mpt_HardResetHandler(ioc
, NO_SLEEP
) < 0) {
2101 printk((KERN_WARNING
2102 " Firmware Reload FAILED!!\n"));
2107 dtmprintk((MYIOC_s_WARN_FMT
" TaskMgmt SUCCESS\n", ioc
->name
));
2109 hd
->abortSCpnt
= NULL
;
2114 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
2116 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
2117 hd
->tmState
= TM_STATE_NONE
;
2122 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2124 * This is anyones guess quite frankly.
2127 mptscsih_bios_param(struct scsi_device
* sdev
, struct block_device
*bdev
,
2128 sector_t capacity
, int geom
[])
2138 dummy
= heads
* sectors
;
2139 cylinders
= capacity
;
2140 sector_div(cylinders
,dummy
);
2143 * Handle extended translation size for logical drives
2146 if ((ulong
)capacity
>= 0x200000) {
2149 dummy
= heads
* sectors
;
2150 cylinders
= capacity
;
2151 sector_div(cylinders
,dummy
);
2157 geom
[2] = cylinders
;
2159 dprintk((KERN_NOTICE
2160 ": bios_param: Id=%i Lun=%i Channel=%i CHS=%i/%i/%i\n",
2161 sdev
->id
, sdev
->lun
,sdev
->channel
,(int)cylinders
,heads
,sectors
));
2166 /* Search IOC page 3 to determine if this is hidden physical disk
2170 mptscsih_is_phys_disk(MPT_ADAPTER
*ioc
, int id
)
2174 if (!ioc
->raid_data
.isRaid
|| !ioc
->raid_data
.pIocPg3
)
2176 for (i
= 0; i
< ioc
->raid_data
.pIocPg3
->NumPhysDisks
; i
++) {
2177 if (id
== ioc
->raid_data
.pIocPg3
->PhysDisk
[i
].PhysDiskID
)
2182 EXPORT_SYMBOL(mptscsih_is_phys_disk
);
2185 mptscsih_raid_id_to_num(MPT_SCSI_HOST
*hd
, uint physdiskid
)
2189 if (!hd
->ioc
->raid_data
.isRaid
|| !hd
->ioc
->raid_data
.pIocPg3
)
2192 for (i
= 0; i
< hd
->ioc
->raid_data
.pIocPg3
->NumPhysDisks
; i
++) {
2194 hd
->ioc
->raid_data
.pIocPg3
->PhysDisk
[i
].PhysDiskID
)
2195 return hd
->ioc
->raid_data
.pIocPg3
->PhysDisk
[i
].PhysDiskNum
;
2200 EXPORT_SYMBOL(mptscsih_raid_id_to_num
);
2202 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2204 * OS entry point to allow host driver to alloc memory
2205 * for each scsi target. Called once per device the bus scan.
2206 * Return non-zero if allocation fails.
2209 mptscsih_target_alloc(struct scsi_target
*starget
)
2211 VirtTarget
*vtarget
;
2213 vtarget
= kzalloc(sizeof(VirtTarget
), GFP_KERNEL
);
2216 starget
->hostdata
= vtarget
;
2217 vtarget
->starget
= starget
;
2221 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2223 * OS entry point to allow host driver to alloc memory
2224 * for each scsi device. Called once per device the bus scan.
2225 * Return non-zero if allocation fails.
2228 mptscsih_slave_alloc(struct scsi_device
*sdev
)
2230 struct Scsi_Host
*host
= sdev
->host
;
2231 MPT_SCSI_HOST
*hd
= (MPT_SCSI_HOST
*)host
->hostdata
;
2232 VirtTarget
*vtarget
;
2234 struct scsi_target
*starget
;
2236 vdev
= kzalloc(sizeof(VirtDevice
), GFP_KERNEL
);
2238 printk(MYIOC_s_ERR_FMT
"slave_alloc kmalloc(%zd) FAILED!\n",
2239 hd
->ioc
->name
, sizeof(VirtDevice
));
2243 vdev
->lun
= sdev
->lun
;
2244 sdev
->hostdata
= vdev
;
2246 starget
= scsi_target(sdev
);
2247 vtarget
= starget
->hostdata
;
2249 vdev
->vtarget
= vtarget
;
2251 if (vtarget
->num_luns
== 0) {
2252 hd
->Targets
[sdev
->id
] = vtarget
;
2253 vtarget
->ioc_id
= hd
->ioc
->id
;
2254 vtarget
->tflags
= MPT_TARGET_FLAGS_Q_YES
;
2255 vtarget
->target_id
= sdev
->id
;
2256 vtarget
->bus_id
= sdev
->channel
;
2257 if (hd
->ioc
->bus_type
== SPI
&& sdev
->channel
== 0 &&
2258 hd
->ioc
->raid_data
.isRaid
& (1 << sdev
->id
)) {
2259 vtarget
->raidVolume
= 1;
2260 ddvtprintk((KERN_INFO
2261 "RAID Volume @ id %d\n", sdev
->id
));
2264 vtarget
->num_luns
++;
2269 * OS entry point to allow for host driver to free allocated memory
2270 * Called if no device present or device being unloaded
2273 mptscsih_target_destroy(struct scsi_target
*starget
)
2275 if (starget
->hostdata
)
2276 kfree(starget
->hostdata
);
2277 starget
->hostdata
= NULL
;
2281 * OS entry point to allow for host driver to free allocated memory
2282 * Called if no device present or device being unloaded
2285 mptscsih_slave_destroy(struct scsi_device
*sdev
)
2287 struct Scsi_Host
*host
= sdev
->host
;
2288 MPT_SCSI_HOST
*hd
= (MPT_SCSI_HOST
*)host
->hostdata
;
2289 VirtTarget
*vtarget
;
2290 VirtDevice
*vdevice
;
2291 struct scsi_target
*starget
;
2293 starget
= scsi_target(sdev
);
2294 vtarget
= starget
->hostdata
;
2295 vdevice
= sdev
->hostdata
;
2297 mptscsih_search_running_cmds(hd
, vdevice
);
2298 vtarget
->luns
[0] &= ~(1 << vdevice
->lun
);
2299 vtarget
->num_luns
--;
2300 if (vtarget
->num_luns
== 0) {
2301 hd
->Targets
[sdev
->id
] = NULL
;
2303 mptscsih_synchronize_cache(hd
, vdevice
);
2305 sdev
->hostdata
= NULL
;
2308 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2310 * mptscsih_change_queue_depth - This function will set a devices queue depth
2311 * @sdev: per scsi_device pointer
2312 * @qdepth: requested queue depth
2314 * Adding support for new 'change_queue_depth' api.
2317 mptscsih_change_queue_depth(struct scsi_device
*sdev
, int qdepth
)
2319 MPT_SCSI_HOST
*hd
= (MPT_SCSI_HOST
*)sdev
->host
->hostdata
;
2320 VirtTarget
*vtarget
;
2321 struct scsi_target
*starget
;
2325 starget
= scsi_target(sdev
);
2326 vtarget
= starget
->hostdata
;
2328 if (hd
->ioc
->bus_type
== SPI
) {
2329 if (!(vtarget
->tflags
& MPT_TARGET_FLAGS_Q_YES
))
2331 else if (sdev
->type
== TYPE_DISK
&&
2332 vtarget
->minSyncFactor
<= MPT_ULTRA160
)
2333 max_depth
= MPT_SCSI_CMD_PER_DEV_HIGH
;
2335 max_depth
= MPT_SCSI_CMD_PER_DEV_LOW
;
2337 max_depth
= MPT_SCSI_CMD_PER_DEV_HIGH
;
2339 if (qdepth
> max_depth
)
2344 tagged
= MSG_SIMPLE_TAG
;
2346 scsi_adjust_queue_depth(sdev
, tagged
, qdepth
);
2347 return sdev
->queue_depth
;
2351 * OS entry point to adjust the queue_depths on a per-device basis.
2352 * Called once per device the bus scan. Use it to force the queue_depth
2353 * member to 1 if a device does not support Q tags.
2354 * Return non-zero if fails.
2357 mptscsih_slave_configure(struct scsi_device
*sdev
)
2359 struct Scsi_Host
*sh
= sdev
->host
;
2360 VirtTarget
*vtarget
;
2361 VirtDevice
*vdevice
;
2362 struct scsi_target
*starget
;
2363 MPT_SCSI_HOST
*hd
= (MPT_SCSI_HOST
*)sh
->hostdata
;
2364 int indexed_lun
, lun_index
;
2366 starget
= scsi_target(sdev
);
2367 vtarget
= starget
->hostdata
;
2368 vdevice
= sdev
->hostdata
;
2370 dsprintk((MYIOC_s_INFO_FMT
2371 "device @ %p, id=%d, LUN=%d, channel=%d\n",
2372 hd
->ioc
->name
, sdev
, sdev
->id
, sdev
->lun
, sdev
->channel
));
2373 if (hd
->ioc
->bus_type
== SPI
)
2374 dsprintk((MYIOC_s_INFO_FMT
2375 "sdtr %d wdtr %d ppr %d inq length=%d\n",
2376 hd
->ioc
->name
, sdev
->sdtr
, sdev
->wdtr
,
2377 sdev
->ppr
, sdev
->inquiry_len
));
2379 if (sdev
->id
> sh
->max_id
) {
2380 /* error case, should never happen */
2381 scsi_adjust_queue_depth(sdev
, 0, 1);
2382 goto slave_configure_exit
;
2385 vdevice
->configured_lun
=1;
2386 lun_index
= (vdevice
->lun
>> 5); /* 32 luns per lun_index */
2387 indexed_lun
= (vdevice
->lun
% 32);
2388 vtarget
->luns
[lun_index
] |= (1 << indexed_lun
);
2389 mptscsih_initTarget(hd
, vtarget
, sdev
);
2390 mptscsih_change_queue_depth(sdev
, MPT_SCSI_CMD_PER_DEV_HIGH
);
2392 dsprintk((MYIOC_s_INFO_FMT
2393 "Queue depth=%d, tflags=%x\n",
2394 hd
->ioc
->name
, sdev
->queue_depth
, vtarget
->tflags
));
2396 if (hd
->ioc
->bus_type
== SPI
)
2397 dsprintk((MYIOC_s_INFO_FMT
2398 "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
2399 hd
->ioc
->name
, vtarget
->negoFlags
, vtarget
->maxOffset
,
2400 vtarget
->minSyncFactor
));
2402 slave_configure_exit
:
2404 dsprintk((MYIOC_s_INFO_FMT
2405 "tagged %d, simple %d, ordered %d\n",
2406 hd
->ioc
->name
,sdev
->tagged_supported
, sdev
->simple_tags
,
2407 sdev
->ordered_tags
));
2412 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2414 * Private routines...
2417 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2418 /* Utility function to copy sense data from the scsi_cmnd buffer
2419 * to the FC and SCSI target structures.
2423 mptscsih_copy_sense_data(struct scsi_cmnd
*sc
, MPT_SCSI_HOST
*hd
, MPT_FRAME_HDR
*mf
, SCSIIOReply_t
*pScsiReply
)
2426 SCSIIORequest_t
*pReq
;
2427 u32 sense_count
= le32_to_cpu(pScsiReply
->SenseCount
);
2429 /* Get target structure
2431 pReq
= (SCSIIORequest_t
*) mf
;
2432 vdev
= sc
->device
->hostdata
;
2438 /* Copy the sense received into the scsi command block. */
2439 req_index
= le16_to_cpu(mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
);
2440 sense_data
= ((u8
*)hd
->ioc
->sense_buf_pool
+ (req_index
* MPT_SENSE_BUFFER_ALLOC
));
2441 memcpy(sc
->sense_buffer
, sense_data
, SNS_LEN(sc
));
2443 /* Log SMART data (asc = 0x5D, non-IM case only) if required.
2445 if ((hd
->ioc
->events
) && (hd
->ioc
->eventTypes
& (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE
))) {
2446 if ((sense_data
[12] == 0x5D) && (vdev
->vtarget
->raidVolume
== 0)) {
2448 MPT_ADAPTER
*ioc
= hd
->ioc
;
2450 idx
= ioc
->eventContext
% MPTCTL_EVENT_LOG_SIZE
;
2451 ioc
->events
[idx
].event
= MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE
;
2452 ioc
->events
[idx
].eventContext
= ioc
->eventContext
;
2454 ioc
->events
[idx
].data
[0] = (pReq
->LUN
[1] << 24) ||
2455 (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA
<< 16) ||
2456 (sc
->device
->channel
<< 8) || sc
->device
->id
;
2458 ioc
->events
[idx
].data
[1] = (sense_data
[13] << 8) || sense_data
[12];
2460 ioc
->eventContext
++;
2461 if (hd
->ioc
->pcidev
->vendor
==
2462 PCI_VENDOR_ID_IBM
) {
2463 mptscsih_issue_sep_command(hd
->ioc
,
2464 vdev
->vtarget
, MPI_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT
);
2465 vdev
->vtarget
->tflags
|=
2466 MPT_TARGET_FLAGS_LED_ON
;
2471 dprintk((MYIOC_s_INFO_FMT
"Hmmm... SenseData len=0! (?)\n",
2477 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd
*sc
)
2482 hd
= (MPT_SCSI_HOST
*) sc
->device
->host
->hostdata
;
2484 for (i
= 0; i
< hd
->ioc
->req_depth
; i
++) {
2485 if (hd
->ScsiLookup
[i
] == sc
) {
2493 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2495 mptscsih_ioc_reset(MPT_ADAPTER
*ioc
, int reset_phase
)
2498 unsigned long flags
;
2501 dtmprintk((KERN_WARNING MYNAM
2502 ": IOC %s_reset routed to SCSI host driver!\n",
2503 reset_phase
==MPT_IOC_SETUP_RESET
? "setup" : (
2504 reset_phase
==MPT_IOC_PRE_RESET
? "pre" : "post")));
2506 /* If a FW reload request arrives after base installed but
2507 * before all scsi hosts have been attached, then an alt_ioc
2508 * may have a NULL sh pointer.
2510 if ((ioc
->sh
== NULL
) || (ioc
->sh
->hostdata
== NULL
))
2513 hd
= (MPT_SCSI_HOST
*) ioc
->sh
->hostdata
;
2515 if (reset_phase
== MPT_IOC_SETUP_RESET
) {
2516 dtmprintk((MYIOC_s_WARN_FMT
"Setup-Diag Reset\n", ioc
->name
));
2519 * 1. Set Hard Reset Pending Flag
2520 * All new commands go to doneQ
2522 hd
->resetPending
= 1;
2524 } else if (reset_phase
== MPT_IOC_PRE_RESET
) {
2525 dtmprintk((MYIOC_s_WARN_FMT
"Pre-Diag Reset\n", ioc
->name
));
2527 /* 2. Flush running commands
2528 * Clean ScsiLookup (and associated memory)
2532 /* 2b. Reply to OS all known outstanding I/O commands.
2534 mptscsih_flush_running_cmds(hd
);
2536 /* 2c. If there was an internal command that
2537 * has not completed, configuration or io request,
2538 * free these resources.
2541 del_timer(&hd
->timer
);
2542 mpt_free_msg_frame(ioc
, hd
->cmdPtr
);
2545 dtmprintk((MYIOC_s_WARN_FMT
"Pre-Reset complete.\n", ioc
->name
));
2548 dtmprintk((MYIOC_s_WARN_FMT
"Post-Diag Reset\n", ioc
->name
));
2550 /* Once a FW reload begins, all new OS commands are
2551 * redirected to the doneQ w/ a reset status.
2552 * Init all control structures.
2555 /* ScsiLookup initialization
2557 for (ii
=0; ii
< hd
->ioc
->req_depth
; ii
++)
2558 hd
->ScsiLookup
[ii
] = NULL
;
2560 /* 2. Chain Buffer initialization
2563 /* 4. Renegotiate to all devices, if SPI
2566 /* 5. Enable new commands to be posted
2568 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
2570 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
2571 hd
->resetPending
= 0;
2572 hd
->tmState
= TM_STATE_NONE
;
2574 /* 6. If there was an internal command,
2575 * wake this process up.
2579 * Wake up the original calling thread
2581 hd
->pLocal
= &hd
->localReply
;
2582 hd
->pLocal
->completion
= MPT_SCANDV_DID_RESET
;
2583 hd
->scandv_wait_done
= 1;
2584 wake_up(&hd
->scandv_waitq
);
2588 dtmprintk((MYIOC_s_WARN_FMT
"Post-Reset complete.\n", ioc
->name
));
2592 return 1; /* currently means nothing really */
2595 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2597 mptscsih_event_process(MPT_ADAPTER
*ioc
, EventNotificationReply_t
*pEvReply
)
2600 u8 event
= le32_to_cpu(pEvReply
->Event
) & 0xFF;
2602 devtverboseprintk((MYIOC_s_INFO_FMT
"MPT event (=%02Xh) routed to SCSI host driver!\n",
2605 if (ioc
->sh
== NULL
||
2606 ((hd
= (MPT_SCSI_HOST
*)ioc
->sh
->hostdata
) == NULL
))
2610 case MPI_EVENT_UNIT_ATTENTION
: /* 03 */
2613 case MPI_EVENT_IOC_BUS_RESET
: /* 04 */
2614 case MPI_EVENT_EXT_BUS_RESET
: /* 05 */
2615 if (hd
&& (ioc
->bus_type
== SPI
) && (hd
->soft_resets
< -1))
2618 case MPI_EVENT_LOGOUT
: /* 09 */
2622 case MPI_EVENT_RESCAN
: /* 06 */
2626 * CHECKME! Don't think we need to do
2627 * anything for these, but...
2629 case MPI_EVENT_LINK_STATUS_CHANGE
: /* 07 */
2630 case MPI_EVENT_LOOP_STATE_CHANGE
: /* 08 */
2632 * CHECKME! Falling thru...
2636 case MPI_EVENT_INTEGRATED_RAID
: /* 0B */
2639 case MPI_EVENT_NONE
: /* 00 */
2640 case MPI_EVENT_LOG_DATA
: /* 01 */
2641 case MPI_EVENT_STATE_CHANGE
: /* 02 */
2642 case MPI_EVENT_EVENT_CHANGE
: /* 0A */
2644 dprintk((KERN_INFO
" Ignoring event (=%02Xh)\n", event
));
2648 return 1; /* currently means nothing really */
2651 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2653 * mptscsih_initTarget - Target, LUN alloc/free functionality.
2654 * @hd: Pointer to MPT_SCSI_HOST structure
2655 * @vtarget: per target private data
2656 * @sdev: SCSI device
2658 * NOTE: It's only SAFE to call this routine if data points to
2659 * sane & valid STANDARD INQUIRY data!
2661 * Allocate and initialize memory for this target.
2662 * Save inquiry data.
2666 mptscsih_initTarget(MPT_SCSI_HOST
*hd
, VirtTarget
*vtarget
,
2667 struct scsi_device
*sdev
)
2669 dinitprintk((MYIOC_s_INFO_FMT
"initTarget bus=%d id=%d lun=%d hd=%p\n",
2670 hd
->ioc
->name
, vtarget
->bus_id
, vtarget
->target_id
, lun
, hd
));
2672 /* Is LUN supported? If so, upper 2 bits will be 0
2673 * in first byte of inquiry data.
2675 if (sdev
->inq_periph_qual
!= 0)
2678 if (vtarget
== NULL
)
2681 vtarget
->type
= sdev
->type
;
2683 if (hd
->ioc
->bus_type
!= SPI
)
2686 if ((sdev
->type
== TYPE_PROCESSOR
) && (hd
->ioc
->spi_data
.Saf_Te
)) {
2687 /* Treat all Processors as SAF-TE if
2688 * command line option is set */
2689 vtarget
->tflags
|= MPT_TARGET_FLAGS_SAF_TE_ISSUED
;
2690 mptscsih_writeIOCPage4(hd
, vtarget
->target_id
, vtarget
->bus_id
);
2691 }else if ((sdev
->type
== TYPE_PROCESSOR
) &&
2692 !(vtarget
->tflags
& MPT_TARGET_FLAGS_SAF_TE_ISSUED
)) {
2693 if (sdev
->inquiry_len
> 49 ) {
2694 if (sdev
->inquiry
[44] == 'S' &&
2695 sdev
->inquiry
[45] == 'A' &&
2696 sdev
->inquiry
[46] == 'F' &&
2697 sdev
->inquiry
[47] == '-' &&
2698 sdev
->inquiry
[48] == 'T' &&
2699 sdev
->inquiry
[49] == 'E' ) {
2700 vtarget
->tflags
|= MPT_TARGET_FLAGS_SAF_TE_ISSUED
;
2701 mptscsih_writeIOCPage4(hd
, vtarget
->target_id
, vtarget
->bus_id
);
2705 mptscsih_setTargetNegoParms(hd
, vtarget
, sdev
);
2708 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2710 * Update the target negotiation parameters based on the
2711 * the Inquiry data, adapter capabilities, and NVRAM settings.
2715 mptscsih_setTargetNegoParms(MPT_SCSI_HOST
*hd
, VirtTarget
*target
,
2716 struct scsi_device
*sdev
)
2718 SpiCfgData
*pspi_data
= &hd
->ioc
->spi_data
;
2719 int id
= (int) target
->target_id
;
2721 u8 width
= MPT_NARROW
;
2722 u8 factor
= MPT_ASYNC
;
2727 target
->negoFlags
= pspi_data
->noQas
;
2729 /* noQas == 0 => device supports QAS. */
2731 if (sdev
->scsi_level
< SCSI_2
) {
2733 factor
= MPT_ULTRA2
;
2734 offset
= pspi_data
->maxSyncOffset
;
2735 target
->tflags
&= ~MPT_TARGET_FLAGS_Q_YES
;
2737 if (scsi_device_wide(sdev
)) {
2741 if (scsi_device_sync(sdev
)) {
2742 factor
= pspi_data
->minSyncFactor
;
2743 if (!scsi_device_dt(sdev
))
2744 factor
= MPT_ULTRA2
;
2746 if (!scsi_device_ius(sdev
) &&
2747 !scsi_device_qas(sdev
))
2748 factor
= MPT_ULTRA160
;
2750 factor
= MPT_ULTRA320
;
2751 if (scsi_device_qas(sdev
)) {
2752 ddvtprintk((KERN_INFO
"Enabling QAS due to byte56=%02x on id=%d!\n", byte56
, id
));
2755 if (sdev
->type
== TYPE_TAPE
&&
2756 scsi_device_ius(sdev
))
2757 target
->negoFlags
|= MPT_TAPE_NEGO_IDP
;
2760 offset
= pspi_data
->maxSyncOffset
;
2762 /* If RAID, never disable QAS
2763 * else if non RAID, do not disable
2764 * QAS if bit 1 is set
2765 * bit 1 QAS support, non-raid only
2768 if (target
->raidVolume
== 1) {
2777 if (!sdev
->tagged_supported
) {
2778 target
->tflags
&= ~MPT_TARGET_FLAGS_Q_YES
;
2781 /* Update tflags based on NVRAM settings. (SCSI only)
2783 if (pspi_data
->nvram
&& (pspi_data
->nvram
[id
] != MPT_HOST_NVRAM_INVALID
)) {
2784 nvram
= pspi_data
->nvram
[id
];
2785 nfactor
= (nvram
& MPT_NVRAM_SYNC_MASK
) >> 8;
2788 width
= nvram
& MPT_NVRAM_WIDE_DISABLE
? 0 : 1;
2791 /* Ensure factor is set to the
2792 * maximum of: adapter, nvram, inquiry
2795 if (nfactor
< pspi_data
->minSyncFactor
)
2796 nfactor
= pspi_data
->minSyncFactor
;
2798 factor
= max(factor
, nfactor
);
2799 if (factor
== MPT_ASYNC
)
2810 /* Make sure data is consistent
2812 if ((!width
) && (factor
< MPT_ULTRA2
)) {
2813 factor
= MPT_ULTRA2
;
2816 /* Save the data to the target structure.
2818 target
->minSyncFactor
= factor
;
2819 target
->maxOffset
= offset
;
2820 target
->maxWidth
= width
;
2822 target
->tflags
|= MPT_TARGET_FLAGS_VALID_NEGO
;
2824 /* Disable unused features.
2827 target
->negoFlags
|= MPT_TARGET_NO_NEGO_WIDE
;
2830 target
->negoFlags
|= MPT_TARGET_NO_NEGO_SYNC
;
2832 if ( factor
> MPT_ULTRA320
)
2835 if (noQas
&& (pspi_data
->noQas
== 0)) {
2836 pspi_data
->noQas
|= MPT_TARGET_NO_NEGO_QAS
;
2837 target
->negoFlags
|= MPT_TARGET_NO_NEGO_QAS
;
2839 /* Disable QAS in a mixed configuration case
2842 ddvtprintk((KERN_INFO
"Disabling QAS due to noQas=%02x on id=%d!\n", noQas
, id
));
2846 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2848 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2850 * SCSI Config Page functionality ...
2853 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2854 /* mptscsih_writeIOCPage4 - write IOC Page 4
2855 * @hd: Pointer to a SCSI Host Structure
2856 * @target_id: write IOC Page4 for this ID & Bus
2858 * Return: -EAGAIN if unable to obtain a Message Frame
2861 * Remark: We do not wait for a return, write pages sequentially.
2864 mptscsih_writeIOCPage4(MPT_SCSI_HOST
*hd
, int target_id
, int bus
)
2866 MPT_ADAPTER
*ioc
= hd
->ioc
;
2868 IOCPage4_t
*IOCPage4Ptr
;
2876 /* Get a MF for this command.
2878 if ((mf
= mpt_get_msg_frame(ioc
->DoneCtx
, ioc
)) == NULL
) {
2879 dfailprintk((MYIOC_s_WARN_FMT
"writeIOCPage4 : no msg frames!\n",
2884 /* Set the request and the data pointers.
2885 * Place data at end of MF.
2887 pReq
= (Config_t
*)mf
;
2889 req_idx
= le16_to_cpu(mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
);
2890 frameOffset
= ioc
->req_sz
- sizeof(IOCPage4_t
);
2892 /* Complete the request frame (same for all requests).
2894 pReq
->Action
= MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT
;
2896 pReq
->ChainOffset
= 0;
2897 pReq
->Function
= MPI_FUNCTION_CONFIG
;
2898 pReq
->ExtPageLength
= 0;
2899 pReq
->ExtPageType
= 0;
2901 for (ii
=0; ii
< 8; ii
++) {
2902 pReq
->Reserved2
[ii
] = 0;
2905 IOCPage4Ptr
= ioc
->spi_data
.pIocPg4
;
2906 dataDma
= ioc
->spi_data
.IocPg4_dma
;
2907 ii
= IOCPage4Ptr
->ActiveSEP
++;
2908 IOCPage4Ptr
->SEP
[ii
].SEPTargetID
= target_id
;
2909 IOCPage4Ptr
->SEP
[ii
].SEPBus
= bus
;
2910 pReq
->Header
= IOCPage4Ptr
->Header
;
2911 pReq
->PageAddress
= cpu_to_le32(target_id
| (bus
<< 8 ));
2913 /* Add a SGE to the config request.
2915 flagsLength
= MPT_SGE_FLAGS_SSIMPLE_WRITE
|
2916 (IOCPage4Ptr
->Header
.PageLength
+ ii
) * 4;
2918 mpt_add_sge((char *)&pReq
->PageBufferSGE
, flagsLength
, dataDma
);
2920 dinitprintk((MYIOC_s_INFO_FMT
2921 "writeIOCPage4: MaxSEP=%d ActiveSEP=%d id=%d bus=%d\n",
2922 ioc
->name
, IOCPage4Ptr
->MaxSEP
, IOCPage4Ptr
->ActiveSEP
, target_id
, bus
));
2924 mpt_put_msg_frame(ioc
->DoneCtx
, ioc
, mf
);
2929 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2931 * Bus Scan and Domain Validation functionality ...
2934 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2936 * mptscsih_scandv_complete - Scan and DV callback routine registered
2937 * to Fustion MPT (base) driver.
2939 * @ioc: Pointer to MPT_ADAPTER structure
2940 * @mf: Pointer to original MPT request frame
2941 * @mr: Pointer to MPT reply frame (NULL if TurboReply)
2943 * This routine is called from mpt.c::mpt_interrupt() at the completion
2944 * of any SCSI IO request.
2945 * This routine is registered with the Fusion MPT (base) driver at driver
2946 * load/init time via the mpt_register() API call.
2948 * Returns 1 indicating alloc'd request frame ptr should be freed.
2950 * Remark: Sets a completion code and (possibly) saves sense data
2951 * in the IOC member localReply structure.
2952 * Used ONLY for DV and other internal commands.
2955 mptscsih_scandv_complete(MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*mf
, MPT_FRAME_HDR
*mr
)
2958 SCSIIORequest_t
*pReq
;
2962 hd
= (MPT_SCSI_HOST
*) ioc
->sh
->hostdata
;
2965 (mf
>= MPT_INDEX_2_MFPTR(ioc
, ioc
->req_depth
))) {
2966 printk(MYIOC_s_ERR_FMT
2967 "ScanDvComplete, %s req frame ptr! (=%p)\n",
2968 ioc
->name
, mf
?"BAD":"NULL", (void *) mf
);
2972 del_timer(&hd
->timer
);
2973 req_idx
= le16_to_cpu(mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
);
2974 hd
->ScsiLookup
[req_idx
] = NULL
;
2975 pReq
= (SCSIIORequest_t
*) mf
;
2977 if (mf
!= hd
->cmdPtr
) {
2978 printk(MYIOC_s_WARN_FMT
"ScanDvComplete (mf=%p, cmdPtr=%p, idx=%d)\n",
2979 hd
->ioc
->name
, (void *)mf
, (void *) hd
->cmdPtr
, req_idx
);
2983 ddvprintk((MYIOC_s_INFO_FMT
"ScanDvComplete (mf=%p,mr=%p,idx=%d)\n",
2984 hd
->ioc
->name
, mf
, mr
, req_idx
));
2986 hd
->pLocal
= &hd
->localReply
;
2987 hd
->pLocal
->scsiStatus
= 0;
2989 /* If target struct exists, clear sense valid flag.
2992 completionCode
= MPT_SCANDV_GOOD
;
2994 SCSIIOReply_t
*pReply
;
2998 pReply
= (SCSIIOReply_t
*) mr
;
3000 status
= le16_to_cpu(pReply
->IOCStatus
) & MPI_IOCSTATUS_MASK
;
3001 scsi_status
= pReply
->SCSIStatus
;
3003 ddvtprintk((KERN_NOTICE
" IOCStatus=%04xh, SCSIState=%02xh, SCSIStatus=%02xh, IOCLogInfo=%08xh\n",
3004 status
, pReply
->SCSIState
, scsi_status
,
3005 le32_to_cpu(pReply
->IOCLogInfo
)));
3009 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE
: /* 0x0043 */
3010 completionCode
= MPT_SCANDV_SELECTION_TIMEOUT
;
3013 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR
: /* 0x0046 */
3014 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED
: /* 0x0048 */
3015 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED
: /* 0x004B */
3016 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED
: /* 0x004C */
3017 completionCode
= MPT_SCANDV_DID_RESET
;
3020 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN
: /* 0x0045 */
3021 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR
: /* 0x0040 */
3022 case MPI_IOCSTATUS_SUCCESS
: /* 0x0000 */
3023 if (pReply
->Function
== MPI_FUNCTION_CONFIG
) {
3024 ConfigReply_t
*pr
= (ConfigReply_t
*)mr
;
3025 completionCode
= MPT_SCANDV_GOOD
;
3026 hd
->pLocal
->header
.PageVersion
= pr
->Header
.PageVersion
;
3027 hd
->pLocal
->header
.PageLength
= pr
->Header
.PageLength
;
3028 hd
->pLocal
->header
.PageNumber
= pr
->Header
.PageNumber
;
3029 hd
->pLocal
->header
.PageType
= pr
->Header
.PageType
;
3031 } else if (pReply
->Function
== MPI_FUNCTION_RAID_ACTION
) {
3032 /* If the RAID Volume request is successful,
3033 * return GOOD, else indicate that
3034 * some type of error occurred.
3036 MpiRaidActionReply_t
*pr
= (MpiRaidActionReply_t
*)mr
;
3037 if (le16_to_cpu(pr
->ActionStatus
) == MPI_RAID_ACTION_ASTATUS_SUCCESS
)
3038 completionCode
= MPT_SCANDV_GOOD
;
3040 completionCode
= MPT_SCANDV_SOME_ERROR
;
3041 memcpy(hd
->pLocal
->sense
, pr
, sizeof(hd
->pLocal
->sense
));
3043 } else if (pReply
->SCSIState
& MPI_SCSI_STATE_AUTOSENSE_VALID
) {
3047 /* save sense data in global structure
3049 completionCode
= MPT_SCANDV_SENSE
;
3050 hd
->pLocal
->scsiStatus
= scsi_status
;
3051 sense_data
= ((u8
*)hd
->ioc
->sense_buf_pool
+
3052 (req_idx
* MPT_SENSE_BUFFER_ALLOC
));
3054 sz
= min_t(int, pReq
->SenseBufferLength
,
3055 SCSI_STD_SENSE_BYTES
);
3056 memcpy(hd
->pLocal
->sense
, sense_data
, sz
);
3058 ddvprintk((KERN_NOTICE
" Check Condition, sense ptr %p\n",
3060 } else if (pReply
->SCSIState
& MPI_SCSI_STATE_AUTOSENSE_FAILED
) {
3061 if (pReq
->CDB
[0] == INQUIRY
)
3062 completionCode
= MPT_SCANDV_ISSUE_SENSE
;
3064 completionCode
= MPT_SCANDV_DID_RESET
;
3066 else if (pReply
->SCSIState
& MPI_SCSI_STATE_NO_SCSI_STATUS
)
3067 completionCode
= MPT_SCANDV_DID_RESET
;
3068 else if (pReply
->SCSIState
& MPI_SCSI_STATE_TERMINATED
)
3069 completionCode
= MPT_SCANDV_DID_RESET
;
3071 completionCode
= MPT_SCANDV_GOOD
;
3072 hd
->pLocal
->scsiStatus
= scsi_status
;
3076 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR
: /* 0x0047 */
3077 if (pReply
->SCSIState
& MPI_SCSI_STATE_TERMINATED
)
3078 completionCode
= MPT_SCANDV_DID_RESET
;
3080 completionCode
= MPT_SCANDV_SOME_ERROR
;
3084 completionCode
= MPT_SCANDV_SOME_ERROR
;
3087 } /* switch(status) */
3089 ddvtprintk((KERN_NOTICE
" completionCode set to %08xh\n",
3091 } /* end of address reply case */
3093 hd
->pLocal
->completion
= completionCode
;
3095 /* MF and RF are freed in mpt_interrupt
3098 /* Free Chain buffers (will never chain) in scan or dv */
3099 //mptscsih_freeChainBuffers(ioc, req_idx);
3102 * Wake up the original calling thread
3104 hd
->scandv_wait_done
= 1;
3105 wake_up(&hd
->scandv_waitq
);
3110 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3111 /* mptscsih_timer_expired - Call back for timer process.
3112 * Used only for dv functionality.
3113 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
3117 mptscsih_timer_expired(unsigned long data
)
3119 MPT_SCSI_HOST
*hd
= (MPT_SCSI_HOST
*) data
;
3121 ddvprintk((MYIOC_s_WARN_FMT
"Timer Expired! Cmd %p\n", hd
->ioc
->name
, hd
->cmdPtr
));
3124 MPIHeader_t
*cmd
= (MPIHeader_t
*)hd
->cmdPtr
;
3126 if (cmd
->Function
== MPI_FUNCTION_SCSI_IO_REQUEST
) {
3127 /* Desire to issue a task management request here.
3128 * TM requests MUST be single threaded.
3129 * If old eh code and no TM current, issue request.
3130 * If new eh code, do nothing. Wait for OS cmd timeout
3133 ddvtprintk((MYIOC_s_NOTE_FMT
"DV Cmd Timeout: NoOp\n", hd
->ioc
->name
));
3135 /* Perform a FW reload */
3136 if (mpt_HardResetHandler(hd
->ioc
, NO_SLEEP
) < 0) {
3137 printk(MYIOC_s_WARN_FMT
"Firmware Reload FAILED!\n", hd
->ioc
->name
);
3141 /* This should NEVER happen */
3142 printk(MYIOC_s_WARN_FMT
"Null cmdPtr!!!!\n", hd
->ioc
->name
);
3145 /* No more processing.
3146 * TM call will generate an interrupt for SCSI TM Management.
3147 * The FW will reply to all outstanding commands, callback will finish cleanup.
3148 * Hard reset clean-up will free all resources.
3150 ddvprintk((MYIOC_s_WARN_FMT
"Timer Expired Complete!\n", hd
->ioc
->name
));
3156 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3158 * mptscsih_do_cmd - Do internal command.
3159 * @hd: MPT_SCSI_HOST pointer
3160 * @io: INTERNAL_CMD pointer.
3162 * Issue the specified internally generated command and do command
3163 * specific cleanup. For bus scan / DV only.
3164 * NOTES: If command is Inquiry and status is good,
3165 * initialize a target structure, save the data
3167 * Remark: Single threaded access only.
3170 * < 0 if an illegal command or no resources
3174 * > 0 if command complete but some type of completion error.
3177 mptscsih_do_cmd(MPT_SCSI_HOST
*hd
, INTERNAL_CMD
*io
)
3180 SCSIIORequest_t
*pScsiReq
;
3181 SCSIIORequest_t ReqCopy
;
3182 int my_idx
, ii
, dir
;
3186 char CDB
[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
3189 in_isr
= in_interrupt();
3191 dprintk((MYIOC_s_WARN_FMT
"Internal SCSI IO request not allowed in ISR context!\n",
3197 /* Set command specific information
3202 dir
= MPI_SCSIIO_CONTROL_READ
;
3208 case TEST_UNIT_READY
:
3210 dir
= MPI_SCSIIO_CONTROL_READ
;
3216 dir
= MPI_SCSIIO_CONTROL_READ
;
3218 CDB
[4] = 1; /*Spin up the disk */
3226 dir
= MPI_SCSIIO_CONTROL_READ
;
3232 dir
= MPI_SCSIIO_CONTROL_READ
;
3234 if (io
->flags
& MPT_ICFLAG_ECHO
) {
3240 if (io
->flags
& MPT_ICFLAG_BUF_CAP
) {
3243 CDB
[6] = (io
->size
>> 16) & 0xFF;
3244 CDB
[7] = (io
->size
>> 8) & 0xFF;
3245 CDB
[8] = io
->size
& 0xFF;
3251 dir
= MPI_SCSIIO_CONTROL_WRITE
;
3253 if (io
->flags
& MPT_ICFLAG_ECHO
) {
3258 CDB
[6] = (io
->size
>> 16) & 0xFF;
3259 CDB
[7] = (io
->size
>> 8) & 0xFF;
3260 CDB
[8] = io
->size
& 0xFF;
3266 dir
= MPI_SCSIIO_CONTROL_READ
;
3273 dir
= MPI_SCSIIO_CONTROL_READ
;
3278 case SYNCHRONIZE_CACHE
:
3280 dir
= MPI_SCSIIO_CONTROL_READ
;
3282 // CDB[1] = 0x02; /* set immediate bit */
3291 /* Get and Populate a free Frame
3293 if ((mf
= mpt_get_msg_frame(hd
->ioc
->InternalCtx
, hd
->ioc
)) == NULL
) {
3294 ddvprintk((MYIOC_s_WARN_FMT
"No msg frames!\n",
3299 pScsiReq
= (SCSIIORequest_t
*) mf
;
3301 /* Get the request index */
3302 my_idx
= le16_to_cpu(mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
);
3303 ADD_INDEX_LOG(my_idx
); /* for debug */
3305 if (io
->flags
& MPT_ICFLAG_PHYS_DISK
) {
3306 pScsiReq
->TargetID
= io
->physDiskNum
;
3308 pScsiReq
->ChainOffset
= 0;
3309 pScsiReq
->Function
= MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH
;
3311 pScsiReq
->TargetID
= io
->id
;
3312 pScsiReq
->Bus
= io
->bus
;
3313 pScsiReq
->ChainOffset
= 0;
3314 pScsiReq
->Function
= MPI_FUNCTION_SCSI_IO_REQUEST
;
3317 pScsiReq
->CDBLength
= cmdLen
;
3318 pScsiReq
->SenseBufferLength
= MPT_SENSE_BUFFER_SIZE
;
3320 pScsiReq
->Reserved
= 0;
3322 pScsiReq
->MsgFlags
= mpt_msg_flags();
3323 /* MsgContext set in mpt_get_msg_fram call */
3325 for (ii
=0; ii
< 8; ii
++)
3326 pScsiReq
->LUN
[ii
] = 0;
3327 pScsiReq
->LUN
[1] = io
->lun
;
3329 if (io
->flags
& MPT_ICFLAG_TAGGED_CMD
)
3330 pScsiReq
->Control
= cpu_to_le32(dir
| MPI_SCSIIO_CONTROL_SIMPLEQ
);
3332 pScsiReq
->Control
= cpu_to_le32(dir
| MPI_SCSIIO_CONTROL_UNTAGGED
);
3334 if (cmd
== REQUEST_SENSE
) {
3335 pScsiReq
->Control
= cpu_to_le32(dir
| MPI_SCSIIO_CONTROL_UNTAGGED
);
3336 ddvprintk((MYIOC_s_INFO_FMT
"Untagged! 0x%2x\n",
3337 hd
->ioc
->name
, cmd
));
3340 for (ii
=0; ii
< 16; ii
++)
3341 pScsiReq
->CDB
[ii
] = CDB
[ii
];
3343 pScsiReq
->DataLength
= cpu_to_le32(io
->size
);
3344 pScsiReq
->SenseBufferLowAddr
= cpu_to_le32(hd
->ioc
->sense_buf_low_dma
3345 + (my_idx
* MPT_SENSE_BUFFER_ALLOC
));
3347 ddvprintk((MYIOC_s_INFO_FMT
"Sending Command 0x%x for (%d:%d:%d)\n",
3348 hd
->ioc
->name
, cmd
, io
->bus
, io
->id
, io
->lun
));
3350 if (dir
== MPI_SCSIIO_CONTROL_READ
) {
3351 mpt_add_sge((char *) &pScsiReq
->SGL
,
3352 MPT_SGE_FLAGS_SSIMPLE_READ
| io
->size
,
3355 mpt_add_sge((char *) &pScsiReq
->SGL
,
3356 MPT_SGE_FLAGS_SSIMPLE_WRITE
| io
->size
,
3360 /* The ISR will free the request frame, but we need
3361 * the information to initialize the target. Duplicate.
3363 memcpy(&ReqCopy
, pScsiReq
, sizeof(SCSIIORequest_t
));
3365 /* Issue this command after:
3368 * Wait until the reply has been received
3369 * ScsiScanDvCtx callback function will
3371 * set scandv_wait_done and call wake_up
3374 hd
->timer
.expires
= jiffies
+ HZ
*cmdTimeout
;
3375 hd
->scandv_wait_done
= 0;
3377 /* Save cmd pointer, for resource free if timeout or
3382 add_timer(&hd
->timer
);
3383 mpt_put_msg_frame(hd
->ioc
->InternalCtx
, hd
->ioc
, mf
);
3384 wait_event(hd
->scandv_waitq
, hd
->scandv_wait_done
);
3387 rc
= hd
->pLocal
->completion
;
3388 hd
->pLocal
->skip
= 0;
3390 /* Always set fatal error codes in some cases.
3392 if (rc
== MPT_SCANDV_SELECTION_TIMEOUT
)
3394 else if (rc
== MPT_SCANDV_SOME_ERROR
)
3398 /* This should never happen. */
3399 ddvprintk((MYIOC_s_INFO_FMT
"_do_cmd: Null pLocal!!!\n",
3406 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3408 * mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
3409 * @hd: Pointer to a SCSI HOST structure
3410 * @vtarget: per device private data
3413 * Uses the ISR, but with special processing.
3414 * MUST be single-threaded.
3418 mptscsih_synchronize_cache(MPT_SCSI_HOST
*hd
, VirtDevice
*vdevice
)
3422 /* Following parameters will not change
3425 iocmd
.cmd
= SYNCHRONIZE_CACHE
;
3427 iocmd
.physDiskNum
= -1;
3429 iocmd
.data_dma
= -1;
3431 iocmd
.rsvd
= iocmd
.rsvd2
= 0;
3432 iocmd
.bus
= vdevice
->vtarget
->bus_id
;
3433 iocmd
.id
= vdevice
->vtarget
->target_id
;
3434 iocmd
.lun
= (u8
)vdevice
->lun
;
3436 if ((vdevice
->vtarget
->type
== TYPE_DISK
) &&
3437 (vdevice
->configured_lun
))
3438 mptscsih_do_cmd(hd
, &iocmd
);
3441 EXPORT_SYMBOL(mptscsih_remove
);
3442 EXPORT_SYMBOL(mptscsih_shutdown
);
3444 EXPORT_SYMBOL(mptscsih_suspend
);
3445 EXPORT_SYMBOL(mptscsih_resume
);
3447 EXPORT_SYMBOL(mptscsih_proc_info
);
3448 EXPORT_SYMBOL(mptscsih_info
);
3449 EXPORT_SYMBOL(mptscsih_qcmd
);
3450 EXPORT_SYMBOL(mptscsih_target_alloc
);
3451 EXPORT_SYMBOL(mptscsih_slave_alloc
);
3452 EXPORT_SYMBOL(mptscsih_target_destroy
);
3453 EXPORT_SYMBOL(mptscsih_slave_destroy
);
3454 EXPORT_SYMBOL(mptscsih_slave_configure
);
3455 EXPORT_SYMBOL(mptscsih_abort
);
3456 EXPORT_SYMBOL(mptscsih_dev_reset
);
3457 EXPORT_SYMBOL(mptscsih_bus_reset
);
3458 EXPORT_SYMBOL(mptscsih_host_reset
);
3459 EXPORT_SYMBOL(mptscsih_bios_param
);
3460 EXPORT_SYMBOL(mptscsih_io_done
);
3461 EXPORT_SYMBOL(mptscsih_taskmgmt_complete
);
3462 EXPORT_SYMBOL(mptscsih_scandv_complete
);
3463 EXPORT_SYMBOL(mptscsih_event_process
);
3464 EXPORT_SYMBOL(mptscsih_ioc_reset
);
3465 EXPORT_SYMBOL(mptscsih_change_queue_depth
);
3466 EXPORT_SYMBOL(mptscsih_timer_expired
);
3467 EXPORT_SYMBOL(mptscsih_TMHandler
);
3469 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/