Commit d6005ee1 authored by Mike Anderson's avatar Mike Anderson Committed by James Bottomley

[PATCH] scsi_error handler update. (2/4)

This patch series is against scsi-misc-2.5.

01_serror-scmd-add-1.diff:
 	- Add scsi_eh_scmd_add function.

-andmike
--
Michael Anderson
andmike@us.ibm.com

 scsi.c       |    8 ++------
 scsi_error.c |   59 +++++++++++++++++++++++++++++++++++++++++++++++------------
 2 files changed, 49 insertions(+), 18 deletions(-)
parent 65893cf6
......@@ -790,13 +790,9 @@ static void scsi_softirq(struct softirq_action *h)
if ((status_byte(SCpnt->result) & CHECK_CONDITION) != 0) {
SCSI_LOG_MLCOMPLETE(3, print_sense("bh", SCpnt));
}
if (SCpnt->device->host->eh_wait != NULL) {
scsi_eh_eflags_set(SCpnt, SCSI_EH_CMD_FAILED | SCSI_EH_CMD_ERR);
SCpnt->owner = SCSI_OWNER_ERROR_HANDLER;
SCpnt->state = SCSI_STATE_FAILED;
scsi_host_failed_inc_and_test(SCpnt->device->host);
} else {
if (!scsi_eh_scmd_add(SCpnt, 0))
{
/*
* We only get here if the error
* recovery thread has died.
......
......@@ -55,6 +55,49 @@
#define BUS_RESET_SETTLE_TIME 10*HZ
#define HOST_RESET_SETTLE_TIME 10*HZ
/**
* scsi_eh_scmd_add - add scsi cmd to error handling.
* @scmd: scmd to run eh on.
* @eh_flag: optional SCSI_EH flag.
*
* Return value:
* 0 on failure.
**/
int scsi_eh_scmd_add(struct scsi_cmnd *scmd, int eh_flag)
{
struct Scsi_Host *shost = scmd->device->host;
unsigned long flags;
if (shost->eh_wait == NULL)
return 0;
spin_lock_irqsave(shost->host_lock, flags);
scsi_eh_eflags_set(scmd, eh_flag);
/*
* FIXME: Can we stop setting owner and state.
*/
scmd->owner = SCSI_OWNER_ERROR_HANDLER;
scmd->state = SCSI_STATE_FAILED;
/*
* Set the serial_number_at_timeout to the current
* serial_number
*/
scmd->serial_number_at_timeout = scmd->serial_number;
list_add_tail(&scmd->eh_list, &shost->eh_cmd_list);
shost->in_recovery = 1;
shost->host_failed++;
if (shost->host_busy == shost->host_failed) {
up(shost->eh_wait);
SCSI_LOG_ERROR_RECOVERY(5, printk("Waking error handler"
" thread\n"));
}
spin_unlock_irqrestore(shost->host_lock, flags);
return 1;
}
/**
* scsi_add_timer - Start timeout timer for a single scsi command.
* @scmd: scsi command that is about to start running.
......@@ -131,22 +174,14 @@ int scsi_delete_timer(Scsi_Cmnd *scmd)
**/
void scsi_times_out(Scsi_Cmnd *scmd)
{
struct Scsi_Host *shost = scmd->device->host;
/* Set the serial_number_at_timeout to the current serial_number */
scmd->serial_number_at_timeout = scmd->serial_number;
scsi_eh_eflags_set(scmd, SCSI_EH_CMD_TIMEOUT | SCSI_EH_CMD_ERR);
if (unlikely(shost->eh_wait == NULL)) {
if (unlikely(!scsi_eh_scmd_add(scmd, SCSI_EH_CANCEL_CMD))) {
panic("Error handler thread not present at %p %p %s %d",
scmd, shost, __FILE__, __LINE__);
scmd, scmd->device->host, __FILE__, __LINE__);
}
scsi_host_failed_inc_and_test(shost);
SCSI_LOG_TIMEOUT(3, printk("Command timed out busy=%d failed=%d\n",
shost->host_busy, shost->host_failed));
scmd->device->host->host_busy,
scmd->device->host->host_failed));
}
/**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment