summaryrefslogtreecommitdiff
path: root/drivers/scsi/aacraid/src.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/aacraid/src.c')
-rw-r--r--drivers/scsi/aacraid/src.c136
1 files changed, 81 insertions, 55 deletions
diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c
index 7b0410e0f569..48c2b2b34b72 100644
--- a/drivers/scsi/aacraid/src.c
+++ b/drivers/scsi/aacraid/src.c
@@ -694,33 +694,52 @@ 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 bool aac_is_ctrl_up_and_running(struct aac_dev *dev)
{
- u32 var, reset_mask;
+ bool ctrl_up = true;
+ unsigned long status, start;
+ bool is_up = false;
- aac_dump_fw_fib_iop_reset(dev);
+ start = jiffies;
+ do {
+ schedule();
+ status = src_readl(dev, MUnit.OMR);
- bled = aac_adapter_sync_cmd(dev, IOP_RESET_ALWAYS,
- 0, 0, 0, 0, 0, 0, &var,
- &reset_mask, NULL, NULL, NULL);
+ if (status == 0xffffffff)
+ status = 0;
- if ((bled || var != 0x00000001) && !dev->doorbell_mask)
- bled = -EINVAL;
- else if (dev->doorbell_mask) {
- reset_mask = dev->doorbell_mask;
- bled = 0;
- var = 0x00000001;
- }
+ 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,
+ NULL, NULL, NULL, NULL);
+}
+
+static void aac_send_iop_reset(struct aac_dev *dev)
+{
+ aac_dump_fw_fib_iop_reset(dev);
+
+ aac_notify_fw_of_iop_reset(dev);
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);
- }
- msleep(30000);
+ src_writel(dev, MUnit.IDR, IOP_SRC_RESET_MASK);
}
static void aac_send_hardware_soft_reset(struct aac_dev *dev)
@@ -735,14 +754,14 @@ 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;
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
@@ -752,48 +771,55 @@ 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:
- aac_send_iop_reset(dev, bled);
+ 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);
+
/*
- * 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
+ * Creates a delay or wait till up and running comes thru
*/
- 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));
+ is_ctrl_up = aac_is_ctrl_up_and_running(dev);
+ if (!is_ctrl_up)
+ dev_err(&dev->pdev->dev, "IOP reset failed\n");
+ else {
+ dev_info(&dev->pdev->dev, "IOP reset succeded\n");
+ goto set_startup;
}
- 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, bled);
- break;
}
-invalid_out:
+ if (!dev->sa_firmware) {
+ dev_err(&dev->pdev->dev, "ARC Reset attempt failed\n");
+ ret = -ENODEV;
+ goto out;
+ }
- if (src_readl(dev, MUnit.OMR) & KERNEL_PANIC)
- return -ENODEV;
+ 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;
+ 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;
+ } else
+ dev_info(&dev->pdev->dev, "SOFT reset succeded\n");
+ }
+
+set_startup:
if (startup_timeout < 300)
startup_timeout = 300;
- return 0;
+out:
+ return ret;
+
+invalid_out:
+ if (src_readl(dev, MUnit.OMR) & KERNEL_PANIC)
+ ret = -ENODEV;
+goto out;
}
/**