Commit 499e7246 authored by Anand Lodnoor's avatar Anand Lodnoor Committed by Martin K. Petersen
Browse files

scsi: megaraid_sas: Reset adapter if FW is not in READY state after device resume

After device resume we expect the firmware to be in READY state.
Transition to READY might fail due to unhandled exceptions, such as an
internal error or a hardware failure. Retry initiating chip reset and wait
for the controller to come to ready state.

Link: https://lore.kernel.org/r/1579000882-20246-2-git-send-email-anand.lodnoor@broadcom.com


Signed-off-by: default avatarChandrakanth Patil <chandrakanth.patil@broadcom.com>
Signed-off-by: default avatarAnand Lodnoor <anand.lodnoor@broadcom.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent ba304e5b
Loading
Loading
Loading
Loading
+29 −2
Original line number Diff line number Diff line
@@ -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)) {
		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;