aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libsas/sas_scsi_host.c
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@us.ibm.com>2007-01-11 14:14:55 -0800
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2007-01-13 16:12:39 -0600
commitb218a0d8e250e0ae8fd4d4e45bd66a588b380752 (patch)
tree6c60dc11ef8d064404eb2fd6a3b4f37529a2c72f /drivers/scsi/libsas/sas_scsi_host.c
parentbf451207511d049189ddb0a4eae3acdb086a3c82 (diff)
downloadkernel_samsung_espresso10-b218a0d8e250e0ae8fd4d4e45bd66a588b380752.zip
kernel_samsung_espresso10-b218a0d8e250e0ae8fd4d4e45bd66a588b380752.tar.gz
kernel_samsung_espresso10-b218a0d8e250e0ae8fd4d4e45bd66a588b380752.tar.bz2
[SCSI] libsas: Don't give scsi_cmnds to the EH if they never made it to the SAS LLDD or have already returned
On a system with many SAS targets, it appears possible that a scsi_cmnd can time out without ever making it to the SAS LLDD or at the same time that a completion is occurring. In both of these cases, telling the LLDD to abort the sas_task makes no sense because the LLDD won't know about the sas_task; what we really want to do is to increase the timer. Note that this involves creating another sas_task bit to indicate whether or not the task has been sent to the LLDD; I could have implemented this by slightly redefining SAS_TASK_STATE_PENDING, but this way seems cleaner. This second version amends the aic94xx portion to set the TASK_AT_INITIATOR flag for all sas_tasks that were passed to lldd_execute_task. Signed-off-by: Darrick J. Wong <djwong@us.ibm.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/libsas/sas_scsi_host.c')
-rw-r--r--drivers/scsi/libsas/sas_scsi_host.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c
index 22672d5..21bd247 100644
--- a/drivers/scsi/libsas/sas_scsi_host.c
+++ b/drivers/scsi/libsas/sas_scsi_host.c
@@ -542,6 +542,13 @@ enum scsi_eh_timer_return sas_scsi_timed_out(struct scsi_cmnd *cmd)
cmd, task);
return EH_HANDLED;
}
+ if (!(task->task_state_flags & SAS_TASK_AT_INITIATOR)) {
+ spin_unlock_irqrestore(&task->task_state_lock, flags);
+ SAS_DPRINTK("command 0x%p, task 0x%p, not at initiator: "
+ "EH_RESET_TIMER\n",
+ cmd, task);
+ return EH_RESET_TIMER;
+ }
task->task_state_flags |= SAS_TASK_STATE_ABORTED;
spin_unlock_irqrestore(&task->task_state_lock, flags);