Message ID | 1678205182-13943-1-git-send-email-Arthur.Simchaev@wdc.com |
---|---|
State | Superseded |
Headers | show |
Series | [v1] ufs: core: Add support for qTimestamp attribute | expand |
Gentle reminder Regards Arthur > -----Original Message----- > From: Arthur Simchaev <Arthur.Simchaev@wdc.com> > Sent: Tuesday, March 7, 2023 6:06 PM > To: martin.petersen@oracle.com; bvanassche@acm.org > Cc: beanhuo@micron.com; linux-scsi@vger.kernel.org; linux- > kernel@vger.kernel.org; Arthur Simchaev <Arthur.Simchaev@wdc.com> > Subject: [PATCH v1] 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 > recommend > 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 v1: > - Add missed response variable to ufshcd_set_timestamp_attr > --- > drivers/ufs/core/ufshcd.c | 38 > ++++++++++++++++++++++++++++++++++++++ > include/uapi/scsi/scsi_bsg_ufs.h | 25 +++++++++++++++++++++++++ > include/ufs/ufs.h | 1 + > 3 files changed, 64 insertions(+) > > diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c > index 172d25f..cba9ef1 100644 > --- a/drivers/ufs/core/ufshcd.c > +++ b/drivers/ufs/core/ufshcd.c > @@ -8386,6 +8386,41 @@ static int ufshcd_device_params_init(struct > ufs_hba *hba) > return ret; > } > > +static void ufshcd_set_timestamp_attr(struct ufs_hba *hba) > +{ > + int err; > + struct ufs_query_req *request = NULL; > + struct ufs_query_res *response = NULL; > + struct ufs_dev_info *dev_info = &hba->dev_info; > + struct utp_upiu_query_v4_0 *upiu_data; > + > + if (dev_info->wspecversion < 0x400) > + return; > + > + ufshcd_hold(hba, false); > + > + mutex_lock(&hba->dev_cmd.lock); > + > + ufshcd_init_query(hba, &request, &response, > + UPIU_QUERY_OPCODE_WRITE_ATTR, > + QUERY_ATTR_IDN_TIMESTAMP, 0, 0); > + > + request->query_func = > UPIU_QUERY_FUNC_STANDARD_WRITE_REQUEST; > + > + upiu_data = (struct utp_upiu_query_v4_0 *)&request->upiu_req; > + > + put_unaligned_be64(ktime_get_real_ns(), &upiu_data->osf3); > + > + err = ufshcd_exec_dev_cmd(hba, DEV_CMD_TYPE_QUERY, > QUERY_REQ_TIMEOUT); > + > + if (err) > + dev_err(hba->dev, "%s: failed to set timestamp %d\n", > + __func__, err); > + > + mutex_unlock(&hba->dev_cmd.lock); > + ufshcd_release(hba); > +} > + > /** > * ufshcd_add_lus - probe and add UFS logical units > * @hba: per-adapter instance > @@ -8555,6 +8590,8 @@ static int ufshcd_device_init(struct ufs_hba *hba, > bool init_dev_params) > ufshcd_set_ufs_dev_active(hba); > ufshcd_force_reset_auto_bkops(hba); > > + ufshcd_set_timestamp_attr(hba); > + > /* Gear up to HS gear if supported */ > if (hba->max_pwr_info.is_valid) { > /* > @@ -9592,6 +9629,7 @@ static int __ufshcd_wl_resume(struct ufs_hba > *hba, enum ufs_pm_op pm_op) > ret = ufshcd_set_dev_pwr_mode(hba, > UFS_ACTIVE_PWR_MODE); > if (ret) > goto set_old_link_state; > + ufshcd_set_timestamp_attr(hba); > } > > if (ufshcd_keep_autobkops_enabled_except_suspend(hba)) > diff --git a/include/uapi/scsi/scsi_bsg_ufs.h > b/include/uapi/scsi/scsi_bsg_ufs.h > index 2801b65..fd3f9e5e 100644 > --- a/include/uapi/scsi/scsi_bsg_ufs.h > +++ b/include/uapi/scsi/scsi_bsg_ufs.h > @@ -71,6 +71,31 @@ struct utp_upiu_query { > }; > > /** > + * struct utp_upiu_query_v4_0 - upiu request buffer structure for > + * query request >= UFS 4.0 spec. > + * @opcode: command to perform B-0 > + * @idn: a value that indicates the particular type of data B-1 > + * @index: Index to further identify data B-2 > + * @selector: Index to further identify data B-3 > + * @osf4: spec field B-5 > + * @osf5: spec field B 6,7 > + * @osf6: spec field DW 8,9 > + * @osf7: spec field DW 10,11 > + */ > +struct utp_upiu_query_v4_0 { > + __u8 opcode; > + __u8 idn; > + __u8 index; > + __u8 selector; > + __u8 osf3; > + __u8 osf4; > + __be16 osf5; > + __be32 osf6; > + __be32 osf7; > + __be32 reserved; > +}; > + > +/** > * struct utp_upiu_cmd - Command UPIU structure > * @data_transfer_len: Data Transfer Length DW-3 > * @cdb: Command Descriptor Block CDB DW-4 to DW-7 > diff --git a/include/ufs/ufs.h b/include/ufs/ufs.h > index 4e8d624..198cb39 100644 > --- a/include/ufs/ufs.h > +++ b/include/ufs/ufs.h > @@ -170,6 +170,7 @@ enum attr_idn { > QUERY_ATTR_IDN_WB_BUFF_LIFE_TIME_EST = 0x1E, > QUERY_ATTR_IDN_CURR_WB_BUFF_SIZE = 0x1F, > QUERY_ATTR_IDN_EXT_IID_EN = 0x2A, > + QUERY_ATTR_IDN_TIMESTAMP = 0x30 > }; > > /* Descriptor idn for Query requests */ > -- > 2.7.4
diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index 172d25f..cba9ef1 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -8386,6 +8386,41 @@ static int ufshcd_device_params_init(struct ufs_hba *hba) return ret; } +static void ufshcd_set_timestamp_attr(struct ufs_hba *hba) +{ + int err; + struct ufs_query_req *request = NULL; + struct ufs_query_res *response = NULL; + struct ufs_dev_info *dev_info = &hba->dev_info; + struct utp_upiu_query_v4_0 *upiu_data; + + if (dev_info->wspecversion < 0x400) + return; + + ufshcd_hold(hba, false); + + mutex_lock(&hba->dev_cmd.lock); + + ufshcd_init_query(hba, &request, &response, + UPIU_QUERY_OPCODE_WRITE_ATTR, + QUERY_ATTR_IDN_TIMESTAMP, 0, 0); + + request->query_func = UPIU_QUERY_FUNC_STANDARD_WRITE_REQUEST; + + upiu_data = (struct utp_upiu_query_v4_0 *)&request->upiu_req; + + put_unaligned_be64(ktime_get_real_ns(), &upiu_data->osf3); + + err = ufshcd_exec_dev_cmd(hba, DEV_CMD_TYPE_QUERY, QUERY_REQ_TIMEOUT); + + if (err) + dev_err(hba->dev, "%s: failed to set timestamp %d\n", + __func__, err); + + mutex_unlock(&hba->dev_cmd.lock); + ufshcd_release(hba); +} + /** * ufshcd_add_lus - probe and add UFS logical units * @hba: per-adapter instance @@ -8555,6 +8590,8 @@ static int ufshcd_device_init(struct ufs_hba *hba, bool init_dev_params) ufshcd_set_ufs_dev_active(hba); ufshcd_force_reset_auto_bkops(hba); + ufshcd_set_timestamp_attr(hba); + /* Gear up to HS gear if supported */ if (hba->max_pwr_info.is_valid) { /* @@ -9592,6 +9629,7 @@ static int __ufshcd_wl_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op) ret = ufshcd_set_dev_pwr_mode(hba, UFS_ACTIVE_PWR_MODE); if (ret) goto set_old_link_state; + ufshcd_set_timestamp_attr(hba); } if (ufshcd_keep_autobkops_enabled_except_suspend(hba)) diff --git a/include/uapi/scsi/scsi_bsg_ufs.h b/include/uapi/scsi/scsi_bsg_ufs.h index 2801b65..fd3f9e5e 100644 --- a/include/uapi/scsi/scsi_bsg_ufs.h +++ b/include/uapi/scsi/scsi_bsg_ufs.h @@ -71,6 +71,31 @@ struct utp_upiu_query { }; /** + * struct utp_upiu_query_v4_0 - upiu request buffer structure for + * query request >= UFS 4.0 spec. + * @opcode: command to perform B-0 + * @idn: a value that indicates the particular type of data B-1 + * @index: Index to further identify data B-2 + * @selector: Index to further identify data B-3 + * @osf4: spec field B-5 + * @osf5: spec field B 6,7 + * @osf6: spec field DW 8,9 + * @osf7: spec field DW 10,11 + */ +struct utp_upiu_query_v4_0 { + __u8 opcode; + __u8 idn; + __u8 index; + __u8 selector; + __u8 osf3; + __u8 osf4; + __be16 osf5; + __be32 osf6; + __be32 osf7; + __be32 reserved; +}; + +/** * struct utp_upiu_cmd - Command UPIU structure * @data_transfer_len: Data Transfer Length DW-3 * @cdb: Command Descriptor Block CDB DW-4 to DW-7 diff --git a/include/ufs/ufs.h b/include/ufs/ufs.h index 4e8d624..198cb39 100644 --- a/include/ufs/ufs.h +++ b/include/ufs/ufs.h @@ -170,6 +170,7 @@ enum attr_idn { QUERY_ATTR_IDN_WB_BUFF_LIFE_TIME_EST = 0x1E, QUERY_ATTR_IDN_CURR_WB_BUFF_SIZE = 0x1F, QUERY_ATTR_IDN_EXT_IID_EN = 0x2A, + QUERY_ATTR_IDN_TIMESTAMP = 0x30 }; /* Descriptor idn for Query requests */
The new qTimestamp attribute was added to UFS 4.0 spec, in order to synchronize timestamp between device logs and the host.The spec recommend 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 v1: - Add missed response variable to ufshcd_set_timestamp_attr --- drivers/ufs/core/ufshcd.c | 38 ++++++++++++++++++++++++++++++++++++++ include/uapi/scsi/scsi_bsg_ufs.h | 25 +++++++++++++++++++++++++ include/ufs/ufs.h | 1 + 3 files changed, 64 insertions(+)