diff options
| author | Jorge Ramirez-Ortiz <jorge.ramirez@oss.qualcomm.com> | 2026-08-31 17:48:00 +0200 |
|---|---|---|
| committer | Martin K. Petersen (Oracle) <mkp@kernel.org> | 2026-09-09 21:53:11 -0400 |
| commit | a8a34238e5e65609a434fc13aa1d64fcf2df1d23 (patch) | |
| tree | dcbd8c250249ae225dd45df2189b1a2006932e7a | |
| parent | cee9395acd8043be0644b25c34bfa86623f2b935 (diff) | |
| download | linux-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.c | 20 |
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 */ |
