#include <linux/interrupt.h>
#include <linux/blkdev.h>
#include <linux/smp_lock.h>
-#include <scsi/scsi_ioctl.h>
-#include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi.h>
+#include <scsi/scsi_dbg.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_eh.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_ioctl.h>
+#include <scsi/scsi_request.h>
#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)
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__);
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);
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);
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);