aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/aacraid/rx.c36
1 files changed, 28 insertions, 8 deletions
diff --git a/drivers/scsi/aacraid/rx.c b/drivers/scsi/aacraid/rx.c
index 3e23aa6cac06..0c71315cbf1a 100644
--- a/drivers/scsi/aacraid/rx.c
+++ b/drivers/scsi/aacraid/rx.c
@@ -467,16 +467,19 @@ static int aac_rx_restart_adapter(struct aac_dev *dev, int bled)
467 if (bled) 467 if (bled)
468 printk(KERN_ERR "%s%d: adapter kernel panic'd %x.\n", 468 printk(KERN_ERR "%s%d: adapter kernel panic'd %x.\n",
469 dev->name, dev->id, bled); 469 dev->name, dev->id, bled);
470 else 470 else {
471 bled = aac_adapter_sync_cmd(dev, IOP_RESET_ALWAYS, 471 bled = aac_adapter_sync_cmd(dev, IOP_RESET_ALWAYS,
472 0, 0, 0, 0, 0, 0, &var, NULL, NULL, NULL, NULL); 472 0, 0, 0, 0, 0, 0, &var, NULL, NULL, NULL, NULL);
473 if (bled) 473 if (!bled && (var != 0x00000001))
474 bled = -EINVAL;
475 }
476 if (bled && (bled != -ETIMEDOUT))
474 bled = aac_adapter_sync_cmd(dev, IOP_RESET, 477 bled = aac_adapter_sync_cmd(dev, IOP_RESET,
475 0, 0, 0, 0, 0, 0, &var, NULL, NULL, NULL, NULL); 478 0, 0, 0, 0, 0, 0, &var, NULL, NULL, NULL, NULL);
476 479
477 if (bled) 480 if (bled && (bled != -ETIMEDOUT))
478 return -EINVAL; 481 return -EINVAL;
479 if (var == 0x3803000F) { /* USE_OTHER_METHOD */ 482 if (bled || (var == 0x3803000F)) { /* USE_OTHER_METHOD */
480 rx_writel(dev, MUnit.reserved2, 3); 483 rx_writel(dev, MUnit.reserved2, 3);
481 msleep(5000); /* Delay 5 seconds */ 484 msleep(5000); /* Delay 5 seconds */
482 var = 0x00000001; 485 var = 0x00000001;
@@ -526,6 +529,7 @@ int _aac_rx_init(struct aac_dev *dev)
526{ 529{
527 unsigned long start; 530 unsigned long start;
528 unsigned long status; 531 unsigned long status;
532 int restart = 0;
529 int instance = dev->id; 533 int instance = dev->id;
530 const char * name = dev->name; 534 const char * name = dev->name;
531 535
@@ -534,15 +538,19 @@ int _aac_rx_init(struct aac_dev *dev)
534 goto error_iounmap; 538 goto error_iounmap;
535 } 539 }
536 540
541 /* Failure to reset here is an option ... */
542 dev->OIMR = status = rx_readb (dev, MUnit.OIMR);
543 if ((((status & 0xff) != 0xff) || reset_devices) &&
544 !aac_rx_restart_adapter(dev, 0))
545 ++restart;
537 /* 546 /*
538 * Check to see if the board panic'd while booting. 547 * Check to see if the board panic'd while booting.
539 */ 548 */
540 status = rx_readl(dev, MUnit.OMRx[0]); 549 status = rx_readl(dev, MUnit.OMRx[0]);
541 if (status & KERNEL_PANIC) { 550 if (status & KERNEL_PANIC) {
542 if ((status = aac_rx_check_health(dev)) <= 0) 551 if (aac_rx_restart_adapter(dev, aac_rx_check_health(dev)))
543 goto error_iounmap;
544 if (aac_rx_restart_adapter(dev, status))
545 goto error_iounmap; 552 goto error_iounmap;
553 ++restart;
546 } 554 }
547 /* 555 /*
548 * Check to see if the board failed any self tests. 556 * Check to see if the board failed any self tests.
@@ -565,11 +573,23 @@ int _aac_rx_init(struct aac_dev *dev)
565 */ 573 */
566 while (!((status = rx_readl(dev, MUnit.OMRx[0])) & KERNEL_UP_AND_RUNNING)) 574 while (!((status = rx_readl(dev, MUnit.OMRx[0])) & KERNEL_UP_AND_RUNNING))
567 { 575 {
568 if(time_after(jiffies, start+startup_timeout*HZ)) { 576 if ((restart &&
577 (status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC))) ||
578 time_after(jiffies, start+HZ*startup_timeout)) {
569 printk(KERN_ERR "%s%d: adapter kernel failed to start, init status = %lx.\n", 579 printk(KERN_ERR "%s%d: adapter kernel failed to start, init status = %lx.\n",
570 dev->name, instance, status); 580 dev->name, instance, status);
571 goto error_iounmap; 581 goto error_iounmap;
572 } 582 }
583 if (!restart &&
584 ((status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC)) ||
585 time_after(jiffies, start + HZ *
586 ((startup_timeout > 60)
587 ? (startup_timeout - 60)
588 : (startup_timeout / 2))))) {
589 if (likely(!aac_rx_restart_adapter(dev, aac_rx_check_health(dev))))
590 start = jiffies;
591 ++restart;
592 }
573 msleep(1); 593 msleep(1);
574 } 594 }
575 /* 595 /*