|
@@ -290,6 +290,7 @@ static void asd_tmf_tasklet_complete(struct asd_ascb *ascb,
|
|
|
static inline int asd_clear_nexus(struct sas_task *task)
|
|
|
{
|
|
|
int res = TMF_RESP_FUNC_FAILED;
|
|
|
+ int leftover;
|
|
|
struct asd_ascb *tascb = task->lldd_task;
|
|
|
unsigned long flags;
|
|
|
|
|
@@ -298,10 +299,12 @@ static inline int asd_clear_nexus(struct sas_task *task)
|
|
|
res = asd_clear_nexus_tag(task);
|
|
|
else
|
|
|
res = asd_clear_nexus_index(task);
|
|
|
- wait_for_completion_timeout(&tascb->completion,
|
|
|
- AIC94XX_SCB_TIMEOUT);
|
|
|
+ leftover = wait_for_completion_timeout(&tascb->completion,
|
|
|
+ AIC94XX_SCB_TIMEOUT);
|
|
|
ASD_DPRINTK("came back from clear nexus\n");
|
|
|
spin_lock_irqsave(&task->task_state_lock, flags);
|
|
|
+ if (leftover < 1)
|
|
|
+ res = TMF_RESP_FUNC_FAILED;
|
|
|
if (task->task_state_flags & SAS_TASK_STATE_DONE)
|
|
|
res = TMF_RESP_FUNC_COMPLETE;
|
|
|
spin_unlock_irqrestore(&task->task_state_lock, flags);
|
|
@@ -350,6 +353,7 @@ int asd_abort_task(struct sas_task *task)
|
|
|
unsigned long flags;
|
|
|
struct asd_ascb *ascb = NULL;
|
|
|
struct scb *scb;
|
|
|
+ int leftover;
|
|
|
|
|
|
spin_lock_irqsave(&task->task_state_lock, flags);
|
|
|
if (task->task_state_flags & SAS_TASK_STATE_DONE) {
|
|
@@ -455,9 +459,11 @@ int asd_abort_task(struct sas_task *task)
|
|
|
break;
|
|
|
case TF_TMF_TASK_DONE + 0xFF00: /* done but not reported yet */
|
|
|
res = TMF_RESP_FUNC_FAILED;
|
|
|
- wait_for_completion_timeout(&tascb->completion,
|
|
|
- AIC94XX_SCB_TIMEOUT);
|
|
|
+ leftover = wait_for_completion_timeout(&tascb->completion,
|
|
|
+ AIC94XX_SCB_TIMEOUT);
|
|
|
spin_lock_irqsave(&task->task_state_lock, flags);
|
|
|
+ if (leftover < 1)
|
|
|
+ res = TMF_RESP_FUNC_FAILED;
|
|
|
if (task->task_state_flags & SAS_TASK_STATE_DONE)
|
|
|
res = TMF_RESP_FUNC_COMPLETE;
|
|
|
spin_unlock_irqrestore(&task->task_state_lock, flags);
|