2. If the host supports asynchronous completion (as indicated by the
     no_async_abort setting in the host template) scsi_abort_command()
-    is invoked to schedule an asynchrous abort. If that fails
-    Step #3 is taken.
+    is invoked to schedule an asynchrous abort.
+    Asynchronous abort are not invoked for commands which the
+    SCSI_EH_ABORT_SCHEDULED flag is set (this indicates that the command
+    already had been aborted once, and this is a retry which failed),
+    or when the EH deadline is expired. In these case Step #3 is taken.
 
- 2. scsi_eh_scmd_add(scmd, SCSI_EH_CANCEL_CMD) is invoked for the
-    command.  See [1-3] for more information.
+ 3. scsi_eh_scmd_add(scmd, SCSI_EH_CANCEL_CMD) is invoked for the
+    command.  See [1-4] for more information.
 
 [1-3] Asynchronous command aborts
 
 
  3. scmd recovered
     ACTION: scsi_eh_finish_cmd() is invoked to EH-finish scmd
-       - clear scmd->eh_eflags
        - scsi_setup_cmd_retry()
        - move from local eh_work_q to local eh_done_q
     LOCKING: none
 
  - shost->host_failed is zero.
 
- - Each scmd's eh_eflags field is cleared.
-
  - Each scmd is in such a state that scsi_setup_cmd_retry() on the
    scmd doesn't make any difference.
 
 
                SAS_DPRINTK("trying to find task 0x%p\n", task);
                res = sas_scsi_find_task(task);
 
-               cmd->eh_eflags = 0;
-
                switch (res) {
                case TASK_IS_DONE:
                        SAS_DPRINTK("%s: task 0x%p is done\n", __func__,
 
                /*
                 * Retry after abort failed, escalate to next level.
                 */
-               scmd->eh_eflags &= ~SCSI_EH_ABORT_SCHEDULED;
                SCSI_LOG_ERROR_RECOVERY(3,
                        scmd_printk(KERN_INFO, scmd,
                                    "previous abort failed\n"));
        ses->result = scmd->result;
        ses->underflow = scmd->underflow;
        ses->prot_op = scmd->prot_op;
+       ses->eh_eflags = scmd->eh_eflags;
 
        scmd->prot_op = SCSI_PROT_NORMAL;
        scmd->eh_eflags = 0;
        scmd->result = ses->result;
        scmd->underflow = ses->underflow;
        scmd->prot_op = ses->prot_op;
+       scmd->eh_eflags = ses->eh_eflags;
 }
 EXPORT_SYMBOL(scsi_eh_restore_cmnd);
 
  */
 void scsi_eh_finish_cmd(struct scsi_cmnd *scmd, struct list_head *done_q)
 {
-       scmd->eh_eflags = 0;
        list_move_tail(&scmd->eh_entry, done_q);
 }
 EXPORT_SYMBOL(scsi_eh_finish_cmd);
 
 struct scsi_eh_save {
        /* saved state */
        int result;
+       int eh_eflags;
        enum dma_data_direction data_direction;
        unsigned underflow;
        unsigned char cmd_len;