diff options
author | adam radford <aradford@gmail.com> | 2011-05-11 21:34:08 -0400 |
---|---|---|
committer | James Bottomley <jbottomley@parallels.com> | 2011-05-24 12:34:59 -0400 |
commit | 7e70e7336515cd367b9cfcf5379e04808bdcbe96 (patch) | |
tree | ea850e683c1eaa8690b51fa29dcaeee81ab0e50e /drivers/scsi/megaraid | |
parent | 70d031f36fa50a53128d0d2b5f95032cd534778b (diff) |
[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: Adam Radford <aradford@gmail.com>
Signed-off-by: James Bottomley <jbottomley@parallels.com>
Diffstat (limited to 'drivers/scsi/megaraid')
-rw-r--r-- | drivers/scsi/megaraid/megaraid_sas.h | 4 | ||||
-rw-r--r-- | drivers/scsi/megaraid/megaraid_sas_fusion.c | 26 |
2 files changed, 18 insertions, 12 deletions
diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 046dcc672ec1..982ef8364236 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h | |||
@@ -76,8 +76,8 @@ | |||
76 | #define MFI_STATE_READY 0xB0000000 | 76 | #define MFI_STATE_READY 0xB0000000 |
77 | #define MFI_STATE_OPERATIONAL 0xC0000000 | 77 | #define MFI_STATE_OPERATIONAL 0xC0000000 |
78 | #define MFI_STATE_FAULT 0xF0000000 | 78 | #define MFI_STATE_FAULT 0xF0000000 |
79 | #define MFI_RESET_REQUIRED 0x00000001 | 79 | #define MFI_RESET_REQUIRED 0x00000001 |
80 | 80 | #define MFI_RESET_ADAPTER 0x00000002 | |
81 | #define MEGAMFI_FRAME_SIZE 64 | 81 | #define MEGAMFI_FRAME_SIZE 64 |
82 | 82 | ||
83 | /* | 83 | /* |
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 25dd5ce64d5e..de43795ca90f 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c | |||
@@ -2010,17 +2010,11 @@ int megasas_reset_fusion(struct Scsi_Host *shost) | |||
2010 | struct fusion_context *fusion; | 2010 | struct fusion_context *fusion; |
2011 | struct megasas_cmd *cmd_mfi; | 2011 | struct megasas_cmd *cmd_mfi; |
2012 | union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc; | 2012 | union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc; |
2013 | u32 host_diag, abs_state; | 2013 | u32 host_diag, abs_state, status_reg, reset_adapter; |
2014 | 2014 | ||
2015 | instance = (struct megasas_instance *)shost->hostdata; | 2015 | instance = (struct megasas_instance *)shost->hostdata; |
2016 | fusion = instance->ctrl_context; | 2016 | fusion = instance->ctrl_context; |
2017 | 2017 | ||
2018 | mutex_lock(&instance->reset_mutex); | ||
2019 | set_bit(MEGASAS_FUSION_IN_RESET, &instance->reset_flags); | ||
2020 | instance->adprecovery = MEGASAS_ADPRESET_SM_INFAULT; | ||
2021 | instance->instancet->disable_intr(instance->reg_set); | ||
2022 | msleep(1000); | ||
2023 | |||
2024 | if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR) { | 2018 | if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR) { |
2025 | printk(KERN_WARNING "megaraid_sas: Hardware critical error, " | 2019 | printk(KERN_WARNING "megaraid_sas: Hardware critical error, " |
2026 | "returning FAILED.\n"); | 2020 | "returning FAILED.\n"); |
@@ -2028,6 +2022,12 @@ int megasas_reset_fusion(struct Scsi_Host *shost) | |||
2028 | goto out; | 2022 | goto out; |
2029 | } | 2023 | } |
2030 | 2024 | ||
2025 | mutex_lock(&instance->reset_mutex); | ||
2026 | set_bit(MEGASAS_FUSION_IN_RESET, &instance->reset_flags); | ||
2027 | instance->adprecovery = MEGASAS_ADPRESET_SM_INFAULT; | ||
2028 | instance->instancet->disable_intr(instance->reg_set); | ||
2029 | msleep(1000); | ||
2030 | |||
2031 | /* First try waiting for commands to complete */ | 2031 | /* First try waiting for commands to complete */ |
2032 | if (megasas_wait_for_outstanding_fusion(instance)) { | 2032 | if (megasas_wait_for_outstanding_fusion(instance)) { |
2033 | printk(KERN_WARNING "megaraid_sas: resetting fusion " | 2033 | printk(KERN_WARNING "megaraid_sas: resetting fusion " |
@@ -2044,7 +2044,12 @@ int megasas_reset_fusion(struct Scsi_Host *shost) | |||
2044 | } | 2044 | } |
2045 | } | 2045 | } |
2046 | 2046 | ||
2047 | if (instance->disableOnlineCtrlReset == 1) { | 2047 | status_reg = instance->instancet->read_fw_status_reg( |
2048 | instance->reg_set); | ||
2049 | abs_state = status_reg & MFI_STATE_MASK; | ||
2050 | reset_adapter = status_reg & MFI_RESET_ADAPTER; | ||
2051 | if (instance->disableOnlineCtrlReset || | ||
2052 | (abs_state == MFI_STATE_FAULT && !reset_adapter)) { | ||
2048 | /* Reset not supported, kill adapter */ | 2053 | /* Reset not supported, kill adapter */ |
2049 | printk(KERN_WARNING "megaraid_sas: Reset not supported" | 2054 | printk(KERN_WARNING "megaraid_sas: Reset not supported" |
2050 | ", killing adapter.\n"); | 2055 | ", killing adapter.\n"); |
@@ -2073,6 +2078,7 @@ int megasas_reset_fusion(struct Scsi_Host *shost) | |||
2073 | 2078 | ||
2074 | /* Check that the diag write enable (DRWE) bit is on */ | 2079 | /* Check that the diag write enable (DRWE) bit is on */ |
2075 | host_diag = readl(&instance->reg_set->fusion_host_diag); | 2080 | host_diag = readl(&instance->reg_set->fusion_host_diag); |
2081 | retry = 0; | ||
2076 | while (!(host_diag & HOST_DIAG_WRITE_ENABLE)) { | 2082 | while (!(host_diag & HOST_DIAG_WRITE_ENABLE)) { |
2077 | msleep(100); | 2083 | msleep(100); |
2078 | host_diag = | 2084 | host_diag = |
@@ -2110,7 +2116,7 @@ int megasas_reset_fusion(struct Scsi_Host *shost) | |||
2110 | 2116 | ||
2111 | abs_state = | 2117 | abs_state = |
2112 | instance->instancet->read_fw_status_reg( | 2118 | instance->instancet->read_fw_status_reg( |
2113 | instance->reg_set); | 2119 | instance->reg_set) & MFI_STATE_MASK; |
2114 | retry = 0; | 2120 | retry = 0; |
2115 | 2121 | ||
2116 | while ((abs_state <= MFI_STATE_FW_INIT) && | 2122 | while ((abs_state <= MFI_STATE_FW_INIT) && |
@@ -2118,7 +2124,7 @@ int megasas_reset_fusion(struct Scsi_Host *shost) | |||
2118 | msleep(100); | 2124 | msleep(100); |
2119 | abs_state = | 2125 | abs_state = |
2120 | instance->instancet->read_fw_status_reg( | 2126 | instance->instancet->read_fw_status_reg( |
2121 | instance->reg_set); | 2127 | instance->reg_set) & MFI_STATE_MASK; |
2122 | } | 2128 | } |
2123 | if (abs_state <= MFI_STATE_FW_INIT) { | 2129 | if (abs_state <= MFI_STATE_FW_INIT) { |
2124 | printk(KERN_WARNING "megaraid_sas: firmware " | 2130 | printk(KERN_WARNING "megaraid_sas: firmware " |