Commit ccc7507d authored by Sumit Saxena's avatar Sumit Saxena Committed by Martin K. Petersen

megaraid_sas: MFI adapter OCR changes

Optimized MFI adapters' OCR path, particularly
megasas_wait_for_outstanding() function.
Signed-off-by: default avatarKashyap Desai <kashyap.desai@avagotech.com>
Signed-off-by: default avatarSumit Saxena <sumit.saxena@avagotech.com>
Reviewed-by: default avatarTomas Henzl <thenzl@redhat.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 8a01a41d
...@@ -2455,15 +2455,19 @@ void megasas_sriov_heartbeat_handler(unsigned long instance_addr) ...@@ -2455,15 +2455,19 @@ void megasas_sriov_heartbeat_handler(unsigned long instance_addr)
*/ */
static int megasas_wait_for_outstanding(struct megasas_instance *instance) static int megasas_wait_for_outstanding(struct megasas_instance *instance)
{ {
int i; int i, sl, outstanding;
u32 reset_index; u32 reset_index;
u32 wait_time = MEGASAS_RESET_WAIT_TIME; u32 wait_time = MEGASAS_RESET_WAIT_TIME;
unsigned long flags; unsigned long flags;
struct list_head clist_local; struct list_head clist_local;
struct megasas_cmd *reset_cmd; struct megasas_cmd *reset_cmd;
u32 fw_state; u32 fw_state;
u8 kill_adapter_flag;
if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) {
dev_info(&instance->pdev->dev, "%s:%d HBA is killed.\n",
__func__, __LINE__);
return FAILED;
}
if (atomic_read(&instance->adprecovery) != MEGASAS_HBA_OPERATIONAL) { if (atomic_read(&instance->adprecovery) != MEGASAS_HBA_OPERATIONAL) {
...@@ -2520,7 +2524,7 @@ static int megasas_wait_for_outstanding(struct megasas_instance *instance) ...@@ -2520,7 +2524,7 @@ static int megasas_wait_for_outstanding(struct megasas_instance *instance)
} }
for (i = 0; i < resetwaittime; i++) { for (i = 0; i < resetwaittime; i++) {
int outstanding = atomic_read(&instance->fw_outstanding); outstanding = atomic_read(&instance->fw_outstanding);
if (!outstanding) if (!outstanding)
break; break;
...@@ -2539,65 +2543,60 @@ static int megasas_wait_for_outstanding(struct megasas_instance *instance) ...@@ -2539,65 +2543,60 @@ static int megasas_wait_for_outstanding(struct megasas_instance *instance)
} }
i = 0; i = 0;
kill_adapter_flag = 0; outstanding = atomic_read(&instance->fw_outstanding);
fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) & MFI_STATE_MASK;
if ((!outstanding && (fw_state == MFI_STATE_OPERATIONAL)))
goto no_outstanding;
if (instance->disableOnlineCtrlReset)
goto kill_hba_and_failed;
do { do {
fw_state = instance->instancet->read_fw_status_reg( if ((fw_state == MFI_STATE_FAULT) || atomic_read(&instance->fw_outstanding)) {
instance->reg_set) & MFI_STATE_MASK; dev_info(&instance->pdev->dev,
if ((fw_state == MFI_STATE_FAULT) && "%s:%d waiting_for_outstanding: before issue OCR. FW state = 0x%x, oustanding 0x%x\n",
(instance->disableOnlineCtrlReset == 0)) { __func__, __LINE__, fw_state, atomic_read(&instance->fw_outstanding));
if (i == 3) { if (i == 3)
kill_adapter_flag = 2; goto kill_hba_and_failed;
break;
}
megasas_do_ocr(instance); megasas_do_ocr(instance);
kill_adapter_flag = 1;
/* wait for 1 secs to let FW finish the pending cmds */ if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) {
msleep(1000); dev_info(&instance->pdev->dev, "%s:%d OCR failed and HBA is killed.\n",
__func__, __LINE__);
return FAILED;
}
dev_info(&instance->pdev->dev, "%s:%d waiting_for_outstanding: after issue OCR.\n",
__func__, __LINE__);
for (sl = 0; sl < 10; sl++)
msleep(500);
outstanding = atomic_read(&instance->fw_outstanding);
fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) & MFI_STATE_MASK;
if ((!outstanding && (fw_state == MFI_STATE_OPERATIONAL)))
goto no_outstanding;
} }
i++; i++;
} while (i <= 3); } while (i <= 3);
if (atomic_read(&instance->fw_outstanding) && !kill_adapter_flag) { no_outstanding:
if (instance->disableOnlineCtrlReset == 0) {
megasas_do_ocr(instance);
/* wait for 5 secs to let FW finish the pending cmds */ dev_info(&instance->pdev->dev, "%s:%d no more pending commands remain after reset handling.\n",
for (i = 0; i < wait_time; i++) { __func__, __LINE__);
int outstanding = return SUCCESS;
atomic_read(&instance->fw_outstanding);
if (!outstanding)
return SUCCESS;
msleep(1000);
}
}
}
if (atomic_read(&instance->fw_outstanding) || kill_hba_and_failed:
(kill_adapter_flag == 2)) {
dev_notice(&instance->pdev->dev, "pending cmds after reset\n");
/*
* Send signal to FW to stop processing any pending cmds.
* The controller will be taken offline by the OS now.
*/
if ((instance->pdev->device ==
PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
(instance->pdev->device ==
PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
writel(MFI_STOP_ADP,
&instance->reg_set->doorbell);
} else {
writel(MFI_STOP_ADP,
&instance->reg_set->inbound_doorbell);
}
megasas_dump_pending_frames(instance);
atomic_set(&instance->adprecovery, MEGASAS_HW_CRITICAL_ERROR);
return FAILED;
}
dev_notice(&instance->pdev->dev, "no pending cmds after reset\n"); /* Reset not supported, kill adapter */
dev_info(&instance->pdev->dev, "%s:%d killing adapter scsi%d"
" disableOnlineCtrlReset %d fw_outstanding %d \n",
__func__, __LINE__, instance->host->host_no, instance->disableOnlineCtrlReset,
atomic_read(&instance->fw_outstanding));
megasas_dump_pending_frames(instance);
megaraid_sas_kill_hba(instance);
return SUCCESS; return FAILED;
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment