commit 2d367bd043bee47750b26b2a5fbdf998cfa78fe5
Author: James Bottomley <[EMAIL PROTECTED]>
Date:   Sat Feb 23 20:55:15 2008 +0000

    SCSI aic94xx: fix REQ_TASK_ABORT and REQ_DEVICE_RESET
    
    commit: cb84e2d2ff3b50c0da5a7604a6d8634294a00a01
    
    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.
    
    Signed-off-by: James Bottomley <[EMAIL PROTECTED]>
    Signed-off-by: Chris Wright <[EMAIL PROTECTED]>
    Signed-off-by: Greg Kroah-Hartman <[EMAIL PROTECTED]>

diff --git a/drivers/scsi/aic94xx/aic94xx_scb.c 
b/drivers/scsi/aic94xx/aic94xx_scb.c
index db6ab1a..eae2d97 100644
--- a/drivers/scsi/aic94xx/aic94xx_scb.c
+++ b/drivers/scsi/aic94xx/aic94xx_scb.c
@@ -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 (a->tc_index != tc_abort)
+                               continue;
 
-                       if (task && a->tc_index == tc_abort) {
+                       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 &&
_______________________________________________
unionfs-cvs mailing list: http://unionfs.filesystems.org/
[email protected]
http://www.fsl.cs.sunysb.edu/mailman/listinfo/unionfs-cvs

Reply via email to