mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-01 10:43:43 +00:00
SCSI fixes on 20240803
One core change that reverts the double message print patch in sd.c (it was causing regressions on embedded systems). The rest are driver fixes in ufs, mpt3sas and mpi3mr. Signed-off-by: James E.J. Bottomley <James.Bottomley@HansenPartnership.com> -----BEGIN PGP SIGNATURE----- iJwEABMIAEQWIQTnYEDbdso9F2cI+arnQslM7pishQUCZq6lOSYcamFtZXMuYm90 dG9tbGV5QGhhbnNlbnBhcnRuZXJzaGlwLmNvbQAKCRDnQslM7pishbahAQCAOzIU tVtzYqnIaD3ACKJshPYHHUfq89W5tAlU/N3dVwEAp2h3iZV3BNHhTtzEsFwf8giX Q/srm1jHTyviB/rM1Yw= =qK7K -----END PGP SIGNATURE----- Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi Pull SCSI fixes from James Bottomley: "One core change that reverts the double message print patch in sd.c (it was causing regressions on embedded systems). The rest are driver fixes in ufs, mpt3sas and mpi3mr" * tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: scsi: ufs: exynos: Don't resume FMP when crypto support is disabled scsi: mpt3sas: Avoid IOMMU page faults on REPORT ZONES scsi: mpi3mr: Avoid IOMMU page faults on REPORT ZONES scsi: ufs: core: Do not set link to OFF state while waking up from hibernation scsi: Revert "scsi: sd: Do not repeat the starting disk message" scsi: ufs: core: Fix deadlock during RTC update scsi: ufs: core: Bypass quick recovery if force reset is needed scsi: ufs: core: Check LSDBS cap when !mcq
This commit is contained in:
commit
defaf1a211
@ -3575,6 +3575,17 @@ static int mpi3mr_prepare_sg_scmd(struct mpi3mr_ioc *mrioc,
|
||||
scmd->sc_data_direction);
|
||||
priv->meta_sg_valid = 1; /* To unmap meta sg DMA */
|
||||
} 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);
|
||||
sges_left = scsi_dma_map(scmd);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
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
|
||||
* pcie_device is unused here!
|
||||
@ -2717,7 +2733,7 @@ _base_build_sg_scmd(struct MPT3SAS_ADAPTER *ioc,
|
||||
sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
|
||||
|
||||
sg_scmd = scsi_sglist(scmd);
|
||||
sges_left = scsi_dma_map(scmd);
|
||||
sges_left = _base_scsi_dma_map(scmd);
|
||||
if (sges_left < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -2861,7 +2877,7 @@ _base_build_sg_scmd_ieee(struct MPT3SAS_ADAPTER *ioc,
|
||||
}
|
||||
|
||||
sg_scmd = scsi_sglist(scmd);
|
||||
sges_left = scsi_dma_map(scmd);
|
||||
sges_left = _base_scsi_dma_map(scmd);
|
||||
if (sges_left < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -4205,6 +4205,8 @@ static int sd_resume(struct device *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)) {
|
||||
sd_printk(KERN_NOTICE, sdkp, "OPAL unlock failed\n");
|
||||
return -EIO;
|
||||
@ -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() */
|
||||
return 0;
|
||||
|
||||
sd_printk(KERN_NOTICE, sdkp, "Starting disk\n");
|
||||
|
||||
if (!sd_do_start_stop(sdkp->device, runtime)) {
|
||||
sdkp->suspended = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
sd_printk(KERN_NOTICE, sdkp, "Starting disk\n");
|
||||
ret = sd_start_stop_device(sdkp, 1);
|
||||
if (!ret) {
|
||||
sd_resume(dev);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
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);
|
||||
/*
|
||||
* 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)
|
||||
return 0;
|
||||
|
||||
@ -6553,7 +6563,8 @@ static void ufshcd_err_handler(struct work_struct *work)
|
||||
if (ufshcd_err_handling_should_stop(hba))
|
||||
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;
|
||||
|
||||
spin_unlock_irqrestore(hba->host->host_lock, flags);
|
||||
@ -8211,7 +8222,10 @@ static void ufshcd_update_rtc(struct ufs_hba *hba)
|
||||
*/
|
||||
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,
|
||||
0, 0, &val);
|
||||
ufshcd_rpm_put_sync(hba);
|
||||
@ -10265,9 +10279,6 @@ int ufshcd_system_restore(struct device *dev)
|
||||
*/
|
||||
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;
|
||||
|
||||
}
|
||||
@ -10496,6 +10507,12 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
|
||||
}
|
||||
|
||||
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);
|
||||
if (err) {
|
||||
dev_err(hba->dev, "scsi_add_host failed\n");
|
||||
|
@ -1293,6 +1293,9 @@ static void exynos_ufs_fmp_resume(struct ufs_hba *hba)
|
||||
{
|
||||
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,
|
||||
0, 0, 0, 0, &res);
|
||||
if (res.a0)
|
||||
|
@ -1109,6 +1109,7 @@ struct ufs_hba {
|
||||
bool ext_iid_sup;
|
||||
bool scsi_host_added;
|
||||
bool mcq_sup;
|
||||
bool lsdb_sup;
|
||||
bool mcq_enabled;
|
||||
struct ufshcd_res_info res[RES_MAX];
|
||||
void __iomem *mcq_base;
|
||||
|
@ -77,6 +77,7 @@ enum {
|
||||
MASK_OUT_OF_ORDER_DATA_DELIVERY_SUPPORT = 0x02000000,
|
||||
MASK_UIC_DME_TEST_MODE_SUPPORT = 0x04000000,
|
||||
MASK_CRYPTO_SUPPORT = 0x10000000,
|
||||
MASK_LSDB_SUPPORT = 0x20000000,
|
||||
MASK_MCQ_SUPPORT = 0x40000000,
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user