Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=18a6598f2d3bb7275dadba77df5f06bc996a77d4
Commit:     18a6598f2d3bb7275dadba77df5f06bc996a77d4
Parent:     aa2e07b4c2addaa4ad4bd7a6ee205565e83c2a14
Author:     Salyzyn, Mark <[EMAIL PROTECTED]>
AuthorDate: Fri Mar 30 10:30:48 2007 -0400
Committer:  James Bottomley <[EMAIL PROTECTED]>
CommitDate: Sun Apr 1 12:44:57 2007 -0500

    [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 <[EMAIL PROTECTED]>
    Signed-off-by: James Bottomley <[EMAIL PROTECTED]>
---
 drivers/scsi/aacraid/rx.c |   36 ++++++++++++++++++++++++++++--------
 1 files changed, 28 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/aacraid/rx.c b/drivers/scsi/aacraid/rx.c
index 3e23aa6..0c71315 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)
        if (bled)
                printk(KERN_ERR "%s%d: adapter kernel panic'd %x.\n",
                        dev->name, dev->id, bled);
-       else
+       else {
                bled = aac_adapter_sync_cmd(dev, IOP_RESET_ALWAYS,
                  0, 0, 0, 0, 0, 0, &var, NULL, NULL, NULL, NULL);
-       if (bled)
+               if (!bled && (var != 0x00000001))
+                       bled = -EINVAL;
+       }
+       if (bled && (bled != -ETIMEDOUT))
                bled = aac_adapter_sync_cmd(dev, IOP_RESET,
                  0, 0, 0, 0, 0, 0, &var, NULL, NULL, NULL, NULL);
 
-       if (bled)
+       if (bled && (bled != -ETIMEDOUT))
                return -EINVAL;
-       if (var == 0x3803000F) { /* USE_OTHER_METHOD */
+       if (bled || (var == 0x3803000F)) { /* USE_OTHER_METHOD */
                rx_writel(dev, MUnit.reserved2, 3);
                msleep(5000); /* Delay 5 seconds */
                var = 0x00000001;
@@ -526,6 +529,7 @@ int _aac_rx_init(struct aac_dev *dev)
 {
        unsigned long start;
        unsigned long status;
+       int restart = 0;
        int instance = dev->id;
        const char * name = dev->name;
 
@@ -534,15 +538,19 @@ int _aac_rx_init(struct aac_dev *dev)
                goto error_iounmap;
        }
 
+       /* Failure to reset here is an option ... */
+       dev->OIMR = status = rx_readb (dev, MUnit.OIMR);
+       if ((((status & 0xff) != 0xff) || reset_devices) &&
+         !aac_rx_restart_adapter(dev, 0))
+               ++restart;
        /*
         *      Check to see if the board panic'd while booting.
         */
        status = rx_readl(dev, MUnit.OMRx[0]);
        if (status & KERNEL_PANIC) {
-               if ((status = aac_rx_check_health(dev)) <= 0)
-                       goto error_iounmap;
-               if (aac_rx_restart_adapter(dev, status))
+               if (aac_rx_restart_adapter(dev, aac_rx_check_health(dev)))
                        goto error_iounmap;
+               ++restart;
        }
        /*
         *      Check to see if the board failed any self tests.
@@ -565,11 +573,23 @@ int _aac_rx_init(struct aac_dev *dev)
         */
        while (!((status = rx_readl(dev, MUnit.OMRx[0])) & 
KERNEL_UP_AND_RUNNING))
        {
-               if(time_after(jiffies, start+startup_timeout*HZ)) {
+               if ((restart &&
+                 (status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC))) ||
+                 time_after(jiffies, start+HZ*startup_timeout)) {
                        printk(KERN_ERR "%s%d: adapter kernel failed to start, 
init status = %lx.\n", 
                                        dev->name, instance, status);
                        goto error_iounmap;
                }
+               if (!restart &&
+                 ((status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC)) ||
+                 time_after(jiffies, start + HZ *
+                 ((startup_timeout > 60)
+                   ? (startup_timeout - 60)
+                   : (startup_timeout / 2))))) {
+                       if (likely(!aac_rx_restart_adapter(dev, 
aac_rx_check_health(dev))))
+                               start = jiffies;
+                       ++restart;
+               }
                msleep(1);
        }
        /*
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to