|
@@ -1692,22 +1692,66 @@ static int megasas_slave_alloc(struct scsi_device *sdev)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/*
|
|
|
|
+* megasas_complete_outstanding_ioctls - Complete outstanding ioctls after a
|
|
|
|
+* kill adapter
|
|
|
|
+* @instance: Adapter soft state
|
|
|
|
+*
|
|
|
|
+*/
|
|
|
|
+void megasas_complete_outstanding_ioctls(struct megasas_instance *instance)
|
|
|
|
+{
|
|
|
|
+ int i;
|
|
|
|
+ struct megasas_cmd *cmd_mfi;
|
|
|
|
+ struct megasas_cmd_fusion *cmd_fusion;
|
|
|
|
+ struct fusion_context *fusion = instance->ctrl_context;
|
|
|
|
+
|
|
|
|
+ /* Find all outstanding ioctls */
|
|
|
|
+ if (fusion) {
|
|
|
|
+ for (i = 0; i < instance->max_fw_cmds; i++) {
|
|
|
|
+ cmd_fusion = fusion->cmd_list[i];
|
|
|
|
+ if (cmd_fusion->sync_cmd_idx != (u32)ULONG_MAX) {
|
|
|
|
+ cmd_mfi = instance->cmd_list[cmd_fusion->sync_cmd_idx];
|
|
|
|
+ if (cmd_mfi->sync_cmd &&
|
|
|
|
+ cmd_mfi->frame->hdr.cmd != MFI_CMD_ABORT)
|
|
|
|
+ megasas_complete_cmd(instance,
|
|
|
|
+ cmd_mfi, DID_OK);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ for (i = 0; i < instance->max_fw_cmds; i++) {
|
|
|
|
+ cmd_mfi = instance->cmd_list[i];
|
|
|
|
+ if (cmd_mfi->sync_cmd && cmd_mfi->frame->hdr.cmd !=
|
|
|
|
+ MFI_CMD_ABORT)
|
|
|
|
+ megasas_complete_cmd(instance, cmd_mfi, DID_OK);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
void megaraid_sas_kill_hba(struct megasas_instance *instance)
|
|
void megaraid_sas_kill_hba(struct megasas_instance *instance)
|
|
{
|
|
{
|
|
|
|
+ /* Set critical error to block I/O & ioctls in case caller didn't */
|
|
|
|
+ instance->adprecovery = MEGASAS_HW_CRITICAL_ERROR;
|
|
|
|
+ /* Wait 1 second to ensure IO or ioctls in build have posted */
|
|
|
|
+ msleep(1000);
|
|
if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
|
|
if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
|
|
- (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
|
|
|
|
- (instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
|
|
|
|
- (instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA) ||
|
|
|
|
- (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
|
|
|
|
- (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) {
|
|
|
|
- writel(MFI_STOP_ADP, &instance->reg_set->doorbell);
|
|
|
|
|
|
+ (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
|
|
|
|
+ (instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
|
|
|
|
+ (instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA) ||
|
|
|
|
+ (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
|
|
|
|
+ (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) {
|
|
|
|
+ writel(MFI_STOP_ADP,
|
|
|
|
+ &instance->reg_set->doorbell);
|
|
/* Flush */
|
|
/* Flush */
|
|
readl(&instance->reg_set->doorbell);
|
|
readl(&instance->reg_set->doorbell);
|
|
if (instance->mpio && instance->requestorId)
|
|
if (instance->mpio && instance->requestorId)
|
|
memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS);
|
|
memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS);
|
|
} else {
|
|
} else {
|
|
- writel(MFI_STOP_ADP, &instance->reg_set->inbound_doorbell);
|
|
|
|
|
|
+ writel(MFI_STOP_ADP,
|
|
|
|
+ &instance->reg_set->inbound_doorbell);
|
|
}
|
|
}
|
|
|
|
+ /* Complete outstanding ioctls when adapter is killed */
|
|
|
|
+ megasas_complete_outstanding_ioctls(instance);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -3031,10 +3075,9 @@ megasas_issue_pending_cmds_again(struct megasas_instance *instance)
|
|
"was tried multiple times during reset."
|
|
"was tried multiple times during reset."
|
|
"Shutting down the HBA\n",
|
|
"Shutting down the HBA\n",
|
|
cmd, cmd->scmd, cmd->sync_cmd);
|
|
cmd, cmd->scmd, cmd->sync_cmd);
|
|
|
|
+ instance->instancet->disable_intr(instance);
|
|
|
|
+ atomic_set(&instance->fw_reset_no_pci_access, 1);
|
|
megaraid_sas_kill_hba(instance);
|
|
megaraid_sas_kill_hba(instance);
|
|
-
|
|
|
|
- instance->adprecovery =
|
|
|
|
- MEGASAS_HW_CRITICAL_ERROR;
|
|
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -3168,8 +3211,8 @@ process_fw_state_change_wq(struct work_struct *work)
|
|
if (megasas_transition_to_ready(instance, 1)) {
|
|
if (megasas_transition_to_ready(instance, 1)) {
|
|
printk(KERN_NOTICE "megaraid_sas:adapter not ready\n");
|
|
printk(KERN_NOTICE "megaraid_sas:adapter not ready\n");
|
|
|
|
|
|
|
|
+ atomic_set(&instance->fw_reset_no_pci_access, 1);
|
|
megaraid_sas_kill_hba(instance);
|
|
megaraid_sas_kill_hba(instance);
|
|
- instance->adprecovery = MEGASAS_HW_CRITICAL_ERROR;
|
|
|
|
return ;
|
|
return ;
|
|
}
|
|
}
|
|
|
|
|