[PATCH] nvme-sysfs: add tmt1 and tmt2 attributes
Tokunori Ikegami
ikegami.t at gmail.com
Sat Nov 9 22:32:52 PST 2024
The throttling temperature feature not supported by hwmon.
So add temperature feature values as sysfs attributes.
Signed-off-by: Tokunori Ikegami <ikegami.t at gmail.com>
---
drivers/nvme/host/sysfs.c | 90 +++++++++++++++++++++++++++++++++++++++
include/linux/nvme.h | 5 +++
2 files changed, 95 insertions(+)
diff --git a/drivers/nvme/host/sysfs.c b/drivers/nvme/host/sysfs.c
index b68a9e5f1ea3..d376b51e67b3 100644
--- a/drivers/nvme/host/sysfs.c
+++ b/drivers/nvme/host/sysfs.c
@@ -6,6 +6,7 @@
*/
#include <linux/nvme-auth.h>
+#include <linux/units.h>
#include "nvme.h"
#include "fabrics.h"
@@ -664,6 +665,93 @@ static DEVICE_ATTR(dhchap_ctrl_secret, S_IRUGO | S_IWUSR,
nvme_ctrl_dhchap_ctrl_secret_show, nvme_ctrl_dhchap_ctrl_secret_store);
#endif
+static ssize_t nvme_ctrl_tmt_show(struct device *dev, bool tmt2,
+ struct device_attribute *attr, char *buf)
+{
+ struct nvme_ctrl *ctrl = dev_get_drvdata(dev);
+ int ret;
+ u32 status;
+ long val;
+
+ ret = nvme_get_features(ctrl, NVME_FEAT_HCTM, 0, NULL, 0, &status);
+ if (ret)
+ return sysfs_emit(buf, "error\n");
+
+ if (tmt2)
+ val = status & NVME_HCTM_TMT_MASK;
+ else
+ val = status >> NVME_HCTM_TMT1_SHIFT;
+ if (!val)
+ return sysfs_emit(buf, "off\n");
+
+ return sysfs_emit(buf, "%ld\n", kelvin_to_millicelsius(val));
+}
+
+static ssize_t nvme_ctrl_tmt_store(struct device *dev,
+ struct device_attribute *attr, bool tmt2,
+ const char *buf, size_t count)
+{
+ struct nvme_ctrl *ctrl = dev_get_drvdata(dev);
+ unsigned int v = 0;
+ int err;
+ int ret;
+ u32 status;
+
+ err = kstrtou32(buf, 10, &v);
+ if (err)
+ return err;
+
+ if (tmt2)
+ v <<= NVME_HCTM_TMT1_SHIFT;
+
+ ret = nvme_get_features(ctrl, NVME_FEAT_HCTM, 0, NULL, 0, &status);
+ if (ret > 0)
+ return -EIO;
+ if (ret < 0)
+ return ret;
+
+ if (tmt2)
+ v |= status << NVME_HCTM_TMT1_SHIFT;
+ else
+ v |= status & NVME_HCTM_TMT_MASK;
+
+ ret = nvme_set_features(ctrl, NVME_FEAT_HCTM, v, NULL, 0, NULL);
+ if (ret > 0)
+ return -EIO;
+
+ return count;
+}
+
+static ssize_t nvme_ctrl_tmt1_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return nvme_ctrl_tmt_show(dev, false, attr, buf);
+}
+
+static ssize_t nvme_ctrl_tmt1_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ return nvme_ctrl_tmt_store(dev, attr, false, buf, count);
+}
+static DEVICE_ATTR(tmt1, S_IRUGO | S_IWUSR, nvme_ctrl_tmt1_show,
+ nvme_ctrl_tmt1_store);
+
+static ssize_t nvme_ctrl_tmt2_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return nvme_ctrl_tmt_show(dev, true, attr, buf);
+}
+
+static ssize_t nvme_ctrl_tmt2_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ return nvme_ctrl_tmt_store(dev, attr, true, buf, count);
+}
+static DEVICE_ATTR(tmt2, S_IRUGO | S_IWUSR, nvme_ctrl_tmt2_show,
+ nvme_ctrl_tmt2_store);
+
static struct attribute *nvme_dev_attrs[] = {
&dev_attr_reset_controller.attr,
&dev_attr_rescan_controller.attr,
@@ -692,6 +780,8 @@ static struct attribute *nvme_dev_attrs[] = {
&dev_attr_dhchap_ctrl_secret.attr,
#endif
&dev_attr_adm_passthru_err_log_enabled.attr,
+ &dev_attr_tmt1.attr,
+ &dev_attr_tmt2.attr,
NULL
};
diff --git a/include/linux/nvme.h b/include/linux/nvme.h
index b58d9405d65e..89db23b57e6d 100644
--- a/include/linux/nvme.h
+++ b/include/linux/nvme.h
@@ -1144,6 +1144,11 @@ enum {
NVME_ENABLE_LBAFEE = 1,
};
+enum {
+ NVME_HCTM_TMT_MASK = 0xffff,
+ NVME_HCTM_TMT1_SHIFT = 16,
+};
+
/* Admin commands */
enum nvme_admin_opcode {
--
2.45.2
More information about the Linux-nvme
mailing list