summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Haverkamp <markh@osdl.org>2006-08-08 19:52:14 +0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-08-20 00:33:13 +0400
commit8c23cd7457151fc8ace79ec700a8aeaa9fc5b3d9 (patch)
treef957cbf36472ef63872f71d444b0bb75ed594ab4
parentc8f7b073e0e81499474a84ee2a90f77f7805c7f8 (diff)
downloadlinux-8c23cd7457151fc8ace79ec700a8aeaa9fc5b3d9.tar.xz
[SCSI] aacraid: Restart adapter on firmware assert (Update 2)
Received from Mark Salyzyn If the adapter should be in a blinkled (Firmware Assert) state when the driver loads, we will perform a warm restart of the Adapter Firmware to see if we can rescue the adapter. Possible causes of a blinkled can occur on some early release motherboard BIOSes, transitory PCI bus problems on embedded systems or non-x86 based architectures, transitory startup failures of early release drives or transitory hardware failures; some of which can bite the adapter later at runtime. Future enhancements will include recovery during runtime. Fixed extra whitespace space issue. Signed-off-by: Mark Haverkamp <markh@osdl.org> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
-rw-r--r--drivers/scsi/aacraid/aacraid.h1
-rw-r--r--drivers/scsi/aacraid/rkt.c29
-rw-r--r--drivers/scsi/aacraid/rx.c29
3 files changed, 45 insertions, 14 deletions
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index d0eecd4bec83..05f80982efa5 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -1670,6 +1670,7 @@ extern struct aac_common aac_config;
#define RCV_TEMP_READINGS 0x00000025
#define GET_COMM_PREFERRED_SETTINGS 0x00000026
#define IOP_RESET 0x00001000
+#define IOP_RESET_ALWAYS 0x00001001
#define RE_INIT_ADAPTER 0x000000ee
/*
diff --git a/drivers/scsi/aacraid/rkt.c b/drivers/scsi/aacraid/rkt.c
index 458ea897fd72..f850c3a7cce9 100644
--- a/drivers/scsi/aacraid/rkt.c
+++ b/drivers/scsi/aacraid/rkt.c
@@ -395,6 +395,25 @@ static int aac_rkt_send(struct fib * fib)
return 0;
}
+static int aac_rkt_restart_adapter(struct aac_dev *dev)
+{
+ u32 var;
+
+ printk(KERN_ERR "%s%d: adapter kernel panic'd.\n",
+ dev->name, dev->id);
+
+ if (aac_rkt_check_health(dev) <= 0)
+ return 1;
+ if (rkt_sync_cmd(dev, IOP_RESET, 0, 0, 0, 0, 0, 0,
+ &var, NULL, NULL, NULL, NULL))
+ return 1;
+ if (var != 0x00000001)
+ return 1;
+ if (rkt_readl(dev, MUnit.OMRx[0]) & KERNEL_PANIC)
+ return 1;
+ return 0;
+}
+
/**
* aac_rkt_init - initialize an i960 based AAC card
* @dev: device to configure
@@ -417,6 +436,9 @@ int aac_rkt_init(struct aac_dev *dev)
/*
* Check to see if the board panic'd while booting.
*/
+ if (rkt_readl(dev, MUnit.OMRx[0]) & KERNEL_PANIC)
+ if (aac_rkt_restart_adapter(dev))
+ goto error_iounmap;
/*
* Check to see if the board failed any self tests.
*/
@@ -431,13 +453,6 @@ int aac_rkt_init(struct aac_dev *dev)
printk(KERN_ERR "%s%d: adapter monitor panic.\n", dev->name, instance);
goto error_iounmap;
}
- /*
- * Check to see if the board panic'd while booting.
- */
- if (rkt_readl(dev, MUnit.OMRx[0]) & KERNEL_PANIC) {
- printk(KERN_ERR "%s%d: adapter kernel panic'd.\n", dev->name, instance);
- goto error_iounmap;
- }
start = jiffies;
/*
* Wait for the adapter to be up and running. Wait up to 3 minutes
diff --git a/drivers/scsi/aacraid/rx.c b/drivers/scsi/aacraid/rx.c
index 035018db69b1..c715c4b2442d 100644
--- a/drivers/scsi/aacraid/rx.c
+++ b/drivers/scsi/aacraid/rx.c
@@ -394,6 +394,25 @@ static int aac_rx_send(struct fib * fib)
return 0;
}
+static int aac_rx_restart_adapter(struct aac_dev *dev)
+{
+ u32 var;
+
+ printk(KERN_ERR "%s%d: adapter kernel panic'd.\n",
+ dev->name, dev->id);
+
+ if (aac_rx_check_health(dev) <= 0)
+ return 1;
+ if (rx_sync_cmd(dev, IOP_RESET, 0, 0, 0, 0, 0, 0,
+ &var, NULL, NULL, NULL, NULL))
+ return 1;
+ if (var != 0x00000001)
+ return 1;
+ if (rx_readl(dev, MUnit.OMRx[0]) & KERNEL_PANIC)
+ return 1;
+ return 0;
+}
+
/**
* aac_rx_init - initialize an i960 based AAC card
* @dev: device to configure
@@ -416,6 +435,9 @@ int aac_rx_init(struct aac_dev *dev)
/*
* Check to see if the board panic'd while booting.
*/
+ if (rx_readl(dev, MUnit.OMRx[0]) & KERNEL_PANIC)
+ if (aac_rx_restart_adapter(dev))
+ goto error_iounmap;
/*
* Check to see if the board failed any self tests.
*/
@@ -424,13 +446,6 @@ int aac_rx_init(struct aac_dev *dev)
goto error_iounmap;
}
/*
- * Check to see if the board panic'd while booting.
- */
- if (rx_readl(dev, MUnit.OMRx[0]) & KERNEL_PANIC) {
- printk(KERN_ERR "%s%d: adapter kernel panic.\n", dev->name, instance);
- goto error_iounmap;
- }
- /*
* Check to see if the monitor panic'd while booting.
*/
if (rx_readl(dev, MUnit.OMRx[0]) & MONITOR_PANIC) {