Commit 7c632fc3 authored by Martin K. Petersen's avatar Martin K. Petersen

Merge branch '6.11/scsi-queue' into 6.11/scsi-fixes

Pull outstanding commits from 6.11 queue into fixes.
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parents 8400291e 47398f49
...@@ -3575,6 +3575,17 @@ static int mpi3mr_prepare_sg_scmd(struct mpi3mr_ioc *mrioc, ...@@ -3575,6 +3575,17 @@ static int mpi3mr_prepare_sg_scmd(struct mpi3mr_ioc *mrioc,
scmd->sc_data_direction); scmd->sc_data_direction);
priv->meta_sg_valid = 1; /* To unmap meta sg DMA */ priv->meta_sg_valid = 1; /* To unmap meta sg DMA */
} else { } else {
/*
* Some firmware versions byte-swap the REPORT ZONES command
* reply from ATA-ZAC devices by directly accessing in the host
* buffer. This does not respect the default command DMA
* direction and causes IOMMU page faults on some architectures
* with an IOMMU enforcing write mappings (e.g. AMD hosts).
* Avoid such issue by making the REPORT ZONES buffer mapping
* bi-directional.
*/
if (scmd->cmnd[0] == ZBC_IN && scmd->cmnd[1] == ZI_REPORT_ZONES)
scmd->sc_data_direction = DMA_BIDIRECTIONAL;
sg_scmd = scsi_sglist(scmd); sg_scmd = scsi_sglist(scmd);
sges_left = scsi_dma_map(scmd); sges_left = scsi_dma_map(scmd);
} }
......
...@@ -2671,6 +2671,22 @@ _base_build_zero_len_sge_ieee(struct MPT3SAS_ADAPTER *ioc, void *paddr) ...@@ -2671,6 +2671,22 @@ _base_build_zero_len_sge_ieee(struct MPT3SAS_ADAPTER *ioc, void *paddr)
_base_add_sg_single_ieee(paddr, sgl_flags, 0, 0, -1); _base_add_sg_single_ieee(paddr, sgl_flags, 0, 0, -1);
} }
static inline int _base_scsi_dma_map(struct scsi_cmnd *cmd)
{
/*
* Some firmware versions byte-swap the REPORT ZONES command reply from
* ATA-ZAC devices by directly accessing in the host buffer. This does
* not respect the default command DMA direction and causes IOMMU page
* faults on some architectures with an IOMMU enforcing write mappings
* (e.g. AMD hosts). Avoid such issue by making the report zones buffer
* mapping bi-directional.
*/
if (cmd->cmnd[0] == ZBC_IN && cmd->cmnd[1] == ZI_REPORT_ZONES)
cmd->sc_data_direction = DMA_BIDIRECTIONAL;
return scsi_dma_map(cmd);
}
/** /**
* _base_build_sg_scmd - main sg creation routine * _base_build_sg_scmd - main sg creation routine
* pcie_device is unused here! * pcie_device is unused here!
...@@ -2717,7 +2733,7 @@ _base_build_sg_scmd(struct MPT3SAS_ADAPTER *ioc, ...@@ -2717,7 +2733,7 @@ _base_build_sg_scmd(struct MPT3SAS_ADAPTER *ioc,
sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT; sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
sg_scmd = scsi_sglist(scmd); sg_scmd = scsi_sglist(scmd);
sges_left = scsi_dma_map(scmd); sges_left = _base_scsi_dma_map(scmd);
if (sges_left < 0) if (sges_left < 0)
return -ENOMEM; return -ENOMEM;
...@@ -2861,7 +2877,7 @@ _base_build_sg_scmd_ieee(struct MPT3SAS_ADAPTER *ioc, ...@@ -2861,7 +2877,7 @@ _base_build_sg_scmd_ieee(struct MPT3SAS_ADAPTER *ioc,
} }
sg_scmd = scsi_sglist(scmd); sg_scmd = scsi_sglist(scmd);
sges_left = scsi_dma_map(scmd); sges_left = _base_scsi_dma_map(scmd);
if (sges_left < 0) if (sges_left < 0)
return -ENOMEM; return -ENOMEM;
......
...@@ -4205,6 +4205,8 @@ static int sd_resume(struct device *dev) ...@@ -4205,6 +4205,8 @@ static int sd_resume(struct device *dev)
{ {
struct scsi_disk *sdkp = dev_get_drvdata(dev); struct scsi_disk *sdkp = dev_get_drvdata(dev);
sd_printk(KERN_NOTICE, sdkp, "Starting disk\n");
if (opal_unlock_from_suspend(sdkp->opal_dev)) { if (opal_unlock_from_suspend(sdkp->opal_dev)) {
sd_printk(KERN_NOTICE, sdkp, "OPAL unlock failed\n"); sd_printk(KERN_NOTICE, sdkp, "OPAL unlock failed\n");
return -EIO; return -EIO;
...@@ -4221,13 +4223,12 @@ static int sd_resume_common(struct device *dev, bool runtime) ...@@ -4221,13 +4223,12 @@ static int sd_resume_common(struct device *dev, bool runtime)
if (!sdkp) /* E.g.: runtime resume at the start of sd_probe() */ if (!sdkp) /* E.g.: runtime resume at the start of sd_probe() */
return 0; return 0;
sd_printk(KERN_NOTICE, sdkp, "Starting disk\n");
if (!sd_do_start_stop(sdkp->device, runtime)) { if (!sd_do_start_stop(sdkp->device, runtime)) {
sdkp->suspended = false; sdkp->suspended = false;
return 0; return 0;
} }
sd_printk(KERN_NOTICE, sdkp, "Starting disk\n");
ret = sd_start_stop_device(sdkp, 1); ret = sd_start_stop_device(sdkp, 1);
if (!ret) { if (!ret) {
sd_resume(dev); sd_resume(dev);
......
...@@ -316,6 +316,11 @@ static inline int ufshcd_rpm_get_sync(struct ufs_hba *hba) ...@@ -316,6 +316,11 @@ static inline int ufshcd_rpm_get_sync(struct ufs_hba *hba)
return pm_runtime_get_sync(&hba->ufs_device_wlun->sdev_gendev); return pm_runtime_get_sync(&hba->ufs_device_wlun->sdev_gendev);
} }
static inline int ufshcd_rpm_get_if_active(struct ufs_hba *hba)
{
return pm_runtime_get_if_active(&hba->ufs_device_wlun->sdev_gendev);
}
static inline int ufshcd_rpm_put_sync(struct ufs_hba *hba) static inline int ufshcd_rpm_put_sync(struct ufs_hba *hba)
{ {
return pm_runtime_put_sync(&hba->ufs_device_wlun->sdev_gendev); return pm_runtime_put_sync(&hba->ufs_device_wlun->sdev_gendev);
......
...@@ -2416,7 +2416,17 @@ static inline int ufshcd_hba_capabilities(struct ufs_hba *hba) ...@@ -2416,7 +2416,17 @@ static inline int ufshcd_hba_capabilities(struct ufs_hba *hba)
return err; return err;
} }
/*
* The UFSHCI 3.0 specification does not define MCQ_SUPPORT and
* LSDB_SUPPORT, but [31:29] as reserved bits with reset value 0s, which
* means we can simply read values regardless of version.
*/
hba->mcq_sup = FIELD_GET(MASK_MCQ_SUPPORT, hba->capabilities); hba->mcq_sup = FIELD_GET(MASK_MCQ_SUPPORT, hba->capabilities);
/*
* 0h: legacy single doorbell support is available
* 1h: indicate that legacy single doorbell support has been removed
*/
hba->lsdb_sup = !FIELD_GET(MASK_LSDB_SUPPORT, hba->capabilities);
if (!hba->mcq_sup) if (!hba->mcq_sup)
return 0; return 0;
...@@ -6553,7 +6563,8 @@ static void ufshcd_err_handler(struct work_struct *work) ...@@ -6553,7 +6563,8 @@ static void ufshcd_err_handler(struct work_struct *work)
if (ufshcd_err_handling_should_stop(hba)) if (ufshcd_err_handling_should_stop(hba))
goto skip_err_handling; goto skip_err_handling;
if (hba->dev_quirks & UFS_DEVICE_QUIRK_RECOVERY_FROM_DL_NAC_ERRORS) { if ((hba->dev_quirks & UFS_DEVICE_QUIRK_RECOVERY_FROM_DL_NAC_ERRORS) &&
!hba->force_reset) {
bool ret; bool ret;
spin_unlock_irqrestore(hba->host->host_lock, flags); spin_unlock_irqrestore(hba->host->host_lock, flags);
...@@ -8211,7 +8222,10 @@ static void ufshcd_update_rtc(struct ufs_hba *hba) ...@@ -8211,7 +8222,10 @@ static void ufshcd_update_rtc(struct ufs_hba *hba)
*/ */
val = ts64.tv_sec - hba->dev_info.rtc_time_baseline; val = ts64.tv_sec - hba->dev_info.rtc_time_baseline;
ufshcd_rpm_get_sync(hba); /* Skip update RTC if RPM state is not RPM_ACTIVE */
if (ufshcd_rpm_get_if_active(hba) <= 0)
return;
err = ufshcd_query_attr(hba, UPIU_QUERY_OPCODE_WRITE_ATTR, QUERY_ATTR_IDN_SECONDS_PASSED, err = ufshcd_query_attr(hba, UPIU_QUERY_OPCODE_WRITE_ATTR, QUERY_ATTR_IDN_SECONDS_PASSED,
0, 0, &val); 0, 0, &val);
ufshcd_rpm_put_sync(hba); ufshcd_rpm_put_sync(hba);
...@@ -10265,9 +10279,6 @@ int ufshcd_system_restore(struct device *dev) ...@@ -10265,9 +10279,6 @@ int ufshcd_system_restore(struct device *dev)
*/ */
ufshcd_readl(hba, REG_UTP_TASK_REQ_LIST_BASE_H); ufshcd_readl(hba, REG_UTP_TASK_REQ_LIST_BASE_H);
/* Resuming from hibernate, assume that link was OFF */
ufshcd_set_link_off(hba);
return 0; return 0;
} }
...@@ -10496,6 +10507,12 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) ...@@ -10496,6 +10507,12 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
} }
if (!is_mcq_supported(hba)) { if (!is_mcq_supported(hba)) {
if (!hba->lsdb_sup) {
dev_err(hba->dev, "%s: failed to initialize (legacy doorbell mode not supported)\n",
__func__);
err = -EINVAL;
goto out_disable;
}
err = scsi_add_host(host, hba->dev); err = scsi_add_host(host, hba->dev);
if (err) { if (err) {
dev_err(hba->dev, "scsi_add_host failed\n"); dev_err(hba->dev, "scsi_add_host failed\n");
......
...@@ -1293,6 +1293,9 @@ static void exynos_ufs_fmp_resume(struct ufs_hba *hba) ...@@ -1293,6 +1293,9 @@ static void exynos_ufs_fmp_resume(struct ufs_hba *hba)
{ {
struct arm_smccc_res res; struct arm_smccc_res res;
if (!(hba->caps & UFSHCD_CAP_CRYPTO))
return;
arm_smccc_smc(SMC_CMD_FMP_SECURITY, 0, SMU_EMBEDDED, CFG_DESCTYPE_3, arm_smccc_smc(SMC_CMD_FMP_SECURITY, 0, SMU_EMBEDDED, CFG_DESCTYPE_3,
0, 0, 0, 0, &res); 0, 0, 0, 0, &res);
if (res.a0) if (res.a0)
......
...@@ -1109,6 +1109,7 @@ struct ufs_hba { ...@@ -1109,6 +1109,7 @@ struct ufs_hba {
bool ext_iid_sup; bool ext_iid_sup;
bool scsi_host_added; bool scsi_host_added;
bool mcq_sup; bool mcq_sup;
bool lsdb_sup;
bool mcq_enabled; bool mcq_enabled;
struct ufshcd_res_info res[RES_MAX]; struct ufshcd_res_info res[RES_MAX];
void __iomem *mcq_base; void __iomem *mcq_base;
......
...@@ -77,6 +77,7 @@ enum { ...@@ -77,6 +77,7 @@ enum {
MASK_OUT_OF_ORDER_DATA_DELIVERY_SUPPORT = 0x02000000, MASK_OUT_OF_ORDER_DATA_DELIVERY_SUPPORT = 0x02000000,
MASK_UIC_DME_TEST_MODE_SUPPORT = 0x04000000, MASK_UIC_DME_TEST_MODE_SUPPORT = 0x04000000,
MASK_CRYPTO_SUPPORT = 0x10000000, MASK_CRYPTO_SUPPORT = 0x10000000,
MASK_LSDB_SUPPORT = 0x20000000,
MASK_MCQ_SUPPORT = 0x40000000, MASK_MCQ_SUPPORT = 0x40000000,
}; };
......
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