diff options
author | Sumit.Saxena@avagotech.com <Sumit.Saxena@avagotech.com> | 2015-01-05 09:36:18 -0500 |
---|---|---|
committer | Christoph Hellwig <hch@lst.de> | 2015-01-09 09:44:36 -0500 |
commit | c8dd61eff2780c481fcf919c1572e16e397c714e (patch) | |
tree | 49397211633101ac487e2b2f4c1a28d01f8322a8 | |
parent | c2ced1719a1b903350955a511e1666e6d05a7f5b (diff) |
megaraid_sas: complete outstanding IOCTLs before killing adapter
Driver calls megasas_complete_cmd() to call wake_up() for each MFI frame
that was issued through the ioctl() interface prior to the kill adapter.
This ensures userspace ioctl() system calls issued just before a kill
adapter don't get stuck in wait state and IOCTLs are returned to
the application.
Cc: <stable@vger.kernel.org>
Signed-off-by: Sumit Saxena <sumit.saxena@avagotech.com>
Signed-off-by: Chaitra Basappa <chaitra.basappa@avagotech.com>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
-rw-r--r-- | drivers/scsi/megaraid/megaraid_sas_base.c | 65 | ||||
-rw-r--r-- | drivers/scsi/megaraid/megaraid_sas_fusion.c | 4 |
2 files changed, 54 insertions, 15 deletions
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 9f37ddee4d8c..d4e9c4e1bf58 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c | |||
@@ -1692,22 +1692,66 @@ static int megasas_slave_alloc(struct scsi_device *sdev) | |||
1692 | return 0; | 1692 | return 0; |
1693 | } | 1693 | } |
1694 | 1694 | ||
1695 | /* | ||
1696 | * megasas_complete_outstanding_ioctls - Complete outstanding ioctls after a | ||
1697 | * kill adapter | ||
1698 | * @instance: Adapter soft state | ||
1699 | * | ||
1700 | */ | ||
1701 | void megasas_complete_outstanding_ioctls(struct megasas_instance *instance) | ||
1702 | { | ||
1703 | int i; | ||
1704 | struct megasas_cmd *cmd_mfi; | ||
1705 | struct megasas_cmd_fusion *cmd_fusion; | ||
1706 | struct fusion_context *fusion = instance->ctrl_context; | ||
1707 | |||
1708 | /* Find all outstanding ioctls */ | ||
1709 | if (fusion) { | ||
1710 | for (i = 0; i < instance->max_fw_cmds; i++) { | ||
1711 | cmd_fusion = fusion->cmd_list[i]; | ||
1712 | if (cmd_fusion->sync_cmd_idx != (u32)ULONG_MAX) { | ||
1713 | cmd_mfi = instance->cmd_list[cmd_fusion->sync_cmd_idx]; | ||
1714 | if (cmd_mfi->sync_cmd && | ||
1715 | cmd_mfi->frame->hdr.cmd != MFI_CMD_ABORT) | ||
1716 | megasas_complete_cmd(instance, | ||
1717 | cmd_mfi, DID_OK); | ||
1718 | } | ||
1719 | } | ||
1720 | } else { | ||
1721 | for (i = 0; i < instance->max_fw_cmds; i++) { | ||
1722 | cmd_mfi = instance->cmd_list[i]; | ||
1723 | if (cmd_mfi->sync_cmd && cmd_mfi->frame->hdr.cmd != | ||
1724 | MFI_CMD_ABORT) | ||
1725 | megasas_complete_cmd(instance, cmd_mfi, DID_OK); | ||
1726 | } | ||
1727 | } | ||
1728 | } | ||
1729 | |||
1730 | |||
1695 | void megaraid_sas_kill_hba(struct megasas_instance *instance) | 1731 | void megaraid_sas_kill_hba(struct megasas_instance *instance) |
1696 | { | 1732 | { |
1733 | /* Set critical error to block I/O & ioctls in case caller didn't */ | ||
1734 | instance->adprecovery = MEGASAS_HW_CRITICAL_ERROR; | ||
1735 | /* Wait 1 second to ensure IO or ioctls in build have posted */ | ||
1736 | msleep(1000); | ||
1697 | if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) || | 1737 | if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) || |
1698 | (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY) || | 1738 | (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY) || |
1699 | (instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) || | 1739 | (instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) || |
1700 | (instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA) || | 1740 | (instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA) || |
1701 | (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) || | 1741 | (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) || |
1702 | (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) { | 1742 | (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) { |
1703 | writel(MFI_STOP_ADP, &instance->reg_set->doorbell); | 1743 | writel(MFI_STOP_ADP, |
1744 | &instance->reg_set->doorbell); | ||
1704 | /* Flush */ | 1745 | /* Flush */ |
1705 | readl(&instance->reg_set->doorbell); | 1746 | readl(&instance->reg_set->doorbell); |
1706 | if (instance->mpio && instance->requestorId) | 1747 | if (instance->mpio && instance->requestorId) |
1707 | memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS); | 1748 | memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS); |
1708 | } else { | 1749 | } else { |
1709 | writel(MFI_STOP_ADP, &instance->reg_set->inbound_doorbell); | 1750 | writel(MFI_STOP_ADP, |
1751 | &instance->reg_set->inbound_doorbell); | ||
1710 | } | 1752 | } |
1753 | /* Complete outstanding ioctls when adapter is killed */ | ||
1754 | megasas_complete_outstanding_ioctls(instance); | ||
1711 | } | 1755 | } |
1712 | 1756 | ||
1713 | /** | 1757 | /** |
@@ -3031,10 +3075,9 @@ megasas_issue_pending_cmds_again(struct megasas_instance *instance) | |||
3031 | "was tried multiple times during reset." | 3075 | "was tried multiple times during reset." |
3032 | "Shutting down the HBA\n", | 3076 | "Shutting down the HBA\n", |
3033 | cmd, cmd->scmd, cmd->sync_cmd); | 3077 | cmd, cmd->scmd, cmd->sync_cmd); |
3078 | instance->instancet->disable_intr(instance); | ||
3079 | atomic_set(&instance->fw_reset_no_pci_access, 1); | ||
3034 | megaraid_sas_kill_hba(instance); | 3080 | megaraid_sas_kill_hba(instance); |
3035 | |||
3036 | instance->adprecovery = | ||
3037 | MEGASAS_HW_CRITICAL_ERROR; | ||
3038 | return; | 3081 | return; |
3039 | } | 3082 | } |
3040 | } | 3083 | } |
@@ -3168,8 +3211,8 @@ process_fw_state_change_wq(struct work_struct *work) | |||
3168 | if (megasas_transition_to_ready(instance, 1)) { | 3211 | if (megasas_transition_to_ready(instance, 1)) { |
3169 | printk(KERN_NOTICE "megaraid_sas:adapter not ready\n"); | 3212 | printk(KERN_NOTICE "megaraid_sas:adapter not ready\n"); |
3170 | 3213 | ||
3214 | atomic_set(&instance->fw_reset_no_pci_access, 1); | ||
3171 | megaraid_sas_kill_hba(instance); | 3215 | megaraid_sas_kill_hba(instance); |
3172 | instance->adprecovery = MEGASAS_HW_CRITICAL_ERROR; | ||
3173 | return ; | 3216 | return ; |
3174 | } | 3217 | } |
3175 | 3218 | ||
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 075c99e987bf..df280b1d263f 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c | |||
@@ -2631,7 +2631,6 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int iotimeout) | |||
2631 | instance->host->host_no); | 2631 | instance->host->host_no); |
2632 | megaraid_sas_kill_hba(instance); | 2632 | megaraid_sas_kill_hba(instance); |
2633 | instance->skip_heartbeat_timer_del = 1; | 2633 | instance->skip_heartbeat_timer_del = 1; |
2634 | instance->adprecovery = MEGASAS_HW_CRITICAL_ERROR; | ||
2635 | retval = FAILED; | 2634 | retval = FAILED; |
2636 | goto out; | 2635 | goto out; |
2637 | } | 2636 | } |
@@ -2827,8 +2826,6 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int iotimeout) | |||
2827 | dev_info(&instance->pdev->dev, | 2826 | dev_info(&instance->pdev->dev, |
2828 | "Failed from %s %d\n", | 2827 | "Failed from %s %d\n", |
2829 | __func__, __LINE__); | 2828 | __func__, __LINE__); |
2830 | instance->adprecovery = | ||
2831 | MEGASAS_HW_CRITICAL_ERROR; | ||
2832 | megaraid_sas_kill_hba(instance); | 2829 | megaraid_sas_kill_hba(instance); |
2833 | retval = FAILED; | 2830 | retval = FAILED; |
2834 | } | 2831 | } |
@@ -2877,7 +2874,6 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int iotimeout) | |||
2877 | "adapter scsi%d.\n", instance->host->host_no); | 2874 | "adapter scsi%d.\n", instance->host->host_no); |
2878 | megaraid_sas_kill_hba(instance); | 2875 | megaraid_sas_kill_hba(instance); |
2879 | instance->skip_heartbeat_timer_del = 1; | 2876 | instance->skip_heartbeat_timer_del = 1; |
2880 | instance->adprecovery = MEGASAS_HW_CRITICAL_ERROR; | ||
2881 | retval = FAILED; | 2877 | retval = FAILED; |
2882 | } else { | 2878 | } else { |
2883 | /* For VF: Restart HB timer if we didn't OCR */ | 2879 | /* For VF: Restart HB timer if we didn't OCR */ |