aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/aacraid
diff options
context:
space:
mode:
authorMark Haverkamp <markh@osdl.org>2005-09-20 12:56:50 -0700
committerJames Bottomley <jejb@mulgrave.(none)>2005-09-26 17:46:59 -0500
commit9203344cb8ecc554a1d36eae6661235ed422cf59 (patch)
tree190894be25e864910104be1918799eeb32168692 /drivers/scsi/aacraid
parent08efb7b6116927c8b6e0af5064448e3aa13300e6 (diff)
downloadkernel_samsung_espresso10-9203344cb8ecc554a1d36eae6661235ed422cf59.zip
kernel_samsung_espresso10-9203344cb8ecc554a1d36eae6661235ed422cf59.tar.gz
kernel_samsung_espresso10-9203344cb8ecc554a1d36eae6661235ed422cf59.tar.bz2
[SCSI] aacraid: initialization timeout
Received from Mark Salyzyn from Adaptec. In the rare instances where the adapter, or the motherboard, is misbehaving; driver initialization or shutdown becomes problematic. By introducing a 3 minute timeout on the first interrupt driven command during initialization, or the issuance of the adapter shutdown command during driver unload, we can resolve the lockup problems induced by common (but rare) hardware misbehaviors. The timeout during initialization, should it occur, is accompanied by a message presented to the console and the logs indicating that the user should inspect and resolve problems with interrupt routing. Signed-off-by: Mark Haverkamp <markh@osdl.org> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/aacraid')
-rw-r--r--drivers/scsi/aacraid/aachba.c2
-rw-r--r--drivers/scsi/aacraid/comminit.c2
-rw-r--r--drivers/scsi/aacraid/commsup.c30
3 files changed, 31 insertions, 3 deletions
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index 85d133c..a0735a2 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -692,7 +692,7 @@ int aac_get_adapter_info(struct aac_dev* dev)
fibptr,
sizeof(*info),
FsaNormal,
- 1, 1,
+ -1, 1, /* First `interrupt' command uses special wait */
NULL,
NULL);
diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c
index 7f11c85..9e054a5 100644
--- a/drivers/scsi/aacraid/comminit.c
+++ b/drivers/scsi/aacraid/comminit.c
@@ -195,7 +195,7 @@ int aac_send_shutdown(struct aac_dev * dev)
fibctx,
sizeof(struct aac_close),
FsaNormal,
- 1, 1,
+ -2 /* Timeout silently */, 1,
NULL, NULL);
if (status == 0)
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index 69985b0..3b983f3 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -41,6 +41,7 @@
#include <scsi/scsi_host.h>
#include <scsi/scsi_device.h>
#include <asm/semaphore.h>
+#include <asm/delay.h>
#include "aacraid.h"
@@ -541,7 +542,34 @@ int fib_send(u16 command, struct fib * fibptr, unsigned long size, int priority
if (wait) {
spin_unlock_irqrestore(&fibptr->event_lock, flags);
- down(&fibptr->event_wait);
+ /* Only set for first known interruptable command */
+ if (wait < 0) {
+ /*
+ * *VERY* Dangerous to time out a command, the
+ * assumption is made that we have no hope of
+ * functioning because an interrupt routing or other
+ * hardware failure has occurred.
+ */
+ unsigned long count = 36000000L; /* 3 minutes */
+ unsigned long qflags;
+ while (down_trylock(&fibptr->event_wait)) {
+ if (--count == 0) {
+ spin_lock_irqsave(q->lock, qflags);
+ q->numpending--;
+ list_del(&fibptr->queue);
+ spin_unlock_irqrestore(q->lock, qflags);
+ if (wait == -1) {
+ printk(KERN_ERR "aacraid: fib_send: first asynchronous command timed out.\n"
+ "Usually a result of a PCI interrupt routing problem;\n"
+ "update mother board BIOS or consider utilizing one of\n"
+ "the SAFE mode kernel options (acpi, apic etc)\n");
+ }
+ return -ETIMEDOUT;
+ }
+ udelay(5);
+ }
+ } else
+ down(&fibptr->event_wait);
if(fibptr->done == 0)
BUG();