aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/aic94xx
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@us.ibm.com>2007-01-11 17:14:55 -0500
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2007-01-13 17:12:39 -0500
commitb218a0d8e250e0ae8fd4d4e45bd66a588b380752 (patch)
tree6c60dc11ef8d064404eb2fd6a3b4f37529a2c72f /drivers/scsi/aic94xx
parentbf451207511d049189ddb0a4eae3acdb086a3c82 (diff)
[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/aic94xx')
-rw-r--r--drivers/scsi/aic94xx/aic94xx_task.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/drivers/scsi/aic94xx/aic94xx_task.c b/drivers/scsi/aic94xx/aic94xx_task.c
index d202ed5a6709..e2ad5bed9403 100644
--- a/drivers/scsi/aic94xx/aic94xx_task.c
+++ b/drivers/scsi/aic94xx/aic94xx_task.c
@@ -349,6 +349,7 @@ Again:
349 349
350 spin_lock_irqsave(&task->task_state_lock, flags); 350 spin_lock_irqsave(&task->task_state_lock, flags);
351 task->task_state_flags &= ~SAS_TASK_STATE_PENDING; 351 task->task_state_flags &= ~SAS_TASK_STATE_PENDING;
352 task->task_state_flags &= ~SAS_TASK_AT_INITIATOR;
352 task->task_state_flags |= SAS_TASK_STATE_DONE; 353 task->task_state_flags |= SAS_TASK_STATE_DONE;
353 if (unlikely((task->task_state_flags & SAS_TASK_STATE_ABORTED))) { 354 if (unlikely((task->task_state_flags & SAS_TASK_STATE_ABORTED))) {
354 spin_unlock_irqrestore(&task->task_state_lock, flags); 355 spin_unlock_irqrestore(&task->task_state_lock, flags);
@@ -557,6 +558,7 @@ int asd_execute_task(struct sas_task *task, const int num,
557 struct sas_task *t = task; 558 struct sas_task *t = task;
558 struct asd_ascb *ascb = NULL, *a; 559 struct asd_ascb *ascb = NULL, *a;
559 struct asd_ha_struct *asd_ha = task->dev->port->ha->lldd_ha; 560 struct asd_ha_struct *asd_ha = task->dev->port->ha->lldd_ha;
561 unsigned long flags;
560 562
561 res = asd_can_queue(asd_ha, num); 563 res = asd_can_queue(asd_ha, num);
562 if (res) 564 if (res)
@@ -599,6 +601,10 @@ int asd_execute_task(struct sas_task *task, const int num,
599 } 601 }
600 if (res) 602 if (res)
601 goto out_err_unmap; 603 goto out_err_unmap;
604
605 spin_lock_irqsave(&t->task_state_lock, flags);
606 t->task_state_flags |= SAS_TASK_AT_INITIATOR;
607 spin_unlock_irqrestore(&t->task_state_lock, flags);
602 } 608 }
603 list_del_init(&alist); 609 list_del_init(&alist);
604 610
@@ -617,6 +623,9 @@ out_err_unmap:
617 if (a == b) 623 if (a == b)
618 break; 624 break;
619 t = a->uldd_task; 625 t = a->uldd_task;
626 spin_lock_irqsave(&t->task_state_lock, flags);
627 t->task_state_flags &= ~SAS_TASK_AT_INITIATOR;
628 spin_unlock_irqrestore(&t->task_state_lock, flags);
620 switch (t->task_proto) { 629 switch (t->task_proto) {
621 case SATA_PROTO: 630 case SATA_PROTO:
622 case SAS_PROTO_STP: 631 case SAS_PROTO_STP: