On 7/20/26 10:51, Jorge Ramirez-Ortiz wrote:
The RPMB Well-Known LUN is untouched during boot, so its first SECURITY
PROTOCOL command after power-on is answered with a CHECK CONDITION
carrying a power-on UNIT ATTENTION, which ufs_scsi_exec() surfaces as
-EINVAL. U-Boot has no SCSI mid-layer to auto-retry, so the first RPMB
frame OP-TEE sends (the write-counter read that verifies the key) was
lost. Reporting the UNIT ATTENTION clears it, so retry the command once.
OK just squash this change with patch 2.
Neil
Signed-off-by: Jorge Ramirez-Ortiz <[email protected]>
---
drivers/ufs/ufs-rpmb.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/drivers/ufs/ufs-rpmb.c b/drivers/ufs/ufs-rpmb.c
index 7919162ddae..1434161682b 100644
--- a/drivers/ufs/ufs-rpmb.c
+++ b/drivers/ufs/ufs-rpmb.c
@@ -19,6 +19,8 @@
#define RPMB_FRAME_REQ_OFFSET 510
+#define UFS_RPMB_UA_RETRIES 3
+
static u16 rpmb_frame_request(const void *frame)
{
const u8 *p = frame;
@@ -34,6 +36,8 @@ static int ufs_rpmb_secprot(struct udevice *scsi_dev,
unsigned int region,
struct scsi_cmd pccb;
u32 len = nframes * RPMB_FRAME_SIZE;
u16 spsp = (region << 8) | UFS_RPMB_SEC_PROTOCOL_ID;
+ int retries;
+ int ret = 0;
memset(&pccb, 0, sizeof(pccb));
pccb.lun = UFS_UPIU_RPMB_WLUN;
@@ -54,7 +58,13 @@ static int ufs_rpmb_secprot(struct udevice *scsi_dev,
unsigned int region,
pccb.datalen = len;
pccb.dma_dir = dir;
- return scsi_exec(scsi_dev, &pccb);
+ for (retries = UFS_RPMB_UA_RETRIES; retries > 0; retries--) {
+ ret = scsi_exec(scsi_dev, &pccb);
+ if (!ret)
+ break;
+ }
+
+ return ret;
}
static int ufs_rpmb_send(struct udevice *scsi_dev, unsigned int region,