From 6b24d425881792b16ccf2189b43d57b4aff2a4e6 Mon Sep 17 00:00:00 2001 From: Raghava Aditya Renukunta Date: Wed, 10 May 2017 09:39:43 -0700 Subject: scsi: aacraid: Using single reset mask for IOP reset The driver can now trigger IOP reset with a single reset mask. Removed code that retrieves a reset_mask from the firmware. Signed-off-by: Raghava Aditya Renukunta Reviewed-by: David Carroll Signed-off-by: Martin K. Petersen --- drivers/scsi/aacraid/src.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) (limited to 'drivers/scsi/aacraid/src.c') diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c index 7b0410e0f569..f278a21c86db 100644 --- a/drivers/scsi/aacraid/src.c +++ b/drivers/scsi/aacraid/src.c @@ -704,22 +704,10 @@ static void aac_send_iop_reset(struct aac_dev *dev, int bled) 0, 0, 0, 0, 0, 0, &var, &reset_mask, NULL, NULL, NULL); - if ((bled || var != 0x00000001) && !dev->doorbell_mask) - bled = -EINVAL; - else if (dev->doorbell_mask) { - reset_mask = dev->doorbell_mask; - bled = 0; - var = 0x00000001; - } - aac_set_intx_mode(dev); - if (!bled && (dev->supplement_adapter_info.supported_options2 & - AAC_OPTION_DOORBELL_RESET)) { - src_writel(dev, MUnit.IDR, reset_mask); - } else { - src_writel(dev, MUnit.IDR, 0x100); - } + src_writel(dev, MUnit.IDR, IOP_SRC_RESET_MASK); + msleep(30000); } -- cgit v1.2.3 From 80c7d8a5cffa7187c3b3b78eb67705dae91e9a1a Mon Sep 17 00:00:00 2001 From: Raghava Aditya Renukunta Date: Wed, 10 May 2017 09:39:44 -0700 Subject: scsi: aacraid: Rework IOP reset Reworked IOP reset to remove unneeded variable and created a helper function to notify fw of an imminent IOP reset. Signed-off-by: Raghava Aditya Renukunta Reviewed-by: David Carroll Signed-off-by: Martin K. Petersen --- drivers/scsi/aacraid/src.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'drivers/scsi/aacraid/src.c') diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c index f278a21c86db..39ecb58762a7 100644 --- a/drivers/scsi/aacraid/src.c +++ b/drivers/scsi/aacraid/src.c @@ -694,15 +694,17 @@ static void aac_dump_fw_fib_iop_reset(struct aac_dev *dev) 0, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL); } -static void aac_send_iop_reset(struct aac_dev *dev, int bled) +static void aac_notify_fw_of_iop_reset(struct aac_dev *dev) { - u32 var, reset_mask; + aac_adapter_sync_cmd(dev, IOP_RESET_ALWAYS, 0, 0, 0, 0, 0, 0, NULL, + NULL, NULL, NULL, NULL); +} +static void aac_send_iop_reset(struct aac_dev *dev) +{ aac_dump_fw_fib_iop_reset(dev); - bled = aac_adapter_sync_cmd(dev, IOP_RESET_ALWAYS, - 0, 0, 0, 0, 0, 0, &var, - &reset_mask, NULL, NULL, NULL); + aac_notify_fw_of_iop_reset(dev); aac_set_intx_mode(dev); @@ -742,7 +744,7 @@ static int aac_src_restart_adapter(struct aac_dev *dev, int bled, u8 reset_type) switch (reset_type) { case IOP_HWSOFT_RESET: - aac_send_iop_reset(dev, bled); + aac_send_iop_reset(dev); /* * Check to see if KERNEL_UP_AND_RUNNING * Wait for the adapter to be up and running. @@ -769,7 +771,7 @@ static int aac_src_restart_adapter(struct aac_dev *dev, int bled, u8 reset_type) } break; default: - aac_send_iop_reset(dev, bled); + aac_send_iop_reset(dev); break; } -- cgit v1.2.3 From 0e9973ed3382652b324971753745cfe08488bb9f Mon Sep 17 00:00:00 2001 From: Raghava Aditya Renukunta Date: Wed, 10 May 2017 09:39:45 -0700 Subject: scsi: aacraid: Add periodic checks to see IOP reset status Added function that waits with a timeout for the ctrl to be up and running after triggering an IOP reset. Also removed 30 sec sleep as it is not needed. Signed-off-by: Raghava Aditya Renukunta Reviewed-by: David Carroll Signed-off-by: Martin K. Petersen --- drivers/scsi/aacraid/aacraid.h | 1 + drivers/scsi/aacraid/src.c | 45 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 44 insertions(+), 2 deletions(-) (limited to 'drivers/scsi/aacraid/src.c') diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index c74e1aa18a20..bd0afdd7f2e4 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -2516,6 +2516,7 @@ struct aac_hba_info { #define SELF_TEST_FAILED 0x00000004 #define MONITOR_PANIC 0x00000020 +#define KERNEL_BOOTING 0x00000040 #define KERNEL_UP_AND_RUNNING 0x00000080 #define KERNEL_PANIC 0x00000100 #define FLASH_UPD_PENDING 0x00002000 diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c index 39ecb58762a7..cde4160c3e47 100644 --- a/drivers/scsi/aacraid/src.c +++ b/drivers/scsi/aacraid/src.c @@ -694,6 +694,37 @@ static void aac_dump_fw_fib_iop_reset(struct aac_dev *dev) 0, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL); } +static bool aac_is_ctrl_up_and_running(struct aac_dev *dev) +{ + bool ctrl_up = true; + unsigned long status, start; + bool is_up = false; + + start = jiffies; + do { + schedule(); + status = src_readl(dev, MUnit.OMR); + + if (status == 0xffffffff) + status = 0; + + if (status & KERNEL_BOOTING) { + start = jiffies; + continue; + } + + if (time_after(jiffies, start+HZ*SOFT_RESET_TIME)) { + ctrl_up = false; + break; + } + + is_up = status & KERNEL_UP_AND_RUNNING; + + } while (!is_up); + + return ctrl_up; +} + static void aac_notify_fw_of_iop_reset(struct aac_dev *dev) { aac_adapter_sync_cmd(dev, IOP_RESET_ALWAYS, 0, 0, 0, 0, 0, 0, NULL, @@ -709,8 +740,6 @@ static void aac_send_iop_reset(struct aac_dev *dev) aac_set_intx_mode(dev); src_writel(dev, MUnit.IDR, IOP_SRC_RESET_MASK); - - msleep(30000); } static void aac_send_hardware_soft_reset(struct aac_dev *dev) @@ -726,6 +755,7 @@ static void aac_send_hardware_soft_reset(struct aac_dev *dev) static int aac_src_restart_adapter(struct aac_dev *dev, int bled, u8 reset_type) { unsigned long status, start; + bool is_ctrl_up; if (bled < 0) goto invalid_out; @@ -745,6 +775,16 @@ static int aac_src_restart_adapter(struct aac_dev *dev, int bled, u8 reset_type) switch (reset_type) { case IOP_HWSOFT_RESET: aac_send_iop_reset(dev); + + /* + * Creates a delay or wait till up and running comes thru + */ + is_ctrl_up = aac_is_ctrl_up_and_running(dev); + if (!is_ctrl_up) + dev_err(&dev->pdev->dev, "IOP reset failed\n"); + else + goto set_startup; + /* * Check to see if KERNEL_UP_AND_RUNNING * Wait for the adapter to be up and running. @@ -780,6 +820,7 @@ invalid_out: if (src_readl(dev, MUnit.OMR) & KERNEL_PANIC) return -ENODEV; +set_startup: if (startup_timeout < 300) startup_timeout = 300; -- cgit v1.2.3 From 77cb6d5ea6033e5d477947aa682728959d6c3f8f Mon Sep 17 00:00:00 2001 From: Raghava Aditya Renukunta Date: Wed, 10 May 2017 09:39:46 -0700 Subject: scsi: aacraid: Rework SOFT reset code Now the driver issues a soft reset and waits for the controller to be up and running by periodically checking on the status of the controller health registers. Also prevents ARC adapters from issuing soft reset if IOP resets failed. Signed-off-by: Raghava Aditya Renukunta Reviewed-by: David Carroll Signed-off-by: Martin K. Petersen --- drivers/scsi/aacraid/src.c | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) (limited to 'drivers/scsi/aacraid/src.c') diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c index cde4160c3e47..9ad60d63586d 100644 --- a/drivers/scsi/aacraid/src.c +++ b/drivers/scsi/aacraid/src.c @@ -754,8 +754,8 @@ static void aac_send_hardware_soft_reset(struct aac_dev *dev) static int aac_src_restart_adapter(struct aac_dev *dev, int bled, u8 reset_type) { - unsigned long status, start; bool is_ctrl_up; + int ret = 0; if (bled < 0) goto invalid_out; @@ -785,24 +785,21 @@ static int aac_src_restart_adapter(struct aac_dev *dev, int bled, u8 reset_type) else goto set_startup; - /* - * Check to see if KERNEL_UP_AND_RUNNING - * Wait for the adapter to be up and running. - * If !KERNEL_UP_AND_RUNNING issue HW Soft Reset - */ - status = src_readl(dev, MUnit.OMR); - if (dev->sa_firmware - && !(status & KERNEL_UP_AND_RUNNING)) { - start = jiffies; - do { - status = src_readl(dev, MUnit.OMR); - if (time_after(jiffies, - start+HZ*SOFT_RESET_TIME)) { - aac_send_hardware_soft_reset(dev); - start = jiffies; - } - } while (!(status & KERNEL_UP_AND_RUNNING)); + if (!dev->sa_firmware) { + ret = -ENODEV; + goto out; } + + aac_send_hardware_soft_reset(dev); + dev->msi_enabled = 0; + + is_ctrl_up = aac_is_ctrl_up_and_running(dev); + if (!is_ctrl_up) { + dev_err(&dev->pdev->dev, "SOFT reset failed\n"); + ret = -ENODEV; + goto out; + } + break; case HW_SOFT_RESET: if (dev->sa_firmware) { @@ -818,13 +815,14 @@ static int aac_src_restart_adapter(struct aac_dev *dev, int bled, u8 reset_type) invalid_out: if (src_readl(dev, MUnit.OMR) & KERNEL_PANIC) - return -ENODEV; + ret = -ENODEV; set_startup: if (startup_timeout < 300) startup_timeout = 300; - return 0; +out: + return ret; } /** -- cgit v1.2.3 From 5aa60732520dd0476ed9e20047b837780bbb7799 Mon Sep 17 00:00:00 2001 From: Raghava Aditya Renukunta Date: Wed, 10 May 2017 09:39:47 -0700 Subject: scsi: aacraid: Rework aac_src_restart Removed switch case and replaced with if mask checks. Moved KERNEL_PANIC check to when bled is less than 0. Signed-off-by: Raghava Aditya Renukunta Reviewed-by: David Carroll Signed-off-by: Martin K. Petersen --- drivers/scsi/aacraid/src.c | 34 ++++++++++++---------------------- 1 file changed, 12 insertions(+), 22 deletions(-) (limited to 'drivers/scsi/aacraid/src.c') diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c index 9ad60d63586d..e7b4c0782806 100644 --- a/drivers/scsi/aacraid/src.c +++ b/drivers/scsi/aacraid/src.c @@ -772,8 +772,7 @@ static int aac_src_restart_adapter(struct aac_dev *dev, int bled, u8 reset_type) dev->a_ops.adapter_enable_int = aac_src_disable_interrupt; - switch (reset_type) { - case IOP_HWSOFT_RESET: + if (reset_type & HW_IOP_RESET) { aac_send_iop_reset(dev); /* @@ -784,12 +783,14 @@ static int aac_src_restart_adapter(struct aac_dev *dev, int bled, u8 reset_type) dev_err(&dev->pdev->dev, "IOP reset failed\n"); else goto set_startup; + } - if (!dev->sa_firmware) { - ret = -ENODEV; - goto out; - } + if (!dev->sa_firmware) { + ret = -ENODEV; + goto out; + } + if (reset_type & HW_SOFT_RESET) { aac_send_hardware_soft_reset(dev); dev->msi_enabled = 0; @@ -799,30 +800,19 @@ static int aac_src_restart_adapter(struct aac_dev *dev, int bled, u8 reset_type) ret = -ENODEV; goto out; } - - break; - case HW_SOFT_RESET: - if (dev->sa_firmware) { - aac_send_hardware_soft_reset(dev); - aac_set_intx_mode(dev); - } - break; - default: - aac_send_iop_reset(dev); - break; } -invalid_out: - - if (src_readl(dev, MUnit.OMR) & KERNEL_PANIC) - ret = -ENODEV; - set_startup: if (startup_timeout < 300) startup_timeout = 300; out: return ret; + +invalid_out: + if (src_readl(dev, MUnit.OMR) & KERNEL_PANIC) + ret = -ENODEV; +goto out; } /** -- cgit v1.2.3 From 4a76be0dc53a2d725ee126a806e5988135952a05 Mon Sep 17 00:00:00 2001 From: Raghava Aditya Renukunta Date: Wed, 10 May 2017 09:39:51 -0700 Subject: scsi: aacraid: Add reset debugging statements Added info and error messages in controller reset function to log information about the status of the IOP/SOFT reset. Signed-off-by: Raghava Aditya Renukunta Reviewed-by: David Carroll Signed-off-by: Martin K. Petersen --- drivers/scsi/aacraid/src.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'drivers/scsi/aacraid/src.c') diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c index e7b4c0782806..48c2b2b34b72 100644 --- a/drivers/scsi/aacraid/src.c +++ b/drivers/scsi/aacraid/src.c @@ -761,8 +761,7 @@ static int aac_src_restart_adapter(struct aac_dev *dev, int bled, u8 reset_type) goto invalid_out; if (bled) - pr_err("%s%d: adapter kernel panic'd %x.\n", - dev->name, dev->id, bled); + dev_err(&dev->pdev->dev, "adapter kernel panic'd %x.\n", bled); /* * When there is a BlinkLED, IOP_RESET has not effect @@ -772,7 +771,10 @@ static int aac_src_restart_adapter(struct aac_dev *dev, int bled, u8 reset_type) dev->a_ops.adapter_enable_int = aac_src_disable_interrupt; + dev_err(&dev->pdev->dev, "Controller reset type is %d\n", reset_type); + if (reset_type & HW_IOP_RESET) { + dev_info(&dev->pdev->dev, "Issuing IOP reset\n"); aac_send_iop_reset(dev); /* @@ -781,16 +783,20 @@ static int aac_src_restart_adapter(struct aac_dev *dev, int bled, u8 reset_type) is_ctrl_up = aac_is_ctrl_up_and_running(dev); if (!is_ctrl_up) dev_err(&dev->pdev->dev, "IOP reset failed\n"); - else + else { + dev_info(&dev->pdev->dev, "IOP reset succeded\n"); goto set_startup; + } } if (!dev->sa_firmware) { + dev_err(&dev->pdev->dev, "ARC Reset attempt failed\n"); ret = -ENODEV; goto out; } if (reset_type & HW_SOFT_RESET) { + dev_info(&dev->pdev->dev, "Issuing SOFT reset\n"); aac_send_hardware_soft_reset(dev); dev->msi_enabled = 0; @@ -799,7 +805,8 @@ static int aac_src_restart_adapter(struct aac_dev *dev, int bled, u8 reset_type) dev_err(&dev->pdev->dev, "SOFT reset failed\n"); ret = -ENODEV; goto out; - } + } else + dev_info(&dev->pdev->dev, "SOFT reset succeded\n"); } set_startup: -- cgit v1.2.3