diff options
| author | Mark Haverkamp <markh@osdl.org> | 2004-02-19 23:38:25 -0800 |
|---|---|---|
| committer | James Bottomley <jejb@raven.il.steeleye.com> | 2004-02-19 23:38:25 -0800 |
| commit | 77ec183a50507f1d68930886e446fcf30927e386 (patch) | |
| tree | cacd95a0a3fad1fa8f8a882adb3157ee77daa51a | |
| parent | 7bfdc29f072b33cf1df1eefdee1227465f08707f (diff) | |
[PATCH] aacraid reset handler
Adds a reset handler to the aacraid template
| -rw-r--r-- | drivers/scsi/aacraid/aacraid.h | 3 | ||||
| -rw-r--r-- | drivers/scsi/aacraid/linit.c | 47 | ||||
| -rw-r--r-- | drivers/scsi/aacraid/rkt.c | 32 | ||||
| -rw-r--r-- | drivers/scsi/aacraid/rx.c | 32 | ||||
| -rw-r--r-- | drivers/scsi/aacraid/sa.c | 32 |
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 |
