X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fscsi%2Fscsi_error.c;fp=drivers%2Fscsi%2Fscsi_error.c;h=288f2fde9cb4120984b47872fe0b4568e35162d5;hb=9bf4aaab3e101692164d49b7ca357651eb691cb6;hp=58ac2319a342c119f1aee7105bff88672f881457;hpb=db216c3d5e4c040e557a50f8f5d35d5c415e8c1c;p=linux-2.6.git diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 58ac2319a..288f2fde9 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -23,28 +23,27 @@ #include #include #include -#include -#include "scsi.h" -#include "hosts.h" +#include +#include +#include +#include +#include +#include +#include #include "scsi_priv.h" #include "scsi_logging.h" -#ifdef DEBUG -#define SENSE_TIMEOUT SCSI_TIMEOUT -#else -#define SENSE_TIMEOUT (10*HZ) -#endif - -#define START_UNIT_TIMEOUT (30*HZ) +#define SENSE_TIMEOUT (10*HZ) +#define START_UNIT_TIMEOUT (30*HZ) /* * These should *probably* be handled by the host itself. * Since it is allowed to sleep, it probably should. */ -#define BUS_RESET_SETTLE_TIME 10*HZ -#define HOST_RESET_SETTLE_TIME 10*HZ +#define BUS_RESET_SETTLE_TIME (10*HZ) +#define HOST_RESET_SETTLE_TIME (10*HZ) /* called with shost->host_lock held */ void scsi_eh_wakeup(struct Scsi_Host *shost) @@ -167,6 +166,24 @@ int scsi_delete_timer(struct scsi_cmnd *scmd) void scsi_times_out(struct scsi_cmnd *scmd) { scsi_log_completion(scmd, TIMEOUT_ERROR); + + if (scmd->device->host->hostt->eh_timed_out) + switch (scmd->device->host->hostt->eh_timed_out(scmd)) { + case EH_HANDLED: + __scsi_done(scmd); + return; + case EH_RESET_TIMER: + /* This allows a single retry even of a command + * with allowed == 0 */ + if (scmd->retries++ > scmd->allowed) + break; + scsi_add_timer(scmd, scmd->timeout_per_command, + scsi_times_out); + return; + case EH_NOT_HANDLED: + break; + } + if (unlikely(!scsi_eh_scmd_add(scmd, SCSI_EH_CANCEL_CMD))) { panic("Error handler thread not present at %p %p %s %d", scmd, scmd->device->host, __FILE__, __LINE__); @@ -660,7 +677,7 @@ static int scsi_eh_get_sense(struct list_head *work_q, SCSI_LOG_ERROR_RECOVERY(3, printk("sense requested for %p" " result %x\n", scmd, scmd->result)); - SCSI_LOG_ERROR_RECOVERY(3, print_sense("bh", scmd)); + SCSI_LOG_ERROR_RECOVERY(3, scsi_print_sense("bh", scmd)); rtn = scsi_decide_disposition(scmd); @@ -1026,7 +1043,8 @@ static int scsi_try_bus_reset(struct scsi_cmnd *scmd) spin_unlock_irqrestore(scmd->device->host->host_lock, flags); if (rtn == SUCCESS) { - scsi_sleep(BUS_RESET_SETTLE_TIME); + if (!scmd->device->host->hostt->skip_settle_delay) + scsi_sleep(BUS_RESET_SETTLE_TIME); spin_lock_irqsave(scmd->device->host->host_lock, flags); scsi_report_bus_reset(scmd->device->host, scmd->device->channel); spin_unlock_irqrestore(scmd->device->host->host_lock, flags); @@ -1057,7 +1075,8 @@ static int scsi_try_host_reset(struct scsi_cmnd *scmd) spin_unlock_irqrestore(scmd->device->host->host_lock, flags); if (rtn == SUCCESS) { - scsi_sleep(HOST_RESET_SETTLE_TIME); + if (!scmd->device->host->hostt->skip_settle_delay) + scsi_sleep(HOST_RESET_SETTLE_TIME); spin_lock_irqsave(scmd->device->host->host_lock, flags); scsi_report_bus_reset(scmd->device->host, scmd->device->channel); spin_unlock_irqrestore(scmd->device->host->host_lock, flags);