aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ufs
diff options
context:
space:
mode:
authorBean Huo <beanhuo@micron.com>2023-08-09 20:18:46 +0200
committerMartin K. Petersen <martin.petersen@oracle.com>2023-08-30 21:42:30 -0400
commitc91e585cfb3dd7d076e9ba0967908fc504d32def (patch)
tree96cc28decba794f4de2e672fc0db750fabc45e63 /drivers/ufs
parent0854065092a7a49a88bb592473abafb0cecd9f1c (diff)
downloadlinux-c91e585cfb3dd7d076e9ba0967908fc504d32def.tar.gz
scsi: ufs: core: Add advanced RPMB support where UFSHCI 4.0 does not support EHS length in UTRD
According to UFSHCI 4.0 specification: 5.2 Host Controller Capabilities Registers 5.2.1 Offset 00h: CAP – Controller Capabilities: "EHS Length in UTRD Supported (EHSLUTRDS): Indicates whether the host controller supports EHS Length field in UTRD. 0 – Host controller takes EHS length from CMD UPIU, and SW driver use EHS Length field in CMD UPIU. 1 – HW controller takes EHS length from UTRD, and SW driver use EHS Length field in UTRD. NOTE Recommend Host controllers move to taking EHS length from UTRD, and in UFS-5, it will be mandatory." So, when UFSHCI 4.0 doesn't support EHS Length field in UTRD, we could use EHS Length field in CMD UPIU. Remove the limitation that advanced RPMB only works when EHS length is supported in UTRD. Fixes: 6ff265fc5ef6 ("scsi: ufs: core: bsg: Add advanced RPMB support in ufs_bsg") Co-developed-by: "jonghwi.rha" <jonghwi.rha@samsung.com> Signed-off-by: "jonghwi.rha" <jonghwi.rha@samsung.com> Signed-off-by: Bean Huo <beanhuo@micron.com> Link: https://lore.kernel.org/r/20230809181847.102123-2-beanhuo@iokpp.de Reviewed-by: Bart Van Assche <bvanassche@acm.org> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/ufs')
-rw-r--r--drivers/ufs/core/ufs_bsg.c3
-rw-r--r--drivers/ufs/core/ufshcd.c10
2 files changed, 10 insertions, 3 deletions
diff --git a/drivers/ufs/core/ufs_bsg.c b/drivers/ufs/core/ufs_bsg.c
index 34e423924e0655..374e5aae4e7e86 100644
--- a/drivers/ufs/core/ufs_bsg.c
+++ b/drivers/ufs/core/ufs_bsg.c
@@ -76,8 +76,7 @@ static int ufs_bsg_exec_advanced_rpmb_req(struct ufs_hba *hba, struct bsg_job *j
int ret;
int data_len;
- if (hba->ufs_version < ufshci_version(4, 0) || !hba->dev_info.b_advanced_rpmb_en ||
- !(hba->capabilities & MASK_EHSLUTRD_SUPPORTED))
+ if (hba->ufs_version < ufshci_version(4, 0) || !hba->dev_info.b_advanced_rpmb_en)
return -EINVAL;
if (rpmb_request->ehs_req.length != 2 || rpmb_request->ehs_req.ehs_type != 1)
diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
index e4318171381bd9..f774169bf04fa9 100644
--- a/drivers/ufs/core/ufshcd.c
+++ b/drivers/ufs/core/ufshcd.c
@@ -7240,7 +7240,15 @@ int ufshcd_advanced_rpmb_req_handler(struct ufs_hba *hba, struct utp_upiu_req *r
/* Advanced RPMB starts from UFS 4.0, so its command type is UTP_CMD_TYPE_UFS_STORAGE */
lrbp->command_type = UTP_CMD_TYPE_UFS_STORAGE;
- ufshcd_prepare_req_desc_hdr(lrbp, &upiu_flags, dir, 2);
+ /*
+ * According to UFSHCI 4.0 specification page 24, if EHSLUTRDS is 0, host controller takes
+ * EHS length from CMD UPIU, and SW driver use EHS Length field in CMD UPIU. if it is 1,
+ * HW controller takes EHS length from UTRD.
+ */
+ if (hba->capabilities & MASK_EHSLUTRD_SUPPORTED)
+ ufshcd_prepare_req_desc_hdr(lrbp, &upiu_flags, dir, 2);
+ else
+ ufshcd_prepare_req_desc_hdr(lrbp, &upiu_flags, dir, 0);
/* update the task tag and LUN in the request upiu */
req_upiu->header.flags = upiu_flags;