lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20210901123707.5014-4-avri.altman@wdc.com>
Date:   Wed,  1 Sep 2021 15:37:07 +0300
From:   Avri Altman <avri.altman@....com>
To:     "James E . J . Bottomley" <jejb@...ux.vnet.ibm.com>,
        "Martin K . Petersen" <martin.petersen@...cle.com>
Cc:     linux-scsi@...r.kernel.org, linux-kernel@...r.kernel.org,
        Bart Van Assche <bvanassche@....org>,
        Adrian Hunter <adrian.hunter@...el.com>,
        Bean Huo <beanhuo@...ron.com>,
        Avri Altman <avri.altman@....com>
Subject: [PATCH 3/3] scsi: ufs-sysfs: Add sysfs entries for temperature notification

The temperature readings are in degrees Celsius, and to allow negative
temperature, need to subtract 80 from the reported value. Make sure to
enforce the legal range of those values, and properly document it as
well.

Signed-off-by: Avri Altman <avri.altman@....com>
---
 Documentation/ABI/testing/sysfs-driver-ufs | 38 ++++++++++
 drivers/scsi/ufs/ufs-sysfs.c               | 86 ++++++++++++++++++++++
 drivers/scsi/ufs/ufs.h                     |  3 +
 3 files changed, 127 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-driver-ufs b/Documentation/ABI/testing/sysfs-driver-ufs
index ec3a7149ced5..ff2294971e44 100644
--- a/Documentation/ABI/testing/sysfs-driver-ufs
+++ b/Documentation/ABI/testing/sysfs-driver-ufs
@@ -1534,3 +1534,41 @@ Contact:	Avri Altman <avri.altman@....com>
 Description:	In host control mode the host is the originator of map requests.
 		To avoid flooding the device with map requests, use a simple throttling
 		mechanism that limits the number of inflight map requests.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/attributes/case_rough_temp
+Date:		September 2021
+Contact:	Avri Altman <avri.altman@....com>
+Description:	The device case rough temperature (bDeviceCaseRoughTemperature
+		attribute). It is termed "rough" due to the inherent inaccuracy
+		of the temperature sensor inside a semiconductor device,
+		e.g. +- 10 degrees centigrade error range.
+		allowable range is [-79..170].
+		The temperature readings are in decimal degrees Celsius.
+
+		Please note that the Tcase validity depends on the state of the
+		wExceptionEventControl attribute: it is up to the user to
+		verify that the applicable mask (TOO_HIGH_TEMP_EN, and / or
+		TOO_LOW_TEMP_EN) is set for the exception handling control.
+		This can be either done by ufs-bsg or ufs-debugfs.
+
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/attributes/high_temp_bound
+Date:		September 2021
+Contact:	Avri Altman <avri.altman@....com>
+Description:	The high temperature (bDeviceTooHighTempBoundary attribute)
+		from which TOO_HIGH_TEMP in wExceptionEventStatus is turned on.
+		The temperature readings are in decimal degrees Celsius.
+		allowable range is [20..170].
+
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/attributes/low_temp_bound
+Date:		September 2021
+Contact:	Avri Altman <avri.altman@....com>
+Description:	The low temperature (bDeviceTooLowTempBoundary attribute)
+		from which TOO_LOW_TEMP in wExceptionEventStatus is turned on.
+		The temperature readings are in decimal degrees Celsius.
+		allowable range is [-79..0].
+
+		The file is read only.
diff --git a/drivers/scsi/ufs/ufs-sysfs.c b/drivers/scsi/ufs/ufs-sysfs.c
index 5c405ff7b6ea..a9abe33c40e4 100644
--- a/drivers/scsi/ufs/ufs-sysfs.c
+++ b/drivers/scsi/ufs/ufs-sysfs.c
@@ -1047,6 +1047,86 @@ static inline bool ufshcd_is_wb_attrs(enum attr_idn idn)
 		idn <= QUERY_ATTR_IDN_CURR_WB_BUFF_SIZE;
 }
 
+static inline bool ufshcd_is_temp_attrs(enum attr_idn idn)
+{
+	return idn >= QUERY_ATTR_IDN_CASE_ROUGH_TEMP &&
+	       idn <= QUERY_ATTR_IDN_LOW_TEMP_BOUND;
+}
+
+static bool ufshcd_case_temp_legal(struct ufs_hba *hba)
+{
+	u32 ee_mask;
+	int ret;
+
+	ufshcd_rpm_get_sync(hba);
+	ret = ufshcd_query_attr(hba, UPIU_QUERY_OPCODE_READ_ATTR,
+				QUERY_ATTR_IDN_EE_CONTROL, 0, 0, &ee_mask);
+	ufshcd_rpm_put_sync(hba);
+	if (ret)
+		return false;
+
+	return (ufshcd_is_high_temp_notif_allowed(hba) &&
+		(ee_mask & MASK_EE_TOO_HIGH_TEMP)) ||
+	       (ufshcd_is_low_temp_notif_allowed(hba) &&
+		(ee_mask & MASK_EE_TOO_HIGH_TEMP));
+}
+
+static bool ufshcd_temp_legal(struct ufs_hba *hba, enum attr_idn idn,
+			      u32 value)
+{
+	return (idn == QUERY_ATTR_IDN_CASE_ROUGH_TEMP && value >= 1 &&
+		value <= 250 && ufshcd_case_temp_legal(hba)) ||
+	       (idn == QUERY_ATTR_IDN_HIGH_TEMP_BOUND && value >= 100 &&
+		value <= 250) ||
+	       (idn == QUERY_ATTR_IDN_LOW_TEMP_BOUND && value >= 1 &&
+		value <= 80);
+}
+
+#define UFS_ATTRIBUTE_DEC(_name, _uname)				\
+static ssize_t _name##_show(struct device *dev,				\
+	struct device_attribute *attr, char *buf)			\
+{									\
+	struct ufs_hba *hba = dev_get_drvdata(dev);			\
+	u32 value;							\
+	int dec_value;							\
+	int ret;							\
+	u8 index = 0;							\
+									\
+	down(&hba->host_sem);						\
+	if (!ufshcd_is_user_access_allowed(hba)) {			\
+		up(&hba->host_sem);					\
+		return -EBUSY;						\
+	}								\
+	if (ufshcd_is_temp_attrs(QUERY_ATTR_IDN##_uname)) {		\
+		if (!ufshcd_is_temp_notif_allowed(hba)) {		\
+			up(&hba->host_sem);				\
+			return -EOPNOTSUPP;				\
+		}							\
+	}								\
+	ufshcd_rpm_get_sync(hba);					\
+	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;						\
+	}								\
+	dec_value = value;						\
+	if (ufshcd_is_temp_attrs(QUERY_ATTR_IDN##_uname)) {		\
+		if (!ufshcd_temp_legal(hba, QUERY_ATTR_IDN##_uname,	\
+				       value)) {			\
+			ret = -EINVAL;					\
+			goto out;					\
+		}							\
+		dec_value -= 80;					\
+	}								\
+	ret = sysfs_emit(buf, "%d\n", dec_value);			\
+out:									\
+	up(&hba->host_sem);						\
+	return ret;							\
+}									\
+static DEVICE_ATTR_RO(_name)
+
 #define UFS_ATTRIBUTE(_name, _uname)					\
 static ssize_t _name##_show(struct device *dev,				\
 	struct device_attribute *attr, char *buf)			\
@@ -1100,6 +1180,9 @@ UFS_ATTRIBUTE(wb_avail_buf, _AVAIL_WB_BUFF_SIZE);
 UFS_ATTRIBUTE(wb_life_time_est, _WB_BUFF_LIFE_TIME_EST);
 UFS_ATTRIBUTE(wb_cur_buf, _CURR_WB_BUFF_SIZE);
 
+UFS_ATTRIBUTE_DEC(case_rough_temp, _CASE_ROUGH_TEMP);
+UFS_ATTRIBUTE_DEC(high_temp_bound, _HIGH_TEMP_BOUND);
+UFS_ATTRIBUTE_DEC(low_temp_bound, _LOW_TEMP_BOUND);
 
 static struct attribute *ufs_sysfs_attributes[] = {
 	&dev_attr_boot_lun_enabled.attr,
@@ -1119,6 +1202,9 @@ static struct attribute *ufs_sysfs_attributes[] = {
 	&dev_attr_ffu_status.attr,
 	&dev_attr_psa_state.attr,
 	&dev_attr_psa_data_size.attr,
+	&dev_attr_case_rough_temp.attr,
+	&dev_attr_high_temp_bound.attr,
+	&dev_attr_low_temp_bound.attr,
 	&dev_attr_wb_flush_status.attr,
 	&dev_attr_wb_avail_buf.attr,
 	&dev_attr_wb_life_time_est.attr,
diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h
index 4f2a2fe0c84a..03d08fc1bd68 100644
--- a/drivers/scsi/ufs/ufs.h
+++ b/drivers/scsi/ufs/ufs.h
@@ -152,6 +152,9 @@ enum attr_idn {
 	QUERY_ATTR_IDN_PSA_STATE		= 0x15,
 	QUERY_ATTR_IDN_PSA_DATA_SIZE		= 0x16,
 	QUERY_ATTR_IDN_REF_CLK_GATING_WAIT_TIME	= 0x17,
+	QUERY_ATTR_IDN_CASE_ROUGH_TEMP		= 0x18,
+	QUERY_ATTR_IDN_HIGH_TEMP_BOUND		= 0x19,
+	QUERY_ATTR_IDN_LOW_TEMP_BOUND		= 0x1A,
 	QUERY_ATTR_IDN_WB_FLUSH_STATUS	        = 0x1C,
 	QUERY_ATTR_IDN_AVAIL_WB_BUFF_SIZE       = 0x1D,
 	QUERY_ATTR_IDN_WB_BUFF_LIFE_TIME_EST    = 0x1E,
-- 
2.17.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ