aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/aacraid/commsup.c
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 /drivers/scsi/aacraid/commsup.c
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>
Diffstat (limited to 'drivers/scsi/aacraid/commsup.c')
-rw-r--r--drivers/scsi/aacraid/commsup.c30
1 files changed, 29 insertions, 1 deletions
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