[PATCH v1 4/7] ufs: rpmb: retry SECURITY PROTOCOL on power-on UNIT ATTENTION
Jorge Ramirez-Ortiz <[email protected]> Mon, 20 Jul 2026 10:51:44 +0200
| Newsgroups | de.denx.lists.u-boot |
|---|---|
| Message-ID | <[email protected]> |
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. 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, -- 2.54.0