aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--drivers/scsi/megaraid/megaraid_sas_base.c31
1 files changed, 29 insertions, 2 deletions
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c
index a4bc81479284..6a01a605508b 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -7593,6 +7593,7 @@ megasas_resume(struct pci_dev *pdev)
struct Scsi_Host *host;
struct megasas_instance *instance;
int irq_flags = PCI_IRQ_LEGACY;
+ u32 status_reg;
instance = pci_get_drvdata(pdev);
@@ -7620,9 +7621,35 @@ megasas_resume(struct pci_dev *pdev)
/*
* We expect the FW state to be READY
*/
- if (megasas_transition_to_ready(instance, 0))
- goto fail_ready_state;
+ if (megasas_transition_to_ready(instance, 0)) {
+ dev_info(&instance->pdev->dev,
+ "Failed to transition controller to ready from %s!\n",
+ __func__);
+ if (instance->adapter_type != MFI_SERIES) {
+ status_reg =
+ instance->instancet->read_fw_status_reg(instance);
+ if (!(status_reg & MFI_RESET_ADAPTER) ||
+ ((megasas_adp_reset_wait_for_ready
+ (instance, true, 0)) == FAILED))
+ goto fail_ready_state;
+ } else {
+ atomic_set(&instance->fw_reset_no_pci_access, 1);
+ instance->instancet->adp_reset
+ (instance, instance->reg_set);
+ atomic_set(&instance->fw_reset_no_pci_access, 0);
+
+ /* waiting for about 30 seconds before retry */
+ ssleep(30);
+
+ if (megasas_transition_to_ready(instance, 0))
+ goto fail_ready_state;
+ }
+
+ dev_info(&instance->pdev->dev,
+ "FW restarted successfully from %s!\n",
+ __func__);
+ }
if (megasas_set_dma_mask(instance))
goto fail_set_dma_mask;