2 * linux/drivers/message/fusion/mptscsih.c
3 * For use with LSI PCI chip/adapter(s)
4 * running LSI Fusion MPT (Message Passing Technology) firmware.
6 * Copyright (c) 1999-2007 LSI Corporation
7 * (mailto:DL-MPTFusionLinux@lsi.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/module.h>
48 #include <linux/kernel.h>
49 #include <linux/init.h>
50 #include <linux/errno.h>
51 #include <linux/kdev_t.h>
52 #include <linux/blkdev.h>
53 #include <linux/delay.h> /* for mdelay */
54 #include <linux/interrupt.h> /* needed for in_interrupt() proto */
55 #include <linux/reboot.h> /* notifier code */
56 #include <linux/workqueue.h>
58 #include <scsi/scsi.h>
59 #include <scsi/scsi_cmnd.h>
60 #include <scsi/scsi_device.h>
61 #include <scsi/scsi_host.h>
62 #include <scsi/scsi_tcq.h>
63 #include <scsi/scsi_dbg.h>
67 #include "lsi/mpi_log_sas.h"
69 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
70 #define my_NAME "Fusion MPT SCSI Host driver"
71 #define my_VERSION MPT_LINUX_VERSION_COMMON
72 #define MYNAM "mptscsih"
74 MODULE_AUTHOR(MODULEAUTHOR
);
75 MODULE_DESCRIPTION(my_NAME
);
76 MODULE_LICENSE("GPL");
77 MODULE_VERSION(my_VERSION
);
79 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
81 * Other private/forward protos...
83 int mptscsih_io_done(MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*mf
, MPT_FRAME_HDR
*r
);
84 static void mptscsih_report_queue_full(struct scsi_cmnd
*sc
, SCSIIOReply_t
*pScsiReply
, SCSIIORequest_t
*pScsiReq
);
85 int mptscsih_taskmgmt_complete(MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*mf
, MPT_FRAME_HDR
*r
);
87 static int mptscsih_AddSGE(MPT_ADAPTER
*ioc
, struct scsi_cmnd
*SCpnt
,
88 SCSIIORequest_t
*pReq
, int req_idx
);
89 static void mptscsih_freeChainBuffers(MPT_ADAPTER
*ioc
, int req_idx
);
90 static void mptscsih_copy_sense_data(struct scsi_cmnd
*sc
, MPT_SCSI_HOST
*hd
, MPT_FRAME_HDR
*mf
, SCSIIOReply_t
*pScsiReply
);
91 static int mptscsih_tm_pending_wait(MPT_SCSI_HOST
* hd
);
92 static int mptscsih_tm_wait_for_completion(MPT_SCSI_HOST
* hd
, ulong timeout
);
93 static int SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd
*sc
);
95 static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST
*hd
, u8 type
, u8 channel
, u8 id
, int lun
, int ctx2abort
, ulong timeout
);
97 int mptscsih_ioc_reset(MPT_ADAPTER
*ioc
, int post_reset
);
98 int mptscsih_event_process(MPT_ADAPTER
*ioc
, EventNotificationReply_t
*pEvReply
);
100 int mptscsih_scandv_complete(MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*mf
, MPT_FRAME_HDR
*r
);
101 static int mptscsih_do_cmd(MPT_SCSI_HOST
*hd
, INTERNAL_CMD
*iocmd
);
102 static void mptscsih_synchronize_cache(MPT_SCSI_HOST
*hd
, VirtDevice
*vdevice
);
104 void mptscsih_remove(struct pci_dev
*);
105 void mptscsih_shutdown(struct pci_dev
*);
107 int mptscsih_suspend(struct pci_dev
*pdev
, pm_message_t state
);
108 int mptscsih_resume(struct pci_dev
*pdev
);
111 #define SNS_LEN(scp) sizeof((scp)->sense_buffer)
113 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
115 * mptscsih_add_sge - Place a simple SGE at address pAddr.
116 * @pAddr: virtual address for SGE
117 * @flagslength: SGE flags and data transfer length
118 * @dma_addr: Physical address
120 * This routine places a MPT request frame back on the MPT adapter's
124 mptscsih_add_sge(char *pAddr
, u32 flagslength
, dma_addr_t dma_addr
)
126 if (sizeof(dma_addr_t
) == sizeof(u64
)) {
127 SGESimple64_t
*pSge
= (SGESimple64_t
*) pAddr
;
128 u32 tmp
= dma_addr
& 0xFFFFFFFF;
130 pSge
->FlagsLength
= cpu_to_le32(flagslength
);
131 pSge
->Address
.Low
= cpu_to_le32(tmp
);
132 tmp
= (u32
) ((u64
)dma_addr
>> 32);
133 pSge
->Address
.High
= cpu_to_le32(tmp
);
136 SGESimple32_t
*pSge
= (SGESimple32_t
*) pAddr
;
137 pSge
->FlagsLength
= cpu_to_le32(flagslength
);
138 pSge
->Address
= cpu_to_le32(dma_addr
);
140 } /* mptscsih_add_sge() */
142 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
144 * mptscsih_add_chain - Place a chain SGE at address pAddr.
145 * @pAddr: virtual address for SGE
146 * @next: nextChainOffset value (u32's)
147 * @length: length of next SGL segment
148 * @dma_addr: Physical address
150 * This routine places a MPT request frame back on the MPT adapter's
154 mptscsih_add_chain(char *pAddr
, u8 next
, u16 length
, dma_addr_t dma_addr
)
156 if (sizeof(dma_addr_t
) == sizeof(u64
)) {
157 SGEChain64_t
*pChain
= (SGEChain64_t
*) pAddr
;
158 u32 tmp
= dma_addr
& 0xFFFFFFFF;
160 pChain
->Length
= cpu_to_le16(length
);
161 pChain
->Flags
= MPI_SGE_FLAGS_CHAIN_ELEMENT
| mpt_addr_size();
163 pChain
->NextChainOffset
= next
;
165 pChain
->Address
.Low
= cpu_to_le32(tmp
);
166 tmp
= (u32
) ((u64
)dma_addr
>> 32);
167 pChain
->Address
.High
= cpu_to_le32(tmp
);
169 SGEChain32_t
*pChain
= (SGEChain32_t
*) pAddr
;
170 pChain
->Length
= cpu_to_le16(length
);
171 pChain
->Flags
= MPI_SGE_FLAGS_CHAIN_ELEMENT
| mpt_addr_size();
172 pChain
->NextChainOffset
= next
;
173 pChain
->Address
= cpu_to_le32(dma_addr
);
175 } /* mptscsih_add_chain() */
177 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
179 * mptscsih_getFreeChainBuffer - Function to get a free chain
180 * from the MPT_SCSI_HOST FreeChainQ.
181 * @ioc: Pointer to MPT_ADAPTER structure
182 * @req_idx: Index of the SCSI IO request frame. (output)
184 * return SUCCESS or FAILED
187 mptscsih_getFreeChainBuffer(MPT_ADAPTER
*ioc
, int *retIndex
)
189 MPT_FRAME_HDR
*chainBuf
;
194 dsgprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"getFreeChainBuffer called\n",
196 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
197 if (!list_empty(&ioc
->FreeChainQ
)) {
200 chainBuf
= list_entry(ioc
->FreeChainQ
.next
, MPT_FRAME_HDR
,
201 u
.frame
.linkage
.list
);
202 list_del(&chainBuf
->u
.frame
.linkage
.list
);
203 offset
= (u8
*)chainBuf
- (u8
*)ioc
->ChainBuffer
;
204 chain_idx
= offset
/ ioc
->req_sz
;
206 dsgprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
207 "getFreeChainBuffer chainBuf=%p ChainBuffer=%p offset=%d chain_idx=%d\n",
208 ioc
->name
, chainBuf
, ioc
->ChainBuffer
, offset
, chain_idx
));
211 chain_idx
= MPT_HOST_NO_CHAIN
;
212 dfailprintk(ioc
, printk(MYIOC_s_ERR_FMT
"getFreeChainBuffer failed\n",
215 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
217 *retIndex
= chain_idx
;
219 } /* mptscsih_getFreeChainBuffer() */
221 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
223 * mptscsih_AddSGE - Add a SGE (plus chain buffers) to the
224 * SCSIIORequest_t Message Frame.
225 * @ioc: Pointer to MPT_ADAPTER structure
226 * @SCpnt: Pointer to scsi_cmnd structure
227 * @pReq: Pointer to SCSIIORequest_t structure
232 mptscsih_AddSGE(MPT_ADAPTER
*ioc
, struct scsi_cmnd
*SCpnt
,
233 SCSIIORequest_t
*pReq
, int req_idx
)
237 struct scatterlist
*sg
;
239 int sges_left
, sg_done
;
240 int chain_idx
= MPT_HOST_NO_CHAIN
;
242 int numSgeSlots
, numSgeThisFrame
;
243 u32 sgflags
, sgdir
, thisxfer
= 0;
244 int chain_dma_off
= 0;
250 sgdir
= le32_to_cpu(pReq
->Control
) & MPI_SCSIIO_CONTROL_DATADIRECTION_MASK
;
251 if (sgdir
== MPI_SCSIIO_CONTROL_WRITE
) {
252 sgdir
= MPT_TRANSFER_HOST_TO_IOC
;
254 sgdir
= MPT_TRANSFER_IOC_TO_HOST
;
257 psge
= (char *) &pReq
->SGL
;
258 frm_sz
= ioc
->req_sz
;
260 /* Map the data portion, if any.
261 * sges_left = 0 if no data transfer.
263 sges_left
= scsi_dma_map(SCpnt
);
267 /* Handle the SG case.
269 sg
= scsi_sglist(SCpnt
);
271 sgeOffset
= sizeof(SCSIIORequest_t
) - sizeof(SGE_IO_UNION
);
274 /* Prior to entering this loop - the following must be set
275 * current MF: sgeOffset (bytes)
276 * chainSge (Null if original MF is not a chain buffer)
277 * sg_done (num SGE done for this MF)
281 numSgeSlots
= ((frm_sz
- sgeOffset
) / (sizeof(u32
) + sizeof(dma_addr_t
)) );
282 numSgeThisFrame
= (sges_left
< numSgeSlots
) ? sges_left
: numSgeSlots
;
284 sgflags
= MPT_SGE_FLAGS_SIMPLE_ELEMENT
| MPT_SGE_FLAGS_ADDRESSING
| sgdir
;
286 /* Get first (num - 1) SG elements
287 * Skip any SG entries with a length of 0
288 * NOTE: at finish, sg and psge pointed to NEXT data/location positions
290 for (ii
=0; ii
< (numSgeThisFrame
-1); ii
++) {
291 thisxfer
= sg_dma_len(sg
);
293 sg
++; /* Get next SG element from the OS */
298 v2
= sg_dma_address(sg
);
299 mptscsih_add_sge(psge
, sgflags
| thisxfer
, v2
);
301 sg
++; /* Get next SG element from the OS */
302 psge
+= (sizeof(u32
) + sizeof(dma_addr_t
));
303 sgeOffset
+= (sizeof(u32
) + sizeof(dma_addr_t
));
307 if (numSgeThisFrame
== sges_left
) {
308 /* Add last element, end of buffer and end of list flags.
310 sgflags
|= MPT_SGE_FLAGS_LAST_ELEMENT
|
311 MPT_SGE_FLAGS_END_OF_BUFFER
|
312 MPT_SGE_FLAGS_END_OF_LIST
;
314 /* Add last SGE and set termination flags.
315 * Note: Last SGE may have a length of 0 - which should be ok.
317 thisxfer
= sg_dma_len(sg
);
319 v2
= sg_dma_address(sg
);
320 mptscsih_add_sge(psge
, sgflags
| thisxfer
, v2
);
323 psge += (sizeof(u32) + sizeof(dma_addr_t));
325 sgeOffset
+= (sizeof(u32
) + sizeof(dma_addr_t
));
329 /* The current buffer is a chain buffer,
330 * but there is not another one.
331 * Update the chain element
332 * Offset and Length fields.
334 mptscsih_add_chain((char *)chainSge
, 0, sgeOffset
, ioc
->ChainBufferDMA
+ chain_dma_off
);
336 /* The current buffer is the original MF
337 * and there is no Chain buffer.
339 pReq
->ChainOffset
= 0;
340 RequestNB
= (((sgeOffset
- 1) >> ioc
->NBShiftFactor
) + 1) & 0x03;
341 dsgprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
342 "Single Buffer RequestNB=%x, sgeOffset=%d\n", ioc
->name
, RequestNB
, sgeOffset
));
343 ioc
->RequestNB
[req_idx
] = RequestNB
;
346 /* At least one chain buffer is needed.
347 * Complete the first MF
348 * - last SGE element, set the LastElement bit
349 * - set ChainOffset (words) for orig MF
350 * (OR finish previous MF chain buffer)
351 * - update MFStructPtr ChainIndex
352 * - Populate chain element
357 dsgprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"SG: Chain Required! sg done %d\n",
358 ioc
->name
, sg_done
));
360 /* Set LAST_ELEMENT flag for last non-chain element
361 * in the buffer. Since psge points at the NEXT
362 * SGE element, go back one SGE element, update the flags
363 * and reset the pointer. (Note: sgflags & thisxfer are already
367 u32
*ptmp
= (u32
*) (psge
- (sizeof(u32
) + sizeof(dma_addr_t
)));
368 sgflags
= le32_to_cpu(*ptmp
);
369 sgflags
|= MPT_SGE_FLAGS_LAST_ELEMENT
;
370 *ptmp
= cpu_to_le32(sgflags
);
374 /* The current buffer is a chain buffer.
375 * chainSge points to the previous Chain Element.
376 * Update its chain element Offset and Length (must
377 * include chain element size) fields.
378 * Old chain element is now complete.
380 u8 nextChain
= (u8
) (sgeOffset
>> 2);
381 sgeOffset
+= (sizeof(u32
) + sizeof(dma_addr_t
));
382 mptscsih_add_chain((char *)chainSge
, nextChain
, sgeOffset
, ioc
->ChainBufferDMA
+ chain_dma_off
);
384 /* The original MF buffer requires a chain buffer -
386 * Last element in this MF is a chain element.
388 pReq
->ChainOffset
= (u8
) (sgeOffset
>> 2);
389 RequestNB
= (((sgeOffset
- 1) >> ioc
->NBShiftFactor
) + 1) & 0x03;
390 dsgprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Chain Buffer Needed, RequestNB=%x sgeOffset=%d\n", ioc
->name
, RequestNB
, sgeOffset
));
391 ioc
->RequestNB
[req_idx
] = RequestNB
;
394 sges_left
-= sg_done
;
397 /* NOTE: psge points to the beginning of the chain element
398 * in current buffer. Get a chain buffer.
400 if ((mptscsih_getFreeChainBuffer(ioc
, &newIndex
)) == FAILED
) {
401 dfailprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
402 "getFreeChainBuffer FAILED SCSI cmd=%02x (%p)\n",
403 ioc
->name
, pReq
->CDB
[0], SCpnt
));
407 /* Update the tracking arrays.
408 * If chainSge == NULL, update ReqToChain, else ChainToChain
411 ioc
->ChainToChain
[chain_idx
] = newIndex
;
413 ioc
->ReqToChain
[req_idx
] = newIndex
;
415 chain_idx
= newIndex
;
416 chain_dma_off
= ioc
->req_sz
* chain_idx
;
418 /* Populate the chainSGE for the current buffer.
419 * - Set chain buffer pointer to psge and fill
420 * out the Address and Flags fields.
422 chainSge
= (char *) psge
;
423 dsgprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
" Current buff @ %p (index 0x%x)",
424 ioc
->name
, psge
, req_idx
));
426 /* Start the SGE for the next buffer
428 psge
= (char *) (ioc
->ChainBuffer
+ chain_dma_off
);
432 dsgprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
" Chain buff @ %p (index 0x%x)\n",
433 ioc
->name
, psge
, chain_idx
));
435 /* Start the SGE for the next buffer
442 } /* mptscsih_AddSGE() */
445 mptscsih_issue_sep_command(MPT_ADAPTER
*ioc
, VirtTarget
*vtarget
,
449 SEPRequest_t
*SEPMsg
;
451 if (ioc
->bus_type
!= SAS
)
454 /* Not supported for hidden raid components
456 if (vtarget
->tflags
& MPT_TARGET_FLAGS_RAID_COMPONENT
)
459 if ((mf
= mpt_get_msg_frame(ioc
->InternalCtx
, ioc
)) == NULL
) {
460 dfailprintk(ioc
, printk(MYIOC_s_WARN_FMT
"%s: no msg frames!!\n",
461 ioc
->name
,__FUNCTION__
));
465 SEPMsg
= (SEPRequest_t
*)mf
;
466 SEPMsg
->Function
= MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR
;
467 SEPMsg
->Bus
= vtarget
->channel
;
468 SEPMsg
->TargetID
= vtarget
->id
;
469 SEPMsg
->Action
= MPI_SEP_REQ_ACTION_WRITE_STATUS
;
470 SEPMsg
->SlotStatus
= SlotStatus
;
471 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
472 "Sending SEP cmd=%x channel=%d id=%d\n",
473 ioc
->name
, SlotStatus
, SEPMsg
->Bus
, SEPMsg
->TargetID
));
474 mpt_put_msg_frame(ioc
->DoneCtx
, ioc
, mf
);
477 #ifdef CONFIG_FUSION_LOGGING
479 * mptscsih_info_scsiio - debug print info on reply frame
480 * @ioc: Pointer to MPT_ADAPTER structure
481 * @sc: original scsi cmnd pointer
482 * @pScsiReply: Pointer to MPT reply frame
484 * MPT_DEBUG_REPLY needs to be enabled to obtain this info
486 * Refer to lsi/mpi.h.
489 mptscsih_info_scsiio(MPT_ADAPTER
*ioc
, struct scsi_cmnd
*sc
, SCSIIOReply_t
* pScsiReply
)
496 ioc_status
= le16_to_cpu(pScsiReply
->IOCStatus
) & MPI_IOCSTATUS_MASK
;
498 switch (ioc_status
) {
500 case MPI_IOCSTATUS_SUCCESS
:
503 case MPI_IOCSTATUS_SCSI_INVALID_BUS
:
504 desc
= "invalid bus";
506 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID
:
507 desc
= "invalid target_id";
509 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE
:
510 desc
= "device not there";
512 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN
:
513 desc
= "data overrun";
515 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN
:
516 desc
= "data underrun";
518 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR
:
519 desc
= "I/O data error";
521 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR
:
522 desc
= "protocol error";
524 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED
:
525 desc
= "task terminated";
527 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH
:
528 desc
= "residual mismatch";
530 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED
:
531 desc
= "task management failed";
533 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED
:
534 desc
= "IOC terminated";
536 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED
:
537 desc
= "ext terminated";
544 switch (pScsiReply
->SCSIStatus
)
547 case MPI_SCSI_STATUS_SUCCESS
:
550 case MPI_SCSI_STATUS_CHECK_CONDITION
:
551 desc1
= "check condition";
553 case MPI_SCSI_STATUS_CONDITION_MET
:
554 desc1
= "condition met";
556 case MPI_SCSI_STATUS_BUSY
:
559 case MPI_SCSI_STATUS_INTERMEDIATE
:
560 desc1
= "intermediate";
562 case MPI_SCSI_STATUS_INTERMEDIATE_CONDMET
:
563 desc1
= "intermediate condmet";
565 case MPI_SCSI_STATUS_RESERVATION_CONFLICT
:
566 desc1
= "reservation conflict";
568 case MPI_SCSI_STATUS_COMMAND_TERMINATED
:
569 desc1
= "command terminated";
571 case MPI_SCSI_STATUS_TASK_SET_FULL
:
572 desc1
= "task set full";
574 case MPI_SCSI_STATUS_ACA_ACTIVE
:
575 desc1
= "aca active";
577 case MPI_SCSI_STATUS_FCPEXT_DEVICE_LOGGED_OUT
:
578 desc1
= "fcpext device logged out";
580 case MPI_SCSI_STATUS_FCPEXT_NO_LINK
:
581 desc1
= "fcpext no link";
583 case MPI_SCSI_STATUS_FCPEXT_UNASSIGNED
:
584 desc1
= "fcpext unassigned";
591 scsi_print_command(sc
);
592 printk(MYIOC_s_DEBUG_FMT
"\tfw_channel = %d, fw_id = %d\n",
593 ioc
->name
, pScsiReply
->Bus
, pScsiReply
->TargetID
);
594 printk(MYIOC_s_DEBUG_FMT
"\trequest_len = %d, underflow = %d, "
595 "resid = %d\n", ioc
->name
, scsi_bufflen(sc
), sc
->underflow
,
597 printk(MYIOC_s_DEBUG_FMT
"\ttag = %d, transfer_count = %d, "
598 "sc->result = %08X\n", ioc
->name
, le16_to_cpu(pScsiReply
->TaskTag
),
599 le32_to_cpu(pScsiReply
->TransferCount
), sc
->result
);
600 printk(MYIOC_s_DEBUG_FMT
"\tiocstatus = %s (0x%04x), "
601 "scsi_status = %s (0x%02x), scsi_state = (0x%02x)\n",
602 ioc
->name
, desc
, ioc_status
, desc1
, pScsiReply
->SCSIStatus
,
603 pScsiReply
->SCSIState
);
605 if (pScsiReply
->SCSIState
& MPI_SCSI_STATE_AUTOSENSE_VALID
) {
606 skey
= sc
->sense_buffer
[2] & 0x0F;
607 asc
= sc
->sense_buffer
[12];
608 ascq
= sc
->sense_buffer
[13];
610 printk(MYIOC_s_DEBUG_FMT
"\t[sense_key,asc,ascq]: "
611 "[0x%02x,0x%02x,0x%02x]\n", ioc
->name
, skey
, asc
, ascq
);
615 * Look for + dump FCP ResponseInfo[]!
617 if (pScsiReply
->SCSIState
& MPI_SCSI_STATE_RESPONSE_INFO_VALID
&&
618 pScsiReply
->ResponseInfo
)
619 printk(MYIOC_s_DEBUG_FMT
"response_info = %08xh\n",
620 ioc
->name
, le32_to_cpu(pScsiReply
->ResponseInfo
));
624 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
626 * mptscsih_io_done - Main SCSI IO callback routine registered to
627 * Fusion MPT (base) driver
628 * @ioc: Pointer to MPT_ADAPTER structure
629 * @mf: Pointer to original MPT request frame
630 * @r: Pointer to MPT reply frame (NULL if TurboReply)
632 * This routine is called from mpt.c::mpt_interrupt() at the completion
633 * of any SCSI IO request.
634 * This routine is registered with the Fusion MPT (base) driver at driver
635 * load/init time via the mpt_register() API call.
637 * Returns 1 indicating alloc'd request frame ptr should be freed.
640 mptscsih_io_done(MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*mf
, MPT_FRAME_HDR
*mr
)
642 struct scsi_cmnd
*sc
;
644 SCSIIORequest_t
*pScsiReq
;
645 SCSIIOReply_t
*pScsiReply
;
646 u16 req_idx
, req_idx_MR
;
650 hd
= shost_priv(ioc
->sh
);
651 req_idx
= le16_to_cpu(mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
);
652 req_idx_MR
= (mr
!= NULL
) ?
653 le16_to_cpu(mr
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
) : req_idx
;
654 if ((req_idx
!= req_idx_MR
) ||
655 (mf
->u
.frame
.linkage
.arg1
== 0xdeadbeaf)) {
656 printk(MYIOC_s_ERR_FMT
"Received a mf that was already freed\n",
658 printk (MYIOC_s_ERR_FMT
659 "req_idx=%x req_idx_MR=%x mf=%p mr=%p sc=%p\n",
660 ioc
->name
, req_idx
, req_idx_MR
, mf
, mr
,
661 hd
->ScsiLookup
[req_idx_MR
]);
665 sc
= hd
->ScsiLookup
[req_idx
];
666 hd
->ScsiLookup
[req_idx
] = NULL
;
668 MPIHeader_t
*hdr
= (MPIHeader_t
*)mf
;
670 /* Remark: writeSDP1 will use the ScsiDoneCtx
671 * If a SCSI I/O cmd, device disabled by OS and
672 * completion done. Cannot touch sc struct. Just free mem.
674 if (hdr
->Function
== MPI_FUNCTION_SCSI_IO_REQUEST
)
675 printk(MYIOC_s_ERR_FMT
"NULL ScsiCmd ptr!\n",
678 mptscsih_freeChainBuffers(ioc
, req_idx
);
682 if ((unsigned char *)mf
!= sc
->host_scribble
) {
683 mptscsih_freeChainBuffers(ioc
, req_idx
);
687 sc
->host_scribble
= NULL
;
688 sc
->result
= DID_OK
<< 16; /* Set default reply as OK */
689 pScsiReq
= (SCSIIORequest_t
*) mf
;
690 pScsiReply
= (SCSIIOReply_t
*) mr
;
692 if((ioc
->facts
.MsgVersion
>= MPI_VERSION_01_05
) && pScsiReply
){
693 dmfprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
694 "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d,task-tag=%d)\n",
695 ioc
->name
, mf
, mr
, sc
, req_idx
, pScsiReply
->TaskTag
));
697 dmfprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
698 "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n",
699 ioc
->name
, mf
, mr
, sc
, req_idx
));
702 if (pScsiReply
== NULL
) {
703 /* special context reply handling */
708 u8 scsi_state
, scsi_status
;
711 status
= le16_to_cpu(pScsiReply
->IOCStatus
) & MPI_IOCSTATUS_MASK
;
712 scsi_state
= pScsiReply
->SCSIState
;
713 scsi_status
= pScsiReply
->SCSIStatus
;
714 xfer_cnt
= le32_to_cpu(pScsiReply
->TransferCount
);
715 scsi_set_resid(sc
, scsi_bufflen(sc
) - xfer_cnt
);
716 log_info
= le32_to_cpu(pScsiReply
->IOCLogInfo
);
719 * if we get a data underrun indication, yet no data was
720 * transferred and the SCSI status indicates that the
721 * command was never started, change the data underrun
724 if (status
== MPI_IOCSTATUS_SCSI_DATA_UNDERRUN
&& xfer_cnt
== 0 &&
725 (scsi_status
== MPI_SCSI_STATUS_BUSY
||
726 scsi_status
== MPI_SCSI_STATUS_RESERVATION_CONFLICT
||
727 scsi_status
== MPI_SCSI_STATUS_TASK_SET_FULL
)) {
728 status
= MPI_IOCSTATUS_SUCCESS
;
731 if (scsi_state
& MPI_SCSI_STATE_AUTOSENSE_VALID
)
732 mptscsih_copy_sense_data(sc
, hd
, mf
, pScsiReply
);
735 * Look for + dump FCP ResponseInfo[]!
737 if (scsi_state
& MPI_SCSI_STATE_RESPONSE_INFO_VALID
&&
738 pScsiReply
->ResponseInfo
) {
739 printk(MYIOC_s_NOTE_FMT
"[%d:%d:%d:%d] "
740 "FCP_ResponseInfo=%08xh\n", ioc
->name
,
741 sc
->device
->host
->host_no
, sc
->device
->channel
,
742 sc
->device
->id
, sc
->device
->lun
,
743 le32_to_cpu(pScsiReply
->ResponseInfo
));
747 case MPI_IOCSTATUS_BUSY
: /* 0x0002 */
749 * Maybe: DRIVER_BUSY | SUGGEST_RETRY | DID_SOFT_ERROR (retry)
750 * But not: DID_BUS_BUSY lest one risk
751 * killing interrupt handler:-(
753 sc
->result
= SAM_STAT_BUSY
;
756 case MPI_IOCSTATUS_SCSI_INVALID_BUS
: /* 0x0041 */
757 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID
: /* 0x0042 */
758 sc
->result
= DID_BAD_TARGET
<< 16;
761 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE
: /* 0x0043 */
762 /* Spoof to SCSI Selection Timeout! */
763 if (ioc
->bus_type
!= FC
)
764 sc
->result
= DID_NO_CONNECT
<< 16;
765 /* else fibre, just stall until rescan event */
767 sc
->result
= DID_REQUEUE
<< 16;
769 if (hd
->sel_timeout
[pScsiReq
->TargetID
] < 0xFFFF)
770 hd
->sel_timeout
[pScsiReq
->TargetID
]++;
772 vdevice
= sc
->device
->hostdata
;
775 vtarget
= vdevice
->vtarget
;
776 if (vtarget
->tflags
& MPT_TARGET_FLAGS_LED_ON
) {
777 mptscsih_issue_sep_command(ioc
, vtarget
,
778 MPI_SEP_REQ_SLOTSTATUS_UNCONFIGURED
);
779 vtarget
->tflags
&= ~MPT_TARGET_FLAGS_LED_ON
;
783 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED
: /* 0x004B */
784 if ( ioc
->bus_type
== SAS
) {
785 u16 ioc_status
= le16_to_cpu(pScsiReply
->IOCStatus
);
786 if (ioc_status
& MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE
) {
787 if ((log_info
& SAS_LOGINFO_MASK
)
788 == SAS_LOGINFO_NEXUS_LOSS
) {
789 sc
->result
= (DID_BUS_BUSY
<< 16);
793 } else if (ioc
->bus_type
== FC
) {
795 * The FC IOC may kill a request for variety of
796 * reasons, some of which may be recovered by a
797 * retry, some which are unlikely to be
798 * recovered. Return DID_ERROR instead of
799 * DID_RESET to permit retry of the command,
800 * just not an infinite number of them
802 sc
->result
= DID_ERROR
<< 16;
807 * Allow non-SAS & non-NEXUS_LOSS to drop into below code
810 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED
: /* 0x0048 */
811 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED
: /* 0x004C */
812 /* Linux handles an unsolicited DID_RESET better
813 * than an unsolicited DID_ABORT.
815 sc
->result
= DID_RESET
<< 16;
819 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH
: /* 0x0049 */
820 scsi_set_resid(sc
, scsi_bufflen(sc
) - xfer_cnt
);
821 if((xfer_cnt
==0)||(sc
->underflow
> xfer_cnt
))
822 sc
->result
=DID_SOFT_ERROR
<< 16;
823 else /* Sufficient data transfer occurred */
824 sc
->result
= (DID_OK
<< 16) | scsi_status
;
825 dreplyprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
826 "RESIDUAL_MISMATCH: result=%x on channel=%d id=%d\n",
827 ioc
->name
, sc
->result
, sc
->device
->channel
, sc
->device
->id
));
830 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN
: /* 0x0045 */
832 * Do upfront check for valid SenseData and give it
835 sc
->result
= (DID_OK
<< 16) | scsi_status
;
836 if (scsi_state
& MPI_SCSI_STATE_AUTOSENSE_VALID
) {
837 /* Have already saved the status and sense data
841 if (xfer_cnt
< sc
->underflow
) {
842 if (scsi_status
== SAM_STAT_BUSY
)
843 sc
->result
= SAM_STAT_BUSY
;
845 sc
->result
= DID_SOFT_ERROR
<< 16;
847 if (scsi_state
& (MPI_SCSI_STATE_AUTOSENSE_FAILED
| MPI_SCSI_STATE_NO_SCSI_STATUS
)) {
850 sc
->result
= DID_SOFT_ERROR
<< 16;
852 else if (scsi_state
& MPI_SCSI_STATE_TERMINATED
) {
853 /* Not real sure here either... */
854 sc
->result
= DID_RESET
<< 16;
859 dreplyprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
860 " sc->underflow={report ERR if < %02xh bytes xfer'd}\n",
861 ioc
->name
, sc
->underflow
));
862 dreplyprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
863 " ActBytesXferd=%02xh\n", ioc
->name
, xfer_cnt
));
867 if (scsi_status
== MPI_SCSI_STATUS_TASK_SET_FULL
)
868 mptscsih_report_queue_full(sc
, pScsiReply
, pScsiReq
);
872 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN
: /* 0x0044 */
873 scsi_set_resid(sc
, 0);
874 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR
: /* 0x0040 */
875 case MPI_IOCSTATUS_SUCCESS
: /* 0x0000 */
876 sc
->result
= (DID_OK
<< 16) | scsi_status
;
877 if (scsi_state
== 0) {
879 } else if (scsi_state
& MPI_SCSI_STATE_AUTOSENSE_VALID
) {
881 * If running against circa 200003dd 909 MPT f/w,
882 * may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL
883 * (QUEUE_FULL) returned from device! --> get 0x0000?128
884 * and with SenseBytes set to 0.
886 if (pScsiReply
->SCSIStatus
== MPI_SCSI_STATUS_TASK_SET_FULL
)
887 mptscsih_report_queue_full(sc
, pScsiReply
, pScsiReq
);
890 else if (scsi_state
&
891 (MPI_SCSI_STATE_AUTOSENSE_FAILED
| MPI_SCSI_STATE_NO_SCSI_STATUS
)
896 sc
->result
= DID_SOFT_ERROR
<< 16;
898 else if (scsi_state
& MPI_SCSI_STATE_TERMINATED
) {
899 /* Not real sure here either... */
900 sc
->result
= DID_RESET
<< 16;
902 else if (scsi_state
& MPI_SCSI_STATE_QUEUE_TAG_REJECTED
) {
903 /* Device Inq. data indicates that it supports
904 * QTags, but rejects QTag messages.
905 * This command completed OK.
907 * Not real sure here either so do nothing... */
910 if (sc
->result
== MPI_SCSI_STATUS_TASK_SET_FULL
)
911 mptscsih_report_queue_full(sc
, pScsiReply
, pScsiReq
);
914 * Reservation Conflict, Busy,
915 * Command Terminated, CHECK
919 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR
: /* 0x0047 */
920 sc
->result
= DID_SOFT_ERROR
<< 16;
923 case MPI_IOCSTATUS_INVALID_FUNCTION
: /* 0x0001 */
924 case MPI_IOCSTATUS_INVALID_SGL
: /* 0x0003 */
925 case MPI_IOCSTATUS_INTERNAL_ERROR
: /* 0x0004 */
926 case MPI_IOCSTATUS_RESERVED
: /* 0x0005 */
927 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES
: /* 0x0006 */
928 case MPI_IOCSTATUS_INVALID_FIELD
: /* 0x0007 */
929 case MPI_IOCSTATUS_INVALID_STATE
: /* 0x0008 */
930 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR
: /* 0x0046 */
931 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED
: /* 0x004A */
936 sc
->result
= DID_SOFT_ERROR
<< 16;
939 } /* switch(status) */
941 #ifdef CONFIG_FUSION_LOGGING
942 if (sc
->result
&& (ioc
->debug_level
& MPT_DEBUG_REPLY
))
943 mptscsih_info_scsiio(ioc
, sc
, pScsiReply
);
946 } /* end of address reply case */
948 /* Unmap the DMA buffers, if any. */
951 sc
->scsi_done(sc
); /* Issue the command callback */
953 /* Free Chain buffers */
954 mptscsih_freeChainBuffers(ioc
, req_idx
);
959 * mptscsih_flush_running_cmds - For each command found, search
960 * Scsi_Host instance taskQ and reply to OS.
961 * Called only if recovering from a FW reload.
962 * @hd: Pointer to a SCSI HOST structure
966 * Must be called while new I/Os are being queued.
969 mptscsih_flush_running_cmds(MPT_SCSI_HOST
*hd
)
971 MPT_ADAPTER
*ioc
= hd
->ioc
;
972 struct scsi_cmnd
*SCpnt
;
975 int max
= ioc
->req_depth
;
977 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
": flush_ScsiLookup called\n", ioc
->name
));
978 for (ii
= 0; ii
< max
; ii
++) {
979 if ((SCpnt
= hd
->ScsiLookup
[ii
]) != NULL
) {
984 /* Null ScsiLookup index
986 hd
->ScsiLookup
[ii
] = NULL
;
988 mf
= MPT_INDEX_2_MFPTR(ioc
, ii
);
989 dmfprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
": flush: ScsiDone (mf=%p,sc=%p)\n",
990 ioc
->name
, mf
, SCpnt
));
992 /* Free Chain buffers */
993 mptscsih_freeChainBuffers(ioc
, ii
);
995 /* Free Message frames */
996 mpt_free_msg_frame(ioc
, mf
);
998 if ((unsigned char *)mf
!= SCpnt
->host_scribble
)
1001 /* Set status, free OS resources (SG DMA buffers)
1004 scsi_dma_unmap(SCpnt
);
1006 SCpnt
->result
= DID_RESET
<< 16;
1007 SCpnt
->host_scribble
= NULL
;
1009 SCpnt
->scsi_done(SCpnt
); /* Issue the command callback */
1017 * mptscsih_search_running_cmds - Delete any commands associated
1018 * with the specified target and lun. Function called only
1019 * when a lun is disable by mid-layer.
1020 * Do NOT access the referenced scsi_cmnd structure or
1021 * members. Will cause either a paging or NULL ptr error.
1022 * (BUT, BUT, BUT, the code does reference it! - mdr)
1023 * @hd: Pointer to a SCSI HOST structure
1024 * @vdevice: per device private data
1028 * Called from slave_destroy.
1031 mptscsih_search_running_cmds(MPT_SCSI_HOST
*hd
, VirtDevice
*vdevice
)
1033 SCSIIORequest_t
*mf
= NULL
;
1035 int max
= hd
->ioc
->req_depth
;
1036 struct scsi_cmnd
*sc
;
1037 struct scsi_lun lun
;
1038 MPT_ADAPTER
*ioc
= hd
->ioc
;
1040 dsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
": search_running channel %d id %d lun %d max %d\n",
1041 ioc
->name
, vdevice
->vtarget
->channel
, vdevice
->vtarget
->id
, vdevice
->lun
, max
));
1043 for (ii
=0; ii
< max
; ii
++) {
1044 if ((sc
= hd
->ScsiLookup
[ii
]) != NULL
) {
1046 mf
= (SCSIIORequest_t
*)MPT_INDEX_2_MFPTR(ioc
, ii
);
1049 /* If the device is a hidden raid component, then its
1050 * expected that the mf->function will be RAID_SCSI_IO
1052 if (vdevice
->vtarget
->tflags
&
1053 MPT_TARGET_FLAGS_RAID_COMPONENT
&& mf
->Function
!=
1054 MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH
)
1057 int_to_scsilun(vdevice
->lun
, &lun
);
1058 if ((mf
->Bus
!= vdevice
->vtarget
->channel
) ||
1059 (mf
->TargetID
!= vdevice
->vtarget
->id
) ||
1060 memcmp(lun
.scsi_lun
, mf
->LUN
, 8))
1065 hd
->ScsiLookup
[ii
] = NULL
;
1066 mptscsih_freeChainBuffers(ioc
, ii
);
1067 mpt_free_msg_frame(ioc
, (MPT_FRAME_HDR
*)mf
);
1068 if ((unsigned char *)mf
!= sc
->host_scribble
)
1071 sc
->host_scribble
= NULL
;
1072 sc
->result
= DID_NO_CONNECT
<< 16;
1073 sdev_printk(MYIOC_s_INFO_FMT
, sc
->device
, "completing cmds: fw_channel %d,"
1074 "fw_id %d, sc=%p, mf = %p, idx=%x\n", ioc
->name
, vdevice
->vtarget
->channel
,
1075 vdevice
->vtarget
->id
, sc
, mf
, ii
);
1082 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1084 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1086 * mptscsih_report_queue_full - Report QUEUE_FULL status returned
1087 * from a SCSI target device.
1088 * @sc: Pointer to scsi_cmnd structure
1089 * @pScsiReply: Pointer to SCSIIOReply_t
1090 * @pScsiReq: Pointer to original SCSI request
1092 * This routine periodically reports QUEUE_FULL status returned from a
1093 * SCSI target device. It reports this to the console via kernel
1094 * printk() API call, not more than once every 10 seconds.
1097 mptscsih_report_queue_full(struct scsi_cmnd
*sc
, SCSIIOReply_t
*pScsiReply
, SCSIIORequest_t
*pScsiReq
)
1099 long time
= jiffies
;
1103 if (sc
->device
== NULL
)
1105 if (sc
->device
->host
== NULL
)
1107 if ((hd
= shost_priv(sc
->device
->host
)) == NULL
)
1110 if (time
- hd
->last_queue_full
> 10 * HZ
) {
1111 dprintk(ioc
, printk(MYIOC_s_WARN_FMT
"Device (%d:%d:%d) reported QUEUE_FULL!\n",
1112 ioc
->name
, 0, sc
->device
->id
, sc
->device
->lun
));
1113 hd
->last_queue_full
= time
;
1117 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1119 * mptscsih_remove - Removed scsi devices
1120 * @pdev: Pointer to pci_dev structure
1125 mptscsih_remove(struct pci_dev
*pdev
)
1127 MPT_ADAPTER
*ioc
= pci_get_drvdata(pdev
);
1128 struct Scsi_Host
*host
= ioc
->sh
;
1137 scsi_remove_host(host
);
1139 if((hd
= shost_priv(host
)) == NULL
)
1142 mptscsih_shutdown(pdev
);
1146 if (hd
->ScsiLookup
!= NULL
) {
1147 sz1
= ioc
->req_depth
* sizeof(void *);
1148 kfree(hd
->ScsiLookup
);
1149 hd
->ScsiLookup
= NULL
;
1152 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
1153 "Free'd ScsiLookup (%d) memory\n",
1156 kfree(hd
->info_kbuf
);
1158 /* NULL the Scsi_Host pointer
1162 scsi_host_put(host
);
1168 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1170 * mptscsih_shutdown - reboot notifier
1174 mptscsih_shutdown(struct pci_dev
*pdev
)
1179 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1181 * mptscsih_suspend - Fusion MPT scsi driver suspend routine.
1186 mptscsih_suspend(struct pci_dev
*pdev
, pm_message_t state
)
1188 mptscsih_shutdown(pdev
);
1189 return mpt_suspend(pdev
,state
);
1192 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1194 * mptscsih_resume - Fusion MPT scsi driver resume routine.
1199 mptscsih_resume(struct pci_dev
*pdev
)
1201 return mpt_resume(pdev
);
1206 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1208 * mptscsih_info - Return information about MPT adapter
1209 * @SChost: Pointer to Scsi_Host structure
1211 * (linux scsi_host_template.info routine)
1213 * Returns pointer to buffer where information was written.
1216 mptscsih_info(struct Scsi_Host
*SChost
)
1221 h
= shost_priv(SChost
);
1224 if (h
->info_kbuf
== NULL
)
1225 if ((h
->info_kbuf
= kmalloc(0x1000 /* 4Kb */, GFP_KERNEL
)) == NULL
)
1226 return h
->info_kbuf
;
1227 h
->info_kbuf
[0] = '\0';
1229 mpt_print_ioc_summary(h
->ioc
, h
->info_kbuf
, &size
, 0, 0);
1230 h
->info_kbuf
[size
-1] = '\0';
1233 return h
->info_kbuf
;
1244 mptscsih_copy_mem_info(struct info_str
*info
, char *data
, int len
)
1246 if (info
->pos
+ len
> info
->length
)
1247 len
= info
->length
- info
->pos
;
1249 if (info
->pos
+ len
< info
->offset
) {
1254 if (info
->pos
< info
->offset
) {
1255 data
+= (info
->offset
- info
->pos
);
1256 len
-= (info
->offset
- info
->pos
);
1260 memcpy(info
->buffer
+ info
->pos
, data
, len
);
1266 mptscsih_copy_info(struct info_str
*info
, char *fmt
, ...)
1272 va_start(args
, fmt
);
1273 len
= vsprintf(buf
, fmt
, args
);
1276 mptscsih_copy_mem_info(info
, buf
, len
);
1281 mptscsih_host_info(MPT_ADAPTER
*ioc
, char *pbuf
, off_t offset
, int len
)
1283 struct info_str info
;
1287 info
.offset
= offset
;
1290 mptscsih_copy_info(&info
, "%s: %s, ", ioc
->name
, ioc
->prod_name
);
1291 mptscsih_copy_info(&info
, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING
, ioc
->facts
.FWVersion
.Word
);
1292 mptscsih_copy_info(&info
, "Ports=%d, ", ioc
->facts
.NumberOfPorts
);
1293 mptscsih_copy_info(&info
, "MaxQ=%d\n", ioc
->req_depth
);
1295 return ((info
.pos
> info
.offset
) ? info
.pos
- info
.offset
: 0);
1298 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1300 * mptscsih_proc_info - Return information about MPT adapter
1301 * @host: scsi host struct
1302 * @buffer: if write, user data; if read, buffer for user
1303 * @start: returns the buffer address
1304 * @offset: if write, 0; if read, the current offset into the buffer from
1305 * the previous read.
1306 * @length: if write, return length;
1307 * @func: write = 1; read = 0
1309 * (linux scsi_host_template.info routine)
1312 mptscsih_proc_info(struct Scsi_Host
*host
, char *buffer
, char **start
, off_t offset
,
1313 int length
, int func
)
1315 MPT_SCSI_HOST
*hd
= shost_priv(host
);
1316 MPT_ADAPTER
*ioc
= hd
->ioc
;
1321 * write is not supported
1327 size
= mptscsih_host_info(ioc
, buffer
, offset
, length
);
1333 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1334 #define ADD_INDEX_LOG(req_ent) do { } while(0)
1336 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1338 * mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine.
1339 * @SCpnt: Pointer to scsi_cmnd structure
1340 * @done: Pointer SCSI mid-layer IO completion function
1342 * (linux scsi_host_template.queuecommand routine)
1343 * This is the primary SCSI IO start routine. Create a MPI SCSIIORequest
1344 * from a linux scsi_cmnd request and send it to the IOC.
1346 * Returns 0. (rtn value discarded by linux scsi mid-layer)
1349 mptscsih_qcmd(struct scsi_cmnd
*SCpnt
, void (*done
)(struct scsi_cmnd
*))
1353 SCSIIORequest_t
*pScsiReq
;
1354 VirtDevice
*vdevice
= SCpnt
->device
->hostdata
;
1364 hd
= shost_priv(SCpnt
->device
->host
);
1366 lun
= SCpnt
->device
->lun
;
1367 SCpnt
->scsi_done
= done
;
1369 dmfprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"qcmd: SCpnt=%p, done()=%p\n",
1370 ioc
->name
, SCpnt
, done
));
1372 if (hd
->resetPending
) {
1373 dtmprintk(ioc
, printk(MYIOC_s_WARN_FMT
"qcmd: SCpnt=%p timeout + 60HZ\n",
1375 return SCSI_MLQUEUE_HOST_BUSY
;
1379 * Put together a MPT SCSI request...
1381 if ((mf
= mpt_get_msg_frame(ioc
->DoneCtx
, ioc
)) == NULL
) {
1382 dprintk(ioc
, printk(MYIOC_s_WARN_FMT
"QueueCmd, no msg frames!!\n",
1384 return SCSI_MLQUEUE_HOST_BUSY
;
1387 pScsiReq
= (SCSIIORequest_t
*) mf
;
1389 my_idx
= le16_to_cpu(mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
);
1391 ADD_INDEX_LOG(my_idx
);
1393 /* TUR's being issued with scsictl=0x02000000 (DATA_IN)!
1394 * Seems we may receive a buffer (datalen>0) even when there
1395 * will be no data transfer! GRRRRR...
1397 if (SCpnt
->sc_data_direction
== DMA_FROM_DEVICE
) {
1398 datalen
= scsi_bufflen(SCpnt
);
1399 scsidir
= MPI_SCSIIO_CONTROL_READ
; /* DATA IN (host<--ioc<--dev) */
1400 } else if (SCpnt
->sc_data_direction
== DMA_TO_DEVICE
) {
1401 datalen
= scsi_bufflen(SCpnt
);
1402 scsidir
= MPI_SCSIIO_CONTROL_WRITE
; /* DATA OUT (host-->ioc-->dev) */
1405 scsidir
= MPI_SCSIIO_CONTROL_NODATATRANSFER
;
1408 /* Default to untagged. Once a target structure has been allocated,
1409 * use the Inquiry data to determine if device supports tagged.
1412 && (vdevice
->vtarget
->tflags
& MPT_TARGET_FLAGS_Q_YES
)
1413 && (SCpnt
->device
->tagged_supported
)) {
1414 scsictl
= scsidir
| MPI_SCSIIO_CONTROL_SIMPLEQ
;
1416 scsictl
= scsidir
| MPI_SCSIIO_CONTROL_UNTAGGED
;
1419 /* Use the above information to set up the message frame
1421 pScsiReq
->TargetID
= (u8
) vdevice
->vtarget
->id
;
1422 pScsiReq
->Bus
= vdevice
->vtarget
->channel
;
1423 pScsiReq
->ChainOffset
= 0;
1424 if (vdevice
->vtarget
->tflags
& MPT_TARGET_FLAGS_RAID_COMPONENT
)
1425 pScsiReq
->Function
= MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH
;
1427 pScsiReq
->Function
= MPI_FUNCTION_SCSI_IO_REQUEST
;
1428 pScsiReq
->CDBLength
= SCpnt
->cmd_len
;
1429 pScsiReq
->SenseBufferLength
= MPT_SENSE_BUFFER_SIZE
;
1430 pScsiReq
->Reserved
= 0;
1431 pScsiReq
->MsgFlags
= mpt_msg_flags();
1432 int_to_scsilun(SCpnt
->device
->lun
, (struct scsi_lun
*)pScsiReq
->LUN
);
1433 pScsiReq
->Control
= cpu_to_le32(scsictl
);
1436 * Write SCSI CDB into the message
1438 cmd_len
= SCpnt
->cmd_len
;
1439 for (ii
=0; ii
< cmd_len
; ii
++)
1440 pScsiReq
->CDB
[ii
] = SCpnt
->cmnd
[ii
];
1442 for (ii
=cmd_len
; ii
< 16; ii
++)
1443 pScsiReq
->CDB
[ii
] = 0;
1446 pScsiReq
->DataLength
= cpu_to_le32(datalen
);
1448 /* SenseBuffer low address */
1449 pScsiReq
->SenseBufferLowAddr
= cpu_to_le32(ioc
->sense_buf_low_dma
1450 + (my_idx
* MPT_SENSE_BUFFER_ALLOC
));
1452 /* Now add the SG list
1453 * Always have a SGE even if null length.
1456 /* Add a NULL SGE */
1457 mptscsih_add_sge((char *)&pScsiReq
->SGL
, MPT_SGE_FLAGS_SSIMPLE_READ
| 0,
1460 /* Add a 32 or 64 bit SGE */
1461 if (mptscsih_AddSGE(ioc
, SCpnt
, pScsiReq
, my_idx
) != SUCCESS
)
1465 SCpnt
->host_scribble
= (unsigned char *)mf
;
1466 hd
->ScsiLookup
[my_idx
] = SCpnt
;
1468 mpt_put_msg_frame(ioc
->DoneCtx
, ioc
, mf
);
1469 dmfprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Issued SCSI cmd (%p) mf=%p idx=%d\n",
1470 ioc
->name
, SCpnt
, mf
, my_idx
));
1471 DBG_DUMP_REQUEST_FRAME(ioc
, (u32
*)mf
);
1475 hd
->ScsiLookup
[my_idx
] = NULL
;
1476 mptscsih_freeChainBuffers(ioc
, my_idx
);
1477 mpt_free_msg_frame(ioc
, mf
);
1478 return SCSI_MLQUEUE_HOST_BUSY
;
1481 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1483 * mptscsih_freeChainBuffers - Function to free chain buffers associated
1484 * with a SCSI IO request
1485 * @hd: Pointer to the MPT_SCSI_HOST instance
1486 * @req_idx: Index of the SCSI IO request frame.
1488 * Called if SG chain buffer allocation fails and mptscsih callbacks.
1492 mptscsih_freeChainBuffers(MPT_ADAPTER
*ioc
, int req_idx
)
1494 MPT_FRAME_HDR
*chain
;
1495 unsigned long flags
;
1499 /* Get the first chain index and reset
1502 chain_idx
= ioc
->ReqToChain
[req_idx
];
1503 ioc
->ReqToChain
[req_idx
] = MPT_HOST_NO_CHAIN
;
1505 while (chain_idx
!= MPT_HOST_NO_CHAIN
) {
1507 /* Save the next chain buffer index */
1508 next
= ioc
->ChainToChain
[chain_idx
];
1510 /* Free this chain buffer and reset
1513 ioc
->ChainToChain
[chain_idx
] = MPT_HOST_NO_CHAIN
;
1515 chain
= (MPT_FRAME_HDR
*) (ioc
->ChainBuffer
1516 + (chain_idx
* ioc
->req_sz
));
1518 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
1519 list_add_tail(&chain
->u
.frame
.linkage
.list
, &ioc
->FreeChainQ
);
1520 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
1522 dmfprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"FreeChainBuffers (index %d)\n",
1523 ioc
->name
, chain_idx
));
1531 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1536 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1538 * mptscsih_TMHandler - Generic handler for SCSI Task Management.
1539 * @hd: Pointer to MPT SCSI HOST structure
1540 * @type: Task Management type
1541 * @channel: channel number for task management
1542 * @id: Logical Target ID for reset (if appropriate)
1543 * @lun: Logical Unit for reset (if appropriate)
1544 * @ctx2abort: Context for the task to be aborted (if appropriate)
1545 * @timeout: timeout for task management control
1547 * Fall through to mpt_HardResetHandler if: not operational, too many
1548 * failed TM requests or handshake failure.
1550 * Remark: Currently invoked from a non-interrupt thread (_bh).
1552 * Remark: With old EH code, at most 1 SCSI TaskMgmt function per IOC
1555 * Returns 0 for SUCCESS, or %FAILED.
1558 mptscsih_TMHandler(MPT_SCSI_HOST
*hd
, u8 type
, u8 channel
, u8 id
, int lun
, int ctx2abort
, ulong timeout
)
1563 unsigned long flags
;
1566 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"TMHandler Entered!\n", ioc
->name
));
1568 // SJR - CHECKME - Can we avoid this here?
1569 // (mpt_HardResetHandler has this check...)
1570 spin_lock_irqsave(&ioc
->diagLock
, flags
);
1571 if ((ioc
->diagPending
) || (ioc
->alt_ioc
&& ioc
->alt_ioc
->diagPending
)) {
1572 spin_unlock_irqrestore(&ioc
->diagLock
, flags
);
1575 spin_unlock_irqrestore(&ioc
->diagLock
, flags
);
1577 /* Wait a fixed amount of time for the TM pending flag to be cleared.
1578 * If we time out and not bus reset, then we return a FAILED status
1580 * The call to mptscsih_tm_pending_wait() will set the pending flag
1582 * successful. Otherwise, reload the FW.
1584 if (mptscsih_tm_pending_wait(hd
) == FAILED
) {
1585 if (type
== MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK
) {
1586 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"TMHandler abort: "
1587 "Timed out waiting for last TM (%d) to complete! \n",
1588 ioc
->name
, hd
->tmPending
));
1590 } else if (type
== MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET
) {
1591 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"TMHandler target "
1592 "reset: Timed out waiting for last TM (%d) "
1593 "to complete! \n", ioc
->name
,
1596 } else if (type
== MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS
) {
1597 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"TMHandler bus reset: "
1598 "Timed out waiting for last TM (%d) to complete! \n",
1599 ioc
->name
, hd
->tmPending
));
1603 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
1604 hd
->tmPending
|= (1 << type
);
1605 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
1608 ioc_raw_state
= mpt_GetIocState(ioc
, 0);
1610 if ((ioc_raw_state
& MPI_IOC_STATE_MASK
) != MPI_IOC_STATE_OPERATIONAL
) {
1611 printk(MYIOC_s_WARN_FMT
1612 "TM Handler for type=%x: IOC Not operational (0x%x)!\n",
1613 ioc
->name
, type
, ioc_raw_state
);
1614 printk(MYIOC_s_WARN_FMT
" Issuing HardReset!!\n", ioc
->name
);
1615 if (mpt_HardResetHandler(ioc
, CAN_SLEEP
) < 0)
1616 printk(MYIOC_s_WARN_FMT
"TMHandler: HardReset "
1617 "FAILED!!\n", ioc
->name
);
1621 if (ioc_raw_state
& MPI_DOORBELL_ACTIVE
) {
1622 printk(MYIOC_s_WARN_FMT
1623 "TM Handler for type=%x: ioc_state: "
1624 "DOORBELL_ACTIVE (0x%x)!\n",
1625 ioc
->name
, type
, ioc_raw_state
);
1629 /* Isse the Task Mgmt request.
1631 if (hd
->hard_resets
< -1)
1634 rc
= mptscsih_IssueTaskMgmt(hd
, type
, channel
, id
, lun
,
1635 ctx2abort
, timeout
);
1637 printk(MYIOC_s_INFO_FMT
"Issue of TaskMgmt failed!\n",
1640 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Issue of TaskMgmt Successful!\n",
1643 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
1644 "TMHandler rc = %d!\n", ioc
->name
, rc
));
1650 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1652 * mptscsih_IssueTaskMgmt - Generic send Task Management function.
1653 * @hd: Pointer to MPT_SCSI_HOST structure
1654 * @type: Task Management type
1655 * @channel: channel number for task management
1656 * @id: Logical Target ID for reset (if appropriate)
1657 * @lun: Logical Unit for reset (if appropriate)
1658 * @ctx2abort: Context for the task to be aborted (if appropriate)
1659 * @timeout: timeout for task management control
1661 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
1662 * or a non-interrupt thread. In the former, must not call schedule().
1664 * Not all fields are meaningfull for all task types.
1666 * Returns 0 for SUCCESS, or FAILED.
1670 mptscsih_IssueTaskMgmt(MPT_SCSI_HOST
*hd
, u8 type
, u8 channel
, u8 id
, int lun
, int ctx2abort
, ulong timeout
)
1673 SCSITaskMgmt_t
*pScsiTm
;
1676 MPT_ADAPTER
*ioc
= hd
->ioc
;
1678 /* Return Fail to calling function if no message frames available.
1680 if ((mf
= mpt_get_msg_frame(ioc
->TaskCtx
, ioc
)) == NULL
) {
1681 dfailprintk(ioc
, printk(MYIOC_s_ERR_FMT
"IssueTaskMgmt, no msg frames!!\n",
1685 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"IssueTaskMgmt request @ %p\n",
1688 /* Format the Request
1690 pScsiTm
= (SCSITaskMgmt_t
*) mf
;
1691 pScsiTm
->TargetID
= id
;
1692 pScsiTm
->Bus
= channel
;
1693 pScsiTm
->ChainOffset
= 0;
1694 pScsiTm
->Function
= MPI_FUNCTION_SCSI_TASK_MGMT
;
1696 pScsiTm
->Reserved
= 0;
1697 pScsiTm
->TaskType
= type
;
1698 pScsiTm
->Reserved1
= 0;
1699 pScsiTm
->MsgFlags
= (type
== MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS
)
1700 ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION
: 0;
1702 int_to_scsilun(lun
, (struct scsi_lun
*)pScsiTm
->LUN
);
1704 for (ii
=0; ii
< 7; ii
++)
1705 pScsiTm
->Reserved2
[ii
] = 0;
1707 pScsiTm
->TaskMsgContext
= ctx2abort
;
1709 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"IssueTaskMgmt: ctx2abort (0x%08x) "
1710 "type=%d\n", ioc
->name
, ctx2abort
, type
));
1712 DBG_DUMP_TM_REQUEST_FRAME(ioc
, (u32
*)pScsiTm
);
1714 if ((ioc
->facts
.IOCCapabilities
& MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q
) &&
1715 (ioc
->facts
.MsgVersion
>= MPI_VERSION_01_05
))
1716 mpt_put_msg_frame_hi_pri(ioc
->TaskCtx
, ioc
, mf
);
1718 retval
= mpt_send_handshake_request(ioc
->TaskCtx
, ioc
,
1719 sizeof(SCSITaskMgmt_t
), (u32
*)pScsiTm
, CAN_SLEEP
);
1721 dfailprintk(ioc
, printk(MYIOC_s_ERR_FMT
"send_handshake FAILED!"
1722 " (hd %p, ioc %p, mf %p, rc=%d) \n", ioc
->name
, hd
,
1728 if(mptscsih_tm_wait_for_completion(hd
, timeout
) == FAILED
) {
1729 dfailprintk(ioc
, printk(MYIOC_s_ERR_FMT
"task management request TIMED OUT!"
1730 " (hd %p, ioc %p, mf %p) \n", ioc
->name
, hd
,
1732 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Calling HardReset! \n",
1734 retval
= mpt_HardResetHandler(ioc
, CAN_SLEEP
);
1735 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"rc=%d \n",
1736 ioc
->name
, retval
));
1741 * Handle success case, see if theres a non-zero ioc_status.
1743 if (hd
->tm_iocstatus
== MPI_IOCSTATUS_SUCCESS
||
1744 hd
->tm_iocstatus
== MPI_IOCSTATUS_SCSI_TASK_TERMINATED
||
1745 hd
->tm_iocstatus
== MPI_IOCSTATUS_SCSI_IOC_TERMINATED
)
1755 * Free task managment mf, and corresponding tm flags
1757 mpt_free_msg_frame(ioc
, mf
);
1759 hd
->tmState
= TM_STATE_NONE
;
1764 mptscsih_get_tm_timeout(MPT_ADAPTER
*ioc
)
1766 switch (ioc
->bus_type
) {
1777 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1779 * mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant
1780 * @SCpnt: Pointer to scsi_cmnd structure, IO to be aborted
1782 * (linux scsi_host_template.eh_abort_handler routine)
1784 * Returns SUCCESS or FAILED.
1787 mptscsih_abort(struct scsi_cmnd
* SCpnt
)
1794 VirtDevice
*vdevice
;
1795 ulong sn
= SCpnt
->serial_number
;
1798 /* If we can't locate our host adapter structure, return FAILED status.
1800 if ((hd
= shost_priv(SCpnt
->device
->host
)) == NULL
) {
1801 SCpnt
->result
= DID_RESET
<< 16;
1802 SCpnt
->scsi_done(SCpnt
);
1803 printk(KERN_ERR MYNAM
": task abort: "
1804 "can't locate host! (sc=%p)\n", SCpnt
);
1809 printk(MYIOC_s_INFO_FMT
"attempting task abort! (sc=%p)\n",
1811 scsi_print_command(SCpnt
);
1813 vdevice
= SCpnt
->device
->hostdata
;
1814 if (!vdevice
|| !vdevice
->vtarget
) {
1815 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
1816 "task abort: device has been deleted (sc=%p)\n",
1818 SCpnt
->result
= DID_NO_CONNECT
<< 16;
1819 SCpnt
->scsi_done(SCpnt
);
1824 /* Task aborts are not supported for hidden raid components.
1826 if (vdevice
->vtarget
->tflags
& MPT_TARGET_FLAGS_RAID_COMPONENT
) {
1827 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
1828 "task abort: hidden raid component (sc=%p)\n",
1830 SCpnt
->result
= DID_RESET
<< 16;
1835 /* Find this command
1837 if ((scpnt_idx
= SCPNT_TO_LOOKUP_IDX(SCpnt
)) < 0) {
1838 /* Cmd not found in ScsiLookup.
1841 SCpnt
->result
= DID_RESET
<< 16;
1842 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"task abort: "
1843 "Command not in the active list! (sc=%p)\n", ioc
->name
,
1849 if (hd
->resetPending
) {
1854 if (hd
->timeouts
< -1)
1857 /* Most important! Set TaskMsgContext to SCpnt's MsgContext!
1858 * (the IO to be ABORT'd)
1860 * NOTE: Since we do not byteswap MsgContext, we do not
1861 * swap it here either. It is an opaque cookie to
1862 * the controller, so it does not matter. -DaveM
1864 mf
= MPT_INDEX_2_MFPTR(ioc
, scpnt_idx
);
1865 ctx2abort
= mf
->u
.frame
.hwhdr
.msgctxu
.MsgContext
;
1867 hd
->abortSCpnt
= SCpnt
;
1869 retval
= mptscsih_TMHandler(hd
, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK
,
1870 vdevice
->vtarget
->channel
, vdevice
->vtarget
->id
, vdevice
->lun
,
1871 ctx2abort
, mptscsih_get_tm_timeout(ioc
));
1873 if (SCPNT_TO_LOOKUP_IDX(SCpnt
) == scpnt_idx
&&
1874 SCpnt
->serial_number
== sn
)
1878 printk(MYIOC_s_INFO_FMT
"task abort: %s (sc=%p)\n",
1879 ioc
->name
, ((retval
== 0) ? "SUCCESS" : "FAILED" ), SCpnt
);
1887 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1889 * mptscsih_dev_reset - Perform a SCSI TARGET_RESET! new_eh variant
1890 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1892 * (linux scsi_host_template.eh_dev_reset_handler routine)
1894 * Returns SUCCESS or FAILED.
1897 mptscsih_dev_reset(struct scsi_cmnd
* SCpnt
)
1901 VirtDevice
*vdevice
;
1904 /* If we can't locate our host adapter structure, return FAILED status.
1906 if ((hd
= shost_priv(SCpnt
->device
->host
)) == NULL
){
1907 printk(KERN_ERR MYNAM
": target reset: "
1908 "Can't locate host! (sc=%p)\n", SCpnt
);
1913 printk(MYIOC_s_INFO_FMT
"attempting target reset! (sc=%p)\n",
1915 scsi_print_command(SCpnt
);
1917 if (hd
->resetPending
) {
1922 vdevice
= SCpnt
->device
->hostdata
;
1923 if (!vdevice
|| !vdevice
->vtarget
) {
1928 /* Target reset to hidden raid component is not supported
1930 if (vdevice
->vtarget
->tflags
& MPT_TARGET_FLAGS_RAID_COMPONENT
) {
1935 retval
= mptscsih_TMHandler(hd
, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET
,
1936 vdevice
->vtarget
->channel
, vdevice
->vtarget
->id
, 0, 0,
1937 mptscsih_get_tm_timeout(ioc
));
1940 printk (MYIOC_s_INFO_FMT
"target reset: %s (sc=%p)\n",
1941 ioc
->name
, ((retval
== 0) ? "SUCCESS" : "FAILED" ), SCpnt
);
1950 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1952 * mptscsih_bus_reset - Perform a SCSI BUS_RESET! new_eh variant
1953 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1955 * (linux scsi_host_template.eh_bus_reset_handler routine)
1957 * Returns SUCCESS or FAILED.
1960 mptscsih_bus_reset(struct scsi_cmnd
* SCpnt
)
1964 VirtDevice
*vdevice
;
1967 /* If we can't locate our host adapter structure, return FAILED status.
1969 if ((hd
= shost_priv(SCpnt
->device
->host
)) == NULL
){
1970 printk(KERN_ERR MYNAM
": bus reset: "
1971 "Can't locate host! (sc=%p)\n", SCpnt
);
1976 printk(MYIOC_s_INFO_FMT
"attempting bus reset! (sc=%p)\n",
1978 scsi_print_command(SCpnt
);
1980 if (hd
->timeouts
< -1)
1983 vdevice
= SCpnt
->device
->hostdata
;
1984 retval
= mptscsih_TMHandler(hd
, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS
,
1985 vdevice
->vtarget
->channel
, 0, 0, 0, mptscsih_get_tm_timeout(ioc
));
1987 printk(MYIOC_s_INFO_FMT
"bus reset: %s (sc=%p)\n",
1988 ioc
->name
, ((retval
== 0) ? "SUCCESS" : "FAILED" ), SCpnt
);
1996 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1998 * mptscsih_host_reset - Perform a SCSI host adapter RESET (new_eh variant)
1999 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
2001 * (linux scsi_host_template.eh_host_reset_handler routine)
2003 * Returns SUCCESS or FAILED.
2006 mptscsih_host_reset(struct scsi_cmnd
*SCpnt
)
2012 /* If we can't locate the host to reset, then we failed. */
2013 if ((hd
= shost_priv(SCpnt
->device
->host
)) == NULL
){
2014 printk(KERN_ERR MYNAM
": host reset: "
2015 "Can't locate host! (sc=%p)\n", SCpnt
);
2020 printk(MYIOC_s_INFO_FMT
"attempting host reset! (sc=%p)\n",
2023 /* If our attempts to reset the host failed, then return a failed
2024 * status. The host will be taken off line by the SCSI mid-layer.
2026 if (mpt_HardResetHandler(ioc
, CAN_SLEEP
) < 0) {
2029 /* Make sure TM pending is cleared and TM state is set to
2034 hd
->tmState
= TM_STATE_NONE
;
2037 printk(MYIOC_s_INFO_FMT
"host reset: %s (sc=%p)\n",
2038 ioc
->name
, ((retval
== 0) ? "SUCCESS" : "FAILED" ), SCpnt
);
2043 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2045 * mptscsih_tm_pending_wait - wait for pending task management request to complete
2046 * @hd: Pointer to MPT host structure.
2048 * Returns {SUCCESS,FAILED}.
2051 mptscsih_tm_pending_wait(MPT_SCSI_HOST
* hd
)
2053 unsigned long flags
;
2054 int loop_count
= 4 * 10; /* Wait 10 seconds */
2055 int status
= FAILED
;
2056 MPT_ADAPTER
*ioc
= hd
->ioc
;
2059 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
2060 if (hd
->tmState
== TM_STATE_NONE
) {
2061 hd
->tmState
= TM_STATE_IN_PROGRESS
;
2063 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
2067 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
2069 } while (--loop_count
);
2074 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2076 * mptscsih_tm_wait_for_completion - wait for completion of TM task
2077 * @hd: Pointer to MPT host structure.
2078 * @timeout: timeout value
2080 * Returns {SUCCESS,FAILED}.
2083 mptscsih_tm_wait_for_completion(MPT_SCSI_HOST
* hd
, ulong timeout
)
2085 unsigned long flags
;
2086 int loop_count
= 4 * timeout
;
2087 int status
= FAILED
;
2088 MPT_ADAPTER
*ioc
= hd
->ioc
;
2091 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
2092 if(hd
->tmPending
== 0) {
2094 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
2097 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
2099 } while (--loop_count
);
2104 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2106 mptscsih_taskmgmt_response_code(MPT_ADAPTER
*ioc
, u8 response_code
)
2110 switch (response_code
) {
2111 case MPI_SCSITASKMGMT_RSP_TM_COMPLETE
:
2112 desc
= "The task completed.";
2114 case MPI_SCSITASKMGMT_RSP_INVALID_FRAME
:
2115 desc
= "The IOC received an invalid frame status.";
2117 case MPI_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED
:
2118 desc
= "The task type is not supported.";
2120 case MPI_SCSITASKMGMT_RSP_TM_FAILED
:
2121 desc
= "The requested task failed.";
2123 case MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED
:
2124 desc
= "The task completed successfully.";
2126 case MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN
:
2127 desc
= "The LUN request is invalid.";
2129 case MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC
:
2130 desc
= "The task is in the IOC queue and has not been sent to target.";
2136 printk(MYIOC_s_INFO_FMT
"Response Code(0x%08x): F/W: %s\n",
2137 ioc
->name
, response_code
, desc
);
2140 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2142 * mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
2143 * @ioc: Pointer to MPT_ADAPTER structure
2144 * @mf: Pointer to SCSI task mgmt request frame
2145 * @mr: Pointer to SCSI task mgmt reply frame
2147 * This routine is called from mptbase.c::mpt_interrupt() at the completion
2148 * of any SCSI task management request.
2149 * This routine is registered with the MPT (base) driver at driver
2150 * load/init time via the mpt_register() API call.
2152 * Returns 1 indicating alloc'd request frame ptr should be freed.
2155 mptscsih_taskmgmt_complete(MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*mf
, MPT_FRAME_HDR
*mr
)
2157 SCSITaskMgmtReply_t
*pScsiTmReply
;
2158 SCSITaskMgmt_t
*pScsiTmReq
;
2160 unsigned long flags
;
2163 u32 termination_count
;
2165 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"TaskMgmt completed (mf=%p,mr=%p)\n",
2166 ioc
->name
, mf
, mr
));
2168 dtmprintk(ioc
, printk(MYIOC_s_WARN_FMT
2169 "TaskMgmt Complete: NULL Scsi Host Ptr\n", ioc
->name
));
2174 dtmprintk(ioc
, printk(MYIOC_s_WARN_FMT
2175 "ERROR! TaskMgmt Reply: NULL Request %p\n", ioc
->name
, mf
));
2179 hd
= shost_priv(ioc
->sh
);
2180 pScsiTmReply
= (SCSITaskMgmtReply_t
*)mr
;
2181 pScsiTmReq
= (SCSITaskMgmt_t
*)mf
;
2182 tmType
= pScsiTmReq
->TaskType
;
2183 iocstatus
= le16_to_cpu(pScsiTmReply
->IOCStatus
) & MPI_IOCSTATUS_MASK
;
2184 termination_count
= le32_to_cpu(pScsiTmReply
->TerminationCount
);
2186 if (ioc
->facts
.MsgVersion
>= MPI_VERSION_01_05
&&
2187 pScsiTmReply
->ResponseCode
)
2188 mptscsih_taskmgmt_response_code(ioc
,
2189 pScsiTmReply
->ResponseCode
);
2190 DBG_DUMP_TM_REPLY_FRAME(ioc
, (u32
*)pScsiTmReply
);
2192 #ifdef CONFIG_FUSION_LOGGING
2193 if ((ioc
->debug_level
& MPT_DEBUG_REPLY
) ||
2194 (ioc
->debug_level
& MPT_DEBUG_TM
))
2195 printk("%s: ha=%d [%d:%d:0] task_type=0x%02X "
2196 "iocstatus=0x%04X\n\tloginfo=0x%08X response_code=0x%02X "
2197 "term_cmnds=%d\n", __FUNCTION__
, ioc
->id
, pScsiTmReply
->Bus
,
2198 pScsiTmReply
->TargetID
, pScsiTmReq
->TaskType
,
2199 le16_to_cpu(pScsiTmReply
->IOCStatus
),
2200 le32_to_cpu(pScsiTmReply
->IOCLogInfo
),pScsiTmReply
->ResponseCode
,
2201 le32_to_cpu(pScsiTmReply
->TerminationCount
));
2204 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
" TaskMgmt SUCCESS\n", ioc
->name
));
2205 hd
->abortSCpnt
= NULL
;
2209 /* Error? (anything non-zero?) */
2211 /* clear flags and continue.
2215 case MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK
:
2216 if (termination_count
== 1)
2217 iocstatus
= MPI_IOCSTATUS_SCSI_TASK_TERMINATED
;
2218 hd
->abortSCpnt
= NULL
;
2221 case MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS
:
2223 /* If an internal command is present
2224 * or the TM failed - reload the FW.
2225 * FC FW may respond FAILED to an ABORT
2227 if (iocstatus
== MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED
||
2229 if (mpt_HardResetHandler(ioc
, NO_SLEEP
) < 0)
2230 printk(MYIOC_s_WARN_FMT
" Firmware Reload FAILED!!\n", ioc
->name
);
2233 case MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET
:
2239 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
2241 hd
->tmState
= TM_STATE_NONE
;
2242 hd
->tm_iocstatus
= iocstatus
;
2243 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
2248 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2250 * This is anyones guess quite frankly.
2253 mptscsih_bios_param(struct scsi_device
* sdev
, struct block_device
*bdev
,
2254 sector_t capacity
, int geom
[])
2264 dummy
= heads
* sectors
;
2265 cylinders
= capacity
;
2266 sector_div(cylinders
,dummy
);
2269 * Handle extended translation size for logical drives
2272 if ((ulong
)capacity
>= 0x200000) {
2275 dummy
= heads
* sectors
;
2276 cylinders
= capacity
;
2277 sector_div(cylinders
,dummy
);
2283 geom
[2] = cylinders
;
2288 /* Search IOC page 3 to determine if this is hidden physical disk
2292 mptscsih_is_phys_disk(MPT_ADAPTER
*ioc
, u8 channel
, u8 id
)
2294 struct inactive_raid_component_info
*component_info
;
2298 if (!ioc
->raid_data
.pIocPg3
)
2300 for (i
= 0; i
< ioc
->raid_data
.pIocPg3
->NumPhysDisks
; i
++) {
2301 if ((id
== ioc
->raid_data
.pIocPg3
->PhysDisk
[i
].PhysDiskID
) &&
2302 (channel
== ioc
->raid_data
.pIocPg3
->PhysDisk
[i
].PhysDiskBus
)) {
2309 * Check inactive list for matching phys disks
2311 if (list_empty(&ioc
->raid_data
.inactive_list
))
2314 down(&ioc
->raid_data
.inactive_list_mutex
);
2315 list_for_each_entry(component_info
, &ioc
->raid_data
.inactive_list
,
2317 if ((component_info
->d
.PhysDiskID
== id
) &&
2318 (component_info
->d
.PhysDiskBus
== channel
))
2321 up(&ioc
->raid_data
.inactive_list_mutex
);
2326 EXPORT_SYMBOL(mptscsih_is_phys_disk
);
2329 mptscsih_raid_id_to_num(MPT_ADAPTER
*ioc
, u8 channel
, u8 id
)
2331 struct inactive_raid_component_info
*component_info
;
2335 if (!ioc
->raid_data
.pIocPg3
)
2337 for (i
= 0; i
< ioc
->raid_data
.pIocPg3
->NumPhysDisks
; i
++) {
2338 if ((id
== ioc
->raid_data
.pIocPg3
->PhysDisk
[i
].PhysDiskID
) &&
2339 (channel
== ioc
->raid_data
.pIocPg3
->PhysDisk
[i
].PhysDiskBus
)) {
2340 rc
= ioc
->raid_data
.pIocPg3
->PhysDisk
[i
].PhysDiskNum
;
2346 * Check inactive list for matching phys disks
2348 if (list_empty(&ioc
->raid_data
.inactive_list
))
2351 down(&ioc
->raid_data
.inactive_list_mutex
);
2352 list_for_each_entry(component_info
, &ioc
->raid_data
.inactive_list
,
2354 if ((component_info
->d
.PhysDiskID
== id
) &&
2355 (component_info
->d
.PhysDiskBus
== channel
))
2356 rc
= component_info
->d
.PhysDiskNum
;
2358 up(&ioc
->raid_data
.inactive_list_mutex
);
2363 EXPORT_SYMBOL(mptscsih_raid_id_to_num
);
2366 * OS entry point to allow for host driver to free allocated memory
2367 * Called if no device present or device being unloaded
2370 mptscsih_slave_destroy(struct scsi_device
*sdev
)
2372 struct Scsi_Host
*host
= sdev
->host
;
2373 MPT_SCSI_HOST
*hd
= shost_priv(host
);
2374 VirtTarget
*vtarget
;
2375 VirtDevice
*vdevice
;
2376 struct scsi_target
*starget
;
2378 starget
= scsi_target(sdev
);
2379 vtarget
= starget
->hostdata
;
2380 vdevice
= sdev
->hostdata
;
2382 mptscsih_search_running_cmds(hd
, vdevice
);
2383 vtarget
->num_luns
--;
2384 mptscsih_synchronize_cache(hd
, vdevice
);
2386 sdev
->hostdata
= NULL
;
2389 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2391 * mptscsih_change_queue_depth - This function will set a devices queue depth
2392 * @sdev: per scsi_device pointer
2393 * @qdepth: requested queue depth
2395 * Adding support for new 'change_queue_depth' api.
2398 mptscsih_change_queue_depth(struct scsi_device
*sdev
, int qdepth
)
2400 MPT_SCSI_HOST
*hd
= shost_priv(sdev
->host
);
2401 VirtTarget
*vtarget
;
2402 struct scsi_target
*starget
;
2405 MPT_ADAPTER
*ioc
= hd
->ioc
;
2407 starget
= scsi_target(sdev
);
2408 vtarget
= starget
->hostdata
;
2410 if (ioc
->bus_type
== SPI
) {
2411 if (!(vtarget
->tflags
& MPT_TARGET_FLAGS_Q_YES
))
2413 else if (sdev
->type
== TYPE_DISK
&&
2414 vtarget
->minSyncFactor
<= MPT_ULTRA160
)
2415 max_depth
= MPT_SCSI_CMD_PER_DEV_HIGH
;
2417 max_depth
= MPT_SCSI_CMD_PER_DEV_LOW
;
2419 max_depth
= MPT_SCSI_CMD_PER_DEV_HIGH
;
2421 if (qdepth
> max_depth
)
2426 tagged
= MSG_SIMPLE_TAG
;
2428 scsi_adjust_queue_depth(sdev
, tagged
, qdepth
);
2429 return sdev
->queue_depth
;
2433 * OS entry point to adjust the queue_depths on a per-device basis.
2434 * Called once per device the bus scan. Use it to force the queue_depth
2435 * member to 1 if a device does not support Q tags.
2436 * Return non-zero if fails.
2439 mptscsih_slave_configure(struct scsi_device
*sdev
)
2441 struct Scsi_Host
*sh
= sdev
->host
;
2442 VirtTarget
*vtarget
;
2443 VirtDevice
*vdevice
;
2444 struct scsi_target
*starget
;
2445 MPT_SCSI_HOST
*hd
= shost_priv(sh
);
2446 MPT_ADAPTER
*ioc
= hd
->ioc
;
2448 starget
= scsi_target(sdev
);
2449 vtarget
= starget
->hostdata
;
2450 vdevice
= sdev
->hostdata
;
2452 dsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2453 "device @ %p, channel=%d, id=%d, lun=%d\n",
2454 ioc
->name
, sdev
, sdev
->channel
, sdev
->id
, sdev
->lun
));
2455 if (ioc
->bus_type
== SPI
)
2456 dsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2457 "sdtr %d wdtr %d ppr %d inq length=%d\n",
2458 ioc
->name
, sdev
->sdtr
, sdev
->wdtr
,
2459 sdev
->ppr
, sdev
->inquiry_len
));
2461 if (sdev
->id
> sh
->max_id
) {
2462 /* error case, should never happen */
2463 scsi_adjust_queue_depth(sdev
, 0, 1);
2464 goto slave_configure_exit
;
2467 vdevice
->configured_lun
= 1;
2468 mptscsih_change_queue_depth(sdev
, MPT_SCSI_CMD_PER_DEV_HIGH
);
2470 dsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2471 "Queue depth=%d, tflags=%x\n",
2472 ioc
->name
, sdev
->queue_depth
, vtarget
->tflags
));
2474 if (ioc
->bus_type
== SPI
)
2475 dsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2476 "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
2477 ioc
->name
, vtarget
->negoFlags
, vtarget
->maxOffset
,
2478 vtarget
->minSyncFactor
));
2480 slave_configure_exit
:
2482 dsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2483 "tagged %d, simple %d, ordered %d\n",
2484 ioc
->name
,sdev
->tagged_supported
, sdev
->simple_tags
,
2485 sdev
->ordered_tags
));
2490 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2492 * Private routines...
2495 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2496 /* Utility function to copy sense data from the scsi_cmnd buffer
2497 * to the FC and SCSI target structures.
2501 mptscsih_copy_sense_data(struct scsi_cmnd
*sc
, MPT_SCSI_HOST
*hd
, MPT_FRAME_HDR
*mf
, SCSIIOReply_t
*pScsiReply
)
2503 VirtDevice
*vdevice
;
2504 SCSIIORequest_t
*pReq
;
2505 u32 sense_count
= le32_to_cpu(pScsiReply
->SenseCount
);
2506 MPT_ADAPTER
*ioc
= hd
->ioc
;
2508 /* Get target structure
2510 pReq
= (SCSIIORequest_t
*) mf
;
2511 vdevice
= sc
->device
->hostdata
;
2517 /* Copy the sense received into the scsi command block. */
2518 req_index
= le16_to_cpu(mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
);
2519 sense_data
= ((u8
*)ioc
->sense_buf_pool
+ (req_index
* MPT_SENSE_BUFFER_ALLOC
));
2520 memcpy(sc
->sense_buffer
, sense_data
, SNS_LEN(sc
));
2522 /* Log SMART data (asc = 0x5D, non-IM case only) if required.
2524 if ((ioc
->events
) && (ioc
->eventTypes
& (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE
))) {
2525 if ((sense_data
[12] == 0x5D) && (vdevice
->vtarget
->raidVolume
== 0)) {
2528 idx
= ioc
->eventContext
% MPTCTL_EVENT_LOG_SIZE
;
2529 ioc
->events
[idx
].event
= MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE
;
2530 ioc
->events
[idx
].eventContext
= ioc
->eventContext
;
2532 ioc
->events
[idx
].data
[0] = (pReq
->LUN
[1] << 24) |
2533 (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA
<< 16) |
2534 (sc
->device
->channel
<< 8) | sc
->device
->id
;
2536 ioc
->events
[idx
].data
[1] = (sense_data
[13] << 8) | sense_data
[12];
2538 ioc
->eventContext
++;
2539 if (ioc
->pcidev
->vendor
==
2540 PCI_VENDOR_ID_IBM
) {
2541 mptscsih_issue_sep_command(ioc
,
2542 vdevice
->vtarget
, MPI_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT
);
2543 vdevice
->vtarget
->tflags
|=
2544 MPT_TARGET_FLAGS_LED_ON
;
2549 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Hmmm... SenseData len=0! (?)\n",
2555 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd
*sc
)
2560 hd
= shost_priv(sc
->device
->host
);
2562 for (i
= 0; i
< hd
->ioc
->req_depth
; i
++) {
2563 if (hd
->ScsiLookup
[i
] == sc
) {
2571 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2573 mptscsih_ioc_reset(MPT_ADAPTER
*ioc
, int reset_phase
)
2576 unsigned long flags
;
2579 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2580 ": IOC %s_reset routed to SCSI host driver!\n",
2581 ioc
->name
, reset_phase
==MPT_IOC_SETUP_RESET
? "setup" : (
2582 reset_phase
==MPT_IOC_PRE_RESET
? "pre" : "post")));
2584 /* If a FW reload request arrives after base installed but
2585 * before all scsi hosts have been attached, then an alt_ioc
2586 * may have a NULL sh pointer.
2588 if (ioc
->sh
== NULL
|| shost_priv(ioc
->sh
) == NULL
)
2591 hd
= shost_priv(ioc
->sh
);
2593 if (reset_phase
== MPT_IOC_SETUP_RESET
) {
2594 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Setup-Diag Reset\n", ioc
->name
));
2597 * 1. Set Hard Reset Pending Flag
2598 * All new commands go to doneQ
2600 hd
->resetPending
= 1;
2602 } else if (reset_phase
== MPT_IOC_PRE_RESET
) {
2603 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Pre-Diag Reset\n", ioc
->name
));
2605 /* 2. Flush running commands
2606 * Clean ScsiLookup (and associated memory)
2610 /* 2b. Reply to OS all known outstanding I/O commands.
2612 mptscsih_flush_running_cmds(hd
);
2614 /* 2c. If there was an internal command that
2615 * has not completed, configuration or io request,
2616 * free these resources.
2619 del_timer(&hd
->timer
);
2620 mpt_free_msg_frame(ioc
, hd
->cmdPtr
);
2623 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Pre-Reset complete.\n", ioc
->name
));
2626 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Post-Diag Reset\n", ioc
->name
));
2628 /* Once a FW reload begins, all new OS commands are
2629 * redirected to the doneQ w/ a reset status.
2630 * Init all control structures.
2633 /* ScsiLookup initialization
2635 for (ii
=0; ii
< ioc
->req_depth
; ii
++)
2636 hd
->ScsiLookup
[ii
] = NULL
;
2638 /* 2. Chain Buffer initialization
2641 /* 4. Renegotiate to all devices, if SPI
2644 /* 5. Enable new commands to be posted
2646 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
2648 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
2649 hd
->resetPending
= 0;
2650 hd
->tmState
= TM_STATE_NONE
;
2652 /* 6. If there was an internal command,
2653 * wake this process up.
2657 * Wake up the original calling thread
2659 hd
->pLocal
= &hd
->localReply
;
2660 hd
->pLocal
->completion
= MPT_SCANDV_DID_RESET
;
2661 hd
->scandv_wait_done
= 1;
2662 wake_up(&hd
->scandv_waitq
);
2666 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Post-Reset complete.\n", ioc
->name
));
2670 return 1; /* currently means nothing really */
2673 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2675 mptscsih_event_process(MPT_ADAPTER
*ioc
, EventNotificationReply_t
*pEvReply
)
2678 u8 event
= le32_to_cpu(pEvReply
->Event
) & 0xFF;
2680 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"MPT event (=%02Xh) routed to SCSI host driver!\n",
2683 if (ioc
->sh
== NULL
||
2684 ((hd
= shost_priv(ioc
->sh
)) == NULL
))
2688 case MPI_EVENT_UNIT_ATTENTION
: /* 03 */
2691 case MPI_EVENT_IOC_BUS_RESET
: /* 04 */
2692 case MPI_EVENT_EXT_BUS_RESET
: /* 05 */
2693 if (hd
&& (ioc
->bus_type
== SPI
) && (hd
->soft_resets
< -1))
2696 case MPI_EVENT_LOGOUT
: /* 09 */
2700 case MPI_EVENT_RESCAN
: /* 06 */
2704 * CHECKME! Don't think we need to do
2705 * anything for these, but...
2707 case MPI_EVENT_LINK_STATUS_CHANGE
: /* 07 */
2708 case MPI_EVENT_LOOP_STATE_CHANGE
: /* 08 */
2710 * CHECKME! Falling thru...
2714 case MPI_EVENT_INTEGRATED_RAID
: /* 0B */
2717 case MPI_EVENT_NONE
: /* 00 */
2718 case MPI_EVENT_LOG_DATA
: /* 01 */
2719 case MPI_EVENT_STATE_CHANGE
: /* 02 */
2720 case MPI_EVENT_EVENT_CHANGE
: /* 0A */
2722 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
": Ignoring event (=%02Xh)\n",
2727 return 1; /* currently means nothing really */
2730 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2732 * Bus Scan and Domain Validation functionality ...
2735 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2737 * mptscsih_scandv_complete - Scan and DV callback routine registered
2738 * to Fustion MPT (base) driver.
2740 * @ioc: Pointer to MPT_ADAPTER structure
2741 * @mf: Pointer to original MPT request frame
2742 * @mr: Pointer to MPT reply frame (NULL if TurboReply)
2744 * This routine is called from mpt.c::mpt_interrupt() at the completion
2745 * of any SCSI IO request.
2746 * This routine is registered with the Fusion MPT (base) driver at driver
2747 * load/init time via the mpt_register() API call.
2749 * Returns 1 indicating alloc'd request frame ptr should be freed.
2751 * Remark: Sets a completion code and (possibly) saves sense data
2752 * in the IOC member localReply structure.
2753 * Used ONLY for DV and other internal commands.
2756 mptscsih_scandv_complete(MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*mf
, MPT_FRAME_HDR
*mr
)
2759 SCSIIORequest_t
*pReq
;
2763 hd
= shost_priv(ioc
->sh
);
2766 (mf
>= MPT_INDEX_2_MFPTR(ioc
, ioc
->req_depth
))) {
2767 printk(MYIOC_s_ERR_FMT
2768 "ScanDvComplete, %s req frame ptr! (=%p)\n",
2769 ioc
->name
, mf
?"BAD":"NULL", (void *) mf
);
2773 del_timer(&hd
->timer
);
2774 req_idx
= le16_to_cpu(mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
);
2775 hd
->ScsiLookup
[req_idx
] = NULL
;
2776 pReq
= (SCSIIORequest_t
*) mf
;
2778 if (mf
!= hd
->cmdPtr
) {
2779 printk(MYIOC_s_WARN_FMT
"ScanDvComplete (mf=%p, cmdPtr=%p, idx=%d)\n",
2780 ioc
->name
, (void *)mf
, (void *) hd
->cmdPtr
, req_idx
);
2784 ddvprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ScanDvComplete (mf=%p,mr=%p,idx=%d)\n",
2785 ioc
->name
, mf
, mr
, req_idx
));
2787 hd
->pLocal
= &hd
->localReply
;
2788 hd
->pLocal
->scsiStatus
= 0;
2790 /* If target struct exists, clear sense valid flag.
2793 completionCode
= MPT_SCANDV_GOOD
;
2795 SCSIIOReply_t
*pReply
;
2799 pReply
= (SCSIIOReply_t
*) mr
;
2801 status
= le16_to_cpu(pReply
->IOCStatus
) & MPI_IOCSTATUS_MASK
;
2802 scsi_status
= pReply
->SCSIStatus
;
2807 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE
: /* 0x0043 */
2808 completionCode
= MPT_SCANDV_SELECTION_TIMEOUT
;
2811 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR
: /* 0x0046 */
2812 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED
: /* 0x0048 */
2813 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED
: /* 0x004B */
2814 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED
: /* 0x004C */
2815 completionCode
= MPT_SCANDV_DID_RESET
;
2818 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN
: /* 0x0045 */
2819 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR
: /* 0x0040 */
2820 case MPI_IOCSTATUS_SUCCESS
: /* 0x0000 */
2821 if (pReply
->Function
== MPI_FUNCTION_CONFIG
) {
2822 ConfigReply_t
*pr
= (ConfigReply_t
*)mr
;
2823 completionCode
= MPT_SCANDV_GOOD
;
2824 hd
->pLocal
->header
.PageVersion
= pr
->Header
.PageVersion
;
2825 hd
->pLocal
->header
.PageLength
= pr
->Header
.PageLength
;
2826 hd
->pLocal
->header
.PageNumber
= pr
->Header
.PageNumber
;
2827 hd
->pLocal
->header
.PageType
= pr
->Header
.PageType
;
2829 } else if (pReply
->Function
== MPI_FUNCTION_RAID_ACTION
) {
2830 /* If the RAID Volume request is successful,
2831 * return GOOD, else indicate that
2832 * some type of error occurred.
2834 MpiRaidActionReply_t
*pr
= (MpiRaidActionReply_t
*)mr
;
2835 if (le16_to_cpu(pr
->ActionStatus
) == MPI_RAID_ACTION_ASTATUS_SUCCESS
)
2836 completionCode
= MPT_SCANDV_GOOD
;
2838 completionCode
= MPT_SCANDV_SOME_ERROR
;
2839 memcpy(hd
->pLocal
->sense
, pr
, sizeof(hd
->pLocal
->sense
));
2841 } else if (pReply
->SCSIState
& MPI_SCSI_STATE_AUTOSENSE_VALID
) {
2845 /* save sense data in global structure
2847 completionCode
= MPT_SCANDV_SENSE
;
2848 hd
->pLocal
->scsiStatus
= scsi_status
;
2849 sense_data
= ((u8
*)ioc
->sense_buf_pool
+
2850 (req_idx
* MPT_SENSE_BUFFER_ALLOC
));
2852 sz
= min_t(int, pReq
->SenseBufferLength
,
2853 SCSI_STD_SENSE_BYTES
);
2854 memcpy(hd
->pLocal
->sense
, sense_data
, sz
);
2856 ddvprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
" Check Condition, sense ptr %p\n",
2857 ioc
->name
, sense_data
));
2858 } else if (pReply
->SCSIState
& MPI_SCSI_STATE_AUTOSENSE_FAILED
) {
2859 if (pReq
->CDB
[0] == INQUIRY
)
2860 completionCode
= MPT_SCANDV_ISSUE_SENSE
;
2862 completionCode
= MPT_SCANDV_DID_RESET
;
2864 else if (pReply
->SCSIState
& MPI_SCSI_STATE_NO_SCSI_STATUS
)
2865 completionCode
= MPT_SCANDV_DID_RESET
;
2866 else if (pReply
->SCSIState
& MPI_SCSI_STATE_TERMINATED
)
2867 completionCode
= MPT_SCANDV_DID_RESET
;
2869 completionCode
= MPT_SCANDV_GOOD
;
2870 hd
->pLocal
->scsiStatus
= scsi_status
;
2874 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR
: /* 0x0047 */
2875 if (pReply
->SCSIState
& MPI_SCSI_STATE_TERMINATED
)
2876 completionCode
= MPT_SCANDV_DID_RESET
;
2878 completionCode
= MPT_SCANDV_SOME_ERROR
;
2882 completionCode
= MPT_SCANDV_SOME_ERROR
;
2885 } /* switch(status) */
2887 } /* end of address reply case */
2889 hd
->pLocal
->completion
= completionCode
;
2891 /* MF and RF are freed in mpt_interrupt
2894 /* Free Chain buffers (will never chain) in scan or dv */
2895 //mptscsih_freeChainBuffers(ioc, req_idx);
2898 * Wake up the original calling thread
2900 hd
->scandv_wait_done
= 1;
2901 wake_up(&hd
->scandv_waitq
);
2906 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2907 /* mptscsih_timer_expired - Call back for timer process.
2908 * Used only for dv functionality.
2909 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
2913 mptscsih_timer_expired(unsigned long data
)
2915 MPT_SCSI_HOST
*hd
= (MPT_SCSI_HOST
*) data
;
2916 MPT_ADAPTER
*ioc
= hd
->ioc
;
2918 ddvprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Timer Expired! Cmd %p\n", ioc
->name
, hd
->cmdPtr
));
2921 MPIHeader_t
*cmd
= (MPIHeader_t
*)hd
->cmdPtr
;
2923 if (cmd
->Function
== MPI_FUNCTION_SCSI_IO_REQUEST
) {
2924 /* Desire to issue a task management request here.
2925 * TM requests MUST be single threaded.
2926 * If old eh code and no TM current, issue request.
2927 * If new eh code, do nothing. Wait for OS cmd timeout
2931 /* Perform a FW reload */
2932 if (mpt_HardResetHandler(ioc
, NO_SLEEP
) < 0) {
2933 printk(MYIOC_s_WARN_FMT
"Firmware Reload FAILED!\n", ioc
->name
);
2937 /* This should NEVER happen */
2938 printk(MYIOC_s_WARN_FMT
"Null cmdPtr!!!!\n", ioc
->name
);
2941 /* No more processing.
2942 * TM call will generate an interrupt for SCSI TM Management.
2943 * The FW will reply to all outstanding commands, callback will finish cleanup.
2944 * Hard reset clean-up will free all resources.
2946 ddvprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Timer Expired Complete!\n", ioc
->name
));
2952 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2954 * mptscsih_do_cmd - Do internal command.
2955 * @hd: MPT_SCSI_HOST pointer
2956 * @io: INTERNAL_CMD pointer.
2958 * Issue the specified internally generated command and do command
2959 * specific cleanup. For bus scan / DV only.
2960 * NOTES: If command is Inquiry and status is good,
2961 * initialize a target structure, save the data
2963 * Remark: Single threaded access only.
2966 * < 0 if an illegal command or no resources
2970 * > 0 if command complete but some type of completion error.
2973 mptscsih_do_cmd(MPT_SCSI_HOST
*hd
, INTERNAL_CMD
*io
)
2976 SCSIIORequest_t
*pScsiReq
;
2977 SCSIIORequest_t ReqCopy
;
2978 int my_idx
, ii
, dir
;
2982 char CDB
[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
2984 MPT_ADAPTER
*ioc
= hd
->ioc
;
2986 in_isr
= in_interrupt();
2988 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Internal SCSI IO request not allowed in ISR context!\n",
2994 /* Set command specific information
2999 dir
= MPI_SCSIIO_CONTROL_READ
;
3005 case TEST_UNIT_READY
:
3007 dir
= MPI_SCSIIO_CONTROL_READ
;
3013 dir
= MPI_SCSIIO_CONTROL_READ
;
3015 CDB
[4] = 1; /*Spin up the disk */
3023 dir
= MPI_SCSIIO_CONTROL_READ
;
3029 dir
= MPI_SCSIIO_CONTROL_READ
;
3031 if (io
->flags
& MPT_ICFLAG_ECHO
) {
3037 if (io
->flags
& MPT_ICFLAG_BUF_CAP
) {
3040 CDB
[6] = (io
->size
>> 16) & 0xFF;
3041 CDB
[7] = (io
->size
>> 8) & 0xFF;
3042 CDB
[8] = io
->size
& 0xFF;
3048 dir
= MPI_SCSIIO_CONTROL_WRITE
;
3050 if (io
->flags
& MPT_ICFLAG_ECHO
) {
3055 CDB
[6] = (io
->size
>> 16) & 0xFF;
3056 CDB
[7] = (io
->size
>> 8) & 0xFF;
3057 CDB
[8] = io
->size
& 0xFF;
3063 dir
= MPI_SCSIIO_CONTROL_READ
;
3070 dir
= MPI_SCSIIO_CONTROL_READ
;
3075 case SYNCHRONIZE_CACHE
:
3077 dir
= MPI_SCSIIO_CONTROL_READ
;
3079 // CDB[1] = 0x02; /* set immediate bit */
3088 /* Get and Populate a free Frame
3090 if ((mf
= mpt_get_msg_frame(ioc
->InternalCtx
, ioc
)) == NULL
) {
3091 dfailprintk(ioc
, printk(MYIOC_s_WARN_FMT
"No msg frames!\n",
3096 pScsiReq
= (SCSIIORequest_t
*) mf
;
3098 /* Get the request index */
3099 my_idx
= le16_to_cpu(mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
);
3100 ADD_INDEX_LOG(my_idx
); /* for debug */
3102 if (io
->flags
& MPT_ICFLAG_PHYS_DISK
) {
3103 pScsiReq
->TargetID
= io
->physDiskNum
;
3105 pScsiReq
->ChainOffset
= 0;
3106 pScsiReq
->Function
= MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH
;
3108 pScsiReq
->TargetID
= io
->id
;
3109 pScsiReq
->Bus
= io
->channel
;
3110 pScsiReq
->ChainOffset
= 0;
3111 pScsiReq
->Function
= MPI_FUNCTION_SCSI_IO_REQUEST
;
3114 pScsiReq
->CDBLength
= cmdLen
;
3115 pScsiReq
->SenseBufferLength
= MPT_SENSE_BUFFER_SIZE
;
3117 pScsiReq
->Reserved
= 0;
3119 pScsiReq
->MsgFlags
= mpt_msg_flags();
3120 /* MsgContext set in mpt_get_msg_fram call */
3122 int_to_scsilun(io
->lun
, (struct scsi_lun
*)pScsiReq
->LUN
);
3124 if (io
->flags
& MPT_ICFLAG_TAGGED_CMD
)
3125 pScsiReq
->Control
= cpu_to_le32(dir
| MPI_SCSIIO_CONTROL_SIMPLEQ
);
3127 pScsiReq
->Control
= cpu_to_le32(dir
| MPI_SCSIIO_CONTROL_UNTAGGED
);
3129 if (cmd
== REQUEST_SENSE
) {
3130 pScsiReq
->Control
= cpu_to_le32(dir
| MPI_SCSIIO_CONTROL_UNTAGGED
);
3131 ddvprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Untagged! 0x%2x\n",
3135 for (ii
=0; ii
< 16; ii
++)
3136 pScsiReq
->CDB
[ii
] = CDB
[ii
];
3138 pScsiReq
->DataLength
= cpu_to_le32(io
->size
);
3139 pScsiReq
->SenseBufferLowAddr
= cpu_to_le32(ioc
->sense_buf_low_dma
3140 + (my_idx
* MPT_SENSE_BUFFER_ALLOC
));
3142 ddvprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending Command 0x%x for (%d:%d:%d)\n",
3143 ioc
->name
, cmd
, io
->channel
, io
->id
, io
->lun
));
3145 if (dir
== MPI_SCSIIO_CONTROL_READ
) {
3146 mpt_add_sge((char *) &pScsiReq
->SGL
,
3147 MPT_SGE_FLAGS_SSIMPLE_READ
| io
->size
,
3150 mpt_add_sge((char *) &pScsiReq
->SGL
,
3151 MPT_SGE_FLAGS_SSIMPLE_WRITE
| io
->size
,
3155 /* The ISR will free the request frame, but we need
3156 * the information to initialize the target. Duplicate.
3158 memcpy(&ReqCopy
, pScsiReq
, sizeof(SCSIIORequest_t
));
3160 /* Issue this command after:
3163 * Wait until the reply has been received
3164 * ScsiScanDvCtx callback function will
3166 * set scandv_wait_done and call wake_up
3169 hd
->timer
.expires
= jiffies
+ HZ
*cmdTimeout
;
3170 hd
->scandv_wait_done
= 0;
3172 /* Save cmd pointer, for resource free if timeout or
3177 add_timer(&hd
->timer
);
3178 mpt_put_msg_frame(ioc
->InternalCtx
, ioc
, mf
);
3179 wait_event(hd
->scandv_waitq
, hd
->scandv_wait_done
);
3182 rc
= hd
->pLocal
->completion
;
3183 hd
->pLocal
->skip
= 0;
3185 /* Always set fatal error codes in some cases.
3187 if (rc
== MPT_SCANDV_SELECTION_TIMEOUT
)
3189 else if (rc
== MPT_SCANDV_SOME_ERROR
)
3193 /* This should never happen. */
3194 ddvprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"_do_cmd: Null pLocal!!!\n",
3201 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3203 * mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
3204 * @hd: Pointer to a SCSI HOST structure
3205 * @vdevice: virtual target device
3207 * Uses the ISR, but with special processing.
3208 * MUST be single-threaded.
3212 mptscsih_synchronize_cache(MPT_SCSI_HOST
*hd
, VirtDevice
*vdevice
)
3216 /* Ignore hidden raid components, this is handled when the command
3217 * is sent to the volume
3219 if (vdevice
->vtarget
->tflags
& MPT_TARGET_FLAGS_RAID_COMPONENT
)
3222 if (vdevice
->vtarget
->type
!= TYPE_DISK
|| vdevice
->vtarget
->deleted
||
3223 !vdevice
->configured_lun
)
3226 /* Following parameters will not change
3229 iocmd
.cmd
= SYNCHRONIZE_CACHE
;
3231 iocmd
.physDiskNum
= -1;
3233 iocmd
.data_dma
= -1;
3235 iocmd
.rsvd
= iocmd
.rsvd2
= 0;
3236 iocmd
.channel
= vdevice
->vtarget
->channel
;
3237 iocmd
.id
= vdevice
->vtarget
->id
;
3238 iocmd
.lun
= vdevice
->lun
;
3240 mptscsih_do_cmd(hd
, &iocmd
);
3244 mptscsih_version_fw_show(struct class_device
*cdev
, char *buf
)
3246 struct Scsi_Host
*host
= class_to_shost(cdev
);
3247 MPT_SCSI_HOST
*hd
= shost_priv(host
);
3248 MPT_ADAPTER
*ioc
= hd
->ioc
;
3250 return snprintf(buf
, PAGE_SIZE
, "%02d.%02d.%02d.%02d\n",
3251 (ioc
->facts
.FWVersion
.Word
& 0xFF000000) >> 24,
3252 (ioc
->facts
.FWVersion
.Word
& 0x00FF0000) >> 16,
3253 (ioc
->facts
.FWVersion
.Word
& 0x0000FF00) >> 8,
3254 ioc
->facts
.FWVersion
.Word
& 0x000000FF);
3256 static CLASS_DEVICE_ATTR(version_fw
, S_IRUGO
, mptscsih_version_fw_show
, NULL
);
3259 mptscsih_version_bios_show(struct class_device
*cdev
, char *buf
)
3261 struct Scsi_Host
*host
= class_to_shost(cdev
);
3262 MPT_SCSI_HOST
*hd
= shost_priv(host
);
3263 MPT_ADAPTER
*ioc
= hd
->ioc
;
3265 return snprintf(buf
, PAGE_SIZE
, "%02x.%02x.%02x.%02x\n",
3266 (ioc
->biosVersion
& 0xFF000000) >> 24,
3267 (ioc
->biosVersion
& 0x00FF0000) >> 16,
3268 (ioc
->biosVersion
& 0x0000FF00) >> 8,
3269 ioc
->biosVersion
& 0x000000FF);
3271 static CLASS_DEVICE_ATTR(version_bios
, S_IRUGO
, mptscsih_version_bios_show
, NULL
);
3274 mptscsih_version_mpi_show(struct class_device
*cdev
, char *buf
)
3276 struct Scsi_Host
*host
= class_to_shost(cdev
);
3277 MPT_SCSI_HOST
*hd
= shost_priv(host
);
3278 MPT_ADAPTER
*ioc
= hd
->ioc
;
3280 return snprintf(buf
, PAGE_SIZE
, "%03x\n", ioc
->facts
.MsgVersion
);
3282 static CLASS_DEVICE_ATTR(version_mpi
, S_IRUGO
, mptscsih_version_mpi_show
, NULL
);
3285 mptscsih_version_product_show(struct class_device
*cdev
, char *buf
)
3287 struct Scsi_Host
*host
= class_to_shost(cdev
);
3288 MPT_SCSI_HOST
*hd
= shost_priv(host
);
3289 MPT_ADAPTER
*ioc
= hd
->ioc
;
3291 return snprintf(buf
, PAGE_SIZE
, "%s\n", ioc
->prod_name
);
3293 static CLASS_DEVICE_ATTR(version_product
, S_IRUGO
,
3294 mptscsih_version_product_show
, NULL
);
3297 mptscsih_version_nvdata_persistent_show(struct class_device
*cdev
, char *buf
)
3299 struct Scsi_Host
*host
= class_to_shost(cdev
);
3300 MPT_SCSI_HOST
*hd
= shost_priv(host
);
3301 MPT_ADAPTER
*ioc
= hd
->ioc
;
3303 return snprintf(buf
, PAGE_SIZE
, "%02xh\n",
3304 ioc
->nvdata_version_persistent
);
3306 static CLASS_DEVICE_ATTR(version_nvdata_persistent
, S_IRUGO
,
3307 mptscsih_version_nvdata_persistent_show
, NULL
);
3310 mptscsih_version_nvdata_default_show(struct class_device
*cdev
, char *buf
)
3312 struct Scsi_Host
*host
= class_to_shost(cdev
);
3313 MPT_SCSI_HOST
*hd
= shost_priv(host
);
3314 MPT_ADAPTER
*ioc
= hd
->ioc
;
3316 return snprintf(buf
, PAGE_SIZE
, "%02xh\n",ioc
->nvdata_version_default
);
3318 static CLASS_DEVICE_ATTR(version_nvdata_default
, S_IRUGO
,
3319 mptscsih_version_nvdata_default_show
, NULL
);
3322 mptscsih_board_name_show(struct class_device
*cdev
, char *buf
)
3324 struct Scsi_Host
*host
= class_to_shost(cdev
);
3325 MPT_SCSI_HOST
*hd
= shost_priv(host
);
3326 MPT_ADAPTER
*ioc
= hd
->ioc
;
3328 return snprintf(buf
, PAGE_SIZE
, "%s\n", ioc
->board_name
);
3330 static CLASS_DEVICE_ATTR(board_name
, S_IRUGO
, mptscsih_board_name_show
, NULL
);
3333 mptscsih_board_assembly_show(struct class_device
*cdev
, char *buf
)
3335 struct Scsi_Host
*host
= class_to_shost(cdev
);
3336 MPT_SCSI_HOST
*hd
= shost_priv(host
);
3337 MPT_ADAPTER
*ioc
= hd
->ioc
;
3339 return snprintf(buf
, PAGE_SIZE
, "%s\n", ioc
->board_assembly
);
3341 static CLASS_DEVICE_ATTR(board_assembly
, S_IRUGO
,
3342 mptscsih_board_assembly_show
, NULL
);
3345 mptscsih_board_tracer_show(struct class_device
*cdev
, char *buf
)
3347 struct Scsi_Host
*host
= class_to_shost(cdev
);
3348 MPT_SCSI_HOST
*hd
= shost_priv(host
);
3349 MPT_ADAPTER
*ioc
= hd
->ioc
;
3351 return snprintf(buf
, PAGE_SIZE
, "%s\n", ioc
->board_tracer
);
3353 static CLASS_DEVICE_ATTR(board_tracer
, S_IRUGO
,
3354 mptscsih_board_tracer_show
, NULL
);
3357 mptscsih_io_delay_show(struct class_device
*cdev
, char *buf
)
3359 struct Scsi_Host
*host
= class_to_shost(cdev
);
3360 MPT_SCSI_HOST
*hd
= shost_priv(host
);
3361 MPT_ADAPTER
*ioc
= hd
->ioc
;
3363 return snprintf(buf
, PAGE_SIZE
, "%02d\n", ioc
->io_missing_delay
);
3365 static CLASS_DEVICE_ATTR(io_delay
, S_IRUGO
,
3366 mptscsih_io_delay_show
, NULL
);
3369 mptscsih_device_delay_show(struct class_device
*cdev
, char *buf
)
3371 struct Scsi_Host
*host
= class_to_shost(cdev
);
3372 MPT_SCSI_HOST
*hd
= shost_priv(host
);
3373 MPT_ADAPTER
*ioc
= hd
->ioc
;
3375 return snprintf(buf
, PAGE_SIZE
, "%02d\n", ioc
->device_missing_delay
);
3377 static CLASS_DEVICE_ATTR(device_delay
, S_IRUGO
,
3378 mptscsih_device_delay_show
, NULL
);
3381 mptscsih_debug_level_show(struct class_device
*cdev
, char *buf
)
3383 struct Scsi_Host
*host
= class_to_shost(cdev
);
3384 MPT_SCSI_HOST
*hd
= shost_priv(host
);
3385 MPT_ADAPTER
*ioc
= hd
->ioc
;
3387 return snprintf(buf
, PAGE_SIZE
, "%08xh\n", ioc
->debug_level
);
3390 mptscsih_debug_level_store(struct class_device
*cdev
, const char *buf
,
3393 struct Scsi_Host
*host
= class_to_shost(cdev
);
3394 MPT_SCSI_HOST
*hd
= shost_priv(host
);
3395 MPT_ADAPTER
*ioc
= hd
->ioc
;
3398 if (sscanf(buf
, "%x", &val
) != 1)
3401 ioc
->debug_level
= val
;
3402 printk(MYIOC_s_INFO_FMT
"debug_level=%08xh\n",
3403 ioc
->name
, ioc
->debug_level
);
3406 static CLASS_DEVICE_ATTR(debug_level
, S_IRUGO
| S_IWUSR
,
3407 mptscsih_debug_level_show
, mptscsih_debug_level_store
);
3409 struct class_device_attribute
*mptscsih_host_attrs
[] = {
3410 &class_device_attr_version_fw
,
3411 &class_device_attr_version_bios
,
3412 &class_device_attr_version_mpi
,
3413 &class_device_attr_version_product
,
3414 &class_device_attr_version_nvdata_persistent
,
3415 &class_device_attr_version_nvdata_default
,
3416 &class_device_attr_board_name
,
3417 &class_device_attr_board_assembly
,
3418 &class_device_attr_board_tracer
,
3419 &class_device_attr_io_delay
,
3420 &class_device_attr_device_delay
,
3421 &class_device_attr_debug_level
,
3424 EXPORT_SYMBOL(mptscsih_host_attrs
);
3426 EXPORT_SYMBOL(mptscsih_remove
);
3427 EXPORT_SYMBOL(mptscsih_shutdown
);
3429 EXPORT_SYMBOL(mptscsih_suspend
);
3430 EXPORT_SYMBOL(mptscsih_resume
);
3432 EXPORT_SYMBOL(mptscsih_proc_info
);
3433 EXPORT_SYMBOL(mptscsih_info
);
3434 EXPORT_SYMBOL(mptscsih_qcmd
);
3435 EXPORT_SYMBOL(mptscsih_slave_destroy
);
3436 EXPORT_SYMBOL(mptscsih_slave_configure
);
3437 EXPORT_SYMBOL(mptscsih_abort
);
3438 EXPORT_SYMBOL(mptscsih_dev_reset
);
3439 EXPORT_SYMBOL(mptscsih_bus_reset
);
3440 EXPORT_SYMBOL(mptscsih_host_reset
);
3441 EXPORT_SYMBOL(mptscsih_bios_param
);
3442 EXPORT_SYMBOL(mptscsih_io_done
);
3443 EXPORT_SYMBOL(mptscsih_taskmgmt_complete
);
3444 EXPORT_SYMBOL(mptscsih_scandv_complete
);
3445 EXPORT_SYMBOL(mptscsih_event_process
);
3446 EXPORT_SYMBOL(mptscsih_ioc_reset
);
3447 EXPORT_SYMBOL(mptscsih_change_queue_depth
);
3448 EXPORT_SYMBOL(mptscsih_timer_expired
);
3449 EXPORT_SYMBOL(mptscsih_TMHandler
);
3451 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/