scsi: ufs: core: Dynamically disable timestamp on unsupported devices

JEDEC JESD220F specifies that the Timestamp attribute (qTimestamp) is an
optional feature for UFS devices. Some compliant UFS 4.0 devices do not
implement it and return QUERY_RESULT_INVALID_IDN (0xFD).

ufshcd_set_timestamp_attr() gates the write on wspecversion >= 0x400 and
the absence of UFS_DEVICE_QUIRK_NO_TIMESTAMP_SUPPORT. Neither covers a
device that advertises UFS 4.0 but declines the attribute, so the write is
reissued on every boot and every resume.

Record the capability in struct ufs_dev_info and clear it when the device
answers -EOPNOTSUPP, so the write is not retried. -ETIMEDOUT and -EIO still
reach dev_err(); they are transient and must not disable the attribute.

Signed-off-by: Stanley Jhu <stanleyjhu@google.com>
Tested-by: Xilin Wu <sophon@radxa.com>
Link: https://patch.msgid.link/20260911024319.1346706-3-stanleyjhu@google.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
This commit is contained in:
Stanley Jhu 2026-09-11 10:43:19 +08:00 committed by Martin K. Petersen (Oracle)
parent d1fa5cea5d
commit 00eec343c7
2 changed files with 8 additions and 3 deletions

View File

@ -8967,6 +8967,9 @@ static int ufs_get_device_desc(struct ufs_hba *hba)
ufs_fixup_device_setup(hba);
dev_info->timestamp_sup = dev_info->wspecversion >= 0x400 &&
!(hba->dev_quirks & UFS_DEVICE_QUIRK_NO_TIMESTAMP_SUPPORT);
ufshcd_wb_probe(hba, desc_buf);
ufshcd_temp_notif_probe(hba, desc_buf);
@ -9267,14 +9270,15 @@ static void ufshcd_set_timestamp_attr(struct ufs_hba *hba)
u64 ts_ns;
int err;
if (dev_info->wspecversion < 0x400 ||
hba->dev_quirks & UFS_DEVICE_QUIRK_NO_TIMESTAMP_SUPPORT)
if (!dev_info->timestamp_sup)
return;
ts_ns = ktime_get_real_ns();
err = ufshcd_query_attr_qword(hba, UPIU_QUERY_OPCODE_WRITE_ATTR,
QUERY_ATTR_IDN_TIMESTAMP, 0, 0, &ts_ns);
if (err)
if (err == -EOPNOTSUPP)
dev_info->timestamp_sup = false;
else if (err)
dev_err(hba->dev, "%s: failed to set timestamp %d\n",
__func__, err);
}

View File

@ -662,6 +662,7 @@ struct ufs_dev_info {
u8 rtt_cap; /* bDeviceRTTCap */
bool hid_sup;
bool timestamp_sup;
/* Unique device ID string (manufacturer+model+serial+version+date) */
char *device_id;