summaryrefslogtreecommitdiff
path: root/drivers/message/fusion/mptscsih.c
diff options
context:
space:
mode:
authorKashyap, Desai <kashyap.desai@lsi.com>2010-07-26 18:56:21 +0530
committerJames Bottomley <James.Bottomley@suse.de>2010-07-28 09:07:46 -0500
commitc9de7dc48307395fb71780b567ae8833b080d1c8 (patch)
treeb034f8833d64b640d9ef9e3f61191d06b51e5027 /drivers/message/fusion/mptscsih.c
parentb5833cbbd7c2bc3462e684feadd8e6a0ca8e5387 (diff)
[SCSI] mptfusion: Block Error handling for deleting devices or Device in DMD
Issue description: In multipath topology, when device deletion is in transient state, multipath driver can call blk_flush_queue() as part of path failure. Before device get deleted from OS, Device may go OFFLINE as part of error handling kicked off triggered from multipathing driver. Above condition hits more frequently if device missing delay timer (which is LSI specific firmware parameter) is non zero value. root cause of this issue is Error handling thread is getting kicked off for device which is not really present(in transient state of deleting). This patch has solution for this issue. driver is now using eh_timed_out callback. See below. mptsas_transport_template->eh_timed_out = mptsas_eh_timed_out Using mptsas_eh_timed_out function, driver can decide weather vdevice is under Device missing delay or deleting state. for either of those cases, there is BLK_EH_RESET_TIMER return to scsi mid and error handling thread will not be kicked off for that particular scsi command. Signed-off-by: Kashyap Desai <kashyap.desai@lsi.com> Cc: Stable Tree <stable@kernel.org> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/message/fusion/mptscsih.c')
-rw-r--r--drivers/message/fusion/mptscsih.c40
1 files changed, 31 insertions, 9 deletions
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index dceb67a2182..59b8f53d1ec 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -664,6 +664,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
u32 log_info;
status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK;
+
scsi_state = pScsiReply->SCSIState;
scsi_status = pScsiReply->SCSIStatus;
xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
@@ -738,15 +739,36 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
if ( ioc->bus_type == SAS ) {
- u16 ioc_status = le16_to_cpu(pScsiReply->IOCStatus);
- if (ioc_status & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
- if ((log_info & SAS_LOGINFO_MASK)
- == SAS_LOGINFO_NEXUS_LOSS) {
- sc->result =
- (DID_TRANSPORT_DISRUPTED
- << 16);
- break;
- }
+ u16 ioc_status =
+ le16_to_cpu(pScsiReply->IOCStatus);
+ if ((ioc_status &
+ MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE)
+ &&
+ ((log_info & SAS_LOGINFO_MASK) ==
+ SAS_LOGINFO_NEXUS_LOSS)) {
+ VirtDevice *vdevice =
+ sc->device->hostdata;
+
+ /* flag the device as being in
+ * device removal delay so we can
+ * notify the midlayer to hold off
+ * on timeout eh */
+ if (vdevice && vdevice->
+ vtarget &&
+ vdevice->vtarget->
+ raidVolume)
+ printk(KERN_INFO
+ "Skipping Raid Volume"
+ "for inDMD\n");
+ else if (vdevice &&
+ vdevice->vtarget)
+ vdevice->vtarget->
+ inDMD = 1;
+
+ sc->result =
+ (DID_TRANSPORT_DISRUPTED
+ << 16);
+ break;
}
} else if (ioc->bus_type == FC) {
/*