forked from Minki/linux
[SCSI] aic94xx: fix REQ_TASK_ABORT and REQ_DEVICE_RESET
This driver has been failing under heavy load with aic94xx: escb_tasklet_complete: REQ_TASK_ABORT, reason=0x6 aic94xx: escb_tasklet_complete: Can't find task (tc=4) to abort! The second message is because the driver fails to identify the task it's being asked to abort. On closer inpection, there's a thinko in the for each task loop over pending tasks in both the REQ_TASK_ABORT and REQ_DEVICE_RESET cases where it doesn't look at the task on the pending list but at the one on the ESCB (which is always NULL). Fix by looking at the right task. Also add a print for the case where the pending SCB doesn't have a task attached. Not sure if this will fix all the problems, but it's a definite first step. Cc: Stable Tree <stable@kernel.org> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
This commit is contained in:
parent
691b4773aa
commit
cb84e2d2ff
@ -458,13 +458,19 @@ static void escb_tasklet_complete(struct asd_ascb *ascb,
|
||||
tc_abort = le16_to_cpu(tc_abort);
|
||||
|
||||
list_for_each_entry_safe(a, b, &asd_ha->seq.pend_q, list) {
|
||||
struct sas_task *task = ascb->uldd_task;
|
||||
struct sas_task *task = a->uldd_task;
|
||||
|
||||
if (task && a->tc_index == tc_abort) {
|
||||
if (a->tc_index != tc_abort)
|
||||
continue;
|
||||
|
||||
if (task) {
|
||||
failed_dev = task->dev;
|
||||
sas_task_abort(task);
|
||||
break;
|
||||
} else {
|
||||
ASD_DPRINTK("R_T_A for non TASK scb 0x%x\n",
|
||||
a->scb->header.opcode);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!failed_dev) {
|
||||
@ -478,7 +484,7 @@ static void escb_tasklet_complete(struct asd_ascb *ascb,
|
||||
* that the EH will wake up and do something.
|
||||
*/
|
||||
list_for_each_entry_safe(a, b, &asd_ha->seq.pend_q, list) {
|
||||
struct sas_task *task = ascb->uldd_task;
|
||||
struct sas_task *task = a->uldd_task;
|
||||
|
||||
if (task &&
|
||||
task->dev == failed_dev &&
|
||||
|
Loading…
Reference in New Issue
Block a user