Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7e70e733 authored by Adam Radford's avatar Adam Radford Committed by James Bottomley
Browse files

[SCSI] megaraid_sas: Check MFI_REG_STATE.fault.resetAdapter



The following patch for megaraid_sas fixes the function
megasas_reset_fusion() and makes the reset code check
MFI_REG_STATE.fault.resetAdapter.

Signed-off-by: default avatarAdam Radford <aradford@gmail.com>
Signed-off-by: default avatarJames Bottomley <jbottomley@parallels.com>
parent 70d031f3
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -77,7 +77,7 @@
#define MFI_STATE_OPERATIONAL			0xC0000000
#define MFI_STATE_OPERATIONAL			0xC0000000
#define MFI_STATE_FAULT				0xF0000000
#define MFI_STATE_FAULT				0xF0000000
#define MFI_RESET_REQUIRED			0x00000001
#define MFI_RESET_REQUIRED			0x00000001

#define MFI_RESET_ADAPTER			0x00000002
#define MEGAMFI_FRAME_SIZE			64
#define MEGAMFI_FRAME_SIZE			64


/*
/*
+16 −10
Original line number Original line Diff line number Diff line
@@ -2010,17 +2010,11 @@ int megasas_reset_fusion(struct Scsi_Host *shost)
	struct fusion_context *fusion;
	struct fusion_context *fusion;
	struct megasas_cmd *cmd_mfi;
	struct megasas_cmd *cmd_mfi;
	union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc;
	union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc;
	u32 host_diag, abs_state;
	u32 host_diag, abs_state, status_reg, reset_adapter;


	instance = (struct megasas_instance *)shost->hostdata;
	instance = (struct megasas_instance *)shost->hostdata;
	fusion = instance->ctrl_context;
	fusion = instance->ctrl_context;


	mutex_lock(&instance->reset_mutex);
	set_bit(MEGASAS_FUSION_IN_RESET, &instance->reset_flags);
	instance->adprecovery = MEGASAS_ADPRESET_SM_INFAULT;
	instance->instancet->disable_intr(instance->reg_set);
	msleep(1000);

	if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR) {
	if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR) {
		printk(KERN_WARNING "megaraid_sas: Hardware critical error, "
		printk(KERN_WARNING "megaraid_sas: Hardware critical error, "
		       "returning FAILED.\n");
		       "returning FAILED.\n");
@@ -2028,6 +2022,12 @@ int megasas_reset_fusion(struct Scsi_Host *shost)
		goto out;
		goto out;
	}
	}


	mutex_lock(&instance->reset_mutex);
	set_bit(MEGASAS_FUSION_IN_RESET, &instance->reset_flags);
	instance->adprecovery = MEGASAS_ADPRESET_SM_INFAULT;
	instance->instancet->disable_intr(instance->reg_set);
	msleep(1000);

	/* First try waiting for commands to complete */
	/* First try waiting for commands to complete */
	if (megasas_wait_for_outstanding_fusion(instance)) {
	if (megasas_wait_for_outstanding_fusion(instance)) {
		printk(KERN_WARNING "megaraid_sas: resetting fusion "
		printk(KERN_WARNING "megaraid_sas: resetting fusion "
@@ -2044,7 +2044,12 @@ int megasas_reset_fusion(struct Scsi_Host *shost)
			}
			}
		}
		}


		if (instance->disableOnlineCtrlReset == 1) {
		status_reg = instance->instancet->read_fw_status_reg(
			instance->reg_set);
		abs_state = status_reg & MFI_STATE_MASK;
		reset_adapter = status_reg & MFI_RESET_ADAPTER;
		if (instance->disableOnlineCtrlReset ||
		    (abs_state == MFI_STATE_FAULT && !reset_adapter)) {
			/* Reset not supported, kill adapter */
			/* Reset not supported, kill adapter */
			printk(KERN_WARNING "megaraid_sas: Reset not supported"
			printk(KERN_WARNING "megaraid_sas: Reset not supported"
			       ", killing adapter.\n");
			       ", killing adapter.\n");
@@ -2073,6 +2078,7 @@ int megasas_reset_fusion(struct Scsi_Host *shost)


			/* Check that the diag write enable (DRWE) bit is on */
			/* Check that the diag write enable (DRWE) bit is on */
			host_diag = readl(&instance->reg_set->fusion_host_diag);
			host_diag = readl(&instance->reg_set->fusion_host_diag);
			retry = 0;
			while (!(host_diag & HOST_DIAG_WRITE_ENABLE)) {
			while (!(host_diag & HOST_DIAG_WRITE_ENABLE)) {
				msleep(100);
				msleep(100);
				host_diag =
				host_diag =
@@ -2110,7 +2116,7 @@ int megasas_reset_fusion(struct Scsi_Host *shost)


			abs_state =
			abs_state =
				instance->instancet->read_fw_status_reg(
				instance->instancet->read_fw_status_reg(
					instance->reg_set);
					instance->reg_set) & MFI_STATE_MASK;
			retry = 0;
			retry = 0;


			while ((abs_state <= MFI_STATE_FW_INIT) &&
			while ((abs_state <= MFI_STATE_FW_INIT) &&
@@ -2118,7 +2124,7 @@ int megasas_reset_fusion(struct Scsi_Host *shost)
				msleep(100);
				msleep(100);
				abs_state =
				abs_state =
				instance->instancet->read_fw_status_reg(
				instance->instancet->read_fw_status_reg(
					instance->reg_set);
					instance->reg_set) & MFI_STATE_MASK;
			}
			}
			if (abs_state <= MFI_STATE_FW_INIT) {
			if (abs_state <= MFI_STATE_FW_INIT) {
				printk(KERN_WARNING "megaraid_sas: firmware "
				printk(KERN_WARNING "megaraid_sas: firmware "