diff options
-rw-r--r-- | drivers/scsi/aacraid/aachba.c | 2 | ||||
-rw-r--r-- | drivers/scsi/aacraid/comminit.c | 2 | ||||
-rw-r--r-- | drivers/scsi/aacraid/commsup.c | 30 |
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 | ||