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;