summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJorge Ramirez-Ortiz <jorge.ramirez@oss.qualcomm.com>2026-08-31 17:48:00 +0200
committerMartin K. Petersen (Oracle) <mkp@kernel.org>2026-09-09 21:53:11 -0400
commita8a34238e5e65609a434fc13aa1d64fcf2df1d23 (patch)
treedcbd8c250249ae225dd45df2189b1a2006932e7a
parentcee9395acd8043be0644b25c34bfa86623f2b935 (diff)
downloadlinux-next-a8a34238e5e65609a434fc13aa1d64fcf2df1d23.tar.gz
linux-next-a8a34238e5e65609a434fc13aa1d64fcf2df1d23.zip
scsi: ufs: rpmb: Retry power-on UNIT ATTENTION on the RPMB WLUN
After a power cycle, the first command sent to any UFS logical unit completes with CHECK CONDITION reporting a power-on UNIT ATTENTION. The SCSI core surfaces this condition to the caller rather than retrying it. For the RPMB well-known LU the first command after boot is the first RPMB frame, and RPMB has no earlier, guaranteed access that could clear the condition beforehand. The power-on UNIT ATTENTION therefore reaches RPMB and fails that first frame, breaking RPMB on every cold boot. The RPMB WLUN needs the power-on UNIT ATTENTION to be retried so that RPMB works from the very first access after a power cycle. Signed-off-by: Jorge Ramirez-Ortiz <jorge.ramirez@oss.qualcomm.com> Reviewed-by: Bean Huo <beanhuo@micron.com> Reviewed-by: Stanley Jhu <stanleyjhu@google.com> Link: https://patch.msgid.link/20260831154804.719528-2-jorge.ramirez@oss.qualcomm.com Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
-rw-r--r--drivers/ufs/core/ufs-rpmb.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/drivers/ufs/core/ufs-rpmb.c b/drivers/ufs/core/ufs-rpmb.c
index aa925cbb07e8..00ba4f3b842b 100644
--- a/drivers/ufs/core/ufs-rpmb.c
+++ b/drivers/ufs/core/ufs-rpmb.c
@@ -21,6 +21,7 @@
#include <linux/unaligned.h>
#include "ufshcd-priv.h"
+#define UFS_RPMB_UA_RETRIES 3 /* Retries for the power-on UNIT ATTENTION */
#define UFS_RPMB_SEC_PROTOCOL 0xEC /* JEDEC UFS application */
#define UFS_RPMB_SEC_PROTOCOL_ID 0x01 /* JEDEC UFS RPMB protocol ID, CDB byte3 */
@@ -40,6 +41,22 @@ struct ufs_rpmb_dev {
static int ufs_sec_submit(struct ufs_hba *hba, u16 spsp, void *buffer, size_t len, bool send)
{
struct scsi_device *sdev = hba->ufs_rpmb_wlun;
+ struct scsi_failure failure_defs[] = {
+ {
+ .sense = UNIT_ATTENTION,
+ .asc = 0x29, /* power on, reset, or bus device reset occurred */
+ .ascq = SCMD_FAILURE_ASCQ_ANY,
+ .allowed = UFS_RPMB_UA_RETRIES,
+ .result = SAM_STAT_CHECK_CONDITION,
+ },
+ {}
+ };
+ struct scsi_failures failures = {
+ .failure_definitions = failure_defs,
+ };
+ const struct scsi_exec_args exec_args = {
+ .failures = &failures,
+ };
u8 cdb[12] = { };
cdb[0] = send ? SECURITY_PROTOCOL_OUT : SECURITY_PROTOCOL_IN;
@@ -48,7 +65,8 @@ static int ufs_sec_submit(struct ufs_hba *hba, u16 spsp, void *buffer, size_t le
put_unaligned_be32(len, &cdb[6]);
return scsi_execute_cmd(sdev, cdb, send ? REQ_OP_DRV_OUT : REQ_OP_DRV_IN,
- buffer, len, /*timeout=*/30 * HZ, 0, NULL);
+ buffer, len, /*timeout=*/30 * HZ, /*retries=*/0,
+ &exec_args);
}
/* UFS RPMB route frames implementation */