Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

scsi: ufs: core: Add support for qTimestamp attribute

The new qTimestamp attribute was added to UFS 4.0 spec, in order to
synchronize timestamp between device logs and the host. The spec recommends
to send this attribute upon device power-on Reset/HW reset or when
switching to Active state (using SSU command). Due to this attribute, the
attribute's max value was extended to 8 bytes. As a result, the new
definition of struct utp_upiu_query_v4_0 was added.

Signed-off-by: Arthur Simchaev <Arthur.Simchaev@wdc.com>

-----------------
Changes to v2:
- Adressed Bart's comments
- Add missed response variable to ufshcd_set_timestamp_attr

Link: https://lore.kernel.org/r/20230626103320.8737-1-arthur.simchaev@wdc.com
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

authored by

Arthur Simchaev and committed by
Martin K. Petersen
24befa92 47699a2b

+64
+38
drivers/ufs/core/ufshcd.c
··· 8520 8520 return ret; 8521 8521 } 8522 8522 8523 + static void ufshcd_set_timestamp_attr(struct ufs_hba *hba) 8524 + { 8525 + int err; 8526 + struct ufs_query_req *request = NULL; 8527 + struct ufs_query_res *response = NULL; 8528 + struct ufs_dev_info *dev_info = &hba->dev_info; 8529 + struct utp_upiu_query_v4_0 *upiu_data; 8530 + 8531 + if (dev_info->wspecversion < 0x400) 8532 + return; 8533 + 8534 + ufshcd_hold(hba); 8535 + 8536 + mutex_lock(&hba->dev_cmd.lock); 8537 + 8538 + ufshcd_init_query(hba, &request, &response, 8539 + UPIU_QUERY_OPCODE_WRITE_ATTR, 8540 + QUERY_ATTR_IDN_TIMESTAMP, 0, 0); 8541 + 8542 + request->query_func = UPIU_QUERY_FUNC_STANDARD_WRITE_REQUEST; 8543 + 8544 + upiu_data = (struct utp_upiu_query_v4_0 *)&request->upiu_req; 8545 + 8546 + put_unaligned_be64(ktime_get_real_ns(), &upiu_data->osf3); 8547 + 8548 + err = ufshcd_exec_dev_cmd(hba, DEV_CMD_TYPE_QUERY, QUERY_REQ_TIMEOUT); 8549 + 8550 + if (err) 8551 + dev_err(hba->dev, "%s: failed to set timestamp %d\n", 8552 + __func__, err); 8553 + 8554 + mutex_unlock(&hba->dev_cmd.lock); 8555 + ufshcd_release(hba); 8556 + } 8557 + 8523 8558 /** 8524 8559 * ufshcd_add_lus - probe and add UFS logical units 8525 8560 * @hba: per-adapter instance ··· 8742 8707 /* UFS device is also active now */ 8743 8708 ufshcd_set_ufs_dev_active(hba); 8744 8709 ufshcd_force_reset_auto_bkops(hba); 8710 + 8711 + ufshcd_set_timestamp_attr(hba); 8745 8712 8746 8713 /* Gear up to HS gear if supported */ 8747 8714 if (hba->max_pwr_info.is_valid) { ··· 9778 9741 ret = ufshcd_set_dev_pwr_mode(hba, UFS_ACTIVE_PWR_MODE); 9779 9742 if (ret) 9780 9743 goto set_old_link_state; 9744 + ufshcd_set_timestamp_attr(hba); 9781 9745 } 9782 9746 9783 9747 if (ufshcd_keep_autobkops_enabled_except_suspend(hba))
+25
include/uapi/scsi/scsi_bsg_ufs.h
··· 71 71 }; 72 72 73 73 /** 74 + * struct utp_upiu_query_v4_0 - upiu request buffer structure for 75 + * query request >= UFS 4.0 spec. 76 + * @opcode: command to perform B-0 77 + * @idn: a value that indicates the particular type of data B-1 78 + * @index: Index to further identify data B-2 79 + * @selector: Index to further identify data B-3 80 + * @osf4: spec field B-5 81 + * @osf5: spec field B 6,7 82 + * @osf6: spec field DW 8,9 83 + * @osf7: spec field DW 10,11 84 + */ 85 + struct utp_upiu_query_v4_0 { 86 + __u8 opcode; 87 + __u8 idn; 88 + __u8 index; 89 + __u8 selector; 90 + __u8 osf3; 91 + __u8 osf4; 92 + __be16 osf5; 93 + __be32 osf6; 94 + __be32 osf7; 95 + __be32 reserved; 96 + }; 97 + 98 + /** 74 99 * struct utp_upiu_cmd - Command UPIU structure 75 100 * @data_transfer_len: Data Transfer Length DW-3 76 101 * @cdb: Command Descriptor Block CDB DW-4 to DW-7
+1
include/ufs/ufs.h
··· 170 170 QUERY_ATTR_IDN_WB_BUFF_LIFE_TIME_EST = 0x1E, 171 171 QUERY_ATTR_IDN_CURR_WB_BUFF_SIZE = 0x1F, 172 172 QUERY_ATTR_IDN_EXT_IID_EN = 0x2A, 173 + QUERY_ATTR_IDN_TIMESTAMP = 0x30 173 174 }; 174 175 175 176 /* Descriptor idn for Query requests */