scsi: megaraid_sas: In probe context, retry IOC INIT once if firmware is in fault

Issue: Under certain conditions, controller goes in FAULT state after IOC
INIT fired to firmware. Such Fault can be recovered through controller
reset.

Fix: In driver probe context, if firmware fault is observed post IOC INIT,
driver would do controller reset followed by retry logic for IOC INIT
command.

Signed-off-by: Shivasharan S <shivasharan.srikanteshwara@broadcom.com>
Signed-off-by: Chandrakanth Patil <chandrakanth.patil@broadcom.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
Chandrakanth Patil 2019-06-25 16:34:24 +05:30 коммит произвёл Martin K. Petersen
Родитель 7fa3174b3e
Коммит ccf6c1f2e2
1 изменённых файлов: 23 добавлений и 2 удалений

Просмотреть файл

@ -1009,6 +1009,7 @@ wait_and_poll(struct megasas_instance *instance, struct megasas_cmd *cmd,
{
int i;
struct megasas_header *frame_hdr = &cmd->frame->hdr;
u32 status_reg;
u32 msecs = seconds * 1000;
@ -1018,6 +1019,12 @@ wait_and_poll(struct megasas_instance *instance, struct megasas_cmd *cmd,
for (i = 0; (i < msecs) && (frame_hdr->cmd_status == 0xff); i += 20) {
rmb();
msleep(20);
if (!(i % 5000)) {
status_reg = instance->instancet->read_fw_status_reg(instance)
& MFI_STATE_MASK;
if (status_reg == MFI_STATE_FAULT)
break;
}
}
if (frame_hdr->cmd_status == MFI_STAT_INVALID_STATUS)
@ -1720,6 +1727,7 @@ megasas_init_adapter_fusion(struct megasas_instance *instance)
struct fusion_context *fusion;
u32 scratch_pad_1;
int i = 0, count;
u32 status_reg;
fusion = instance->ctrl_context;
@ -1802,8 +1810,21 @@ megasas_init_adapter_fusion(struct megasas_instance *instance)
if (megasas_alloc_cmds_fusion(instance))
goto fail_alloc_cmds;
if (megasas_ioc_init_fusion(instance))
goto fail_ioc_init;
if (megasas_ioc_init_fusion(instance)) {
status_reg = instance->instancet->read_fw_status_reg(instance);
if (((status_reg & MFI_STATE_MASK) == MFI_STATE_FAULT) &&
(status_reg & MFI_RESET_ADAPTER)) {
/* Do a chip reset and then retry IOC INIT once */
if (megasas_adp_reset_wait_for_ready
(instance, true, 0) == FAILED)
goto fail_ioc_init;
if (megasas_ioc_init_fusion(instance))
goto fail_ioc_init;
} else {
goto fail_ioc_init;
}
}
megasas_display_intel_branding(instance);
if (megasas_get_ctrl_info(instance)) {