summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/aacraid
diff options
context:
space:
mode:
authorRaghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>2017-05-10 09:39:45 -0700
committerMartin K. Petersen <martin.petersen@oracle.com>2017-06-12 20:47:59 -0400
commit0e9973ed3382652b324971753745cfe08488bb9f (patch)
tree2c9e7729da0fa01441e7be6bb51127d167f42843 /drivers/scsi/aacraid
parent80c7d8a5cffa7187c3b3b78eb67705dae91e9a1a (diff)
downloadlinux-0e9973ed3382652b324971753745cfe08488bb9f.tar.bz2
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 <RaghavaAditya.Renukunta@microsemi.com> Reviewed-by: David Carroll <david.carroll@microsemi.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/aacraid')
-rw-r--r--drivers/scsi/aacraid/aacraid.h1
-rw-r--r--drivers/scsi/aacraid/src.c45
2 files changed, 44 insertions, 2 deletions
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;