Index: linux-2.6.22/drivers/scsi/scsi_error.c
===================================================================
--- linux-2.6.22.orig/drivers/scsi/scsi_error.c 2007-12-17 13:51:15.000000000
+0100
+++ linux-2.6.22/drivers/scsi/scsi_error.c 2007-12-17 13:56:25.000000000
+0100
@@ -1444,6 +1444,9 @@ static void scsi_restart_operations(stru
wake_up(&shost->host_wait);
+ /* before starting the queues save the time of recovery */
+ shost->last_recovery = jiffies;
+
/*
* finally we need to re-initiate requests that may be pending. we will
* have had everything blocked while error handling is taking place, and
@@ -1550,6 +1553,30 @@ static void scsi_unjam_host(struct Scsi_
}
/**
+ * deactivate_host - deactiave all devices.
+ * @shost: Host for which we are deactivating the devices
+ *
+ */
+static void deactivate_host (struct Scsi_Host *shost)
+{
+ unsigned long flags;
+ LIST_HEAD(eh_work_q);
+ LIST_HEAD(eh_done_q);
+
+ spin_lock_irqsave(shost->host_lock, flags);
+ list_splice_init(&shost->eh_cmd_q, &eh_work_q);
+ spin_unlock_irqrestore(shost->host_lock, flags);
+
+ printk (KERN_WARNING "Too many errors for this scsi host, "
+ "deactivating its devices\n");
+
+ scsi_eh_offline_sdevs (&eh_work_q, &eh_done_q);
+
+ wake_up(&shost->host_wait);
+ scsi_run_host_queues(shost);
+}
+
+/**
* scsi_error_handler - SCSI error handler thread
* @data: Host for which we are running.
*
@@ -1586,6 +1613,19 @@ int scsi_error_handler(void *data)
printk("Error handler scsi_eh_%d waking up\n",
shost->host_no));
+ if (shost->last_recovery < jiffies + 300 * HZ)
+ shost->n_errors++;
+ else
+ shost->n_errors = 1;
+
+ if (shost->n_errors > 5) {
+ deactivate_host(shost);
+ goto out;
+ }
+
+ printk (KERN_WARNING "Starting device recovery %d\n",
+ shost->n_errors);
+
/*
* We have a host that is failing for some reason. Figure out
* what we need to do to get it up and online again (if we can).
@@ -1603,6 +1643,8 @@ int scsi_error_handler(void *data)
* restart, we restart any I/O to any other devices on the bus
* which are still online.
*/
+
+out:
scsi_restart_operations(shost);
set_current_state(TASK_INTERRUPTIBLE);
}
Index: linux-2.6.22/include/scsi/scsi_host.h
===================================================================
--- linux-2.6.22.orig/include/scsi/scsi_host.h 2007-12-17 13:56:49.000000000
+0100
+++ linux-2.6.22/include/scsi/scsi_host.h 2007-12-17 13:57:55.000000000
+0100
@@ -518,6 +518,9 @@ struct Scsi_Host {
struct task_struct * ehandler; /* Error recovery thread. */
struct completion * eh_action; /* Wait for specific actions on the
host. */
+ time_t last_recovery; /* last time eh completed */
+ int n_errors; /* number failures within
+ time limit */
wait_queue_head_t host_wait;
struct scsi_host_template *hostt;
struct scsi_transport_template *transportt;
--
Bernd Schubert
Q-Leap Networks GmbH
-
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html