aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Haverkamp <markh@osdl.org>2005-09-20 15:56:50 -0400
committerJames Bottomley <jejb@mulgrave.(none)>2005-09-26 18:46:59 -0400
commit9203344cb8ecc554a1d36eae6661235ed422cf59 (patch)
tree190894be25e864910104be1918799eeb32168692
parent08efb7b6116927c8b6e0af5064448e3aa13300e6 (diff)
[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>
-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 85d133c40bd3..a0735a247e5b 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)
692 fibptr, 692 fibptr,
693 sizeof(*info), 693 sizeof(*info),
694 FsaNormal, 694 FsaNormal,
695 1, 1, 695 -1, 1, /* First `interrupt' command uses special wait */
696 NULL, 696 NULL,
697 NULL); 697 NULL);
698 698
diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c
index 7f11c8540ead..9e054a509b41 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)
195 fibctx, 195 fibctx,
196 sizeof(struct aac_close), 196 sizeof(struct aac_close),
197 FsaNormal, 197 FsaNormal,
198 1, 1, 198 -2 /* Timeout silently */, 1,
199 NULL, NULL); 199 NULL, NULL);
200 200
201 if (status == 0) 201 if (status == 0)
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index 69985b08a270..3b983f3ed960 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -41,6 +41,7 @@
41#include <scsi/scsi_host.h> 41#include <scsi/scsi_host.h>
42#include <scsi/scsi_device.h> 42#include <scsi/scsi_device.h>
43#include <asm/semaphore.h> 43#include <asm/semaphore.h>
44#include <asm/delay.h>
44 45
45#include "aacraid.h" 46#include "aacraid.h"
46 47
@@ -541,7 +542,34 @@ int fib_send(u16 command, struct fib * fibptr, unsigned long size, int priority
541 542
542 if (wait) { 543 if (wait) {
543 spin_unlock_irqrestore(&fibptr->event_lock, flags); 544 spin_unlock_irqrestore(&fibptr->event_lock, flags);
544 down(&fibptr->event_wait); 545 /* Only set for first known interruptable command */
546 if (wait < 0) {
547 /*
548 * *VERY* Dangerous to time out a command, the
549 * assumption is made that we have no hope of
550 * functioning because an interrupt routing or other
551 * hardware failure has occurred.
552 */
553 unsigned long count = 36000000L; /* 3 minutes */
554 unsigned long qflags;
555 while (down_trylock(&fibptr->event_wait)) {
556 if (--count == 0) {
557 spin_lock_irqsave(q->lock, qflags);
558 q->numpending--;
559 list_del(&fibptr->queue);
560 spin_unlock_irqrestore(q->lock, qflags);
561 if (wait == -1) {
562 printk(KERN_ERR "aacraid: fib_send: first asynchronous command timed out.\n"
563 "Usually a result of a PCI interrupt routing problem;\n"
564 "update mother board BIOS or consider utilizing one of\n"
565 "the SAFE mode kernel options (acpi, apic etc)\n");
566 }
567 return -ETIMEDOUT;
568 }
569 udelay(5);
570 }
571 } else
572 down(&fibptr->event_wait);
545 if(fibptr->done == 0) 573 if(fibptr->done == 0)
546 BUG(); 574 BUG();
547 575