aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSalyzyn, Mark <mark_salyzyn@adaptec.com>2007-03-30 10:30:48 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2007-04-01 13:44:57 -0400
commit18a6598f2d3bb7275dadba77df5f06bc996a77d4 (patch)
treed4dc43a9e7a4fd1391782b090d4f5e20c231f6ac
parentaa2e07b4c2addaa4ad4bd7a6ee205565e83c2a14 (diff)
[SCSI] aacraid: [Fastboot] Panics for AACRAID driver during 'insmod' for kexec test.
Attached is the patch I feel will address this issue. As an added 'perk' I have also added the code to detect if the controller was previously initialized for interrupted operations by ANY operating system should the reset_devices kernel parameter not be set and we are dealing with a naïve kexec without the addition of this kernel parameter. The reset handler is also improved. Related to reset operations, but not pertinent specifically to this issue, I have also altered the handling somewhat so that we reset the adapter if we feel it is taking too long (three minutes) to start up. We have not unit tested the reset_devices flag propagation to this driver code, nor have we unit tested the check for the interrupted operations under the conditions of a naively issued kexec. We are submitting this modified driver to our Q/A department for integration testing in our current programs. I would appreciate an ACK to this patch should it resolve the issue described in this thread... Signed-off-by: Mark Salyzyn <aacraid@adaptec.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
-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 /*