summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Haverkamp <markh@osdl.org>2004-02-19 23:38:25 -0800
committerJames Bottomley <jejb@raven.il.steeleye.com>2004-02-19 23:38:25 -0800
commit77ec183a50507f1d68930886e446fcf30927e386 (patch)
treecacd95a0a3fad1fa8f8a882adb3157ee77daa51a
parent7bfdc29f072b33cf1df1eefdee1227465f08707f (diff)
[PATCH] aacraid reset handler
Adds a reset handler to the aacraid template
-rw-r--r--drivers/scsi/aacraid/aacraid.h3
-rw-r--r--drivers/scsi/aacraid/linit.c47
-rw-r--r--drivers/scsi/aacraid/rkt.c32
-rw-r--r--drivers/scsi/aacraid/rx.c32
-rw-r--r--drivers/scsi/aacraid/sa.c32
5 files changed, 146 insertions, 0 deletions
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index a593c57d3729..8736443ca9d1 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -512,6 +512,7 @@ struct adapter_ops
void (*adapter_enable_int)(struct aac_dev *dev, u32 event);
void (*adapter_disable_int)(struct aac_dev *dev, u32 event);
int (*adapter_sync_cmd)(struct aac_dev *dev, u32 command, u32 p1, u32 *status);
+ int (*adapter_check_health)(struct aac_dev *dev);
};
/*
@@ -942,6 +943,8 @@ struct aac_dev
#define aac_adapter_disable_int(dev, event) \
dev->a_ops.adapter_disable_int(dev, event)
+#define aac_adapter_check_health(dev) \
+ (dev)->a_ops.adapter_check_health(dev)
#define FIB_CONTEXT_FLAG_TIMED_OUT (0x00000001)
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 63fe0c57ed27..0e8381717712 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -49,6 +49,7 @@
#include <scsi/scsi_host.h>
#include <scsi/scsi_tcq.h>
#include <scsi/scsicam.h>
+#include <scsi/scsi_eh.h>
#include "aacraid.h"
@@ -339,6 +340,51 @@ static int aac_eh_abort(struct scsi_cmnd *cmd)
return FAILED;
}
+/*
+ * aac_eh_reset - Reset command handling
+ * @scsi_cmd: SCSI command block causing the reset
+ *
+ */
+static int aac_eh_reset(struct scsi_cmnd* cmd)
+{
+ struct scsi_device * dev = cmd->device;
+ struct Scsi_Host * host = dev->host;
+ struct scsi_cmnd * command;
+ int count;
+ unsigned long flags;
+
+ printk(KERN_ERR "%s: Host adapter reset request. SCSI hang ?\n",
+ AAC_DRIVERNAME);
+
+
+ if (aac_adapter_check_health((struct aac_dev *)host->hostdata)) {
+ printk(KERN_ERR "%s: Host adapter appears dead\n",
+ AAC_DRIVERNAME);
+ return -ENODEV;
+ }
+ /*
+ * Wait for all commands to complete to this specific
+ * target (block maximum 60 seconds).
+ */
+ for (count = 60; count; --count) {
+ __shost_for_each_device(dev, host) {
+ spin_lock_irqsave(&dev->list_lock, flags);
+ list_for_each_entry(command, &dev->cmd_list, list) {
+ if (command->serial_number) {
+ spin_unlock_irqrestore(&dev->list_lock, flags);
+ return SUCCESS;
+ }
+ }
+ spin_unlock_irqrestore(&dev->list_lock, flags);
+ }
+ spin_unlock_irq(host->host_lock);
+ scsi_sleep(HZ);
+ spin_lock_irq(host->host_lock);
+ }
+ printk(KERN_ERR "%s: SCSI bus appears hung\n", AAC_DRIVERNAME);
+ return -ETIMEDOUT;
+}
+
/**
* aac_cfg_open - open a configuration file
* @inode: inode being opened
@@ -397,6 +443,7 @@ static struct scsi_host_template aac_driver_template = {
.bios_param = aac_biosparm,
.slave_configure = aac_slave_configure,
.eh_abort_handler = aac_eh_abort,
+ .eh_host_reset_handler = aac_eh_reset,
.can_queue = AAC_NUM_IO_FIB,
.this_id = 16,
.sg_tablesize = 16,
diff --git a/drivers/scsi/aacraid/rkt.c b/drivers/scsi/aacraid/rkt.c
index 0f568fe251bf..4742c50ec94c 100644
--- a/drivers/scsi/aacraid/rkt.c
+++ b/drivers/scsi/aacraid/rkt.c
@@ -325,6 +325,38 @@ static void aac_rkt_start_adapter(struct aac_dev *dev)
}
/**
+ * aac_rkt_check_health
+ * @dev: device to check if healthy
+ *
+ * Will attempt to determine if the specified adapter is alive and
+ * capable of handling requests, returning 0 if alive.
+ */
+static int aac_rkt_check_health(struct aac_dev *dev)
+{
+ long status = rkt_readl(dev, IndexRegs.Mailbox[7]);
+
+ /*
+ * Check to see if the board failed any self tests.
+ */
+ if (status & SELF_TEST_FAILED)
+ return -1;
+ /*
+ * Check to see if the board panic'd while booting.
+ */
+ if (status & KERNEL_PANIC)
+ return -2;
+ /*
+ * Wait for the adapter to be up and running. Wait up to 3 minutes
+ */
+ if (!(status & KERNEL_UP_AND_RUNNING))
+ return -3;
+ /*
+ * Everything is OK
+ */
+ return 0;
+} /* aac_rkt_check_health */
+
+/**
* aac_rkt_init - initialize an i960 based AAC card
* @dev: device to configure
* @devnum: adapter number
diff --git a/drivers/scsi/aacraid/rx.c b/drivers/scsi/aacraid/rx.c
index e121061b1811..14caab1da747 100644
--- a/drivers/scsi/aacraid/rx.c
+++ b/drivers/scsi/aacraid/rx.c
@@ -325,6 +325,38 @@ static void aac_rx_start_adapter(struct aac_dev *dev)
}
/**
+ * aac_rx_check_health
+ * @dev: device to check if healthy
+ *
+ * Will attempt to determine if the specified adapter is alive and
+ * capable of handling requests, returning 0 if alive.
+ */
+static int aac_rx_check_health(struct aac_dev *dev)
+{
+ long status = rx_readl(dev, IndexRegs.Mailbox[7]);
+
+ /*
+ * Check to see if the board failed any self tests.
+ */
+ if (status & SELF_TEST_FAILED)
+ return -1;
+ /*
+ * Check to see if the board panic'd while booting.
+ */
+ if (status & KERNEL_PANIC)
+ return -2;
+ /*
+ * Wait for the adapter to be up and running. Wait up to 3 minutes
+ */
+ if (!(status & KERNEL_UP_AND_RUNNING))
+ return -3;
+ /*
+ * Everything is OK
+ */
+ return 0;
+} /* aac_rx_check_health */
+
+/**
* aac_rx_init - initialize an i960 based AAC card
* @dev: device to configure
* @devnum: adapter number
diff --git a/drivers/scsi/aacraid/sa.c b/drivers/scsi/aacraid/sa.c
index 13560a9a9fda..1f18764246af 100644
--- a/drivers/scsi/aacraid/sa.c
+++ b/drivers/scsi/aacraid/sa.c
@@ -300,6 +300,38 @@ static void aac_sa_start_adapter(struct aac_dev *dev)
}
/**
+ * aac_sa_check_health
+ * @dev: device to check if healthy
+ *
+ * Will attempt to determine if the specified adapter is alive and
+ * capable of handling requests, returning 0 if alive.
+ */
+static int aac_sa_check_health(struct aac_dev *dev)
+{
+ long status = sa_readl(dev, Mailbox7);
+
+ /*
+ * Check to see if the board failed any self tests.
+ */
+ if (status & SELF_TEST_FAILED)
+ return -1;
+ /*
+ * Check to see if the board panic'd while booting.
+ */
+ if (status & KERNEL_PANIC)
+ return -2;
+ /*
+ * Wait for the adapter to be up and running. Wait up to 3 minutes
+ */
+ if (!(status & KERNEL_UP_AND_RUNNING))
+ return -3;
+ /*
+ * Everything is OK
+ */
+ return 0;
+} /* aac_sa_check_health */
+
+/**
* aac_sa_init - initialize an ARM based AAC card
* @dev: device to configure
* @devnum: adapter number