Skip to content

Commit defaf1a

Browse files
committed
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
2 parents d3426a6 + 7c632fc commit defaf1a

File tree

8 files changed

+64
-9
lines changed

8 files changed

+64
-9
lines changed

drivers/scsi/mpi3mr/mpi3mr_os.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3575,6 +3575,17 @@ static int mpi3mr_prepare_sg_scmd(struct mpi3mr_ioc *mrioc,
35753575
scmd->sc_data_direction);
35763576
priv->meta_sg_valid = 1; /* To unmap meta sg DMA */
35773577
} else {
3578+
/*
3579+
* Some firmware versions byte-swap the REPORT ZONES command
3580+
* reply from ATA-ZAC devices by directly accessing in the host
3581+
* buffer. This does not respect the default command DMA
3582+
* direction and causes IOMMU page faults on some architectures
3583+
* with an IOMMU enforcing write mappings (e.g. AMD hosts).
3584+
* Avoid such issue by making the REPORT ZONES buffer mapping
3585+
* bi-directional.
3586+
*/
3587+
if (scmd->cmnd[0] == ZBC_IN && scmd->cmnd[1] == ZI_REPORT_ZONES)
3588+
scmd->sc_data_direction = DMA_BIDIRECTIONAL;
35783589
sg_scmd = scsi_sglist(scmd);
35793590
sges_left = scsi_dma_map(scmd);
35803591
}

drivers/scsi/mpt3sas/mpt3sas_base.c

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2671,6 +2671,22 @@ _base_build_zero_len_sge_ieee(struct MPT3SAS_ADAPTER *ioc, void *paddr)
26712671
_base_add_sg_single_ieee(paddr, sgl_flags, 0, 0, -1);
26722672
}
26732673

2674+
static inline int _base_scsi_dma_map(struct scsi_cmnd *cmd)
2675+
{
2676+
/*
2677+
* Some firmware versions byte-swap the REPORT ZONES command reply from
2678+
* ATA-ZAC devices by directly accessing in the host buffer. This does
2679+
* not respect the default command DMA direction and causes IOMMU page
2680+
* faults on some architectures with an IOMMU enforcing write mappings
2681+
* (e.g. AMD hosts). Avoid such issue by making the report zones buffer
2682+
* mapping bi-directional.
2683+
*/
2684+
if (cmd->cmnd[0] == ZBC_IN && cmd->cmnd[1] == ZI_REPORT_ZONES)
2685+
cmd->sc_data_direction = DMA_BIDIRECTIONAL;
2686+
2687+
return scsi_dma_map(cmd);
2688+
}
2689+
26742690
/**
26752691
* _base_build_sg_scmd - main sg creation routine
26762692
* pcie_device is unused here!
@@ -2717,7 +2733,7 @@ _base_build_sg_scmd(struct MPT3SAS_ADAPTER *ioc,
27172733
sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
27182734

27192735
sg_scmd = scsi_sglist(scmd);
2720-
sges_left = scsi_dma_map(scmd);
2736+
sges_left = _base_scsi_dma_map(scmd);
27212737
if (sges_left < 0)
27222738
return -ENOMEM;
27232739

@@ -2861,7 +2877,7 @@ _base_build_sg_scmd_ieee(struct MPT3SAS_ADAPTER *ioc,
28612877
}
28622878

28632879
sg_scmd = scsi_sglist(scmd);
2864-
sges_left = scsi_dma_map(scmd);
2880+
sges_left = _base_scsi_dma_map(scmd);
28652881
if (sges_left < 0)
28662882
return -ENOMEM;
28672883

drivers/scsi/sd.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4205,6 +4205,8 @@ static int sd_resume(struct device *dev)
42054205
{
42064206
struct scsi_disk *sdkp = dev_get_drvdata(dev);
42074207

4208+
sd_printk(KERN_NOTICE, sdkp, "Starting disk\n");
4209+
42084210
if (opal_unlock_from_suspend(sdkp->opal_dev)) {
42094211
sd_printk(KERN_NOTICE, sdkp, "OPAL unlock failed\n");
42104212
return -EIO;
@@ -4221,13 +4223,12 @@ static int sd_resume_common(struct device *dev, bool runtime)
42214223
if (!sdkp) /* E.g.: runtime resume at the start of sd_probe() */
42224224
return 0;
42234225

4224-
sd_printk(KERN_NOTICE, sdkp, "Starting disk\n");
4225-
42264226
if (!sd_do_start_stop(sdkp->device, runtime)) {
42274227
sdkp->suspended = false;
42284228
return 0;
42294229
}
42304230

4231+
sd_printk(KERN_NOTICE, sdkp, "Starting disk\n");
42314232
ret = sd_start_stop_device(sdkp, 1);
42324233
if (!ret) {
42334234
sd_resume(dev);

drivers/ufs/core/ufshcd-priv.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,11 @@ static inline int ufshcd_rpm_get_sync(struct ufs_hba *hba)
316316
return pm_runtime_get_sync(&hba->ufs_device_wlun->sdev_gendev);
317317
}
318318

319+
static inline int ufshcd_rpm_get_if_active(struct ufs_hba *hba)
320+
{
321+
return pm_runtime_get_if_active(&hba->ufs_device_wlun->sdev_gendev);
322+
}
323+
319324
static inline int ufshcd_rpm_put_sync(struct ufs_hba *hba)
320325
{
321326
return pm_runtime_put_sync(&hba->ufs_device_wlun->sdev_gendev);

drivers/ufs/core/ufshcd.c

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2416,7 +2416,17 @@ static inline int ufshcd_hba_capabilities(struct ufs_hba *hba)
24162416
return err;
24172417
}
24182418

2419+
/*
2420+
* The UFSHCI 3.0 specification does not define MCQ_SUPPORT and
2421+
* LSDB_SUPPORT, but [31:29] as reserved bits with reset value 0s, which
2422+
* means we can simply read values regardless of version.
2423+
*/
24192424
hba->mcq_sup = FIELD_GET(MASK_MCQ_SUPPORT, hba->capabilities);
2425+
/*
2426+
* 0h: legacy single doorbell support is available
2427+
* 1h: indicate that legacy single doorbell support has been removed
2428+
*/
2429+
hba->lsdb_sup = !FIELD_GET(MASK_LSDB_SUPPORT, hba->capabilities);
24202430
if (!hba->mcq_sup)
24212431
return 0;
24222432

@@ -6553,7 +6563,8 @@ static void ufshcd_err_handler(struct work_struct *work)
65536563
if (ufshcd_err_handling_should_stop(hba))
65546564
goto skip_err_handling;
65556565

6556-
if (hba->dev_quirks & UFS_DEVICE_QUIRK_RECOVERY_FROM_DL_NAC_ERRORS) {
6566+
if ((hba->dev_quirks & UFS_DEVICE_QUIRK_RECOVERY_FROM_DL_NAC_ERRORS) &&
6567+
!hba->force_reset) {
65576568
bool ret;
65586569

65596570
spin_unlock_irqrestore(hba->host->host_lock, flags);
@@ -8211,7 +8222,10 @@ static void ufshcd_update_rtc(struct ufs_hba *hba)
82118222
*/
82128223
val = ts64.tv_sec - hba->dev_info.rtc_time_baseline;
82138224

8214-
ufshcd_rpm_get_sync(hba);
8225+
/* Skip update RTC if RPM state is not RPM_ACTIVE */
8226+
if (ufshcd_rpm_get_if_active(hba) <= 0)
8227+
return;
8228+
82158229
err = ufshcd_query_attr(hba, UPIU_QUERY_OPCODE_WRITE_ATTR, QUERY_ATTR_IDN_SECONDS_PASSED,
82168230
0, 0, &val);
82178231
ufshcd_rpm_put_sync(hba);
@@ -10265,9 +10279,6 @@ int ufshcd_system_restore(struct device *dev)
1026510279
*/
1026610280
ufshcd_readl(hba, REG_UTP_TASK_REQ_LIST_BASE_H);
1026710281

10268-
/* Resuming from hibernate, assume that link was OFF */
10269-
ufshcd_set_link_off(hba);
10270-
1027110282
return 0;
1027210283

1027310284
}
@@ -10496,6 +10507,12 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
1049610507
}
1049710508

1049810509
if (!is_mcq_supported(hba)) {
10510+
if (!hba->lsdb_sup) {
10511+
dev_err(hba->dev, "%s: failed to initialize (legacy doorbell mode not supported)\n",
10512+
__func__);
10513+
err = -EINVAL;
10514+
goto out_disable;
10515+
}
1049910516
err = scsi_add_host(host, hba->dev);
1050010517
if (err) {
1050110518
dev_err(hba->dev, "scsi_add_host failed\n");

drivers/ufs/host/ufs-exynos.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1293,6 +1293,9 @@ static void exynos_ufs_fmp_resume(struct ufs_hba *hba)
12931293
{
12941294
struct arm_smccc_res res;
12951295

1296+
if (!(hba->caps & UFSHCD_CAP_CRYPTO))
1297+
return;
1298+
12961299
arm_smccc_smc(SMC_CMD_FMP_SECURITY, 0, SMU_EMBEDDED, CFG_DESCTYPE_3,
12971300
0, 0, 0, 0, &res);
12981301
if (res.a0)

include/ufs/ufshcd.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1109,6 +1109,7 @@ struct ufs_hba {
11091109
bool ext_iid_sup;
11101110
bool scsi_host_added;
11111111
bool mcq_sup;
1112+
bool lsdb_sup;
11121113
bool mcq_enabled;
11131114
struct ufshcd_res_info res[RES_MAX];
11141115
void __iomem *mcq_base;

include/ufs/ufshci.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ enum {
7777
MASK_OUT_OF_ORDER_DATA_DELIVERY_SUPPORT = 0x02000000,
7878
MASK_UIC_DME_TEST_MODE_SUPPORT = 0x04000000,
7979
MASK_CRYPTO_SUPPORT = 0x10000000,
80+
MASK_LSDB_SUPPORT = 0x20000000,
8081
MASK_MCQ_SUPPORT = 0x40000000,
8182
};
8283

0 commit comments

Comments
 (0)