From: Can Guo <can.guo@oss.qualcomm.com>
To: avri.altman@wdc.com, bvanassche@acm.org, beanhuo@micron.com,
peter.wang@mediatek.com, martin.petersen@oracle.com,
mani@kernel.org
Cc: linux-scsi@vger.kernel.org, Can Guo <can.guo@oss.qualcomm.com>,
Alim Akhtar <alim.akhtar@samsung.com>,
"James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>,
Matthias Brugger <matthias.bgg@gmail.com>,
AngeloGioacchino Del Regno
<angelogioacchino.delregno@collabora.com>,
Neil Armstrong <neil.armstrong@linaro.org>,
Ram Kumar Dwivedi <ram.dwivedi@oss.qualcomm.com>,
Zhongqiu Han <zhongqiu.han@oss.qualcomm.com>,
Huan Tang <tanghuan@vivo.com>, Daniel Lee <chullee@google.com>,
Liu Song <liu.song13@zte.com.cn>, Bean Huo <huobean@gmail.com>,
vamshi gajjela <vamshigajjela@google.com>,
"Rafael J. Wysocki" <rafael.j.wysocki@intel.com>,
Adrian Hunter <adrian.hunter@intel.com>,
linux-kernel@vger.kernel.org (open list),
linux-arm-kernel@lists.infradead.org (moderated
list:ARM/Mediatek SoC support:Keyword:mediatek),
linux-mediatek@lists.infradead.org (moderated list:ARM/Mediatek
SoC support:Keyword:mediatek)
Subject: [PATCH v2 1/2] scsi: ufs: core: Introduce function ufshcd_query_attr_qword()
Date: Fri, 24 Apr 2026 08:14:19 -0700 [thread overview]
Message-ID: <20260424151420.111675-2-can.guo@oss.qualcomm.com> (raw)
In-Reply-To: <20260424151420.111675-1-can.guo@oss.qualcomm.com>
Introduce a new generic function ufshcd_query_attr_qword() to handle
quad-word (64-bit) UFS attribute operations. This consolidates the
handling of 64-bit attributes which was previously scattered across
multiple specialized functions.
Reviewed-by: Peter Wang <peter.wang@mediatek.com>
Signed-off-by: Can Guo <can.guo@oss.qualcomm.com>
---
drivers/ufs/core/ufs-sysfs.c | 30 ++++++--
drivers/ufs/core/ufshcd-priv.h | 3 +-
drivers/ufs/core/ufshcd.c | 126 +++++++++++++++++----------------
3 files changed, 94 insertions(+), 65 deletions(-)
diff --git a/drivers/ufs/core/ufs-sysfs.c b/drivers/ufs/core/ufs-sysfs.c
index 99af3c73f1af..d9dc4cc3452e 100644
--- a/drivers/ufs/core/ufs-sysfs.c
+++ b/drivers/ufs/core/ufs-sysfs.c
@@ -594,8 +594,13 @@ static ssize_t device_lvl_exception_id_show(struct device *dev,
u64 exception_id;
int err;
+ if (hba->dev_info.wspecversion < 0x410)
+ return -EOPNOTSUPP;
+
ufshcd_rpm_get_sync(hba);
- err = ufshcd_read_device_lvl_exception_id(hba, &exception_id);
+ err = ufshcd_query_attr_qword(hba, UPIU_QUERY_OPCODE_READ_ATTR,
+ QUERY_ATTR_IDN_DEV_LVL_EXCEPTION_ID,
+ 0, 0, &exception_id);
ufshcd_rpm_put_sync(hba);
if (err)
@@ -1670,6 +1675,12 @@ static inline bool ufshcd_is_wb_attrs(enum attr_idn idn)
idn <= QUERY_ATTR_IDN_CURR_WB_BUFF_SIZE;
}
+static inline bool ufshcd_is_qword_attr(enum attr_idn idn)
+{
+ return idn == QUERY_ATTR_IDN_TIMESTAMP ||
+ idn == QUERY_ATTR_IDN_DEV_LVL_EXCEPTION_ID;
+}
+
static int wb_read_resize_attrs(struct ufs_hba *hba,
enum attr_idn idn, u32 *attr_val)
{
@@ -1736,6 +1747,7 @@ static ssize_t _name##_show(struct device *dev, \
struct device_attribute *attr, char *buf) \
{ \
struct ufs_hba *hba = dev_get_drvdata(dev); \
+ u64 qword_value; \
u32 value; \
int ret; \
u8 index = 0; \
@@ -1748,14 +1760,24 @@ static ssize_t _name##_show(struct device *dev, \
if (ufshcd_is_wb_attrs(QUERY_ATTR_IDN##_uname)) \
index = ufshcd_wb_get_query_index(hba); \
ufshcd_rpm_get_sync(hba); \
- ret = ufshcd_query_attr(hba, UPIU_QUERY_OPCODE_READ_ATTR, \
- QUERY_ATTR_IDN##_uname, index, 0, &value); \
+ if (ufshcd_is_qword_attr(QUERY_ATTR_IDN##_uname)) \
+ ret = ufshcd_query_attr_qword(hba, \
+ UPIU_QUERY_OPCODE_READ_ATTR, \
+ QUERY_ATTR_IDN##_uname, \
+ index, 0, &qword_value); \
+ else \
+ ret = ufshcd_query_attr(hba, \
+ UPIU_QUERY_OPCODE_READ_ATTR, \
+ QUERY_ATTR_IDN##_uname, index, 0, &value); \
ufshcd_rpm_put_sync(hba); \
if (ret) { \
ret = -EINVAL; \
goto out; \
} \
- ret = sysfs_emit(buf, "0x%08X\n", value); \
+ if (ufshcd_is_qword_attr(QUERY_ATTR_IDN##_uname)) \
+ ret = sysfs_emit(buf, "0x%016llX\n", qword_value); \
+ else \
+ ret = sysfs_emit(buf, "0x%08X\n", value); \
out: \
up(&hba->host_sem); \
return ret; \
diff --git a/drivers/ufs/core/ufshcd-priv.h b/drivers/ufs/core/ufshcd-priv.h
index 0a72148cb053..ed1adeb22ec6 100644
--- a/drivers/ufs/core/ufshcd-priv.h
+++ b/drivers/ufs/core/ufshcd-priv.h
@@ -60,6 +60,8 @@ int ufshcd_query_attr_retry(struct ufs_hba *hba, enum query_opcode opcode,
u32 *attr_val);
int ufshcd_query_attr(struct ufs_hba *hba, enum query_opcode opcode,
enum attr_idn idn, u8 index, u8 selector, u32 *attr_val);
+int ufshcd_query_attr_qword(struct ufs_hba *hba, enum query_opcode opcode,
+ enum attr_idn idn, u8 index, u8 sel, u64 *attr_val);
int ufshcd_query_flag(struct ufs_hba *hba, enum query_opcode opcode,
enum flag_idn idn, u8 index, bool *flag_res);
void ufshcd_auto_hibern8_update(struct ufs_hba *hba, u32 ahit);
@@ -106,7 +108,6 @@ int ufshcd_exec_raw_upiu_cmd(struct ufs_hba *hba,
enum query_opcode desc_op);
int ufshcd_wb_toggle(struct ufs_hba *hba, bool enable);
-int ufshcd_read_device_lvl_exception_id(struct ufs_hba *hba, u64 *exception_id);
int ufshcd_uic_tx_eqtr(struct ufs_hba *hba, int gear);
void ufshcd_apply_valid_tx_eq_settings(struct ufs_hba *hba);
diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
index 4805e40ed4d7..c92e0409c793 100644
--- a/drivers/ufs/core/ufshcd.c
+++ b/drivers/ufs/core/ufshcd.c
@@ -3611,6 +3611,67 @@ int ufshcd_query_attr_retry(struct ufs_hba *hba,
return ret;
}
+/**
+ * ufshcd_query_attr_qword - Function of sending query requests for quad-word attributes
+ * @hba: per-adapter instance
+ * @opcode: attribute opcode
+ * @idn: attribute idn to access
+ * @index: index field
+ * @sel: selector field
+ * @attr_val: the attribute value after the query request completes
+ *
+ * Return: 0 for success, non-zero in case of failure.
+ */
+int ufshcd_query_attr_qword(struct ufs_hba *hba, enum query_opcode opcode,
+ enum attr_idn idn, u8 index, u8 sel, u64 *attr_val)
+{
+ struct utp_upiu_query_v4_0 *upiu_req;
+ struct utp_upiu_query_v4_0 *upiu_resp;
+ struct ufs_query_req *request = NULL;
+ struct ufs_query_res *response = NULL;
+ int err;
+
+ if (!attr_val) {
+ dev_err(hba->dev, "%s: attribute value required for opcode 0x%x\n",
+ __func__, opcode);
+ return -EINVAL;
+ }
+
+ ufshcd_dev_man_lock(hba);
+
+ ufshcd_init_query(hba, &request, &response, opcode, idn, index, sel);
+
+ switch (opcode) {
+ case UPIU_QUERY_OPCODE_WRITE_ATTR:
+ request->query_func = UPIU_QUERY_FUNC_STANDARD_WRITE_REQUEST;
+ upiu_req = (struct utp_upiu_query_v4_0 *)&request->upiu_req;
+ put_unaligned_be64(*attr_val, &upiu_req->osf3);
+ break;
+ case UPIU_QUERY_OPCODE_READ_ATTR:
+ request->query_func = UPIU_QUERY_FUNC_STANDARD_READ_REQUEST;
+ break;
+ default:
+ dev_err(hba->dev, "%s: Expected query attr opcode but got = 0x%.2x\n",
+ __func__, opcode);
+ err = -EINVAL;
+ goto out_unlock;
+ }
+
+ err = ufshcd_exec_dev_cmd(hba, DEV_CMD_TYPE_QUERY, dev_cmd_timeout);
+ if (err) {
+ dev_err(hba->dev, "%s: opcode 0x%.2x for idn %d failed, index %d, selector %d, err = %d\n",
+ __func__, opcode, idn, index, sel, err);
+ goto out_unlock;
+ }
+
+ upiu_resp = (struct utp_upiu_query_v4_0 *)response;
+ *attr_val = get_unaligned_be64(&upiu_resp->osf3);
+
+out_unlock:
+ ufshcd_dev_man_unlock(hba);
+ return err;
+}
+
/*
* Return: 0 upon success; > 0 in case the UFS device reported an OCS error;
* < 0 if another error occurred.
@@ -6224,46 +6285,6 @@ static void ufshcd_bkops_exception_event_handler(struct ufs_hba *hba)
__func__, err);
}
-/*
- * Return: 0 upon success; > 0 in case the UFS device reported an OCS error;
- * < 0 if another error occurred.
- */
-int ufshcd_read_device_lvl_exception_id(struct ufs_hba *hba, u64 *exception_id)
-{
- struct utp_upiu_query_v4_0 *upiu_resp;
- struct ufs_query_req *request = NULL;
- struct ufs_query_res *response = NULL;
- int err;
-
- if (hba->dev_info.wspecversion < 0x410)
- return -EOPNOTSUPP;
-
- ufshcd_hold(hba);
- mutex_lock(&hba->dev_cmd.lock);
-
- ufshcd_init_query(hba, &request, &response,
- UPIU_QUERY_OPCODE_READ_ATTR,
- QUERY_ATTR_IDN_DEV_LVL_EXCEPTION_ID, 0, 0);
-
- request->query_func = UPIU_QUERY_FUNC_STANDARD_READ_REQUEST;
-
- err = ufshcd_exec_dev_cmd(hba, DEV_CMD_TYPE_QUERY, dev_cmd_timeout);
-
- if (err) {
- dev_err(hba->dev, "%s: failed to read device level exception %d\n",
- __func__, err);
- goto out;
- }
-
- upiu_resp = (struct utp_upiu_query_v4_0 *)response;
- *exception_id = get_unaligned_be64(&upiu_resp->osf3);
-out:
- mutex_unlock(&hba->dev_cmd.lock);
- ufshcd_release(hba);
-
- return err;
-}
-
static int __ufshcd_wb_toggle(struct ufs_hba *hba, bool set, enum flag_idn idn)
{
u8 index;
@@ -9113,35 +9134,20 @@ static int ufshcd_device_params_init(struct ufs_hba *hba)
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;
+ u64 ts_ns;
+ int err;
if (dev_info->wspecversion < 0x400 ||
hba->dev_quirks & UFS_DEVICE_QUIRK_NO_TIMESTAMP_SUPPORT)
return;
- ufshcd_dev_man_lock(hba);
-
- 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, dev_cmd_timeout);
-
+ 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)
dev_err(hba->dev, "%s: failed to set timestamp %d\n",
__func__, err);
-
- ufshcd_dev_man_unlock(hba);
}
/**
--
2.34.1
next parent reply other threads:[~2026-04-24 15:15 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20260424151420.111675-1-can.guo@oss.qualcomm.com>
2026-04-24 15:14 ` Can Guo [this message]
2026-04-27 8:36 ` [PATCH v2 1/2] scsi: ufs: core: Introduce function ufshcd_query_attr_qword() Bean Huo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260424151420.111675-2-can.guo@oss.qualcomm.com \
--to=can.guo@oss.qualcomm.com \
--cc=James.Bottomley@HansenPartnership.com \
--cc=adrian.hunter@intel.com \
--cc=alim.akhtar@samsung.com \
--cc=angelogioacchino.delregno@collabora.com \
--cc=avri.altman@wdc.com \
--cc=beanhuo@micron.com \
--cc=bvanassche@acm.org \
--cc=chullee@google.com \
--cc=huobean@gmail.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mediatek@lists.infradead.org \
--cc=linux-scsi@vger.kernel.org \
--cc=liu.song13@zte.com.cn \
--cc=mani@kernel.org \
--cc=martin.petersen@oracle.com \
--cc=matthias.bgg@gmail.com \
--cc=neil.armstrong@linaro.org \
--cc=peter.wang@mediatek.com \
--cc=rafael.j.wysocki@intel.com \
--cc=ram.dwivedi@oss.qualcomm.com \
--cc=tanghuan@vivo.com \
--cc=vamshigajjela@google.com \
--cc=zhongqiu.han@oss.qualcomm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox