All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v5 00/11] ufs: sysfs: read-only access to device
@ 2018-02-06 16:06 Stanislav Nijnikov
  2018-02-06 16:06 ` [PATCH v5 01/11] scsi: ufs: sysfs: attribute group for existing sysfs entries Stanislav Nijnikov
                   ` (10 more replies)
  0 siblings, 11 replies; 19+ messages in thread
From: Stanislav Nijnikov @ 2018-02-06 16:06 UTC (permalink / raw)
  To: linux-scsi, linux-kernel, gregkh, jaegeuk
  Cc: alex.lemberg, Stanislav Nijnikov

This patch introduces sysfs entries that will provide read-only access to
device management data that could be received with UFS query requests.
User-space applications will be able to read UFS device descriptors,
flags and attributes. This will allow to get full UFS device configuration
and its status. The descriptors are provided as set of files representing
its parameters. The flags are using "true"/"false" representation of
their value. The attributes are shown as hexadecimal value. The
descriptors, attributes and flags are placed in separate subfolders under
the UFS device sysfs entry (/sys/bus/platform/drivers/ufshcd/*/). The
string descriptor subfolder contains five string descriptors defined by
UFS specification 2.1. The LUN specific descriptor and attribute are 
placed under corresponding SCSI device sysfs entries
(/sys/class/scsi_device/*/device/).
In addition the patch presents an additional field in the
scsi_host_template structure - struct attribute_group **sdev_group.
This field allows to define groups of attributes. It will provide an
ability to use binary attributes in addition to device attributes and
to group them under subfolders if necessary.

Changelog:
v4 -> v5
Added "scsi: " to clarify the patch naming
The scsi: ufs: sysfs: unit descriptor was split to two patches
"scsi: host template attribute groups" and "scsi: ufs: sysfs: unit
descriptor"
The "const" modificator was added to the sdev_groups member type and
all corresponding data structures. The type conversions in the relative
calls of sysfs_create_groups/sysfs_remove_groups were cleared.
The ufs_desc_param_size enumeration was replaced with numeric constants
The UFS_LUN_ATTRIBUTE macro was removed
The be*_to_cpu function calls were replaced with corresponding 
get_unaligned_be* calls
The legal information was cut leaving only the SPDX line and the
copyright information

v3 -> v4
Additional patch that introduces default attributes group for the
existing ufs sysfs entries (rpm_lvl and spm_lvl)
The ufs_sysfs_read_desc_param function calls to ufshcd_read_desc_param
insted of ufshcd_query_descriptor_retry to avoid code duplication.
The code was updated to remove the checkpatch error "ERROR: Macros 
with complex values should be enclosed in parentheses"
Added "_" to macros parameters to remove "#undef DEVICE_CLASS"
The legal information was updated to satisfy the SPDX requirements
The date in Documentation/ABI/testing/sysfs-driver-ufs was updated.

v2 -> v3
The Makefile is updated to make ufs-sysfs.c part of the ufshcd module.
The unnecessary EXPORT_SYMBOL were removed
Added a legal info header to the new files
The date in Documentation/ABI/testing/sysfs-driver-ufs was updated.

v1 -> v2
Provided additional description for the changes

Stanislav Nijnikov (11):
  scsi: ufs: sysfs: attribute group for existing sysfs entries.
  scsi: ufs: sysfs: device descriptor
  scsi: ufs: sysfs: interconnect descriptor
  scsi: ufs: sysfs: geometry descriptor
  scsi: ufs: sysfs: health descriptor
  scsi: ufs: sysfs: power descriptor
  scsi: ufs: sysfs: string descriptors
  scsi: host template attribute groups
  scsi: ufs: sysfs: unit descriptor
  scsi: ufs: sysfs: flags
  scsi: ufs: sysfs: attributes

 Documentation/ABI/testing/sysfs-driver-ufs | 804 +++++++++++++++++++++++++++++
 drivers/scsi/scsi_sysfs.c                  |  12 +
 drivers/scsi/ufs/Makefile                  |   3 +-
 drivers/scsi/ufs/ufs-sysfs.c               | 737 ++++++++++++++++++++++++++
 drivers/scsi/ufs/ufs-sysfs.h               |  17 +
 drivers/scsi/ufs/ufs.h                     | 115 ++++-
 drivers/scsi/ufs/ufshcd.c                  | 218 ++------
 drivers/scsi/ufs/ufshcd.h                  |  34 ++
 include/scsi/scsi_host.h                   |   6 +
 9 files changed, 1755 insertions(+), 191 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-driver-ufs
 create mode 100644 drivers/scsi/ufs/ufs-sysfs.c
 create mode 100644 drivers/scsi/ufs/ufs-sysfs.h

-- 
2.7.4

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH v5 01/11] scsi: ufs: sysfs: attribute group for existing sysfs entries.
  2018-02-06 16:06 [PATCH v5 00/11] ufs: sysfs: read-only access to device Stanislav Nijnikov
@ 2018-02-06 16:06 ` Stanislav Nijnikov
  2018-02-12  1:06   ` Jaegeuk Kim
  2018-02-06 16:06 ` [PATCH v5 02/11] scsi: ufs: sysfs: device descriptor Stanislav Nijnikov
                   ` (9 subsequent siblings)
  10 siblings, 1 reply; 19+ messages in thread
From: Stanislav Nijnikov @ 2018-02-06 16:06 UTC (permalink / raw)
  To: linux-scsi, linux-kernel, gregkh, jaegeuk
  Cc: alex.lemberg, Stanislav Nijnikov

This patch introduces attribute group to show existing sysfs entries.

Signed-off-by: Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
---
 drivers/scsi/ufs/Makefile    |   3 +-
 drivers/scsi/ufs/ufs-sysfs.c | 156 +++++++++++++++++++++++++++++++++++++++++++
 drivers/scsi/ufs/ufs-sysfs.h |  14 ++++
 drivers/scsi/ufs/ufshcd.c    | 156 ++-----------------------------------------
 drivers/scsi/ufs/ufshcd.h    |   2 +
 5 files changed, 178 insertions(+), 153 deletions(-)
 create mode 100644 drivers/scsi/ufs/ufs-sysfs.c
 create mode 100644 drivers/scsi/ufs/ufs-sysfs.h

diff --git a/drivers/scsi/ufs/Makefile b/drivers/scsi/ufs/Makefile
index 9310c6c..918f579 100644
--- a/drivers/scsi/ufs/Makefile
+++ b/drivers/scsi/ufs/Makefile
@@ -3,6 +3,7 @@
 obj-$(CONFIG_SCSI_UFS_DWC_TC_PCI) += tc-dwc-g210-pci.o ufshcd-dwc.o tc-dwc-g210.o
 obj-$(CONFIG_SCSI_UFS_DWC_TC_PLATFORM) += tc-dwc-g210-pltfrm.o ufshcd-dwc.o tc-dwc-g210.o
 obj-$(CONFIG_SCSI_UFS_QCOM) += ufs-qcom.o
-obj-$(CONFIG_SCSI_UFSHCD) += ufshcd.o
+obj-$(CONFIG_SCSI_UFSHCD) += ufshcd-core.o
+ufshcd-core-objs := ufshcd.o ufs-sysfs.o
 obj-$(CONFIG_SCSI_UFSHCD_PCI) += ufshcd-pci.o
 obj-$(CONFIG_SCSI_UFSHCD_PLATFORM) += ufshcd-pltfrm.o
diff --git a/drivers/scsi/ufs/ufs-sysfs.c b/drivers/scsi/ufs/ufs-sysfs.c
new file mode 100644
index 0000000..ce8dcb6
--- /dev/null
+++ b/drivers/scsi/ufs/ufs-sysfs.c
@@ -0,0 +1,156 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (C) 2018 Western Digital Corporation
+
+#include <linux/err.h>
+#include <linux/string.h>
+
+#include "ufs-sysfs.h"
+
+static const char *ufschd_uic_link_state_to_string(
+			enum uic_link_state state)
+{
+	switch (state) {
+	case UIC_LINK_OFF_STATE:	return "OFF";
+	case UIC_LINK_ACTIVE_STATE:	return "ACTIVE";
+	case UIC_LINK_HIBERN8_STATE:	return "HIBERN8";
+	default:			return "UNKNOWN";
+	}
+}
+
+static const char *ufschd_ufs_dev_pwr_mode_to_string(
+			enum ufs_dev_pwr_mode state)
+{
+	switch (state) {
+	case UFS_ACTIVE_PWR_MODE:	return "ACTIVE";
+	case UFS_SLEEP_PWR_MODE:	return "SLEEP";
+	case UFS_POWERDOWN_PWR_MODE:	return "POWERDOWN";
+	default:			return "UNKNOWN";
+	}
+}
+
+static inline ssize_t ufs_sysfs_pm_lvl_store(struct device *dev,
+					     struct device_attribute *attr,
+					     const char *buf, size_t count,
+					     bool rpm)
+{
+	struct ufs_hba *hba = dev_get_drvdata(dev);
+	unsigned long flags, value;
+
+	if (kstrtoul(buf, 0, &value))
+		return -EINVAL;
+
+	if (value >= UFS_PM_LVL_MAX)
+		return -EINVAL;
+
+	spin_lock_irqsave(hba->host->host_lock, flags);
+	if (rpm)
+		hba->rpm_lvl = value;
+	else
+		hba->spm_lvl = value;
+	spin_unlock_irqrestore(hba->host->host_lock, flags);
+	return count;
+}
+
+static ssize_t rpm_lvl_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct ufs_hba *hba = dev_get_drvdata(dev);
+	int curr_len;
+	u8 lvl;
+
+	curr_len = snprintf(buf, PAGE_SIZE,
+			    "\nCurrent Runtime PM level [%d] => dev_state [%s] link_state [%s]\n",
+			    hba->rpm_lvl,
+			    ufschd_ufs_dev_pwr_mode_to_string(
+				ufs_pm_lvl_states[hba->rpm_lvl].dev_state),
+			    ufschd_uic_link_state_to_string(
+				ufs_pm_lvl_states[hba->rpm_lvl].link_state));
+
+	curr_len += snprintf((buf + curr_len), (PAGE_SIZE - curr_len),
+			     "\nAll available Runtime PM levels info:\n");
+	for (lvl = UFS_PM_LVL_0; lvl < UFS_PM_LVL_MAX; lvl++)
+		curr_len += snprintf((buf + curr_len), (PAGE_SIZE - curr_len),
+				     "\tRuntime PM level [%d] => dev_state [%s] link_state [%s]\n",
+				    lvl,
+				    ufschd_ufs_dev_pwr_mode_to_string(
+					ufs_pm_lvl_states[lvl].dev_state),
+				    ufschd_uic_link_state_to_string(
+					ufs_pm_lvl_states[lvl].link_state));
+
+	return curr_len;
+}
+
+static ssize_t rpm_lvl_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	return ufs_sysfs_pm_lvl_store(dev, attr, buf, count, true);
+}
+
+static ssize_t spm_lvl_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct ufs_hba *hba = dev_get_drvdata(dev);
+	int curr_len;
+	u8 lvl;
+
+	curr_len = snprintf(buf, PAGE_SIZE,
+			    "\nCurrent System PM level [%d] => dev_state [%s] link_state [%s]\n",
+			    hba->spm_lvl,
+			    ufschd_ufs_dev_pwr_mode_to_string(
+				ufs_pm_lvl_states[hba->spm_lvl].dev_state),
+			    ufschd_uic_link_state_to_string(
+				ufs_pm_lvl_states[hba->spm_lvl].link_state));
+
+	curr_len += snprintf((buf + curr_len), (PAGE_SIZE - curr_len),
+			     "\nAll available System PM levels info:\n");
+	for (lvl = UFS_PM_LVL_0; lvl < UFS_PM_LVL_MAX; lvl++)
+		curr_len += snprintf((buf + curr_len), (PAGE_SIZE - curr_len),
+				     "\tSystem PM level [%d] => dev_state [%s] link_state [%s]\n",
+				    lvl,
+				    ufschd_ufs_dev_pwr_mode_to_string(
+					ufs_pm_lvl_states[lvl].dev_state),
+				    ufschd_uic_link_state_to_string(
+					ufs_pm_lvl_states[lvl].link_state));
+
+	return curr_len;
+}
+
+static ssize_t spm_lvl_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	return ufs_sysfs_pm_lvl_store(dev, attr, buf, count, false);
+}
+
+static DEVICE_ATTR_RW(rpm_lvl);
+static DEVICE_ATTR_RW(spm_lvl);
+
+static struct attribute *ufs_sysfs_ufshcd_attrs[] = {
+	&dev_attr_rpm_lvl.attr,
+	&dev_attr_spm_lvl.attr,
+	NULL
+};
+
+static const struct attribute_group ufs_sysfs_default_group = {
+	.attrs = ufs_sysfs_ufshcd_attrs,
+};
+
+static const struct attribute_group *ufs_sysfs_groups[] = {
+	&ufs_sysfs_default_group,
+	NULL,
+};
+
+void ufs_sysfs_add_nodes(struct device *dev)
+{
+	int ret;
+
+	ret = sysfs_create_groups(&dev->kobj, ufs_sysfs_groups);
+	if (ret)
+		dev_err(dev,
+			"%s: sysfs groups creation failed (err = %d)\n",
+			__func__, ret);
+}
+
+void ufs_sysfs_remove_nodes(struct device *dev)
+{
+	sysfs_remove_groups(&dev->kobj, ufs_sysfs_groups);
+}
diff --git a/drivers/scsi/ufs/ufs-sysfs.h b/drivers/scsi/ufs/ufs-sysfs.h
new file mode 100644
index 0000000..4a984ca
--- /dev/null
+++ b/drivers/scsi/ufs/ufs-sysfs.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0-only
+ * Copyright (C) 2018 Western Digital Corporation
+ */
+
+#ifndef __UFS_SYSFS_H__
+#define __UFS_SYSFS_H__
+
+#include <linux/sysfs.h>
+
+#include "ufshcd.h"
+
+void ufs_sysfs_add_nodes(struct device *dev);
+void ufs_sysfs_remove_nodes(struct device *dev);
+#endif
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index a355d98..e7621a0a 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -44,6 +44,7 @@
 #include "ufshcd.h"
 #include "ufs_quirks.h"
 #include "unipro.h"
+#include "ufs-sysfs.h"
 
 #define CREATE_TRACE_POINTS
 #include <trace/events/ufs.h>
@@ -150,7 +151,7 @@ enum {
 #define ufshcd_is_ufs_dev_poweroff(h) \
 	((h)->curr_dev_pwr_mode == UFS_POWERDOWN_PWR_MODE)
 
-static struct ufs_pm_lvl_states ufs_pm_lvl_states[] = {
+struct ufs_pm_lvl_states ufs_pm_lvl_states[] = {
 	{UFS_ACTIVE_PWR_MODE, UIC_LINK_ACTIVE_STATE},
 	{UFS_ACTIVE_PWR_MODE, UIC_LINK_HIBERN8_STATE},
 	{UFS_SLEEP_PWR_MODE, UIC_LINK_ACTIVE_STATE},
@@ -813,28 +814,6 @@ static inline bool ufshcd_is_hba_active(struct ufs_hba *hba)
 		? false : true;
 }
 
-static const char *ufschd_uic_link_state_to_string(
-			enum uic_link_state state)
-{
-	switch (state) {
-	case UIC_LINK_OFF_STATE:	return "OFF";
-	case UIC_LINK_ACTIVE_STATE:	return "ACTIVE";
-	case UIC_LINK_HIBERN8_STATE:	return "HIBERN8";
-	default:			return "UNKNOWN";
-	}
-}
-
-static const char *ufschd_ufs_dev_pwr_mode_to_string(
-			enum ufs_dev_pwr_mode state)
-{
-	switch (state) {
-	case UFS_ACTIVE_PWR_MODE:	return "ACTIVE";
-	case UFS_SLEEP_PWR_MODE:	return "SLEEP";
-	case UFS_POWERDOWN_PWR_MODE:	return "POWERDOWN";
-	default:			return "UNKNOWN";
-	}
-}
-
 u32 ufshcd_get_local_unipro_ver(struct ufs_hba *hba)
 {
 	/* HCI version 1.0 and 1.1 supports UniPro 1.41 */
@@ -7585,133 +7564,6 @@ int ufshcd_runtime_idle(struct ufs_hba *hba)
 }
 EXPORT_SYMBOL(ufshcd_runtime_idle);
 
-static inline ssize_t ufshcd_pm_lvl_store(struct device *dev,
-					   struct device_attribute *attr,
-					   const char *buf, size_t count,
-					   bool rpm)
-{
-	struct ufs_hba *hba = dev_get_drvdata(dev);
-	unsigned long flags, value;
-
-	if (kstrtoul(buf, 0, &value))
-		return -EINVAL;
-
-	if (value >= UFS_PM_LVL_MAX)
-		return -EINVAL;
-
-	spin_lock_irqsave(hba->host->host_lock, flags);
-	if (rpm)
-		hba->rpm_lvl = value;
-	else
-		hba->spm_lvl = value;
-	spin_unlock_irqrestore(hba->host->host_lock, flags);
-	return count;
-}
-
-static ssize_t ufshcd_rpm_lvl_show(struct device *dev,
-		struct device_attribute *attr, char *buf)
-{
-	struct ufs_hba *hba = dev_get_drvdata(dev);
-	int curr_len;
-	u8 lvl;
-
-	curr_len = snprintf(buf, PAGE_SIZE,
-			    "\nCurrent Runtime PM level [%d] => dev_state [%s] link_state [%s]\n",
-			    hba->rpm_lvl,
-			    ufschd_ufs_dev_pwr_mode_to_string(
-				ufs_pm_lvl_states[hba->rpm_lvl].dev_state),
-			    ufschd_uic_link_state_to_string(
-				ufs_pm_lvl_states[hba->rpm_lvl].link_state));
-
-	curr_len += snprintf((buf + curr_len), (PAGE_SIZE - curr_len),
-			     "\nAll available Runtime PM levels info:\n");
-	for (lvl = UFS_PM_LVL_0; lvl < UFS_PM_LVL_MAX; lvl++)
-		curr_len += snprintf((buf + curr_len), (PAGE_SIZE - curr_len),
-				     "\tRuntime PM level [%d] => dev_state [%s] link_state [%s]\n",
-				    lvl,
-				    ufschd_ufs_dev_pwr_mode_to_string(
-					ufs_pm_lvl_states[lvl].dev_state),
-				    ufschd_uic_link_state_to_string(
-					ufs_pm_lvl_states[lvl].link_state));
-
-	return curr_len;
-}
-
-static ssize_t ufshcd_rpm_lvl_store(struct device *dev,
-		struct device_attribute *attr, const char *buf, size_t count)
-{
-	return ufshcd_pm_lvl_store(dev, attr, buf, count, true);
-}
-
-static void ufshcd_add_rpm_lvl_sysfs_nodes(struct ufs_hba *hba)
-{
-	hba->rpm_lvl_attr.show = ufshcd_rpm_lvl_show;
-	hba->rpm_lvl_attr.store = ufshcd_rpm_lvl_store;
-	sysfs_attr_init(&hba->rpm_lvl_attr.attr);
-	hba->rpm_lvl_attr.attr.name = "rpm_lvl";
-	hba->rpm_lvl_attr.attr.mode = 0644;
-	if (device_create_file(hba->dev, &hba->rpm_lvl_attr))
-		dev_err(hba->dev, "Failed to create sysfs for rpm_lvl\n");
-}
-
-static ssize_t ufshcd_spm_lvl_show(struct device *dev,
-		struct device_attribute *attr, char *buf)
-{
-	struct ufs_hba *hba = dev_get_drvdata(dev);
-	int curr_len;
-	u8 lvl;
-
-	curr_len = snprintf(buf, PAGE_SIZE,
-			    "\nCurrent System PM level [%d] => dev_state [%s] link_state [%s]\n",
-			    hba->spm_lvl,
-			    ufschd_ufs_dev_pwr_mode_to_string(
-				ufs_pm_lvl_states[hba->spm_lvl].dev_state),
-			    ufschd_uic_link_state_to_string(
-				ufs_pm_lvl_states[hba->spm_lvl].link_state));
-
-	curr_len += snprintf((buf + curr_len), (PAGE_SIZE - curr_len),
-			     "\nAll available System PM levels info:\n");
-	for (lvl = UFS_PM_LVL_0; lvl < UFS_PM_LVL_MAX; lvl++)
-		curr_len += snprintf((buf + curr_len), (PAGE_SIZE - curr_len),
-				     "\tSystem PM level [%d] => dev_state [%s] link_state [%s]\n",
-				    lvl,
-				    ufschd_ufs_dev_pwr_mode_to_string(
-					ufs_pm_lvl_states[lvl].dev_state),
-				    ufschd_uic_link_state_to_string(
-					ufs_pm_lvl_states[lvl].link_state));
-
-	return curr_len;
-}
-
-static ssize_t ufshcd_spm_lvl_store(struct device *dev,
-		struct device_attribute *attr, const char *buf, size_t count)
-{
-	return ufshcd_pm_lvl_store(dev, attr, buf, count, false);
-}
-
-static void ufshcd_add_spm_lvl_sysfs_nodes(struct ufs_hba *hba)
-{
-	hba->spm_lvl_attr.show = ufshcd_spm_lvl_show;
-	hba->spm_lvl_attr.store = ufshcd_spm_lvl_store;
-	sysfs_attr_init(&hba->spm_lvl_attr.attr);
-	hba->spm_lvl_attr.attr.name = "spm_lvl";
-	hba->spm_lvl_attr.attr.mode = 0644;
-	if (device_create_file(hba->dev, &hba->spm_lvl_attr))
-		dev_err(hba->dev, "Failed to create sysfs for spm_lvl\n");
-}
-
-static inline void ufshcd_add_sysfs_nodes(struct ufs_hba *hba)
-{
-	ufshcd_add_rpm_lvl_sysfs_nodes(hba);
-	ufshcd_add_spm_lvl_sysfs_nodes(hba);
-}
-
-static inline void ufshcd_remove_sysfs_nodes(struct ufs_hba *hba)
-{
-	device_remove_file(hba->dev, &hba->rpm_lvl_attr);
-	device_remove_file(hba->dev, &hba->spm_lvl_attr);
-}
-
 /**
  * ufshcd_shutdown - shutdown routine
  * @hba: per adapter instance
@@ -7749,7 +7601,7 @@ EXPORT_SYMBOL(ufshcd_shutdown);
  */
 void ufshcd_remove(struct ufs_hba *hba)
 {
-	ufshcd_remove_sysfs_nodes(hba);
+	ufs_sysfs_remove_nodes(hba->dev);
 	scsi_remove_host(hba->host);
 	/* disable interrupts */
 	ufshcd_disable_intr(hba, hba->intr_mask);
@@ -7996,7 +7848,7 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
 	ufshcd_set_ufs_dev_active(hba);
 
 	async_schedule(ufshcd_async_scan, hba);
-	ufshcd_add_sysfs_nodes(hba);
+	ufs_sysfs_add_nodes(hba->dev);
 
 	return 0;
 
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index 1332e54..53e2779 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -985,4 +985,6 @@ static inline void ufshcd_vops_dbg_register_dump(struct ufs_hba *hba)
 		hba->vops->dbg_register_dump(hba);
 }
 
+extern struct ufs_pm_lvl_states ufs_pm_lvl_states[];
+
 #endif /* End of Header */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v5 02/11] scsi: ufs: sysfs: device descriptor
  2018-02-06 16:06 [PATCH v5 00/11] ufs: sysfs: read-only access to device Stanislav Nijnikov
  2018-02-06 16:06 ` [PATCH v5 01/11] scsi: ufs: sysfs: attribute group for existing sysfs entries Stanislav Nijnikov
@ 2018-02-06 16:06 ` Stanislav Nijnikov
  2018-02-12  1:07   ` Jaegeuk Kim
  2018-02-06 16:06 ` [PATCH v5 03/11] scsi: ufs: sysfs: interconnect descriptor Stanislav Nijnikov
                   ` (8 subsequent siblings)
  10 siblings, 1 reply; 19+ messages in thread
From: Stanislav Nijnikov @ 2018-02-06 16:06 UTC (permalink / raw)
  To: linux-scsi, linux-kernel, gregkh, jaegeuk
  Cc: alex.lemberg, Stanislav Nijnikov

This patch introduces a sysfs group entry for the UFS device descriptor
parameters. The group adds "device_descriptor" folder under the UFS driver
sysfs entry (/sys/bus/platform/drivers/ufshcd/*). The parameters are shown
as hexadecimal numbers. The full information about the parameters could be
found at UFS specifications 2.1.

Signed-off-by: Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
---
 Documentation/ABI/testing/sysfs-driver-ufs | 223 +++++++++++++++++++++++++++++
 drivers/scsi/ufs/ufs-sysfs.c               | 116 +++++++++++++++
 drivers/scsi/ufs/ufs.h                     |   8 ++
 drivers/scsi/ufs/ufshcd.c                  |  12 +-
 drivers/scsi/ufs/ufshcd.h                  |   6 +
 5 files changed, 359 insertions(+), 6 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-driver-ufs

diff --git a/Documentation/ABI/testing/sysfs-driver-ufs b/Documentation/ABI/testing/sysfs-driver-ufs
new file mode 100644
index 0000000..8da7b84
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-driver-ufs
@@ -0,0 +1,223 @@
+What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/device_type
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the device type. This is one of the UFS
+		device descriptor parameters. The full information about
+		the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/device_class
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the device class. This is one of the UFS
+		device descriptor parameters. The full information about
+		the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/device_sub_class
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the UFS storage subclass. This is one of
+		the UFS device descriptor parameters. The full information
+		about the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/protocol
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the protocol supported by an UFS device.
+		This is one of the UFS device descriptor parameters.
+		The full information about the descriptor could be found
+		at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/number_of_luns
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows number of logical units. This is one of
+		the UFS device descriptor parameters. The full information
+		about the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/number_of_wluns
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows number of well known logical units.
+		This is one of the UFS device descriptor parameters.
+		The full information about the descriptor could be found
+		at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/boot_enable
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows value that indicates whether the device is
+		enabled for boot. This is one of the UFS device descriptor
+		parameters. The full information about the descriptor could
+		be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/descriptor_access_enable
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows value that indicates whether the device
+		descriptor could be read after partial initialization phase
+		of the boot sequence. This is one of the UFS device descriptor
+		parameters. The full information about the descriptor could
+		be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/initial_power_mode
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows value that defines the power mode after
+		device initialization or hardware reset. This is one of
+		the UFS device descriptor parameters. The full information
+		about the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/high_priority_lun
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the high priority lun. This is one of
+		the UFS device descriptor parameters. The full information
+		about the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/secure_removal_type
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the secure removal type. This is one of
+		the UFS device descriptor parameters. The full information
+		about the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/support_security_lun
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows whether the security lun is supported.
+		This is one of the UFS device descriptor parameters.
+		The full information about the descriptor could be found
+		at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/bkops_termination_latency
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the background operations termination
+		latency. This is one of the UFS device descriptor parameters.
+		The full information about the descriptor could be found
+		at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/initial_active_icc_level
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the initial active ICC level. This is one
+		of the UFS device descriptor parameters. The full information
+		about the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/specification_version
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the specification version. This is one
+		of the UFS device descriptor parameters. The full information
+		about the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/manufacturing_date
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the manufacturing date in BCD format.
+		This is one of the UFS device descriptor parameters.
+		The full information about the descriptor could be found
+		at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/manufacturer_id
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the manufacturee ID. This is one of the
+		UFS device descriptor parameters. The full information about
+		the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/rtt_capability
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the maximum number of outstanding RTTs
+		supported by the device. This is one of the UFS device
+		descriptor parameters. The full information about
+		the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/rtc_update
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the frequency and method of the realtime
+		clock update. This is one of the UFS device descriptor
+		parameters. The full information about the descriptor
+		could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/ufs_features
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows which features are supported by the device.
+		This is one of the UFS device descriptor parameters.
+		The full information about the descriptor could be
+		found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/ffu_timeout
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the FFU timeout. This is one of the
+		UFS device descriptor parameters. The full information
+		about the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/queue_depth
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the device queue depth. This is one of the
+		UFS device descriptor parameters. The full information
+		about the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/device_version
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the device version. This is one of the
+		UFS device descriptor parameters. The full information
+		about the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/number_of_secure_wpa
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows number of secure write protect areas
+		supported by the device. This is one of the UFS device
+		descriptor parameters. The full information about
+		the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/psa_max_data_size
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the maximum amount of data that may be
+		written during the pre-soldering phase of the PSA flow.
+		This is one of the UFS device descriptor parameters.
+		The full information about the descriptor could be found
+		at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/psa_state_timeout
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the command maximum timeout for a change
+		in PSA state. This is one of the UFS device descriptor
+		parameters. The full information about the descriptor could
+		be found at UFS specifications 2.1.
+		The file is read only.
diff --git a/drivers/scsi/ufs/ufs-sysfs.c b/drivers/scsi/ufs/ufs-sysfs.c
index ce8dcb6..aa2779a 100644
--- a/drivers/scsi/ufs/ufs-sysfs.c
+++ b/drivers/scsi/ufs/ufs-sysfs.c
@@ -3,7 +3,9 @@
 
 #include <linux/err.h>
 #include <linux/string.h>
+#include <asm/unaligned.h>
 
+#include "ufs.h"
 #include "ufs-sysfs.h"
 
 static const char *ufschd_uic_link_state_to_string(
@@ -134,8 +136,122 @@ static const struct attribute_group ufs_sysfs_default_group = {
 	.attrs = ufs_sysfs_ufshcd_attrs,
 };
 
+static ssize_t ufs_sysfs_read_desc_param(struct ufs_hba *hba,
+				  enum desc_idn desc_id,
+				  u8 desc_index,
+				  u8 param_offset,
+				  u8 *sysfs_buf,
+				  u8 param_size)
+{
+	u8 desc_buf[8] = {0};
+	int ret;
+
+	if (param_size > 8)
+		return -EINVAL;
+
+	ret = ufshcd_read_desc_param(hba, desc_id, desc_index,
+				param_offset, desc_buf, param_size);
+	if (ret)
+		return -EINVAL;
+	switch (param_size) {
+	case 1:
+		ret = sprintf(sysfs_buf, "0x%02X\n", *desc_buf);
+		break;
+	case 2:
+		ret = sprintf(sysfs_buf, "0x%04X\n",
+			get_unaligned_be16(desc_buf));
+		break;
+	case 4:
+		ret = sprintf(sysfs_buf, "0x%08X\n",
+			get_unaligned_be32(desc_buf));
+		break;
+	case 8:
+		ret = sprintf(sysfs_buf, "0x%016llX\n",
+			get_unaligned_be64(desc_buf));
+		break;
+	}
+
+	return ret;
+}
+
+#define UFS_DESC_PARAM(_name, _puname, _duname, _size)			\
+static ssize_t _name##_show(struct device *dev,				\
+	struct device_attribute *attr, char *buf)			\
+{									\
+	struct ufs_hba *hba = dev_get_drvdata(dev);			\
+	return ufs_sysfs_read_desc_param(hba, QUERY_DESC_IDN_##_duname,	\
+		0, _duname##_DESC_PARAM##_puname, buf, _size);		\
+}									\
+static DEVICE_ATTR_RO(_name)
+
+#define UFS_DEVICE_DESC_PARAM(_name, _uname, _size)			\
+	UFS_DESC_PARAM(_name, _uname, DEVICE, _size)
+
+UFS_DEVICE_DESC_PARAM(device_type, _DEVICE_TYPE, 1);
+UFS_DEVICE_DESC_PARAM(device_class, _DEVICE_CLASS, 1);
+UFS_DEVICE_DESC_PARAM(device_sub_class, _DEVICE_SUB_CLASS, 1);
+UFS_DEVICE_DESC_PARAM(protocol, _PRTCL, 1);
+UFS_DEVICE_DESC_PARAM(number_of_luns, _NUM_LU, 1);
+UFS_DEVICE_DESC_PARAM(number_of_wluns, _NUM_WLU, 1);
+UFS_DEVICE_DESC_PARAM(boot_enable, _BOOT_ENBL, 1);
+UFS_DEVICE_DESC_PARAM(descriptor_access_enable, _DESC_ACCSS_ENBL, 1);
+UFS_DEVICE_DESC_PARAM(initial_power_mode, _INIT_PWR_MODE, 1);
+UFS_DEVICE_DESC_PARAM(high_priority_lun, _HIGH_PR_LUN, 1);
+UFS_DEVICE_DESC_PARAM(secure_removal_type, _SEC_RMV_TYPE, 1);
+UFS_DEVICE_DESC_PARAM(support_security_lun, _SEC_LU, 1);
+UFS_DEVICE_DESC_PARAM(bkops_termination_latency, _BKOP_TERM_LT, 1);
+UFS_DEVICE_DESC_PARAM(initial_active_icc_level, _ACTVE_ICC_LVL, 1);
+UFS_DEVICE_DESC_PARAM(specification_version, _SPEC_VER, 2);
+UFS_DEVICE_DESC_PARAM(manufacturing_date, _MANF_DATE, 2);
+UFS_DEVICE_DESC_PARAM(manufacturer_id, _MANF_ID, 2);
+UFS_DEVICE_DESC_PARAM(rtt_capability, _RTT_CAP, 1);
+UFS_DEVICE_DESC_PARAM(rtc_update, _FRQ_RTC, 2);
+UFS_DEVICE_DESC_PARAM(ufs_features, _UFS_FEAT, 1);
+UFS_DEVICE_DESC_PARAM(ffu_timeout, _FFU_TMT, 1);
+UFS_DEVICE_DESC_PARAM(queue_depth, _Q_DPTH, 1);
+UFS_DEVICE_DESC_PARAM(device_version, _DEV_VER, 2);
+UFS_DEVICE_DESC_PARAM(number_of_secure_wpa, _NUM_SEC_WPA, 1);
+UFS_DEVICE_DESC_PARAM(psa_max_data_size, _PSA_MAX_DATA, 4);
+UFS_DEVICE_DESC_PARAM(psa_state_timeout, _PSA_TMT, 1);
+
+static struct attribute *ufs_sysfs_device_descriptor[] = {
+	&dev_attr_device_type.attr,
+	&dev_attr_device_class.attr,
+	&dev_attr_device_sub_class.attr,
+	&dev_attr_protocol.attr,
+	&dev_attr_number_of_luns.attr,
+	&dev_attr_number_of_wluns.attr,
+	&dev_attr_boot_enable.attr,
+	&dev_attr_descriptor_access_enable.attr,
+	&dev_attr_initial_power_mode.attr,
+	&dev_attr_high_priority_lun.attr,
+	&dev_attr_secure_removal_type.attr,
+	&dev_attr_support_security_lun.attr,
+	&dev_attr_bkops_termination_latency.attr,
+	&dev_attr_initial_active_icc_level.attr,
+	&dev_attr_specification_version.attr,
+	&dev_attr_manufacturing_date.attr,
+	&dev_attr_manufacturer_id.attr,
+	&dev_attr_rtt_capability.attr,
+	&dev_attr_rtc_update.attr,
+	&dev_attr_ufs_features.attr,
+	&dev_attr_ffu_timeout.attr,
+	&dev_attr_queue_depth.attr,
+	&dev_attr_device_version.attr,
+	&dev_attr_number_of_secure_wpa.attr,
+	&dev_attr_psa_max_data_size.attr,
+	&dev_attr_psa_state_timeout.attr,
+	NULL,
+};
+
+static const struct attribute_group ufs_sysfs_device_descriptor_group = {
+	.name = "device_descriptor",
+	.attrs = ufs_sysfs_device_descriptor,
+};
+
 static const struct attribute_group *ufs_sysfs_groups[] = {
 	&ufs_sysfs_default_group,
+	&ufs_sysfs_device_descriptor_group,
 	NULL,
 };
 
diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h
index 54deeb7..6ae1e08 100644
--- a/drivers/scsi/ufs/ufs.h
+++ b/drivers/scsi/ufs/ufs.h
@@ -220,6 +220,14 @@ enum device_desc_param {
 	DEVICE_DESC_PARAM_UD_LEN		= 0x1B,
 	DEVICE_DESC_PARAM_RTT_CAP		= 0x1C,
 	DEVICE_DESC_PARAM_FRQ_RTC		= 0x1D,
+	DEVICE_DESC_PARAM_UFS_FEAT		= 0x1F,
+	DEVICE_DESC_PARAM_FFU_TMT		= 0x20,
+	DEVICE_DESC_PARAM_Q_DPTH		= 0x21,
+	DEVICE_DESC_PARAM_DEV_VER		= 0x22,
+	DEVICE_DESC_PARAM_NUM_SEC_WPA		= 0x24,
+	DEVICE_DESC_PARAM_PSA_MAX_DATA		= 0x25,
+	DEVICE_DESC_PARAM_PSA_TMT		= 0x29,
+	DEVICE_DESC_PARAM_PRDCT_REV		= 0x2A,
 };
 
 /*
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index e7621a0a..540a431 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -2989,12 +2989,12 @@ EXPORT_SYMBOL(ufshcd_map_desc_id_to_length);
  *
  * Return 0 in case of success, non-zero otherwise
  */
-static int ufshcd_read_desc_param(struct ufs_hba *hba,
-				  enum desc_idn desc_id,
-				  int desc_index,
-				  u8 param_offset,
-				  u8 *param_read_buf,
-				  u8 param_size)
+int ufshcd_read_desc_param(struct ufs_hba *hba,
+			   enum desc_idn desc_id,
+			   int desc_index,
+			   u8 param_offset,
+			   u8 *param_read_buf,
+			   u8 param_size)
 {
 	int ret;
 	u8 *desc_buf;
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index 53e2779..38c307d 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -841,6 +841,12 @@ static inline bool ufshcd_is_hs_mode(struct ufs_pa_layer_attr *pwr_info)
 }
 
 /* Expose Query-Request API */
+int ufshcd_read_desc_param(struct ufs_hba *hba,
+			   enum desc_idn desc_id,
+			   int desc_index,
+			   u8 param_offset,
+			   u8 *param_read_buf,
+			   u8 param_size);
 int ufshcd_query_flag(struct ufs_hba *hba, enum query_opcode opcode,
 	enum flag_idn idn, bool *flag_res);
 int ufshcd_hold(struct ufs_hba *hba, bool async);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v5 03/11] scsi: ufs: sysfs: interconnect descriptor
  2018-02-06 16:06 [PATCH v5 00/11] ufs: sysfs: read-only access to device Stanislav Nijnikov
  2018-02-06 16:06 ` [PATCH v5 01/11] scsi: ufs: sysfs: attribute group for existing sysfs entries Stanislav Nijnikov
  2018-02-06 16:06 ` [PATCH v5 02/11] scsi: ufs: sysfs: device descriptor Stanislav Nijnikov
@ 2018-02-06 16:06 ` Stanislav Nijnikov
  2018-02-06 16:06 ` [PATCH v5 04/11] scsi: ufs: sysfs: geometry descriptor Stanislav Nijnikov
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 19+ messages in thread
From: Stanislav Nijnikov @ 2018-02-06 16:06 UTC (permalink / raw)
  To: linux-scsi, linux-kernel, gregkh, jaegeuk
  Cc: alex.lemberg, Stanislav Nijnikov

This patch introduces a sysfs group entry for the UFS interconnect
descriptor parameters. The group adds "interconnect_descriptor" folder
under the UFS driver sysfs entry (/sys/bus/platform/drivers/ufshcd/*).
The parameters are shown as hexadecimal numbers. The full information
about the parameters could be found at UFS specifications 2.1.

Signed-off-by: Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 Documentation/ABI/testing/sysfs-driver-ufs | 19 +++++++++++++++++++
 drivers/scsi/ufs/ufs-sysfs.c               | 18 ++++++++++++++++++
 drivers/scsi/ufs/ufs.h                     |  8 ++++++++
 3 files changed, 45 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-driver-ufs b/Documentation/ABI/testing/sysfs-driver-ufs
index 8da7b84..099e6fa 100644
--- a/Documentation/ABI/testing/sysfs-driver-ufs
+++ b/Documentation/ABI/testing/sysfs-driver-ufs
@@ -221,3 +221,22 @@ Description:	This file shows the command maximum timeout for a change
 		parameters. The full information about the descriptor could
 		be found at UFS specifications 2.1.
 		The file is read only.
+
+
+What:		/sys/bus/platform/drivers/ufshcd/*/interconnect_descriptor/unipro_version
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the MIPI UniPro version number in BCD format.
+		This is one of the UFS interconnect descriptor parameters.
+		The full information about the descriptor could be found at
+		UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/interconnect_descriptor/mphy_version
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the MIPI M-PHY version number in BCD format.
+		This is one of the UFS interconnect descriptor parameters.
+		The full information about the descriptor could be found at
+		UFS specifications 2.1.
+		The file is read only.
diff --git a/drivers/scsi/ufs/ufs-sysfs.c b/drivers/scsi/ufs/ufs-sysfs.c
index aa2779a..e9e6ee4 100644
--- a/drivers/scsi/ufs/ufs-sysfs.c
+++ b/drivers/scsi/ufs/ufs-sysfs.c
@@ -249,9 +249,27 @@ static const struct attribute_group ufs_sysfs_device_descriptor_group = {
 	.attrs = ufs_sysfs_device_descriptor,
 };
 
+#define UFS_INTERCONNECT_DESC_PARAM(_name, _uname, _size)		\
+	UFS_DESC_PARAM(_name, _uname, INTERCONNECT, _size)
+
+UFS_INTERCONNECT_DESC_PARAM(unipro_version, _UNIPRO_VER, 2);
+UFS_INTERCONNECT_DESC_PARAM(mphy_version, _MPHY_VER, 2);
+
+static struct attribute *ufs_sysfs_interconnect_descriptor[] = {
+	&dev_attr_unipro_version.attr,
+	&dev_attr_mphy_version.attr,
+	NULL,
+};
+
+static const struct attribute_group ufs_sysfs_interconnect_descriptor_group = {
+	.name = "interconnect_descriptor",
+	.attrs = ufs_sysfs_interconnect_descriptor,
+};
+
 static const struct attribute_group *ufs_sysfs_groups[] = {
 	&ufs_sysfs_default_group,
 	&ufs_sysfs_device_descriptor_group,
+	&ufs_sysfs_interconnect_descriptor_group,
 	NULL,
 };
 
diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h
index 6ae1e08..773c049 100644
--- a/drivers/scsi/ufs/ufs.h
+++ b/drivers/scsi/ufs/ufs.h
@@ -230,6 +230,14 @@ enum device_desc_param {
 	DEVICE_DESC_PARAM_PRDCT_REV		= 0x2A,
 };
 
+/* Interconnect descriptor parameters offsets in bytes*/
+enum interconnect_desc_param {
+	INTERCONNECT_DESC_PARAM_LEN		= 0x0,
+	INTERCONNECT_DESC_PARAM_TYPE		= 0x1,
+	INTERCONNECT_DESC_PARAM_UNIPRO_VER	= 0x2,
+	INTERCONNECT_DESC_PARAM_MPHY_VER	= 0x4,
+};
+
 /*
  * Logical Unit Write Protect
  * 00h: LU not write protected
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v5 04/11] scsi: ufs: sysfs: geometry descriptor
  2018-02-06 16:06 [PATCH v5 00/11] ufs: sysfs: read-only access to device Stanislav Nijnikov
                   ` (2 preceding siblings ...)
  2018-02-06 16:06 ` [PATCH v5 03/11] scsi: ufs: sysfs: interconnect descriptor Stanislav Nijnikov
@ 2018-02-06 16:06 ` Stanislav Nijnikov
  2018-02-06 16:06 ` [PATCH v5 05/11] scsi: ufs: sysfs: health descriptor Stanislav Nijnikov
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 19+ messages in thread
From: Stanislav Nijnikov @ 2018-02-06 16:06 UTC (permalink / raw)
  To: linux-scsi, linux-kernel, gregkh, jaegeuk
  Cc: alex.lemberg, Stanislav Nijnikov

This patch introduces a sysfs group entry for the UFS geometry descriptor
parameters. The group adds "geometry_descriptor" folder under the UFS
driver sysfs entry (/sys/bus/platform/drivers/ufshcd/*). The parameters
are shown as hexadecimal numbers. The full information about the parameters
could be found at UFS specifications 2.1.

Signed-off-by: Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 Documentation/ABI/testing/sysfs-driver-ufs | 173 +++++++++++++++++++++++++++++
 drivers/scsi/ufs/ufs-sysfs.c               |  84 ++++++++++++++
 drivers/scsi/ufs/ufs.h                     |  36 ++++++
 3 files changed, 293 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-driver-ufs b/Documentation/ABI/testing/sysfs-driver-ufs
index 099e6fa..6ea7613 100644
--- a/Documentation/ABI/testing/sysfs-driver-ufs
+++ b/Documentation/ABI/testing/sysfs-driver-ufs
@@ -240,3 +240,176 @@ Description:	This file shows the MIPI M-PHY version number in BCD format.
 		The full information about the descriptor could be found at
 		UFS specifications 2.1.
 		The file is read only.
+
+
+What:		/sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/raw_device_capacity
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the total memory quantity available to
+		the user to configure the device logical units. This is one
+		of the UFS geometry descriptor parameters. The full
+		information about the descriptor could be found at
+		UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/max_number_of_luns
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the maximum number of logical units
+		supported by the UFS device. This is one of the UFS
+		geometry descriptor parameters. The full information about
+		the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/segment_size
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the segment size. This is one of the UFS
+		geometry descriptor parameters. The full information about
+		the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/allocation_unit_size
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the allocation unit size. This is one of
+		the UFS geometry descriptor parameters. The full information
+		about the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/min_addressable_block_size
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the minimum addressable block size. This
+		is one of the UFS geometry descriptor parameters. The full
+		information about the descriptor could be found at UFS
+		specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/optimal_read_block_size
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the optimal read block size. This is one
+		of the UFS geometry descriptor parameters. The full
+		information about the descriptor could be found at UFS
+		specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/optimal_write_block_size
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the optimal write block size. This is one
+		of the UFS geometry descriptor parameters. The full
+		information about the descriptor could be found at UFS
+		specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/max_in_buffer_size
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the maximum data-in buffer size. This
+		is one of the UFS geometry descriptor parameters. The full
+		information about the descriptor could be found at UFS
+		specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/max_out_buffer_size
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the maximum data-out buffer size. This
+		is one of the UFS geometry descriptor parameters. The full
+		information about the descriptor could be found at UFS
+		specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/rpmb_rw_size
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the maximum number of RPMB frames allowed
+		in Security Protocol In/Out. This is one of the UFS geometry
+		descriptor parameters. The full information about the
+		descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/dyn_capacity_resource_policy
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the dynamic capacity resource policy. This
+		is one of the UFS geometry descriptor parameters. The full
+		information about the descriptor could be found at
+		UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/data_ordering
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows support for out-of-order data transfer.
+		This is one of the UFS geometry descriptor parameters.
+		The full information about the descriptor could be found at
+		UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/max_number_of_contexts
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows maximum available number of contexts which
+		are supported by the device. This is one of the UFS geometry
+		descriptor parameters. The full information about the
+		descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/sys_data_tag_unit_size
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows system data tag unit size. This is one of
+		the UFS geometry descriptor parameters. The full information
+		about the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/sys_data_tag_resource_size
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows maximum storage area size allocated by
+		the device to handle system data by the tagging mechanism.
+		This is one of the UFS geometry descriptor parameters.
+		The full information about the descriptor could be found at
+		UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/secure_removal_types
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows supported secure removal types. This is
+		one of the UFS geometry descriptor parameters. The full
+		information about the descriptor could be found at
+		UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/memory_types
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows supported memory types. This is one of
+		the UFS geometry descriptor parameters. The full
+		information about the descriptor could be found at
+		UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/*_memory_max_alloc_units
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the maximum number of allocation units for
+		different memory types (system code, non persistent,
+		enhanced type 1-4). This is one of the UFS geometry
+		descriptor parameters. The full information about the
+		descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/*_memory_capacity_adjustment_factor
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the memory capacity adjustment factor for
+		different memory types (system code, non persistent,
+		enhanced type 1-4). This is one of the UFS geometry
+		descriptor parameters. The full information about the
+		descriptor could be found at UFS specifications 2.1.
+		The file is read only.
diff --git a/drivers/scsi/ufs/ufs-sysfs.c b/drivers/scsi/ufs/ufs-sysfs.c
index e9e6ee4..7dfa8fb 100644
--- a/drivers/scsi/ufs/ufs-sysfs.c
+++ b/drivers/scsi/ufs/ufs-sysfs.c
@@ -266,10 +266,94 @@ static const struct attribute_group ufs_sysfs_interconnect_descriptor_group = {
 	.attrs = ufs_sysfs_interconnect_descriptor,
 };
 
+#define UFS_GEOMETRY_DESC_PARAM(_name, _uname, _size)			\
+	UFS_DESC_PARAM(_name, _uname, GEOMETRY, _size)
+
+UFS_GEOMETRY_DESC_PARAM(raw_device_capacity, _DEV_CAP, 8);
+UFS_GEOMETRY_DESC_PARAM(max_number_of_luns, _MAX_NUM_LUN, 1);
+UFS_GEOMETRY_DESC_PARAM(segment_size, _SEG_SIZE, 4);
+UFS_GEOMETRY_DESC_PARAM(allocation_unit_size, _ALLOC_UNIT_SIZE, 1);
+UFS_GEOMETRY_DESC_PARAM(min_addressable_block_size, _MIN_BLK_SIZE, 1);
+UFS_GEOMETRY_DESC_PARAM(optimal_read_block_size, _OPT_RD_BLK_SIZE, 1);
+UFS_GEOMETRY_DESC_PARAM(optimal_write_block_size, _OPT_WR_BLK_SIZE, 1);
+UFS_GEOMETRY_DESC_PARAM(max_in_buffer_size, _MAX_IN_BUF_SIZE, 1);
+UFS_GEOMETRY_DESC_PARAM(max_out_buffer_size, _MAX_OUT_BUF_SIZE, 1);
+UFS_GEOMETRY_DESC_PARAM(rpmb_rw_size, _RPMB_RW_SIZE, 1);
+UFS_GEOMETRY_DESC_PARAM(dyn_capacity_resource_policy, _DYN_CAP_RSRC_PLC, 1);
+UFS_GEOMETRY_DESC_PARAM(data_ordering, _DATA_ORDER, 1);
+UFS_GEOMETRY_DESC_PARAM(max_number_of_contexts, _MAX_NUM_CTX, 1);
+UFS_GEOMETRY_DESC_PARAM(sys_data_tag_unit_size, _TAG_UNIT_SIZE, 1);
+UFS_GEOMETRY_DESC_PARAM(sys_data_tag_resource_size, _TAG_RSRC_SIZE, 1);
+UFS_GEOMETRY_DESC_PARAM(secure_removal_types, _SEC_RM_TYPES, 1);
+UFS_GEOMETRY_DESC_PARAM(memory_types, _MEM_TYPES, 2);
+UFS_GEOMETRY_DESC_PARAM(sys_code_memory_max_alloc_units,
+	_SCM_MAX_NUM_UNITS, 4);
+UFS_GEOMETRY_DESC_PARAM(sys_code_memory_capacity_adjustment_factor,
+	_SCM_CAP_ADJ_FCTR, 2);
+UFS_GEOMETRY_DESC_PARAM(non_persist_memory_max_alloc_units,
+	_NPM_MAX_NUM_UNITS, 4);
+UFS_GEOMETRY_DESC_PARAM(non_persist_memory_capacity_adjustment_factor,
+	_NPM_CAP_ADJ_FCTR, 2);
+UFS_GEOMETRY_DESC_PARAM(enh1_memory_max_alloc_units,
+	_ENM1_MAX_NUM_UNITS, 4);
+UFS_GEOMETRY_DESC_PARAM(enh1_memory_capacity_adjustment_factor,
+	_ENM1_CAP_ADJ_FCTR, 2);
+UFS_GEOMETRY_DESC_PARAM(enh2_memory_max_alloc_units,
+	_ENM2_MAX_NUM_UNITS, 4);
+UFS_GEOMETRY_DESC_PARAM(enh2_memory_capacity_adjustment_factor,
+	_ENM2_CAP_ADJ_FCTR, 2);
+UFS_GEOMETRY_DESC_PARAM(enh3_memory_max_alloc_units,
+	_ENM3_MAX_NUM_UNITS, 4);
+UFS_GEOMETRY_DESC_PARAM(enh3_memory_capacity_adjustment_factor,
+	_ENM3_CAP_ADJ_FCTR, 2);
+UFS_GEOMETRY_DESC_PARAM(enh4_memory_max_alloc_units,
+	_ENM4_MAX_NUM_UNITS, 4);
+UFS_GEOMETRY_DESC_PARAM(enh4_memory_capacity_adjustment_factor,
+	_ENM4_CAP_ADJ_FCTR, 2);
+
+static struct attribute *ufs_sysfs_geometry_descriptor[] = {
+	&dev_attr_raw_device_capacity.attr,
+	&dev_attr_max_number_of_luns.attr,
+	&dev_attr_segment_size.attr,
+	&dev_attr_allocation_unit_size.attr,
+	&dev_attr_min_addressable_block_size.attr,
+	&dev_attr_optimal_read_block_size.attr,
+	&dev_attr_optimal_write_block_size.attr,
+	&dev_attr_max_in_buffer_size.attr,
+	&dev_attr_max_out_buffer_size.attr,
+	&dev_attr_rpmb_rw_size.attr,
+	&dev_attr_dyn_capacity_resource_policy.attr,
+	&dev_attr_data_ordering.attr,
+	&dev_attr_max_number_of_contexts.attr,
+	&dev_attr_sys_data_tag_unit_size.attr,
+	&dev_attr_sys_data_tag_resource_size.attr,
+	&dev_attr_secure_removal_types.attr,
+	&dev_attr_memory_types.attr,
+	&dev_attr_sys_code_memory_max_alloc_units.attr,
+	&dev_attr_sys_code_memory_capacity_adjustment_factor.attr,
+	&dev_attr_non_persist_memory_max_alloc_units.attr,
+	&dev_attr_non_persist_memory_capacity_adjustment_factor.attr,
+	&dev_attr_enh1_memory_max_alloc_units.attr,
+	&dev_attr_enh1_memory_capacity_adjustment_factor.attr,
+	&dev_attr_enh2_memory_max_alloc_units.attr,
+	&dev_attr_enh2_memory_capacity_adjustment_factor.attr,
+	&dev_attr_enh3_memory_max_alloc_units.attr,
+	&dev_attr_enh3_memory_capacity_adjustment_factor.attr,
+	&dev_attr_enh4_memory_max_alloc_units.attr,
+	&dev_attr_enh4_memory_capacity_adjustment_factor.attr,
+	NULL,
+};
+
+static const struct attribute_group ufs_sysfs_geometry_descriptor_group = {
+	.name = "geometry_descriptor",
+	.attrs = ufs_sysfs_geometry_descriptor,
+};
+
 static const struct attribute_group *ufs_sysfs_groups[] = {
 	&ufs_sysfs_default_group,
 	&ufs_sysfs_device_descriptor_group,
 	&ufs_sysfs_interconnect_descriptor_group,
+	&ufs_sysfs_geometry_descriptor_group,
 	NULL,
 };
 
diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h
index 773c049..04d41c8 100644
--- a/drivers/scsi/ufs/ufs.h
+++ b/drivers/scsi/ufs/ufs.h
@@ -238,6 +238,42 @@ enum interconnect_desc_param {
 	INTERCONNECT_DESC_PARAM_MPHY_VER	= 0x4,
 };
 
+/* Geometry descriptor parameters offsets in bytes*/
+enum geometry_desc_param {
+	GEOMETRY_DESC_PARAM_LEN			= 0x0,
+	GEOMETRY_DESC_PARAM_TYPE		= 0x1,
+	GEOMETRY_DESC_PARAM_DEV_CAP		= 0x4,
+	GEOMETRY_DESC_PARAM_MAX_NUM_LUN		= 0xC,
+	GEOMETRY_DESC_PARAM_SEG_SIZE		= 0xD,
+	GEOMETRY_DESC_PARAM_ALLOC_UNIT_SIZE	= 0x11,
+	GEOMETRY_DESC_PARAM_MIN_BLK_SIZE	= 0x12,
+	GEOMETRY_DESC_PARAM_OPT_RD_BLK_SIZE	= 0x13,
+	GEOMETRY_DESC_PARAM_OPT_WR_BLK_SIZE	= 0x14,
+	GEOMETRY_DESC_PARAM_MAX_IN_BUF_SIZE	= 0x15,
+	GEOMETRY_DESC_PARAM_MAX_OUT_BUF_SIZE	= 0x16,
+	GEOMETRY_DESC_PARAM_RPMB_RW_SIZE	= 0x17,
+	GEOMETRY_DESC_PARAM_DYN_CAP_RSRC_PLC	= 0x18,
+	GEOMETRY_DESC_PARAM_DATA_ORDER		= 0x19,
+	GEOMETRY_DESC_PARAM_MAX_NUM_CTX		= 0x1A,
+	GEOMETRY_DESC_PARAM_TAG_UNIT_SIZE	= 0x1B,
+	GEOMETRY_DESC_PARAM_TAG_RSRC_SIZE	= 0x1C,
+	GEOMETRY_DESC_PARAM_SEC_RM_TYPES	= 0x1D,
+	GEOMETRY_DESC_PARAM_MEM_TYPES		= 0x1E,
+	GEOMETRY_DESC_PARAM_SCM_MAX_NUM_UNITS	= 0x20,
+	GEOMETRY_DESC_PARAM_SCM_CAP_ADJ_FCTR	= 0x24,
+	GEOMETRY_DESC_PARAM_NPM_MAX_NUM_UNITS	= 0x26,
+	GEOMETRY_DESC_PARAM_NPM_CAP_ADJ_FCTR	= 0x2A,
+	GEOMETRY_DESC_PARAM_ENM1_MAX_NUM_UNITS	= 0x2C,
+	GEOMETRY_DESC_PARAM_ENM1_CAP_ADJ_FCTR	= 0x30,
+	GEOMETRY_DESC_PARAM_ENM2_MAX_NUM_UNITS	= 0x32,
+	GEOMETRY_DESC_PARAM_ENM2_CAP_ADJ_FCTR	= 0x36,
+	GEOMETRY_DESC_PARAM_ENM3_MAX_NUM_UNITS	= 0x38,
+	GEOMETRY_DESC_PARAM_ENM3_CAP_ADJ_FCTR	= 0x3C,
+	GEOMETRY_DESC_PARAM_ENM4_MAX_NUM_UNITS	= 0x3E,
+	GEOMETRY_DESC_PARAM_ENM4_CAP_ADJ_FCTR	= 0x42,
+	GEOMETRY_DESC_PARAM_OPT_LOG_BLK_SIZE	= 0x44,
+};
+
 /*
  * Logical Unit Write Protect
  * 00h: LU not write protected
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v5 05/11] scsi: ufs: sysfs: health descriptor
  2018-02-06 16:06 [PATCH v5 00/11] ufs: sysfs: read-only access to device Stanislav Nijnikov
                   ` (3 preceding siblings ...)
  2018-02-06 16:06 ` [PATCH v5 04/11] scsi: ufs: sysfs: geometry descriptor Stanislav Nijnikov
@ 2018-02-06 16:06 ` Stanislav Nijnikov
  2018-02-06 16:06 ` [PATCH v5 06/11] scsi: ufs: sysfs: power descriptor Stanislav Nijnikov
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 19+ messages in thread
From: Stanislav Nijnikov @ 2018-02-06 16:06 UTC (permalink / raw)
  To: linux-scsi, linux-kernel, gregkh, jaegeuk
  Cc: alex.lemberg, Stanislav Nijnikov

This patch introduces a sysfs group entry for the UFS health descriptor
parameters. The group adds "health_descriptor" folder under the UFS driver
sysfs entry (/sys/bus/platform/drivers/ufshcd/*). The parameters are shown
as hexadecimal numbers. The full information about the parameters could be
found at UFS specifications 2.1.

Signed-off-by: Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 Documentation/ABI/testing/sysfs-driver-ufs | 28 ++++++++++++++++++++++++++++
 drivers/scsi/ufs/ufs-sysfs.c               | 20 ++++++++++++++++++++
 drivers/scsi/ufs/ufs.h                     | 11 +++++++++++
 drivers/scsi/ufs/ufshcd.c                  |  8 ++++++++
 drivers/scsi/ufs/ufshcd.h                  |  1 +
 5 files changed, 68 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-driver-ufs b/Documentation/ABI/testing/sysfs-driver-ufs
index 6ea7613..ddb012b 100644
--- a/Documentation/ABI/testing/sysfs-driver-ufs
+++ b/Documentation/ABI/testing/sysfs-driver-ufs
@@ -413,3 +413,31 @@ Description:	This file shows the memory capacity adjustment factor for
 		descriptor parameters. The full information about the
 		descriptor could be found at UFS specifications 2.1.
 		The file is read only.
+
+
+What:		/sys/bus/platform/drivers/ufshcd/*/health_descriptor/eol_info
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows preend of life information. This is one
+		of the UFS health descriptor parameters. The full
+		information about the descriptor could be found at
+		UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/health_descriptor/life_time_estimation_a
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows indication of the device life time
+		(method a). This is one of the UFS health descriptor
+		parameters. The full information about the descriptor
+		could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/health_descriptor/life_time_estimation_b
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows indication of the device life time
+		(method b). This is one of the UFS health descriptor
+		parameters. The full information about the descriptor
+		could be found at UFS specifications 2.1.
+		The file is read only.
diff --git a/drivers/scsi/ufs/ufs-sysfs.c b/drivers/scsi/ufs/ufs-sysfs.c
index 7dfa8fb..3279514 100644
--- a/drivers/scsi/ufs/ufs-sysfs.c
+++ b/drivers/scsi/ufs/ufs-sysfs.c
@@ -349,11 +349,31 @@ static const struct attribute_group ufs_sysfs_geometry_descriptor_group = {
 	.attrs = ufs_sysfs_geometry_descriptor,
 };
 
+#define UFS_HEALTH_DESC_PARAM(_name, _uname, _size)			\
+	UFS_DESC_PARAM(_name, _uname, HEALTH, _size)
+
+UFS_HEALTH_DESC_PARAM(eol_info, _EOL_INFO, 1);
+UFS_HEALTH_DESC_PARAM(life_time_estimation_a, _LIFE_TIME_EST_A, 1);
+UFS_HEALTH_DESC_PARAM(life_time_estimation_b, _LIFE_TIME_EST_B, 1);
+
+static struct attribute *ufs_sysfs_health_descriptor[] = {
+	&dev_attr_eol_info.attr,
+	&dev_attr_life_time_estimation_a.attr,
+	&dev_attr_life_time_estimation_b.attr,
+	NULL,
+};
+
+static const struct attribute_group ufs_sysfs_health_descriptor_group = {
+	.name = "health_descriptor",
+	.attrs = ufs_sysfs_health_descriptor,
+};
+
 static const struct attribute_group *ufs_sysfs_groups[] = {
 	&ufs_sysfs_default_group,
 	&ufs_sysfs_device_descriptor_group,
 	&ufs_sysfs_interconnect_descriptor_group,
 	&ufs_sysfs_geometry_descriptor_group,
+	&ufs_sysfs_health_descriptor_group,
 	NULL,
 };
 
diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h
index 04d41c8..6bfeedb 100644
--- a/drivers/scsi/ufs/ufs.h
+++ b/drivers/scsi/ufs/ufs.h
@@ -154,6 +154,7 @@ enum desc_idn {
 	QUERY_DESC_IDN_RFU_1		= 0x6,
 	QUERY_DESC_IDN_GEOMETRY		= 0x7,
 	QUERY_DESC_IDN_POWER		= 0x8,
+	QUERY_DESC_IDN_HEALTH           = 0x9,
 	QUERY_DESC_IDN_MAX,
 };
 
@@ -169,6 +170,7 @@ enum ufs_desc_def_size {
 	QUERY_DESC_INTERCONNECT_DEF_SIZE	= 0x06,
 	QUERY_DESC_GEOMETRY_DEF_SIZE		= 0x44,
 	QUERY_DESC_POWER_DEF_SIZE		= 0x62,
+	QUERY_DESC_HEALTH_DEF_SIZE		= 0x25,
 };
 
 /* Unit descriptor parameters offsets in bytes*/
@@ -274,6 +276,15 @@ enum geometry_desc_param {
 	GEOMETRY_DESC_PARAM_OPT_LOG_BLK_SIZE	= 0x44,
 };
 
+/* Health descriptor parameters offsets in bytes*/
+enum health_desc_param {
+	HEALTH_DESC_PARAM_LEN			= 0x0,
+	HEALTH_DESC_PARAM_TYPE			= 0x1,
+	HEALTH_DESC_PARAM_EOL_INFO		= 0x2,
+	HEALTH_DESC_PARAM_LIFE_TIME_EST_A	= 0x3,
+	HEALTH_DESC_PARAM_LIFE_TIME_EST_B	= 0x4,
+};
+
 /*
  * Logical Unit Write Protect
  * 00h: LU not write protected
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 540a431..b88fcf7 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -2966,6 +2966,9 @@ int ufshcd_map_desc_id_to_length(struct ufs_hba *hba,
 	case QUERY_DESC_IDN_STRING:
 		*desc_len = QUERY_DESC_MAX_SIZE;
 		break;
+	case QUERY_DESC_IDN_HEALTH:
+		*desc_len = hba->desc_size.hlth_desc;
+		break;
 	case QUERY_DESC_IDN_RFU_0:
 	case QUERY_DESC_IDN_RFU_1:
 		*desc_len = 0;
@@ -6277,6 +6280,10 @@ static void ufshcd_init_desc_sizes(struct ufs_hba *hba)
 		&hba->desc_size.geom_desc);
 	if (err)
 		hba->desc_size.geom_desc = QUERY_DESC_GEOMETRY_DEF_SIZE;
+	err = ufshcd_read_desc_length(hba, QUERY_DESC_IDN_HEALTH, 0,
+		&hba->desc_size.hlth_desc);
+	if (err)
+		hba->desc_size.hlth_desc = QUERY_DESC_HEALTH_DEF_SIZE;
 }
 
 static void ufshcd_def_desc_sizes(struct ufs_hba *hba)
@@ -6287,6 +6294,7 @@ static void ufshcd_def_desc_sizes(struct ufs_hba *hba)
 	hba->desc_size.conf_desc = QUERY_DESC_CONFIGURATION_DEF_SIZE;
 	hba->desc_size.unit_desc = QUERY_DESC_UNIT_DEF_SIZE;
 	hba->desc_size.geom_desc = QUERY_DESC_GEOMETRY_DEF_SIZE;
+	hba->desc_size.hlth_desc = QUERY_DESC_HEALTH_DEF_SIZE;
 }
 
 /**
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index 38c307d..515c6e6 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -229,6 +229,7 @@ struct ufs_desc_size {
 	int interc_desc;
 	int unit_desc;
 	int conf_desc;
+	int hlth_desc;
 };
 
 /**
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v5 06/11] scsi: ufs: sysfs: power descriptor
  2018-02-06 16:06 [PATCH v5 00/11] ufs: sysfs: read-only access to device Stanislav Nijnikov
                   ` (4 preceding siblings ...)
  2018-02-06 16:06 ` [PATCH v5 05/11] scsi: ufs: sysfs: health descriptor Stanislav Nijnikov
@ 2018-02-06 16:06 ` Stanislav Nijnikov
  2018-02-06 16:06 ` [PATCH v5 07/11] scsi: ufs: sysfs: string descriptors Stanislav Nijnikov
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 19+ messages in thread
From: Stanislav Nijnikov @ 2018-02-06 16:06 UTC (permalink / raw)
  To: linux-scsi, linux-kernel, gregkh, jaegeuk
  Cc: alex.lemberg, Stanislav Nijnikov

This patch introduces a sysfs group entry for the UFS power descriptor
parameters. The group adds "power_descriptor" folder under the UFS driver
sysfs entry (/sys/bus/platform/drivers/ufshcd/*). The parameters are shown
as hexadecimal numbers. The full information about the parameters could be
found at UFS specifications 2.1.

Signed-off-by: Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 Documentation/ABI/testing/sysfs-driver-ufs |  10 +++
 drivers/scsi/ufs/ufs-sysfs.c               | 117 +++++++++++++++++++++++++++++
 2 files changed, 127 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-driver-ufs b/Documentation/ABI/testing/sysfs-driver-ufs
index ddb012b..7460566 100644
--- a/Documentation/ABI/testing/sysfs-driver-ufs
+++ b/Documentation/ABI/testing/sysfs-driver-ufs
@@ -441,3 +441,13 @@ Description:	This file shows indication of the device life time
 		parameters. The full information about the descriptor
 		could be found at UFS specifications 2.1.
 		The file is read only.
+
+
+What:		/sys/bus/platform/drivers/ufshcd/*/power_descriptor/active_icc_levels_vcc*
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows maximum VCC, VCCQ and VCCQ2 value for
+		active ICC levels from 0 to 15. This is one of the UFS
+		power descriptor parameters. The full information about
+		the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
diff --git a/drivers/scsi/ufs/ufs-sysfs.c b/drivers/scsi/ufs/ufs-sysfs.c
index 3279514..43f965a 100644
--- a/drivers/scsi/ufs/ufs-sysfs.c
+++ b/drivers/scsi/ufs/ufs-sysfs.c
@@ -368,12 +368,129 @@ static const struct attribute_group ufs_sysfs_health_descriptor_group = {
 	.attrs = ufs_sysfs_health_descriptor,
 };
 
+#define UFS_POWER_DESC_PARAM(_name, _uname, _index)			\
+static ssize_t _name##_index##_show(struct device *dev,			\
+	struct device_attribute *attr, char *buf)			\
+{									\
+	struct ufs_hba *hba = dev_get_drvdata(dev);			\
+	return ufs_sysfs_read_desc_param(hba, QUERY_DESC_IDN_POWER, 0,	\
+		PWR_DESC##_uname##_0 + _index * 2, buf, 2);		\
+}									\
+static DEVICE_ATTR_RO(_name##_index)
+
+UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 0);
+UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 1);
+UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 2);
+UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 3);
+UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 4);
+UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 5);
+UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 6);
+UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 7);
+UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 8);
+UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 9);
+UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 10);
+UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 11);
+UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 12);
+UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 13);
+UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 14);
+UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 15);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 0);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 1);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 2);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 3);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 4);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 5);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 6);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 7);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 8);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 9);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 10);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 11);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 12);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 13);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 14);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 15);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 0);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 1);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 2);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 3);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 4);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 5);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 6);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 7);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 8);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 9);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 10);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 11);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 12);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 13);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 14);
+UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 15);
+
+static struct attribute *ufs_sysfs_power_descriptor[] = {
+	&dev_attr_active_icc_levels_vcc0.attr,
+	&dev_attr_active_icc_levels_vcc1.attr,
+	&dev_attr_active_icc_levels_vcc2.attr,
+	&dev_attr_active_icc_levels_vcc3.attr,
+	&dev_attr_active_icc_levels_vcc4.attr,
+	&dev_attr_active_icc_levels_vcc5.attr,
+	&dev_attr_active_icc_levels_vcc6.attr,
+	&dev_attr_active_icc_levels_vcc7.attr,
+	&dev_attr_active_icc_levels_vcc8.attr,
+	&dev_attr_active_icc_levels_vcc9.attr,
+	&dev_attr_active_icc_levels_vcc10.attr,
+	&dev_attr_active_icc_levels_vcc11.attr,
+	&dev_attr_active_icc_levels_vcc12.attr,
+	&dev_attr_active_icc_levels_vcc13.attr,
+	&dev_attr_active_icc_levels_vcc14.attr,
+	&dev_attr_active_icc_levels_vcc15.attr,
+	&dev_attr_active_icc_levels_vccq0.attr,
+	&dev_attr_active_icc_levels_vccq1.attr,
+	&dev_attr_active_icc_levels_vccq2.attr,
+	&dev_attr_active_icc_levels_vccq3.attr,
+	&dev_attr_active_icc_levels_vccq4.attr,
+	&dev_attr_active_icc_levels_vccq5.attr,
+	&dev_attr_active_icc_levels_vccq6.attr,
+	&dev_attr_active_icc_levels_vccq7.attr,
+	&dev_attr_active_icc_levels_vccq8.attr,
+	&dev_attr_active_icc_levels_vccq9.attr,
+	&dev_attr_active_icc_levels_vccq10.attr,
+	&dev_attr_active_icc_levels_vccq11.attr,
+	&dev_attr_active_icc_levels_vccq12.attr,
+	&dev_attr_active_icc_levels_vccq13.attr,
+	&dev_attr_active_icc_levels_vccq14.attr,
+	&dev_attr_active_icc_levels_vccq15.attr,
+	&dev_attr_active_icc_levels_vccq20.attr,
+	&dev_attr_active_icc_levels_vccq21.attr,
+	&dev_attr_active_icc_levels_vccq22.attr,
+	&dev_attr_active_icc_levels_vccq23.attr,
+	&dev_attr_active_icc_levels_vccq24.attr,
+	&dev_attr_active_icc_levels_vccq25.attr,
+	&dev_attr_active_icc_levels_vccq26.attr,
+	&dev_attr_active_icc_levels_vccq27.attr,
+	&dev_attr_active_icc_levels_vccq28.attr,
+	&dev_attr_active_icc_levels_vccq29.attr,
+	&dev_attr_active_icc_levels_vccq210.attr,
+	&dev_attr_active_icc_levels_vccq211.attr,
+	&dev_attr_active_icc_levels_vccq212.attr,
+	&dev_attr_active_icc_levels_vccq213.attr,
+	&dev_attr_active_icc_levels_vccq214.attr,
+	&dev_attr_active_icc_levels_vccq215.attr,
+	NULL,
+};
+
+static const struct attribute_group ufs_sysfs_power_descriptor_group = {
+	.name = "power_descriptor",
+	.attrs = ufs_sysfs_power_descriptor,
+};
+
 static const struct attribute_group *ufs_sysfs_groups[] = {
 	&ufs_sysfs_default_group,
 	&ufs_sysfs_device_descriptor_group,
 	&ufs_sysfs_interconnect_descriptor_group,
 	&ufs_sysfs_geometry_descriptor_group,
 	&ufs_sysfs_health_descriptor_group,
+	&ufs_sysfs_power_descriptor_group,
 	NULL,
 };
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v5 07/11] scsi: ufs: sysfs: string descriptors
  2018-02-06 16:06 [PATCH v5 00/11] ufs: sysfs: read-only access to device Stanislav Nijnikov
                   ` (5 preceding siblings ...)
  2018-02-06 16:06 ` [PATCH v5 06/11] scsi: ufs: sysfs: power descriptor Stanislav Nijnikov
@ 2018-02-06 16:06 ` Stanislav Nijnikov
  2018-02-06 16:06 ` [PATCH v5 08/11] scsi: host template attribute groups Stanislav Nijnikov
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 19+ messages in thread
From: Stanislav Nijnikov @ 2018-02-06 16:06 UTC (permalink / raw)
  To: linux-scsi, linux-kernel, gregkh, jaegeuk
  Cc: alex.lemberg, Stanislav Nijnikov

This patch introduces a sysfs group entry for the UFS string descriptors.
The group adds "string_descriptors" folder under the UFS driver
sysfs entry (/sys/bus/platform/drivers/ufshcd/*). The folder will contain
5 files that will show string values defined by the UFS spec:
a manufacturer name, a product name, an OEM id, a serial number and a
product revision.  The full information about the string descriptors
could be found at UFS specifications 2.1.

Signed-off-by: Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 Documentation/ABI/testing/sysfs-driver-ufs | 39 +++++++++++++++++++++
 drivers/scsi/ufs/ufs-sysfs.c               | 56 ++++++++++++++++++++++++++++++
 drivers/scsi/ufs/ufshcd.c                  | 14 ++++----
 drivers/scsi/ufs/ufshcd.h                  |  9 +++++
 4 files changed, 111 insertions(+), 7 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-driver-ufs b/Documentation/ABI/testing/sysfs-driver-ufs
index 7460566..c17a968 100644
--- a/Documentation/ABI/testing/sysfs-driver-ufs
+++ b/Documentation/ABI/testing/sysfs-driver-ufs
@@ -451,3 +451,42 @@ Description:	This file shows maximum VCC, VCCQ and VCCQ2 value for
 		power descriptor parameters. The full information about
 		the descriptor could be found at UFS specifications 2.1.
 		The file is read only.
+
+
+What:		/sys/bus/platform/drivers/ufshcd/*/string_descriptors/manufacturer_name
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file contains a device manufactureer name string.
+		The full information about the descriptor could be found at
+		UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/string_descriptors/product_name
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file contains a product name string. The full information
+		about the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/string_descriptors/oem_id
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file contains a OEM ID string. The full information
+		about the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/string_descriptors/serial_number
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file contains a device serial number string. The full
+		information about the descriptor could be found at
+		UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/string_descriptors/product_revision
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file contains a product revision string. The full
+		information about the descriptor could be found at
+		UFS specifications 2.1.
+		The file is read only.
diff --git a/drivers/scsi/ufs/ufs-sysfs.c b/drivers/scsi/ufs/ufs-sysfs.c
index 43f965a..7130e0d 100644
--- a/drivers/scsi/ufs/ufs-sysfs.c
+++ b/drivers/scsi/ufs/ufs-sysfs.c
@@ -484,6 +484,61 @@ static const struct attribute_group ufs_sysfs_power_descriptor_group = {
 	.attrs = ufs_sysfs_power_descriptor,
 };
 
+#define UFS_STRING_DESCRIPTOR(_name, _pname)				\
+static ssize_t _name##_show(struct device *dev,				\
+	struct device_attribute *attr, char *buf)			\
+{									\
+	u8 index;							\
+	struct ufs_hba *hba = dev_get_drvdata(dev);			\
+	int ret;							\
+	int desc_len = QUERY_DESC_MAX_SIZE;				\
+	u8 *desc_buf;							\
+	desc_buf = kzalloc(QUERY_DESC_MAX_SIZE, GFP_ATOMIC);		\
+	if (!desc_buf)							\
+		return -ENOMEM;						\
+	ret = ufshcd_query_descriptor_retry(hba,			\
+		UPIU_QUERY_OPCODE_READ_DESC, QUERY_DESC_IDN_DEVICE,	\
+		0, 0, desc_buf, &desc_len);				\
+	if (ret) {							\
+		ret = -EINVAL;						\
+		goto out;						\
+	}								\
+	index = desc_buf[DEVICE_DESC_PARAM##_pname];			\
+	memset(desc_buf, 0, QUERY_DESC_MAX_SIZE);			\
+	if (ufshcd_read_string_desc(hba, index, desc_buf,		\
+		QUERY_DESC_MAX_SIZE, true)) {				\
+		ret = -EINVAL;						\
+		goto out;						\
+	}								\
+	ret = snprintf(buf, PAGE_SIZE, "%s\n",				\
+		desc_buf + QUERY_DESC_HDR_SIZE);			\
+out:									\
+	kfree(desc_buf);						\
+	return ret;							\
+}									\
+static DEVICE_ATTR_RO(_name)
+
+UFS_STRING_DESCRIPTOR(manufacturer_name, _MANF_NAME);
+UFS_STRING_DESCRIPTOR(product_name, _PRDCT_NAME);
+UFS_STRING_DESCRIPTOR(oem_id, _OEM_ID);
+UFS_STRING_DESCRIPTOR(serial_number, _SN);
+UFS_STRING_DESCRIPTOR(product_revision, _PRDCT_REV);
+
+static struct attribute *ufs_sysfs_string_descriptors[] = {
+	&dev_attr_manufacturer_name.attr,
+	&dev_attr_product_name.attr,
+	&dev_attr_oem_id.attr,
+	&dev_attr_serial_number.attr,
+	&dev_attr_product_revision.attr,
+	NULL,
+};
+
+static const struct attribute_group ufs_sysfs_string_descriptors_group = {
+	.name = "string_descriptors",
+	.attrs = ufs_sysfs_string_descriptors,
+};
+
+
 static const struct attribute_group *ufs_sysfs_groups[] = {
 	&ufs_sysfs_default_group,
 	&ufs_sysfs_device_descriptor_group,
@@ -491,6 +546,7 @@ static const struct attribute_group *ufs_sysfs_groups[] = {
 	&ufs_sysfs_geometry_descriptor_group,
 	&ufs_sysfs_health_descriptor_group,
 	&ufs_sysfs_power_descriptor_group,
+	&ufs_sysfs_string_descriptors_group,
 	NULL,
 };
 
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index b88fcf7..9cfdd8e 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -2873,11 +2873,11 @@ static int __ufshcd_query_descriptor(struct ufs_hba *hba,
  * The buf_len parameter will contain, on return, the length parameter
  * received on the response.
  */
-static int ufshcd_query_descriptor_retry(struct ufs_hba *hba,
-					 enum query_opcode opcode,
-					 enum desc_idn idn, u8 index,
-					 u8 selector,
-					 u8 *desc_buf, int *buf_len)
+int ufshcd_query_descriptor_retry(struct ufs_hba *hba,
+				  enum query_opcode opcode,
+				  enum desc_idn idn, u8 index,
+				  u8 selector,
+				  u8 *desc_buf, int *buf_len)
 {
 	int err;
 	int retries;
@@ -3093,8 +3093,8 @@ static int ufshcd_read_device_desc(struct ufs_hba *hba, u8 *buf, u32 size)
  * Return 0 in case of success, non-zero otherwise
  */
 #define ASCII_STD true
-static int ufshcd_read_string_desc(struct ufs_hba *hba, int desc_index,
-				   u8 *buf, u32 size, bool ascii)
+int ufshcd_read_string_desc(struct ufs_hba *hba, int desc_index,
+			    u8 *buf, u32 size, bool ascii)
 {
 	int err = 0;
 
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index 515c6e6..2dad9da 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -842,6 +842,12 @@ static inline bool ufshcd_is_hs_mode(struct ufs_pa_layer_attr *pwr_info)
 }
 
 /* Expose Query-Request API */
+int ufshcd_query_descriptor_retry(struct ufs_hba *hba,
+				  enum query_opcode opcode,
+				  enum desc_idn idn, u8 index,
+				  u8 selector,
+				  u8 *desc_buf, int *buf_len);
+
 int ufshcd_read_desc_param(struct ufs_hba *hba,
 			   enum desc_idn desc_id,
 			   int desc_index,
@@ -850,6 +856,9 @@ int ufshcd_read_desc_param(struct ufs_hba *hba,
 			   u8 param_size);
 int ufshcd_query_flag(struct ufs_hba *hba, enum query_opcode opcode,
 	enum flag_idn idn, bool *flag_res);
+int ufshcd_read_string_desc(struct ufs_hba *hba, int desc_index,
+			    u8 *buf, u32 size, bool ascii);
+
 int ufshcd_hold(struct ufs_hba *hba, bool async);
 void ufshcd_release(struct ufs_hba *hba);
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v5 08/11] scsi: host template attribute groups
  2018-02-06 16:06 [PATCH v5 00/11] ufs: sysfs: read-only access to device Stanislav Nijnikov
                   ` (6 preceding siblings ...)
  2018-02-06 16:06 ` [PATCH v5 07/11] scsi: ufs: sysfs: string descriptors Stanislav Nijnikov
@ 2018-02-06 16:06 ` Stanislav Nijnikov
  2018-02-06 19:06   ` Bart Van Assche
  2018-02-06 16:06 ` [PATCH v5 09/11] scsi: ufs: sysfs: unit descriptor Stanislav Nijnikov
                   ` (2 subsequent siblings)
  10 siblings, 1 reply; 19+ messages in thread
From: Stanislav Nijnikov @ 2018-02-06 16:06 UTC (permalink / raw)
  To: linux-scsi, linux-kernel, gregkh, jaegeuk
  Cc: alex.lemberg, Stanislav Nijnikov

The patch introduces an additional field in the scsi_host_template
structure - struct attribute_group **sdev_group.
This field allows to define groups of attributes. It will provide an
ability to use binary attributes as well as device attributes and
to group them under subfolders if necessary.

Signed-off-by: Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/scsi/scsi_sysfs.c | 12 ++++++++++++
 include/scsi/scsi_host.h  |  6 ++++++
 2 files changed, 18 insertions(+)

diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index cbc0fe2..fe5d1cb 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -1309,6 +1309,13 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev)
 		}
 	}
 
+	if (sdev->host->hostt->sdev_groups) {
+		error = sysfs_create_groups(&sdev->sdev_gendev.kobj,
+			sdev->host->hostt->sdev_groups);
+			if (error)
+				return error;
+	}
+
 	scsi_autopm_put_device(sdev);
 	return error;
 }
@@ -1326,6 +1333,11 @@ void __scsi_remove_device(struct scsi_device *sdev)
 	if (sdev->sdev_state == SDEV_DEL)
 		return;
 
+	if (sdev->host->hostt->sdev_groups) {
+		sysfs_remove_groups(&sdev->sdev_gendev.kobj,
+			sdev->host->hostt->sdev_groups);
+	}
+
 	if (sdev->is_visible) {
 		/*
 		 * If scsi_internal_target_block() is running concurrently,
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
index 1a1df0d..1931758 100644
--- a/include/scsi/scsi_host.h
+++ b/include/scsi/scsi_host.h
@@ -477,6 +477,12 @@ struct scsi_host_template {
 	struct device_attribute **sdev_attrs;
 
 	/*
+	 * Pointer to the SCSI device attribute groups for this host,
+	 * NULL terminated.
+	 */
+	const struct attribute_group **sdev_groups;
+
+	/*
 	 * List of hosts per template.
 	 *
 	 * This is only for use by scsi_module.c for legacy templates.
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v5 09/11] scsi: ufs: sysfs: unit descriptor
  2018-02-06 16:06 [PATCH v5 00/11] ufs: sysfs: read-only access to device Stanislav Nijnikov
                   ` (7 preceding siblings ...)
  2018-02-06 16:06 ` [PATCH v5 08/11] scsi: host template attribute groups Stanislav Nijnikov
@ 2018-02-06 16:06 ` Stanislav Nijnikov
  2018-02-06 16:06 ` [PATCH v5 10/11] scsi: ufs: sysfs: flags Stanislav Nijnikov
  2018-02-06 16:06 ` [PATCH v5 11/11] scsi: ufs: sysfs: attributes Stanislav Nijnikov
  10 siblings, 0 replies; 19+ messages in thread
From: Stanislav Nijnikov @ 2018-02-06 16:06 UTC (permalink / raw)
  To: linux-scsi, linux-kernel, gregkh, jaegeuk
  Cc: alex.lemberg, Stanislav Nijnikov

This patch introduces a sysfs group entry for the UFS unit descriptor
parameters. The group adds "unit_descriptor" folder under the corresponding
SCSI device sysfs entry (/sys/class/scsi_device/*/device/). The parameters
are shown as hexadecimal numbers. The full information about the parameters
could be found at UFS specifications 2.1.

Signed-off-by: Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 Documentation/ABI/testing/sysfs-driver-ufs | 108 +++++++++++++++++++++++++++++
 drivers/scsi/ufs/ufs-sysfs.c               |  53 ++++++++++++++
 drivers/scsi/ufs/ufs-sysfs.h               |   2 +
 drivers/scsi/ufs/ufs.h                     |  11 +++
 drivers/scsi/ufs/ufshcd.c                  |  23 ++----
 drivers/scsi/ufs/ufshcd.h                  |  15 ++++
 6 files changed, 196 insertions(+), 16 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-driver-ufs b/Documentation/ABI/testing/sysfs-driver-ufs
index c17a968..57c6a90 100644
--- a/Documentation/ABI/testing/sysfs-driver-ufs
+++ b/Documentation/ABI/testing/sysfs-driver-ufs
@@ -490,3 +490,111 @@ Description:	This file contains a product revision string. The full
 		information about the descriptor could be found at
 		UFS specifications 2.1.
 		The file is read only.
+
+
+What:		/sys/class/scsi_device/*/device/unit_descriptor/boot_lun_id
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows boot LUN information. This is one of
+		the UFS unit descriptor parameters. The full information
+		about the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/class/scsi_device/*/device/unit_descriptor/lun_write_protect
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows LUN write protection status. This is one of
+		the UFS unit descriptor parameters. The full information
+		about the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/class/scsi_device/*/device/unit_descriptor/lun_queue_depth
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows LUN queue depth. This is one of the UFS
+		unit descriptor parameters. The full information about
+		the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/class/scsi_device/*/device/unit_descriptor/psa_sensitive
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows PSA sensitivity. This is one of the UFS
+		unit descriptor parameters. The full information about
+		the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/class/scsi_device/*/device/unit_descriptor/lun_memory_type
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows LUN memory type. This is one of the UFS
+		unit descriptor parameters. The full information about
+		the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/class/scsi_device/*/device/unit_descriptor/data_reliability
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file defines the device behavior when a power failure
+		occurs during a write operation. This is one of the UFS
+		unit descriptor parameters. The full information about
+		the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/class/scsi_device/*/device/unit_descriptor/logical_block_size
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the size of addressable logical blocks
+		(calculated as an exponent with base 2). This is one of
+		the UFS unit descriptor parameters. The full information about
+		the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/class/scsi_device/*/device/unit_descriptor/logical_block_count
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows total number of addressable logical blocks.
+		This is one of the UFS unit descriptor parameters. The full
+		information about the descriptor could be found at
+		UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/class/scsi_device/*/device/unit_descriptor/erase_block_size
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the erase block size. This is one of
+		the UFS unit descriptor parameters. The full information
+		about the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/class/scsi_device/*/device/unit_descriptor/provisioning_type
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the thin provisioning type. This is one of
+		the UFS unit descriptor parameters. The full information
+		about the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/class/scsi_device/*/device/unit_descriptor/physical_memory_resourse_count
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the total physical memory resources. This is
+		one of the UFS unit descriptor parameters. The full information
+		about the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/class/scsi_device/*/device/unit_descriptor/context_capabilities
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the context capabilities. This is one of
+		the UFS unit descriptor parameters. The full information
+		about the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/class/scsi_device/*/device/unit_descriptor/large_unit_granularity
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the granularity of the LUN. This is one of
+		the UFS unit descriptor parameters. The full information
+		about the descriptor could be found at UFS specifications 2.1.
+		The file is read only.
diff --git a/drivers/scsi/ufs/ufs-sysfs.c b/drivers/scsi/ufs/ufs-sysfs.c
index 7130e0d..fc43583 100644
--- a/drivers/scsi/ufs/ufs-sysfs.c
+++ b/drivers/scsi/ufs/ufs-sysfs.c
@@ -550,6 +550,59 @@ static const struct attribute_group *ufs_sysfs_groups[] = {
 	NULL,
 };
 
+#define UFS_LUN_DESC_PARAM(_pname, _puname, _duname, _size)		\
+static ssize_t _pname##_show(struct device *dev,			\
+	struct device_attribute *attr, char *buf)			\
+{									\
+	struct scsi_device *sdev = to_scsi_device(dev);			\
+	struct ufs_hba *hba = shost_priv(sdev->host);			\
+	u8 lun = ufshcd_scsi_to_upiu_lun(sdev->lun);			\
+	if (!ufs_is_valid_unit_desc_lun(lun))				\
+		return -EINVAL;						\
+	return ufs_sysfs_read_desc_param(hba, QUERY_DESC_IDN_##_duname,	\
+		lun, _duname##_DESC_PARAM##_puname, buf, _size);	\
+}									\
+static DEVICE_ATTR_RO(_pname)
+
+#define UFS_UNIT_DESC_PARAM(_name, _uname, _size)			\
+	UFS_LUN_DESC_PARAM(_name, _uname, UNIT, _size)
+
+UFS_UNIT_DESC_PARAM(boot_lun_id, _BOOT_LUN_ID, 1);
+UFS_UNIT_DESC_PARAM(lun_write_protect, _LU_WR_PROTECT, 1);
+UFS_UNIT_DESC_PARAM(lun_queue_depth, _LU_Q_DEPTH, 1);
+UFS_UNIT_DESC_PARAM(psa_sensitive, _PSA_SENSITIVE, 1);
+UFS_UNIT_DESC_PARAM(lun_memory_type, _MEM_TYPE, 1);
+UFS_UNIT_DESC_PARAM(data_reliability, _DATA_RELIABILITY, 1);
+UFS_UNIT_DESC_PARAM(logical_block_size, _LOGICAL_BLK_SIZE, 1);
+UFS_UNIT_DESC_PARAM(logical_block_count, _LOGICAL_BLK_COUNT, 8);
+UFS_UNIT_DESC_PARAM(erase_block_size, _ERASE_BLK_SIZE, 4);
+UFS_UNIT_DESC_PARAM(provisioning_type, _PROVISIONING_TYPE, 1);
+UFS_UNIT_DESC_PARAM(physical_memory_resourse_count, _PHY_MEM_RSRC_CNT, 8);
+UFS_UNIT_DESC_PARAM(context_capabilities, _CTX_CAPABILITIES, 2);
+UFS_UNIT_DESC_PARAM(large_unit_granularity, _LARGE_UNIT_SIZE_M1, 1);
+
+static struct attribute *ufs_sysfs_unit_descriptor[] = {
+	&dev_attr_boot_lun_id.attr,
+	&dev_attr_lun_write_protect.attr,
+	&dev_attr_lun_queue_depth.attr,
+	&dev_attr_psa_sensitive.attr,
+	&dev_attr_lun_memory_type.attr,
+	&dev_attr_data_reliability.attr,
+	&dev_attr_logical_block_size.attr,
+	&dev_attr_logical_block_count.attr,
+	&dev_attr_erase_block_size.attr,
+	&dev_attr_provisioning_type.attr,
+	&dev_attr_physical_memory_resourse_count.attr,
+	&dev_attr_context_capabilities.attr,
+	&dev_attr_large_unit_granularity.attr,
+	NULL,
+};
+
+const struct attribute_group ufs_sysfs_unit_descriptor_group = {
+	.name = "unit_descriptor",
+	.attrs = ufs_sysfs_unit_descriptor,
+};
+
 void ufs_sysfs_add_nodes(struct device *dev)
 {
 	int ret;
diff --git a/drivers/scsi/ufs/ufs-sysfs.h b/drivers/scsi/ufs/ufs-sysfs.h
index 4a984ca..dd2fadc 100644
--- a/drivers/scsi/ufs/ufs-sysfs.h
+++ b/drivers/scsi/ufs/ufs-sysfs.h
@@ -11,4 +11,6 @@
 
 void ufs_sysfs_add_nodes(struct device *dev);
 void ufs_sysfs_remove_nodes(struct device *dev);
+
+extern const struct attribute_group ufs_sysfs_unit_descriptor_group;
 #endif
diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h
index 6bfeedb..7387059 100644
--- a/drivers/scsi/ufs/ufs.h
+++ b/drivers/scsi/ufs/ufs.h
@@ -182,6 +182,7 @@ enum unit_desc_param {
 	UNIT_DESC_PARAM_BOOT_LUN_ID		= 0x4,
 	UNIT_DESC_PARAM_LU_WR_PROTECT		= 0x5,
 	UNIT_DESC_PARAM_LU_Q_DEPTH		= 0x6,
+	UNIT_DESC_PARAM_PSA_SENSITIVE		= 0x7,
 	UNIT_DESC_PARAM_MEM_TYPE		= 0x8,
 	UNIT_DESC_PARAM_DATA_RELIABILITY	= 0x9,
 	UNIT_DESC_PARAM_LOGICAL_BLK_SIZE	= 0xA,
@@ -592,4 +593,14 @@ struct ufs_dev_desc {
 	char model[MAX_MODEL_LEN + 1];
 };
 
+/**
+ * ufs_is_valid_unit_desc_lun - checks if the given LUN has a unit descriptor
+ * @lun: LU number to check
+ * @return: true if the lun has a matching unit descriptor, false otherwise
+ */
+static inline bool ufs_is_valid_unit_desc_lun(u8 lun)
+{
+	return lun == UFS_UPIU_RPMB_WLUN || (lun < UFS_UPIU_MAX_GENERAL_LUN);
+}
+
 #endif /* End of Header */
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 9cfdd8e..ace3acd 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -2222,21 +2222,6 @@ static int ufshcd_comp_scsi_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
 	return ret;
 }
 
-/*
- * ufshcd_scsi_to_upiu_lun - maps scsi LUN to UPIU LUN
- * @scsi_lun: scsi LUN id
- *
- * Returns UPIU LUN id
- */
-static inline u8 ufshcd_scsi_to_upiu_lun(unsigned int scsi_lun)
-{
-	if (scsi_is_wlun(scsi_lun))
-		return (scsi_lun & UFS_UPIU_MAX_UNIT_NUM_ID)
-			| UFS_UPIU_WLUN_ID;
-	else
-		return scsi_lun & UFS_UPIU_MAX_UNIT_NUM_ID;
-}
-
 /**
  * ufshcd_upiu_wlun_to_scsi_wlun - maps UPIU W-LUN id to SCSI W-LUN ID
  * @scsi_lun: UPIU W-LUN id
@@ -3171,7 +3156,7 @@ static inline int ufshcd_read_unit_desc_param(struct ufs_hba *hba,
 	 * Unit descriptors are only available for general purpose LUs (LUN id
 	 * from 0 to 7) and RPMB Well known LU.
 	 */
-	if (lun != UFS_UPIU_RPMB_WLUN && (lun >= UFS_UPIU_MAX_GENERAL_LUN))
+	if (!ufs_is_valid_unit_desc_lun(lun))
 		return -EOPNOTSUPP;
 
 	return ufshcd_read_desc_param(hba, QUERY_DESC_IDN_UNIT, lun,
@@ -6481,6 +6466,11 @@ static enum blk_eh_timer_return ufshcd_eh_timed_out(struct scsi_cmnd *scmd)
 	return found ? BLK_EH_NOT_HANDLED : BLK_EH_RESET_TIMER;
 }
 
+static const struct attribute_group *ufshcd_driver_groups[] = {
+	&ufs_sysfs_unit_descriptor_group,
+	NULL,
+};
+
 static struct scsi_host_template ufshcd_driver_template = {
 	.module			= THIS_MODULE,
 	.name			= UFSHCD,
@@ -6500,6 +6490,7 @@ static struct scsi_host_template ufshcd_driver_template = {
 	.can_queue		= UFSHCD_CAN_QUEUE,
 	.max_host_blocked	= 1,
 	.track_queue_depth	= 1,
+	.sdev_groups		= ufshcd_driver_groups,
 };
 
 static int ufshcd_config_vreg_load(struct device *dev, struct ufs_vreg *vreg,
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index 2dad9da..f4cb31b 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -1003,4 +1003,19 @@ static inline void ufshcd_vops_dbg_register_dump(struct ufs_hba *hba)
 
 extern struct ufs_pm_lvl_states ufs_pm_lvl_states[];
 
+/*
+ * ufshcd_scsi_to_upiu_lun - maps scsi LUN to UPIU LUN
+ * @scsi_lun: scsi LUN id
+ *
+ * Returns UPIU LUN id
+ */
+static inline u8 ufshcd_scsi_to_upiu_lun(unsigned int scsi_lun)
+{
+	if (scsi_is_wlun(scsi_lun))
+		return (scsi_lun & UFS_UPIU_MAX_UNIT_NUM_ID)
+			| UFS_UPIU_WLUN_ID;
+	else
+		return scsi_lun & UFS_UPIU_MAX_UNIT_NUM_ID;
+}
+
 #endif /* End of Header */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v5 10/11] scsi: ufs: sysfs: flags
  2018-02-06 16:06 [PATCH v5 00/11] ufs: sysfs: read-only access to device Stanislav Nijnikov
                   ` (8 preceding siblings ...)
  2018-02-06 16:06 ` [PATCH v5 09/11] scsi: ufs: sysfs: unit descriptor Stanislav Nijnikov
@ 2018-02-06 16:06 ` Stanislav Nijnikov
  2018-02-06 16:06 ` [PATCH v5 11/11] scsi: ufs: sysfs: attributes Stanislav Nijnikov
  10 siblings, 0 replies; 19+ messages in thread
From: Stanislav Nijnikov @ 2018-02-06 16:06 UTC (permalink / raw)
  To: linux-scsi, linux-kernel, gregkh, jaegeuk
  Cc: alex.lemberg, Stanislav Nijnikov

This patch introduces a sysfs group entry for the UFS flags. The group adds
"flags" folder under the UFS driver sysfs entry
(/sys/bus/platform/drivers/ufshcd/*). The flags are shown as boolean value
("true" or "false"). The full information about the UFS flags could be
found at UFS specifications 2.1.

Signed-off-by: Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
---
 Documentation/ABI/testing/sysfs-driver-ufs | 65 ++++++++++++++++++++++++++++++
 drivers/scsi/ufs/ufs-sysfs.c               | 39 ++++++++++++++++++
 drivers/scsi/ufs/ufs.h                     | 14 +++++--
 3 files changed, 115 insertions(+), 3 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-driver-ufs b/Documentation/ABI/testing/sysfs-driver-ufs
index 57c6a90..f4f49e2 100644
--- a/Documentation/ABI/testing/sysfs-driver-ufs
+++ b/Documentation/ABI/testing/sysfs-driver-ufs
@@ -598,3 +598,68 @@ Description:	This file shows the granularity of the LUN. This is one of
 		the UFS unit descriptor parameters. The full information
 		about the descriptor could be found at UFS specifications 2.1.
 		The file is read only.
+
+
+What:		/sys/bus/platform/drivers/ufshcd/*/flags/device_init
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the device init status. The full information
+		about the flag could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/flags/permanent_wpe
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows whether permanent write protection is enabled.
+		The full information about the flag could be found at
+		UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/flags/power_on_wpe
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows whether write protection is enabled on all
+		logical units configured as power on write protected. The
+		full information about the flag could be found at
+		UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/flags/bkops_enable
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows whether the device background operations are
+		enabled. The full information about the flag could be
+		found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/flags/life_span_mode_enable
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows whether the device life span mode is enabled.
+		The full information about the flag could be found at
+		UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/flags/phy_resource_removal
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows whether physical resource removal is enable.
+		The full information about the flag could be found at
+		UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/flags/busy_rtc
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows whether the device is executing internal
+		operation related to real time clock. The full information
+		about the flag could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/flags/disable_fw_update
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows whether the device FW update is permanently
+		disabled. The full information about the flag could be found
+		at UFS specifications 2.1.
+		The file is read only.
diff --git a/drivers/scsi/ufs/ufs-sysfs.c b/drivers/scsi/ufs/ufs-sysfs.c
index fc43583..258fb75 100644
--- a/drivers/scsi/ufs/ufs-sysfs.c
+++ b/drivers/scsi/ufs/ufs-sysfs.c
@@ -538,6 +538,44 @@ static const struct attribute_group ufs_sysfs_string_descriptors_group = {
 	.attrs = ufs_sysfs_string_descriptors,
 };
 
+#define UFS_FLAG(_name, _uname)						\
+static ssize_t _name##_show(struct device *dev,				\
+	struct device_attribute *attr, char *buf)			\
+{									\
+	bool flag;							\
+	struct ufs_hba *hba = dev_get_drvdata(dev);			\
+	if (ufshcd_query_flag(hba, UPIU_QUERY_OPCODE_READ_FLAG,		\
+		QUERY_FLAG_IDN##_uname, &flag))				\
+		return -EINVAL;						\
+	return sprintf(buf, "%s\n", flag ? "true" : "false");		\
+}									\
+static DEVICE_ATTR_RO(_name)
+
+UFS_FLAG(device_init, _FDEVICEINIT);
+UFS_FLAG(permanent_wpe, _PERMANENT_WPE);
+UFS_FLAG(power_on_wpe, _PWR_ON_WPE);
+UFS_FLAG(bkops_enable, _BKOPS_EN);
+UFS_FLAG(life_span_mode_enable, _LIFE_SPAN_MODE_ENABLE);
+UFS_FLAG(phy_resource_removal, _FPHYRESOURCEREMOVAL);
+UFS_FLAG(busy_rtc, _BUSY_RTC);
+UFS_FLAG(disable_fw_update, _PERMANENTLY_DISABLE_FW_UPDATE);
+
+static struct attribute *ufs_sysfs_device_flags[] = {
+	&dev_attr_device_init.attr,
+	&dev_attr_permanent_wpe.attr,
+	&dev_attr_power_on_wpe.attr,
+	&dev_attr_bkops_enable.attr,
+	&dev_attr_life_span_mode_enable.attr,
+	&dev_attr_phy_resource_removal.attr,
+	&dev_attr_busy_rtc.attr,
+	&dev_attr_disable_fw_update.attr,
+	NULL,
+};
+
+static const struct attribute_group ufs_sysfs_flags_group = {
+	.name = "flags",
+	.attrs = ufs_sysfs_device_flags,
+};
 
 static const struct attribute_group *ufs_sysfs_groups[] = {
 	&ufs_sysfs_default_group,
@@ -547,6 +585,7 @@ static const struct attribute_group *ufs_sysfs_groups[] = {
 	&ufs_sysfs_health_descriptor_group,
 	&ufs_sysfs_power_descriptor_group,
 	&ufs_sysfs_string_descriptors_group,
+	&ufs_sysfs_flags_group,
 	NULL,
 };
 
diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h
index 7387059..df5e73e 100644
--- a/drivers/scsi/ufs/ufs.h
+++ b/drivers/scsi/ufs/ufs.h
@@ -130,9 +130,17 @@ enum {
 
 /* Flag idn for Query Requests*/
 enum flag_idn {
-	QUERY_FLAG_IDN_FDEVICEINIT      = 0x01,
-	QUERY_FLAG_IDN_PWR_ON_WPE	= 0x03,
-	QUERY_FLAG_IDN_BKOPS_EN         = 0x04,
+	QUERY_FLAG_IDN_FDEVICEINIT			= 0x01,
+	QUERY_FLAG_IDN_PERMANENT_WPE			= 0x02,
+	QUERY_FLAG_IDN_PWR_ON_WPE			= 0x03,
+	QUERY_FLAG_IDN_BKOPS_EN				= 0x04,
+	QUERY_FLAG_IDN_LIFE_SPAN_MODE_ENABLE		= 0x05,
+	QUERY_FLAG_IDN_PURGE_ENABLE			= 0x06,
+	QUERY_FLAG_IDN_RESERVED2			= 0x07,
+	QUERY_FLAG_IDN_FPHYRESOURCEREMOVAL		= 0x08,
+	QUERY_FLAG_IDN_BUSY_RTC				= 0x09,
+	QUERY_FLAG_IDN_RESERVED3			= 0x0A,
+	QUERY_FLAG_IDN_PERMANENTLY_DISABLE_FW_UPDATE	= 0x0B,
 };
 
 /* Attribute idn for Query requests */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v5 11/11] scsi: ufs: sysfs: attributes
  2018-02-06 16:06 [PATCH v5 00/11] ufs: sysfs: read-only access to device Stanislav Nijnikov
                   ` (9 preceding siblings ...)
  2018-02-06 16:06 ` [PATCH v5 10/11] scsi: ufs: sysfs: flags Stanislav Nijnikov
@ 2018-02-06 16:06 ` Stanislav Nijnikov
  10 siblings, 0 replies; 19+ messages in thread
From: Stanislav Nijnikov @ 2018-02-06 16:06 UTC (permalink / raw)
  To: linux-scsi, linux-kernel, gregkh, jaegeuk
  Cc: alex.lemberg, Stanislav Nijnikov

This patch introduces a sysfs group entry for the UFS attributes. The
group adds "attributes" folder under the UFS driver sysfs entry
(/sys/bus/platform/drivers/ufshcd/*). The attributes are shown
as hexadecimal numbers. The full information about the attributes could
be found at UFS specifications 2.1.

Signed-off-by: Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
---
 Documentation/ABI/testing/sysfs-driver-ufs | 139 +++++++++++++++++++++++++++++
 drivers/scsi/ufs/ufs-sysfs.c               |  80 +++++++++++++++++
 drivers/scsi/ufs/ufs-sysfs.h               |   1 +
 drivers/scsi/ufs/ufs.h                     |  27 +++++-
 drivers/scsi/ufs/ufshcd.c                  |   5 +-
 drivers/scsi/ufs/ufshcd.h                  |   3 +-
 6 files changed, 248 insertions(+), 7 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-driver-ufs b/Documentation/ABI/testing/sysfs-driver-ufs
index f4f49e2..07f1c2f 100644
--- a/Documentation/ABI/testing/sysfs-driver-ufs
+++ b/Documentation/ABI/testing/sysfs-driver-ufs
@@ -663,3 +663,142 @@ Description:	This file shows whether the device FW update is permanently
 		disabled. The full information about the flag could be found
 		at UFS specifications 2.1.
 		The file is read only.
+
+
+What:		/sys/bus/platform/drivers/ufshcd/*/attributes/boot_lun_enabled
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file provides the boot lun enabled UFS device attribute.
+		The full information about the attribute could be found at
+		UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/attributes/current_power_mode
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file provides the current power mode UFS device attribute.
+		The full information about the attribute could be found at
+		UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/attributes/active_icc_level
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file provides the active icc level UFS device attribute.
+		The full information about the attribute could be found at
+		UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/attributes/ooo_data_enabled
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file provides the out of order data transfer enabled UFS
+		device attribute. The full information about the attribute
+		could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/attributes/bkops_status
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file provides the background operations status UFS device
+		attribute. The full information about the attribute could
+		be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/attributes/purge_status
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file provides the purge operation status UFS device
+		attribute. The full information about the attribute could
+		be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/attributes/max_data_in_size
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the maximum data size in a DATA IN
+		UPIU. The full information about the attribute could
+		be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/attributes/max_data_out_size
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the maximum number of bytes that can be
+		requested with a READY TO TRANSFER UPIU. The full information
+		about the attribute could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/attributes/reference_clock_frequency
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file provides the reference clock frequency UFS device
+		attribute. The full information about the attribute could
+		be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/attributes/configuration_descriptor_lock
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows whether the configuration descriptor is locked.
+		The full information about the attribute could be found at
+		UFS specifications 2.1. The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/attributes/max_number_of_rtt
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file provides the maximum current number of
+		outstanding RTTs in device that is allowed. The full
+		information about the attribute could be found at
+		UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/attributes/exception_event_control
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file provides the exception event control UFS device
+		attribute. The full information about the attribute could
+		be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/attributes/exception_event_status
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file provides the exception event status UFS device
+		attribute. The full information about the attribute could
+		be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/attributes/ffu_status
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file provides the ffu status UFS device attribute.
+		The full information about the attribute could be found at
+		UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/attributes/psa_state
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file show the PSA feature status. The full information
+		about the attribute could be found at UFS specifications 2.1.
+		The file is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/attributes/psa_data_size
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the amount of data that the host plans to
+		load to all logical units in pre-soldering state.
+		The full information about the attribute could be found at
+		UFS specifications 2.1.
+		The file is read only.
+
+
+What:		/sys/class/scsi_device/*/device/dyn_cap_needed
+Date:		February 2018
+Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
+Description:	This file shows the The amount of physical memory needed
+		to be removed from the physical memory resources pool of
+		the particular logical unit. The full information about
+		the attribute could be found at UFS specifications 2.1.
+		The file is read only.
diff --git a/drivers/scsi/ufs/ufs-sysfs.c b/drivers/scsi/ufs/ufs-sysfs.c
index 258fb75..cb5d5a4 100644
--- a/drivers/scsi/ufs/ufs-sysfs.c
+++ b/drivers/scsi/ufs/ufs-sysfs.c
@@ -577,6 +577,61 @@ static const struct attribute_group ufs_sysfs_flags_group = {
 	.attrs = ufs_sysfs_device_flags,
 };
 
+#define UFS_ATTRIBUTE(_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;							\
+	if (ufshcd_query_attr(hba, UPIU_QUERY_OPCODE_READ_ATTR,		\
+		QUERY_ATTR_IDN##_uname, 0, 0, &value))			\
+		return -EINVAL;						\
+	return sprintf(buf, "0x%08X\n", value);				\
+}									\
+static DEVICE_ATTR_RO(_name)
+
+UFS_ATTRIBUTE(boot_lun_enabled, _BOOT_LU_EN);
+UFS_ATTRIBUTE(current_power_mode, _POWER_MODE);
+UFS_ATTRIBUTE(active_icc_level, _ACTIVE_ICC_LVL);
+UFS_ATTRIBUTE(ooo_data_enabled, _OOO_DATA_EN);
+UFS_ATTRIBUTE(bkops_status, _BKOPS_STATUS);
+UFS_ATTRIBUTE(purge_status, _PURGE_STATUS);
+UFS_ATTRIBUTE(max_data_in_size, _MAX_DATA_IN);
+UFS_ATTRIBUTE(max_data_out_size, _MAX_DATA_OUT);
+UFS_ATTRIBUTE(reference_clock_frequency, _REF_CLK_FREQ);
+UFS_ATTRIBUTE(configuration_descriptor_lock, _CONF_DESC_LOCK);
+UFS_ATTRIBUTE(max_number_of_rtt, _MAX_NUM_OF_RTT);
+UFS_ATTRIBUTE(exception_event_control, _EE_CONTROL);
+UFS_ATTRIBUTE(exception_event_status, _EE_STATUS);
+UFS_ATTRIBUTE(ffu_status, _FFU_STATUS);
+UFS_ATTRIBUTE(psa_state, _PSA_STATE);
+UFS_ATTRIBUTE(psa_data_size, _PSA_DATA_SIZE);
+
+static struct attribute *ufs_sysfs_attributes[] = {
+	&dev_attr_boot_lun_enabled.attr,
+	&dev_attr_current_power_mode.attr,
+	&dev_attr_active_icc_level.attr,
+	&dev_attr_ooo_data_enabled.attr,
+	&dev_attr_bkops_status.attr,
+	&dev_attr_purge_status.attr,
+	&dev_attr_max_data_in_size.attr,
+	&dev_attr_max_data_out_size.attr,
+	&dev_attr_reference_clock_frequency.attr,
+	&dev_attr_configuration_descriptor_lock.attr,
+	&dev_attr_max_number_of_rtt.attr,
+	&dev_attr_exception_event_control.attr,
+	&dev_attr_exception_event_status.attr,
+	&dev_attr_ffu_status.attr,
+	&dev_attr_psa_state.attr,
+	&dev_attr_psa_data_size.attr,
+	NULL,
+};
+
+static const struct attribute_group ufs_sysfs_attributes_group = {
+	.name = "attributes",
+	.attrs = ufs_sysfs_attributes,
+};
+
 static const struct attribute_group *ufs_sysfs_groups[] = {
 	&ufs_sysfs_default_group,
 	&ufs_sysfs_device_descriptor_group,
@@ -586,6 +641,7 @@ static const struct attribute_group *ufs_sysfs_groups[] = {
 	&ufs_sysfs_power_descriptor_group,
 	&ufs_sysfs_string_descriptors_group,
 	&ufs_sysfs_flags_group,
+	&ufs_sysfs_attributes_group,
 	NULL,
 };
 
@@ -642,6 +698,30 @@ const struct attribute_group ufs_sysfs_unit_descriptor_group = {
 	.attrs = ufs_sysfs_unit_descriptor,
 };
 
+static ssize_t dyn_cap_needed_attribute_show(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	u32 value;
+	struct scsi_device *sdev = to_scsi_device(dev);
+	struct ufs_hba *hba = shost_priv(sdev->host);
+	u8 lun = ufshcd_scsi_to_upiu_lun(sdev->lun);
+
+	if (ufshcd_query_attr(hba, UPIU_QUERY_OPCODE_READ_ATTR,
+		QUERY_ATTR_IDN_DYN_CAP_NEEDED, lun, 0, &value))
+		return -EINVAL;
+	return sprintf(buf, "0x%08X\n", value);
+}
+static DEVICE_ATTR_RO(dyn_cap_needed_attribute);
+
+static struct attribute *ufs_sysfs_lun_attributes[] = {
+	&dev_attr_dyn_cap_needed_attribute.attr,
+	NULL,
+};
+
+const struct attribute_group ufs_sysfs_lun_attributes_group = {
+	.attrs = ufs_sysfs_lun_attributes,
+};
+
 void ufs_sysfs_add_nodes(struct device *dev)
 {
 	int ret;
diff --git a/drivers/scsi/ufs/ufs-sysfs.h b/drivers/scsi/ufs/ufs-sysfs.h
index dd2fadc..7f29715 100644
--- a/drivers/scsi/ufs/ufs-sysfs.h
+++ b/drivers/scsi/ufs/ufs-sysfs.h
@@ -13,4 +13,5 @@ void ufs_sysfs_add_nodes(struct device *dev);
 void ufs_sysfs_remove_nodes(struct device *dev);
 
 extern const struct attribute_group ufs_sysfs_unit_descriptor_group;
+extern const struct attribute_group ufs_sysfs_lun_attributes_group;
 #endif
diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h
index df5e73e..14e5bf7 100644
--- a/drivers/scsi/ufs/ufs.h
+++ b/drivers/scsi/ufs/ufs.h
@@ -145,10 +145,29 @@ enum flag_idn {
 
 /* Attribute idn for Query requests */
 enum attr_idn {
-	QUERY_ATTR_IDN_ACTIVE_ICC_LVL	= 0x03,
-	QUERY_ATTR_IDN_BKOPS_STATUS	= 0x05,
-	QUERY_ATTR_IDN_EE_CONTROL	= 0x0D,
-	QUERY_ATTR_IDN_EE_STATUS	= 0x0E,
+	QUERY_ATTR_IDN_BOOT_LU_EN		= 0x00,
+	QUERY_ATTR_IDN_RESERVED			= 0x01,
+	QUERY_ATTR_IDN_POWER_MODE		= 0x02,
+	QUERY_ATTR_IDN_ACTIVE_ICC_LVL		= 0x03,
+	QUERY_ATTR_IDN_OOO_DATA_EN		= 0x04,
+	QUERY_ATTR_IDN_BKOPS_STATUS		= 0x05,
+	QUERY_ATTR_IDN_PURGE_STATUS		= 0x06,
+	QUERY_ATTR_IDN_MAX_DATA_IN		= 0x07,
+	QUERY_ATTR_IDN_MAX_DATA_OUT		= 0x08,
+	QUERY_ATTR_IDN_DYN_CAP_NEEDED		= 0x09,
+	QUERY_ATTR_IDN_REF_CLK_FREQ		= 0x0A,
+	QUERY_ATTR_IDN_CONF_DESC_LOCK		= 0x0B,
+	QUERY_ATTR_IDN_MAX_NUM_OF_RTT		= 0x0C,
+	QUERY_ATTR_IDN_EE_CONTROL		= 0x0D,
+	QUERY_ATTR_IDN_EE_STATUS		= 0x0E,
+	QUERY_ATTR_IDN_SECONDS_PASSED		= 0x0F,
+	QUERY_ATTR_IDN_CNTX_CONF		= 0x10,
+	QUERY_ATTR_IDN_CORR_PRG_BLK_NUM		= 0x11,
+	QUERY_ATTR_IDN_RESERVED2		= 0x12,
+	QUERY_ATTR_IDN_RESERVED3		= 0x13,
+	QUERY_ATTR_IDN_FFU_STATUS		= 0x14,
+	QUERY_ATTR_IDN_PSA_STATE		= 0x15,
+	QUERY_ATTR_IDN_PSA_DATA_SIZE		= 0x16,
 };
 
 /* Descriptor idn for Query requests */
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index ace3acd..1fbb17b 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -2689,8 +2689,8 @@ int ufshcd_query_flag(struct ufs_hba *hba, enum query_opcode opcode,
  *
  * Returns 0 for success, non-zero in case of failure
 */
-static 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(struct ufs_hba *hba, enum query_opcode opcode,
+		      enum attr_idn idn, u8 index, u8 selector, u32 *attr_val)
 {
 	struct ufs_query_req *request = NULL;
 	struct ufs_query_res *response = NULL;
@@ -6468,6 +6468,7 @@ static enum blk_eh_timer_return ufshcd_eh_timed_out(struct scsi_cmnd *scmd)
 
 static const struct attribute_group *ufshcd_driver_groups[] = {
 	&ufs_sysfs_unit_descriptor_group,
+	&ufs_sysfs_lun_attributes_group,
 	NULL,
 };
 
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index f4cb31b..deb3c5d 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -847,13 +847,14 @@ int ufshcd_query_descriptor_retry(struct ufs_hba *hba,
 				  enum desc_idn idn, u8 index,
 				  u8 selector,
 				  u8 *desc_buf, int *buf_len);
-
 int ufshcd_read_desc_param(struct ufs_hba *hba,
 			   enum desc_idn desc_id,
 			   int desc_index,
 			   u8 param_offset,
 			   u8 *param_read_buf,
 			   u8 param_size);
+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_flag(struct ufs_hba *hba, enum query_opcode opcode,
 	enum flag_idn idn, bool *flag_res);
 int ufshcd_read_string_desc(struct ufs_hba *hba, int desc_index,
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH v5 08/11] scsi: host template attribute groups
  2018-02-06 16:06 ` [PATCH v5 08/11] scsi: host template attribute groups Stanislav Nijnikov
@ 2018-02-06 19:06   ` Bart Van Assche
  0 siblings, 0 replies; 19+ messages in thread
From: Bart Van Assche @ 2018-02-06 19:06 UTC (permalink / raw)
  To: linux-scsi, linux-kernel, jaegeuk, gregkh, Stanislav Nijnikov
  Cc: Alex Lemberg

On Tue, 2018-02-06 at 18:06 +0200, Stanislav Nijnikov wrote:
> +	if (sdev->host->hostt->sdev_groups) {
> +		error = sysfs_create_groups(&sdev->sdev_gendev.kobj,
> +			sdev->host->hostt->sdev_groups);
> +			if (error)
> +				return error;
> +	}

Please follow the indentation style that is used elsewhere in the kernel and
move the sdev->host->hostt->sdev_groups argument to the right such that it
starts one position to the right of the sysfs_create_groups() opening
parenthesis. Please also indent the if (error) statement correctly.

> @@ -1326,6 +1333,11 @@ void __scsi_remove_device(struct scsi_device *sdev)
>  	if (sdev->sdev_state == SDEV_DEL)
>  		return;
>  
> +	if (sdev->host->hostt->sdev_groups) {
> +		sysfs_remove_groups(&sdev->sdev_gendev.kobj,
> +			sdev->host->hostt->sdev_groups);
> +	}

If sdev->is_visible is false then the device_add() call for sdev->sdev_gendev
may have failed so calling sysfs_remove_groups() is not necessary. Please move
this call down to just before the device_del(dev) since that call also removes
sysfs attributes. Additionally, I think that checkpatch will complain about the
above code and will report that braces are not necessary for single-line
statements?

Thanks,

Bart.




^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v5 01/11] scsi: ufs: sysfs: attribute group for existing sysfs entries.
  2018-02-06 16:06 ` [PATCH v5 01/11] scsi: ufs: sysfs: attribute group for existing sysfs entries Stanislav Nijnikov
@ 2018-02-12  1:06   ` Jaegeuk Kim
  2018-02-12  9:31     ` Philippe Ombredanne
  2018-02-12 11:06     ` Stanislav Nijnikov
  0 siblings, 2 replies; 19+ messages in thread
From: Jaegeuk Kim @ 2018-02-12  1:06 UTC (permalink / raw)
  To: Stanislav Nijnikov; +Cc: linux-scsi, linux-kernel, gregkh, alex.lemberg

On 02/06, Stanislav Nijnikov wrote:
> This patch introduces attribute group to show existing sysfs entries.
> 
> Signed-off-by: Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> ---
>  drivers/scsi/ufs/Makefile    |   3 +-
>  drivers/scsi/ufs/ufs-sysfs.c | 156 +++++++++++++++++++++++++++++++++++++++++++
>  drivers/scsi/ufs/ufs-sysfs.h |  14 ++++
>  drivers/scsi/ufs/ufshcd.c    | 156 ++-----------------------------------------
>  drivers/scsi/ufs/ufshcd.h    |   2 +
>  5 files changed, 178 insertions(+), 153 deletions(-)
>  create mode 100644 drivers/scsi/ufs/ufs-sysfs.c
>  create mode 100644 drivers/scsi/ufs/ufs-sysfs.h
> 
> diff --git a/drivers/scsi/ufs/Makefile b/drivers/scsi/ufs/Makefile
> index 9310c6c..918f579 100644
> --- a/drivers/scsi/ufs/Makefile
> +++ b/drivers/scsi/ufs/Makefile
> @@ -3,6 +3,7 @@
>  obj-$(CONFIG_SCSI_UFS_DWC_TC_PCI) += tc-dwc-g210-pci.o ufshcd-dwc.o tc-dwc-g210.o
>  obj-$(CONFIG_SCSI_UFS_DWC_TC_PLATFORM) += tc-dwc-g210-pltfrm.o ufshcd-dwc.o tc-dwc-g210.o
>  obj-$(CONFIG_SCSI_UFS_QCOM) += ufs-qcom.o
> -obj-$(CONFIG_SCSI_UFSHCD) += ufshcd.o
> +obj-$(CONFIG_SCSI_UFSHCD) += ufshcd-core.o
> +ufshcd-core-objs := ufshcd.o ufs-sysfs.o
>  obj-$(CONFIG_SCSI_UFSHCD_PCI) += ufshcd-pci.o
>  obj-$(CONFIG_SCSI_UFSHCD_PLATFORM) += ufshcd-pltfrm.o
> diff --git a/drivers/scsi/ufs/ufs-sysfs.c b/drivers/scsi/ufs/ufs-sysfs.c
> new file mode 100644
> index 0000000..ce8dcb6
> --- /dev/null
> +++ b/drivers/scsi/ufs/ufs-sysfs.c
> @@ -0,0 +1,156 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +// Copyright (C) 2018 Western Digital Corporation
> +
> +#include <linux/err.h>
> +#include <linux/string.h>
> +
> +#include "ufs-sysfs.h"
> +
> +static const char *ufschd_uic_link_state_to_string(
> +			enum uic_link_state state)
> +{
> +	switch (state) {
> +	case UIC_LINK_OFF_STATE:	return "OFF";
> +	case UIC_LINK_ACTIVE_STATE:	return "ACTIVE";
> +	case UIC_LINK_HIBERN8_STATE:	return "HIBERN8";
> +	default:			return "UNKNOWN";
> +	}
> +}
> +
> +static const char *ufschd_ufs_dev_pwr_mode_to_string(
> +			enum ufs_dev_pwr_mode state)
> +{
> +	switch (state) {
> +	case UFS_ACTIVE_PWR_MODE:	return "ACTIVE";
> +	case UFS_SLEEP_PWR_MODE:	return "SLEEP";
> +	case UFS_POWERDOWN_PWR_MODE:	return "POWERDOWN";
> +	default:			return "UNKNOWN";
> +	}
> +}
> +
> +static inline ssize_t ufs_sysfs_pm_lvl_store(struct device *dev,
> +					     struct device_attribute *attr,
> +					     const char *buf, size_t count,
> +					     bool rpm)
> +{
> +	struct ufs_hba *hba = dev_get_drvdata(dev);
> +	unsigned long flags, value;
> +
> +	if (kstrtoul(buf, 0, &value))
> +		return -EINVAL;
> +
> +	if (value >= UFS_PM_LVL_MAX)
> +		return -EINVAL;
> +
> +	spin_lock_irqsave(hba->host->host_lock, flags);
> +	if (rpm)
> +		hba->rpm_lvl = value;
> +	else
> +		hba->spm_lvl = value;
> +	spin_unlock_irqrestore(hba->host->host_lock, flags);
> +	return count;
> +}
> +
> +static ssize_t rpm_lvl_show(struct device *dev,
> +		struct device_attribute *attr, char *buf)
> +{
> +	struct ufs_hba *hba = dev_get_drvdata(dev);
> +	int curr_len;
> +	u8 lvl;
> +
> +	curr_len = snprintf(buf, PAGE_SIZE,
> +			    "\nCurrent Runtime PM level [%d] => dev_state [%s] link_state [%s]\n",
> +			    hba->rpm_lvl,
> +			    ufschd_ufs_dev_pwr_mode_to_string(
> +				ufs_pm_lvl_states[hba->rpm_lvl].dev_state),
> +			    ufschd_uic_link_state_to_string(
> +				ufs_pm_lvl_states[hba->rpm_lvl].link_state));

If there is no objection regarding to backward compatibility, can we also
clean this up by adding multiple entries having single string each, as Greg
recommended?

For example,

/rpm_level
1

/rpm_dev_state
ACTIVE

/rpm_link_state
HIBERN8

/spm_level
2

/spm_dev_state
SLEEP

/spm_link_state
ACTIVE

/avail_dev_states
0:ACTIVE 1:ACTIVE 2:SLEEP 3:SLEEP 4:POWERDOWN 5:POWERDOWN

/avail_link_states
0:ACTIVE 1:HIBERN8 2:ACTIVE 3:HIBERN8 4:HIBERN8 5:OFF

Thanks,

> +
> +	curr_len += snprintf((buf + curr_len), (PAGE_SIZE - curr_len),
> +			     "\nAll available Runtime PM levels info:\n");
> +	for (lvl = UFS_PM_LVL_0; lvl < UFS_PM_LVL_MAX; lvl++)
> +		curr_len += snprintf((buf + curr_len), (PAGE_SIZE - curr_len),
> +				     "\tRuntime PM level [%d] => dev_state [%s] link_state [%s]\n",
> +				    lvl,
> +				    ufschd_ufs_dev_pwr_mode_to_string(
> +					ufs_pm_lvl_states[lvl].dev_state),
> +				    ufschd_uic_link_state_to_string(
> +					ufs_pm_lvl_states[lvl].link_state));
> +
> +	return curr_len;
> +}
> +
> +static ssize_t rpm_lvl_store(struct device *dev,
> +		struct device_attribute *attr, const char *buf, size_t count)
> +{
> +	return ufs_sysfs_pm_lvl_store(dev, attr, buf, count, true);
> +}
> +
> +static ssize_t spm_lvl_show(struct device *dev,
> +		struct device_attribute *attr, char *buf)
> +{
> +	struct ufs_hba *hba = dev_get_drvdata(dev);
> +	int curr_len;
> +	u8 lvl;
> +
> +	curr_len = snprintf(buf, PAGE_SIZE,
> +			    "\nCurrent System PM level [%d] => dev_state [%s] link_state [%s]\n",
> +			    hba->spm_lvl,
> +			    ufschd_ufs_dev_pwr_mode_to_string(
> +				ufs_pm_lvl_states[hba->spm_lvl].dev_state),
> +			    ufschd_uic_link_state_to_string(
> +				ufs_pm_lvl_states[hba->spm_lvl].link_state));
> +
> +	curr_len += snprintf((buf + curr_len), (PAGE_SIZE - curr_len),
> +			     "\nAll available System PM levels info:\n");
> +	for (lvl = UFS_PM_LVL_0; lvl < UFS_PM_LVL_MAX; lvl++)
> +		curr_len += snprintf((buf + curr_len), (PAGE_SIZE - curr_len),
> +				     "\tSystem PM level [%d] => dev_state [%s] link_state [%s]\n",
> +				    lvl,
> +				    ufschd_ufs_dev_pwr_mode_to_string(
> +					ufs_pm_lvl_states[lvl].dev_state),
> +				    ufschd_uic_link_state_to_string(
> +					ufs_pm_lvl_states[lvl].link_state));
> +
> +	return curr_len;
> +}
> +
> +static ssize_t spm_lvl_store(struct device *dev,
> +		struct device_attribute *attr, const char *buf, size_t count)
> +{
> +	return ufs_sysfs_pm_lvl_store(dev, attr, buf, count, false);
> +}
> +
> +static DEVICE_ATTR_RW(rpm_lvl);
> +static DEVICE_ATTR_RW(spm_lvl);
> +
> +static struct attribute *ufs_sysfs_ufshcd_attrs[] = {
> +	&dev_attr_rpm_lvl.attr,
> +	&dev_attr_spm_lvl.attr,
> +	NULL
> +};
> +
> +static const struct attribute_group ufs_sysfs_default_group = {
> +	.attrs = ufs_sysfs_ufshcd_attrs,
> +};
> +
> +static const struct attribute_group *ufs_sysfs_groups[] = {
> +	&ufs_sysfs_default_group,
> +	NULL,
> +};
> +
> +void ufs_sysfs_add_nodes(struct device *dev)
> +{
> +	int ret;
> +
> +	ret = sysfs_create_groups(&dev->kobj, ufs_sysfs_groups);
> +	if (ret)
> +		dev_err(dev,
> +			"%s: sysfs groups creation failed (err = %d)\n",
> +			__func__, ret);
> +}
> +
> +void ufs_sysfs_remove_nodes(struct device *dev)
> +{
> +	sysfs_remove_groups(&dev->kobj, ufs_sysfs_groups);
> +}
> diff --git a/drivers/scsi/ufs/ufs-sysfs.h b/drivers/scsi/ufs/ufs-sysfs.h
> new file mode 100644
> index 0000000..4a984ca
> --- /dev/null
> +++ b/drivers/scsi/ufs/ufs-sysfs.h
> @@ -0,0 +1,14 @@
> +/* SPDX-License-Identifier: GPL-2.0-only
> + * Copyright (C) 2018 Western Digital Corporation
> + */
> +
> +#ifndef __UFS_SYSFS_H__
> +#define __UFS_SYSFS_H__
> +
> +#include <linux/sysfs.h>
> +
> +#include "ufshcd.h"
> +
> +void ufs_sysfs_add_nodes(struct device *dev);
> +void ufs_sysfs_remove_nodes(struct device *dev);
> +#endif
> diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
> index a355d98..e7621a0a 100644
> --- a/drivers/scsi/ufs/ufshcd.c
> +++ b/drivers/scsi/ufs/ufshcd.c
> @@ -44,6 +44,7 @@
>  #include "ufshcd.h"
>  #include "ufs_quirks.h"
>  #include "unipro.h"
> +#include "ufs-sysfs.h"
>  
>  #define CREATE_TRACE_POINTS
>  #include <trace/events/ufs.h>
> @@ -150,7 +151,7 @@ enum {
>  #define ufshcd_is_ufs_dev_poweroff(h) \
>  	((h)->curr_dev_pwr_mode == UFS_POWERDOWN_PWR_MODE)
>  
> -static struct ufs_pm_lvl_states ufs_pm_lvl_states[] = {
> +struct ufs_pm_lvl_states ufs_pm_lvl_states[] = {
>  	{UFS_ACTIVE_PWR_MODE, UIC_LINK_ACTIVE_STATE},
>  	{UFS_ACTIVE_PWR_MODE, UIC_LINK_HIBERN8_STATE},
>  	{UFS_SLEEP_PWR_MODE, UIC_LINK_ACTIVE_STATE},
> @@ -813,28 +814,6 @@ static inline bool ufshcd_is_hba_active(struct ufs_hba *hba)
>  		? false : true;
>  }
>  
> -static const char *ufschd_uic_link_state_to_string(
> -			enum uic_link_state state)
> -{
> -	switch (state) {
> -	case UIC_LINK_OFF_STATE:	return "OFF";
> -	case UIC_LINK_ACTIVE_STATE:	return "ACTIVE";
> -	case UIC_LINK_HIBERN8_STATE:	return "HIBERN8";
> -	default:			return "UNKNOWN";
> -	}
> -}
> -
> -static const char *ufschd_ufs_dev_pwr_mode_to_string(
> -			enum ufs_dev_pwr_mode state)
> -{
> -	switch (state) {
> -	case UFS_ACTIVE_PWR_MODE:	return "ACTIVE";
> -	case UFS_SLEEP_PWR_MODE:	return "SLEEP";
> -	case UFS_POWERDOWN_PWR_MODE:	return "POWERDOWN";
> -	default:			return "UNKNOWN";
> -	}
> -}
> -
>  u32 ufshcd_get_local_unipro_ver(struct ufs_hba *hba)
>  {
>  	/* HCI version 1.0 and 1.1 supports UniPro 1.41 */
> @@ -7585,133 +7564,6 @@ int ufshcd_runtime_idle(struct ufs_hba *hba)
>  }
>  EXPORT_SYMBOL(ufshcd_runtime_idle);
>  
> -static inline ssize_t ufshcd_pm_lvl_store(struct device *dev,
> -					   struct device_attribute *attr,
> -					   const char *buf, size_t count,
> -					   bool rpm)
> -{
> -	struct ufs_hba *hba = dev_get_drvdata(dev);
> -	unsigned long flags, value;
> -
> -	if (kstrtoul(buf, 0, &value))
> -		return -EINVAL;
> -
> -	if (value >= UFS_PM_LVL_MAX)
> -		return -EINVAL;
> -
> -	spin_lock_irqsave(hba->host->host_lock, flags);
> -	if (rpm)
> -		hba->rpm_lvl = value;
> -	else
> -		hba->spm_lvl = value;
> -	spin_unlock_irqrestore(hba->host->host_lock, flags);
> -	return count;
> -}
> -
> -static ssize_t ufshcd_rpm_lvl_show(struct device *dev,
> -		struct device_attribute *attr, char *buf)
> -{
> -	struct ufs_hba *hba = dev_get_drvdata(dev);
> -	int curr_len;
> -	u8 lvl;
> -
> -	curr_len = snprintf(buf, PAGE_SIZE,
> -			    "\nCurrent Runtime PM level [%d] => dev_state [%s] link_state [%s]\n",
> -			    hba->rpm_lvl,
> -			    ufschd_ufs_dev_pwr_mode_to_string(
> -				ufs_pm_lvl_states[hba->rpm_lvl].dev_state),
> -			    ufschd_uic_link_state_to_string(
> -				ufs_pm_lvl_states[hba->rpm_lvl].link_state));
> -
> -	curr_len += snprintf((buf + curr_len), (PAGE_SIZE - curr_len),
> -			     "\nAll available Runtime PM levels info:\n");
> -	for (lvl = UFS_PM_LVL_0; lvl < UFS_PM_LVL_MAX; lvl++)
> -		curr_len += snprintf((buf + curr_len), (PAGE_SIZE - curr_len),
> -				     "\tRuntime PM level [%d] => dev_state [%s] link_state [%s]\n",
> -				    lvl,
> -				    ufschd_ufs_dev_pwr_mode_to_string(
> -					ufs_pm_lvl_states[lvl].dev_state),
> -				    ufschd_uic_link_state_to_string(
> -					ufs_pm_lvl_states[lvl].link_state));
> -
> -	return curr_len;
> -}
> -
> -static ssize_t ufshcd_rpm_lvl_store(struct device *dev,
> -		struct device_attribute *attr, const char *buf, size_t count)
> -{
> -	return ufshcd_pm_lvl_store(dev, attr, buf, count, true);
> -}
> -
> -static void ufshcd_add_rpm_lvl_sysfs_nodes(struct ufs_hba *hba)
> -{
> -	hba->rpm_lvl_attr.show = ufshcd_rpm_lvl_show;
> -	hba->rpm_lvl_attr.store = ufshcd_rpm_lvl_store;
> -	sysfs_attr_init(&hba->rpm_lvl_attr.attr);
> -	hba->rpm_lvl_attr.attr.name = "rpm_lvl";
> -	hba->rpm_lvl_attr.attr.mode = 0644;
> -	if (device_create_file(hba->dev, &hba->rpm_lvl_attr))
> -		dev_err(hba->dev, "Failed to create sysfs for rpm_lvl\n");
> -}
> -
> -static ssize_t ufshcd_spm_lvl_show(struct device *dev,
> -		struct device_attribute *attr, char *buf)
> -{
> -	struct ufs_hba *hba = dev_get_drvdata(dev);
> -	int curr_len;
> -	u8 lvl;
> -
> -	curr_len = snprintf(buf, PAGE_SIZE,
> -			    "\nCurrent System PM level [%d] => dev_state [%s] link_state [%s]\n",
> -			    hba->spm_lvl,
> -			    ufschd_ufs_dev_pwr_mode_to_string(
> -				ufs_pm_lvl_states[hba->spm_lvl].dev_state),
> -			    ufschd_uic_link_state_to_string(
> -				ufs_pm_lvl_states[hba->spm_lvl].link_state));
> -
> -	curr_len += snprintf((buf + curr_len), (PAGE_SIZE - curr_len),
> -			     "\nAll available System PM levels info:\n");
> -	for (lvl = UFS_PM_LVL_0; lvl < UFS_PM_LVL_MAX; lvl++)
> -		curr_len += snprintf((buf + curr_len), (PAGE_SIZE - curr_len),
> -				     "\tSystem PM level [%d] => dev_state [%s] link_state [%s]\n",
> -				    lvl,
> -				    ufschd_ufs_dev_pwr_mode_to_string(
> -					ufs_pm_lvl_states[lvl].dev_state),
> -				    ufschd_uic_link_state_to_string(
> -					ufs_pm_lvl_states[lvl].link_state));
> -
> -	return curr_len;
> -}
> -
> -static ssize_t ufshcd_spm_lvl_store(struct device *dev,
> -		struct device_attribute *attr, const char *buf, size_t count)
> -{
> -	return ufshcd_pm_lvl_store(dev, attr, buf, count, false);
> -}
> -
> -static void ufshcd_add_spm_lvl_sysfs_nodes(struct ufs_hba *hba)
> -{
> -	hba->spm_lvl_attr.show = ufshcd_spm_lvl_show;
> -	hba->spm_lvl_attr.store = ufshcd_spm_lvl_store;
> -	sysfs_attr_init(&hba->spm_lvl_attr.attr);
> -	hba->spm_lvl_attr.attr.name = "spm_lvl";
> -	hba->spm_lvl_attr.attr.mode = 0644;
> -	if (device_create_file(hba->dev, &hba->spm_lvl_attr))
> -		dev_err(hba->dev, "Failed to create sysfs for spm_lvl\n");
> -}
> -
> -static inline void ufshcd_add_sysfs_nodes(struct ufs_hba *hba)
> -{
> -	ufshcd_add_rpm_lvl_sysfs_nodes(hba);
> -	ufshcd_add_spm_lvl_sysfs_nodes(hba);
> -}
> -
> -static inline void ufshcd_remove_sysfs_nodes(struct ufs_hba *hba)
> -{
> -	device_remove_file(hba->dev, &hba->rpm_lvl_attr);
> -	device_remove_file(hba->dev, &hba->spm_lvl_attr);
> -}
> -
>  /**
>   * ufshcd_shutdown - shutdown routine
>   * @hba: per adapter instance
> @@ -7749,7 +7601,7 @@ EXPORT_SYMBOL(ufshcd_shutdown);
>   */
>  void ufshcd_remove(struct ufs_hba *hba)
>  {
> -	ufshcd_remove_sysfs_nodes(hba);
> +	ufs_sysfs_remove_nodes(hba->dev);
>  	scsi_remove_host(hba->host);
>  	/* disable interrupts */
>  	ufshcd_disable_intr(hba, hba->intr_mask);
> @@ -7996,7 +7848,7 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
>  	ufshcd_set_ufs_dev_active(hba);
>  
>  	async_schedule(ufshcd_async_scan, hba);
> -	ufshcd_add_sysfs_nodes(hba);
> +	ufs_sysfs_add_nodes(hba->dev);
>  
>  	return 0;
>  
> diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
> index 1332e54..53e2779 100644
> --- a/drivers/scsi/ufs/ufshcd.h
> +++ b/drivers/scsi/ufs/ufshcd.h
> @@ -985,4 +985,6 @@ static inline void ufshcd_vops_dbg_register_dump(struct ufs_hba *hba)
>  		hba->vops->dbg_register_dump(hba);
>  }
>  
> +extern struct ufs_pm_lvl_states ufs_pm_lvl_states[];
> +
>  #endif /* End of Header */
> -- 
> 2.7.4

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v5 02/11] scsi: ufs: sysfs: device descriptor
  2018-02-06 16:06 ` [PATCH v5 02/11] scsi: ufs: sysfs: device descriptor Stanislav Nijnikov
@ 2018-02-12  1:07   ` Jaegeuk Kim
  2018-02-12 11:21     ` Stanislav Nijnikov
  0 siblings, 1 reply; 19+ messages in thread
From: Jaegeuk Kim @ 2018-02-12  1:07 UTC (permalink / raw)
  To: Stanislav Nijnikov; +Cc: linux-scsi, linux-kernel, gregkh, alex.lemberg

On 02/06, Stanislav Nijnikov wrote:
> This patch introduces a sysfs group entry for the UFS device descriptor
> parameters. The group adds "device_descriptor" folder under the UFS driver
> sysfs entry (/sys/bus/platform/drivers/ufshcd/*). The parameters are shown
> as hexadecimal numbers. The full information about the parameters could be
> found at UFS specifications 2.1.
> 
> Signed-off-by: Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> ---
>  Documentation/ABI/testing/sysfs-driver-ufs | 223 +++++++++++++++++++++++++++++
>  drivers/scsi/ufs/ufs-sysfs.c               | 116 +++++++++++++++
>  drivers/scsi/ufs/ufs.h                     |   8 ++
>  drivers/scsi/ufs/ufshcd.c                  |  12 +-
>  drivers/scsi/ufs/ufshcd.h                  |   6 +
>  5 files changed, 359 insertions(+), 6 deletions(-)
>  create mode 100644 Documentation/ABI/testing/sysfs-driver-ufs
> 
> diff --git a/Documentation/ABI/testing/sysfs-driver-ufs b/Documentation/ABI/testing/sysfs-driver-ufs
> new file mode 100644
> index 0000000..8da7b84
> --- /dev/null
> +++ b/Documentation/ABI/testing/sysfs-driver-ufs
> @@ -0,0 +1,223 @@
> +What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/device_type
> +Date:		February 2018
> +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> +Description:	This file shows the device type. This is one of the UFS
> +		device descriptor parameters. The full information about
> +		the descriptor could be found at UFS specifications 2.1.
> +		The file is read only.
> +
> +What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/device_class
> +Date:		February 2018
> +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> +Description:	This file shows the device class. This is one of the UFS
> +		device descriptor parameters. The full information about
> +		the descriptor could be found at UFS specifications 2.1.
> +		The file is read only.
> +
> +What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/device_sub_class
> +Date:		February 2018
> +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> +Description:	This file shows the UFS storage subclass. This is one of
> +		the UFS device descriptor parameters. The full information
> +		about the descriptor could be found at UFS specifications 2.1.
> +		The file is read only.
> +
> +What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/protocol
> +Date:		February 2018
> +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> +Description:	This file shows the protocol supported by an UFS device.
> +		This is one of the UFS device descriptor parameters.
> +		The full information about the descriptor could be found
> +		at UFS specifications 2.1.
> +		The file is read only.
> +
> +What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/number_of_luns
> +Date:		February 2018
> +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> +Description:	This file shows number of logical units. This is one of
> +		the UFS device descriptor parameters. The full information
> +		about the descriptor could be found at UFS specifications 2.1.
> +		The file is read only.
> +
> +What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/number_of_wluns
> +Date:		February 2018
> +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> +Description:	This file shows number of well known logical units.
> +		This is one of the UFS device descriptor parameters.
> +		The full information about the descriptor could be found
> +		at UFS specifications 2.1.
> +		The file is read only.
> +
> +What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/boot_enable
> +Date:		February 2018
> +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> +Description:	This file shows value that indicates whether the device is
> +		enabled for boot. This is one of the UFS device descriptor
> +		parameters. The full information about the descriptor could
> +		be found at UFS specifications 2.1.
> +		The file is read only.
> +
> +What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/descriptor_access_enable
> +Date:		February 2018
> +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> +Description:	This file shows value that indicates whether the device
> +		descriptor could be read after partial initialization phase
> +		of the boot sequence. This is one of the UFS device descriptor
> +		parameters. The full information about the descriptor could
> +		be found at UFS specifications 2.1.
> +		The file is read only.
> +
> +What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/initial_power_mode
> +Date:		February 2018
> +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> +Description:	This file shows value that defines the power mode after
> +		device initialization or hardware reset. This is one of
> +		the UFS device descriptor parameters. The full information
> +		about the descriptor could be found at UFS specifications 2.1.
> +		The file is read only.
> +
> +What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/high_priority_lun
> +Date:		February 2018
> +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> +Description:	This file shows the high priority lun. This is one of
> +		the UFS device descriptor parameters. The full information
> +		about the descriptor could be found at UFS specifications 2.1.
> +		The file is read only.
> +
> +What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/secure_removal_type
> +Date:		February 2018
> +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> +Description:	This file shows the secure removal type. This is one of
> +		the UFS device descriptor parameters. The full information
> +		about the descriptor could be found at UFS specifications 2.1.
> +		The file is read only.
> +
> +What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/support_security_lun
> +Date:		February 2018
> +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> +Description:	This file shows whether the security lun is supported.
> +		This is one of the UFS device descriptor parameters.
> +		The full information about the descriptor could be found
> +		at UFS specifications 2.1.
> +		The file is read only.
> +
> +What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/bkops_termination_latency
> +Date:		February 2018
> +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> +Description:	This file shows the background operations termination
> +		latency. This is one of the UFS device descriptor parameters.
> +		The full information about the descriptor could be found
> +		at UFS specifications 2.1.
> +		The file is read only.
> +
> +What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/initial_active_icc_level
> +Date:		February 2018
> +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> +Description:	This file shows the initial active ICC level. This is one
> +		of the UFS device descriptor parameters. The full information
> +		about the descriptor could be found at UFS specifications 2.1.
> +		The file is read only.
> +
> +What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/specification_version
> +Date:		February 2018
> +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> +Description:	This file shows the specification version. This is one
> +		of the UFS device descriptor parameters. The full information
> +		about the descriptor could be found at UFS specifications 2.1.
> +		The file is read only.
> +
> +What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/manufacturing_date
> +Date:		February 2018
> +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> +Description:	This file shows the manufacturing date in BCD format.
> +		This is one of the UFS device descriptor parameters.
> +		The full information about the descriptor could be found
> +		at UFS specifications 2.1.
> +		The file is read only.
> +
> +What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/manufacturer_id
> +Date:		February 2018
> +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> +Description:	This file shows the manufacturee ID. This is one of the
> +		UFS device descriptor parameters. The full information about
> +		the descriptor could be found at UFS specifications 2.1.
> +		The file is read only.
> +
> +What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/rtt_capability
> +Date:		February 2018
> +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> +Description:	This file shows the maximum number of outstanding RTTs
> +		supported by the device. This is one of the UFS device
> +		descriptor parameters. The full information about
> +		the descriptor could be found at UFS specifications 2.1.
> +		The file is read only.
> +
> +What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/rtc_update
> +Date:		February 2018
> +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> +Description:	This file shows the frequency and method of the realtime
> +		clock update. This is one of the UFS device descriptor
> +		parameters. The full information about the descriptor
> +		could be found at UFS specifications 2.1.
> +		The file is read only.
> +
> +What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/ufs_features
> +Date:		February 2018
> +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> +Description:	This file shows which features are supported by the device.
> +		This is one of the UFS device descriptor parameters.
> +		The full information about the descriptor could be
> +		found at UFS specifications 2.1.
> +		The file is read only.
> +
> +What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/ffu_timeout
> +Date:		February 2018
> +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> +Description:	This file shows the FFU timeout. This is one of the
> +		UFS device descriptor parameters. The full information
> +		about the descriptor could be found at UFS specifications 2.1.
> +		The file is read only.
> +
> +What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/queue_depth
> +Date:		February 2018
> +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> +Description:	This file shows the device queue depth. This is one of the
> +		UFS device descriptor parameters. The full information
> +		about the descriptor could be found at UFS specifications 2.1.
> +		The file is read only.
> +
> +What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/device_version
> +Date:		February 2018
> +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> +Description:	This file shows the device version. This is one of the
> +		UFS device descriptor parameters. The full information
> +		about the descriptor could be found at UFS specifications 2.1.
> +		The file is read only.
> +
> +What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/number_of_secure_wpa
> +Date:		February 2018
> +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> +Description:	This file shows number of secure write protect areas
> +		supported by the device. This is one of the UFS device
> +		descriptor parameters. The full information about
> +		the descriptor could be found at UFS specifications 2.1.
> +		The file is read only.
> +
> +What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/psa_max_data_size
> +Date:		February 2018
> +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> +Description:	This file shows the maximum amount of data that may be
> +		written during the pre-soldering phase of the PSA flow.
> +		This is one of the UFS device descriptor parameters.
> +		The full information about the descriptor could be found
> +		at UFS specifications 2.1.
> +		The file is read only.
> +
> +What:		/sys/bus/platform/drivers/ufshcd/*/device_descriptor/psa_state_timeout
> +Date:		February 2018
> +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> +Description:	This file shows the command maximum timeout for a change
> +		in PSA state. This is one of the UFS device descriptor
> +		parameters. The full information about the descriptor could
> +		be found at UFS specifications 2.1.
> +		The file is read only.
> diff --git a/drivers/scsi/ufs/ufs-sysfs.c b/drivers/scsi/ufs/ufs-sysfs.c
> index ce8dcb6..aa2779a 100644
> --- a/drivers/scsi/ufs/ufs-sysfs.c
> +++ b/drivers/scsi/ufs/ufs-sysfs.c
> @@ -3,7 +3,9 @@
>  
>  #include <linux/err.h>
>  #include <linux/string.h>
> +#include <asm/unaligned.h>
>  
> +#include "ufs.h"
>  #include "ufs-sysfs.h"
>  
>  static const char *ufschd_uic_link_state_to_string(
> @@ -134,8 +136,122 @@ static const struct attribute_group ufs_sysfs_default_group = {
>  	.attrs = ufs_sysfs_ufshcd_attrs,
>  };
>  
> +static ssize_t ufs_sysfs_read_desc_param(struct ufs_hba *hba,
> +				  enum desc_idn desc_id,
> +				  u8 desc_index,
> +				  u8 param_offset,
> +				  u8 *sysfs_buf,
> +				  u8 param_size)
> +{
> +	u8 desc_buf[8] = {0};
> +	int ret;
> +
> +	if (param_size > 8)
> +		return -EINVAL;
> +
> +	ret = ufshcd_read_desc_param(hba, desc_id, desc_index,
> +				param_offset, desc_buf, param_size);
> +	if (ret)
> +		return -EINVAL;
> +	switch (param_size) {
> +	case 1:
> +		ret = sprintf(sysfs_buf, "0x%02X\n", *desc_buf);
> +		break;
> +	case 2:
> +		ret = sprintf(sysfs_buf, "0x%04X\n",
> +			get_unaligned_be16(desc_buf));
> +		break;
> +	case 4:
> +		ret = sprintf(sysfs_buf, "0x%08X\n",
> +			get_unaligned_be32(desc_buf));
> +		break;
> +	case 8:
> +		ret = sprintf(sysfs_buf, "0x%016llX\n",
> +			get_unaligned_be64(desc_buf));
> +		break;
> +	}
> +
> +	return ret;
> +}
> +
> +#define UFS_DESC_PARAM(_name, _puname, _duname, _size)			\
> +static ssize_t _name##_show(struct device *dev,				\
> +	struct device_attribute *attr, char *buf)			\
> +{									\
> +	struct ufs_hba *hba = dev_get_drvdata(dev);			\
> +	return ufs_sysfs_read_desc_param(hba, QUERY_DESC_IDN_##_duname,	\
> +		0, _duname##_DESC_PARAM##_puname, buf, _size);		\
> +}									\
> +static DEVICE_ATTR_RO(_name)
> +
> +#define UFS_DEVICE_DESC_PARAM(_name, _uname, _size)			\
> +	UFS_DESC_PARAM(_name, _uname, DEVICE, _size)
> +
> +UFS_DEVICE_DESC_PARAM(device_type, _DEVICE_TYPE, 1);
> +UFS_DEVICE_DESC_PARAM(device_class, _DEVICE_CLASS, 1);
> +UFS_DEVICE_DESC_PARAM(device_sub_class, _DEVICE_SUB_CLASS, 1);
> +UFS_DEVICE_DESC_PARAM(protocol, _PRTCL, 1);
> +UFS_DEVICE_DESC_PARAM(number_of_luns, _NUM_LU, 1);
> +UFS_DEVICE_DESC_PARAM(number_of_wluns, _NUM_WLU, 1);
> +UFS_DEVICE_DESC_PARAM(boot_enable, _BOOT_ENBL, 1);
> +UFS_DEVICE_DESC_PARAM(descriptor_access_enable, _DESC_ACCSS_ENBL, 1);
> +UFS_DEVICE_DESC_PARAM(initial_power_mode, _INIT_PWR_MODE, 1);
> +UFS_DEVICE_DESC_PARAM(high_priority_lun, _HIGH_PR_LUN, 1);
> +UFS_DEVICE_DESC_PARAM(secure_removal_type, _SEC_RMV_TYPE, 1);
> +UFS_DEVICE_DESC_PARAM(support_security_lun, _SEC_LU, 1);
> +UFS_DEVICE_DESC_PARAM(bkops_termination_latency, _BKOP_TERM_LT, 1);
> +UFS_DEVICE_DESC_PARAM(initial_active_icc_level, _ACTVE_ICC_LVL, 1);
> +UFS_DEVICE_DESC_PARAM(specification_version, _SPEC_VER, 2);
> +UFS_DEVICE_DESC_PARAM(manufacturing_date, _MANF_DATE, 2);
> +UFS_DEVICE_DESC_PARAM(manufacturer_id, _MANF_ID, 2);
> +UFS_DEVICE_DESC_PARAM(rtt_capability, _RTT_CAP, 1);
> +UFS_DEVICE_DESC_PARAM(rtc_update, _FRQ_RTC, 2);
> +UFS_DEVICE_DESC_PARAM(ufs_features, _UFS_FEAT, 1);
> +UFS_DEVICE_DESC_PARAM(ffu_timeout, _FFU_TMT, 1);
> +UFS_DEVICE_DESC_PARAM(queue_depth, _Q_DPTH, 1);
> +UFS_DEVICE_DESC_PARAM(device_version, _DEV_VER, 2);
> +UFS_DEVICE_DESC_PARAM(number_of_secure_wpa, _NUM_SEC_WPA, 1);
> +UFS_DEVICE_DESC_PARAM(psa_max_data_size, _PSA_MAX_DATA, 4);
> +UFS_DEVICE_DESC_PARAM(psa_state_timeout, _PSA_TMT, 1);

Could you add this case as well?

DEVICE_DESC_PARAM_PRDCT_REV		= 0x2A,

> +
> +static struct attribute *ufs_sysfs_device_descriptor[] = {
> +	&dev_attr_device_type.attr,
> +	&dev_attr_device_class.attr,
> +	&dev_attr_device_sub_class.attr,
> +	&dev_attr_protocol.attr,
> +	&dev_attr_number_of_luns.attr,
> +	&dev_attr_number_of_wluns.attr,
> +	&dev_attr_boot_enable.attr,
> +	&dev_attr_descriptor_access_enable.attr,
> +	&dev_attr_initial_power_mode.attr,
> +	&dev_attr_high_priority_lun.attr,
> +	&dev_attr_secure_removal_type.attr,
> +	&dev_attr_support_security_lun.attr,
> +	&dev_attr_bkops_termination_latency.attr,
> +	&dev_attr_initial_active_icc_level.attr,
> +	&dev_attr_specification_version.attr,
> +	&dev_attr_manufacturing_date.attr,
> +	&dev_attr_manufacturer_id.attr,
> +	&dev_attr_rtt_capability.attr,
> +	&dev_attr_rtc_update.attr,
> +	&dev_attr_ufs_features.attr,
> +	&dev_attr_ffu_timeout.attr,
> +	&dev_attr_queue_depth.attr,
> +	&dev_attr_device_version.attr,
> +	&dev_attr_number_of_secure_wpa.attr,
> +	&dev_attr_psa_max_data_size.attr,
> +	&dev_attr_psa_state_timeout.attr,
> +	NULL,
> +};
> +
> +static const struct attribute_group ufs_sysfs_device_descriptor_group = {
> +	.name = "device_descriptor",
> +	.attrs = ufs_sysfs_device_descriptor,
> +};
> +
>  static const struct attribute_group *ufs_sysfs_groups[] = {
>  	&ufs_sysfs_default_group,
> +	&ufs_sysfs_device_descriptor_group,
>  	NULL,
>  };
>  
> diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h
> index 54deeb7..6ae1e08 100644
> --- a/drivers/scsi/ufs/ufs.h
> +++ b/drivers/scsi/ufs/ufs.h
> @@ -220,6 +220,14 @@ enum device_desc_param {
>  	DEVICE_DESC_PARAM_UD_LEN		= 0x1B,
>  	DEVICE_DESC_PARAM_RTT_CAP		= 0x1C,
>  	DEVICE_DESC_PARAM_FRQ_RTC		= 0x1D,
> +	DEVICE_DESC_PARAM_UFS_FEAT		= 0x1F,
> +	DEVICE_DESC_PARAM_FFU_TMT		= 0x20,
> +	DEVICE_DESC_PARAM_Q_DPTH		= 0x21,
> +	DEVICE_DESC_PARAM_DEV_VER		= 0x22,
> +	DEVICE_DESC_PARAM_NUM_SEC_WPA		= 0x24,
> +	DEVICE_DESC_PARAM_PSA_MAX_DATA		= 0x25,
> +	DEVICE_DESC_PARAM_PSA_TMT		= 0x29,
> +	DEVICE_DESC_PARAM_PRDCT_REV		= 0x2A,
>  };
>  
>  /*
> diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
> index e7621a0a..540a431 100644
> --- a/drivers/scsi/ufs/ufshcd.c
> +++ b/drivers/scsi/ufs/ufshcd.c
> @@ -2989,12 +2989,12 @@ EXPORT_SYMBOL(ufshcd_map_desc_id_to_length);
>   *
>   * Return 0 in case of success, non-zero otherwise
>   */
> -static int ufshcd_read_desc_param(struct ufs_hba *hba,
> -				  enum desc_idn desc_id,
> -				  int desc_index,
> -				  u8 param_offset,
> -				  u8 *param_read_buf,
> -				  u8 param_size)
> +int ufshcd_read_desc_param(struct ufs_hba *hba,
> +			   enum desc_idn desc_id,
> +			   int desc_index,
> +			   u8 param_offset,
> +			   u8 *param_read_buf,
> +			   u8 param_size)
>  {
>  	int ret;
>  	u8 *desc_buf;
> diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
> index 53e2779..38c307d 100644
> --- a/drivers/scsi/ufs/ufshcd.h
> +++ b/drivers/scsi/ufs/ufshcd.h
> @@ -841,6 +841,12 @@ static inline bool ufshcd_is_hs_mode(struct ufs_pa_layer_attr *pwr_info)
>  }
>  
>  /* Expose Query-Request API */
> +int ufshcd_read_desc_param(struct ufs_hba *hba,
> +			   enum desc_idn desc_id,
> +			   int desc_index,
> +			   u8 param_offset,
> +			   u8 *param_read_buf,
> +			   u8 param_size);
>  int ufshcd_query_flag(struct ufs_hba *hba, enum query_opcode opcode,
>  	enum flag_idn idn, bool *flag_res);
>  int ufshcd_hold(struct ufs_hba *hba, bool async);
> -- 
> 2.7.4

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v5 01/11] scsi: ufs: sysfs: attribute group for existing sysfs entries.
  2018-02-12  1:06   ` Jaegeuk Kim
@ 2018-02-12  9:31     ` Philippe Ombredanne
  2018-02-12 11:06     ` Stanislav Nijnikov
  1 sibling, 0 replies; 19+ messages in thread
From: Philippe Ombredanne @ 2018-02-12  9:31 UTC (permalink / raw)
  To: Jaegeuk Kim
  Cc: Stanislav Nijnikov, linux-scsi, LKML, Greg Kroah-Hartman,
	alex.lemberg, Russell King, Christoph Hellwig, Thomas Gleixner

Dear Stanislav,

On Mon, Feb 12, 2018 at 2:06 AM, Jaegeuk Kim <jaegeuk@kernel.org> wrote:
> On 02/06, Stanislav Nijnikov wrote:
>> This patch introduces attribute group to show existing sysfs entries.
>>
>> Signed-off-by: Stanislav Nijnikov <stanislav.nijnikov@wdc.com>

<snip>

>> --- /dev/null
>> +++ b/drivers/scsi/ufs/ufs-sysfs.c
>> @@ -0,0 +1,156 @@
>> +// SPDX-License-Identifier: GPL-2.0-only

I commend you for using license ids here. But there is an issue with
your attempt to use the latest and greatest license ids from SPDX:
GPL-2.0-only is not a documented license id in our doc [1]
Until this is updated (help welcomed including patching a few 10K+
files) , this should be GPL-2.0 instead to avoid confusion and keep
things homogeneous and tidy.

FYI, using only the doc as the reference was brought forward by
Russell King and Christoph Hellwig and in particular with this:

On Thu, Nov 9, 2017 at 5:44 PM, Russell King <rmk@armlinux.org.uk> wrote:

> I'd be more comfortable if we could have something in the kernel tree
> that identifies the SPDX tags and their meaning, maybe with the
> _standard_ file header for that license included, so there is no
> argument about what any particular SPDX tag means.

Based on this, Thomas Gleixner updated the doc alright following this
important point. So, in case of doubt the doc should be the reference
for this and nothing else. And if there are issue with the doc, then
we can fix it with a patch ;)

CC: Russell King <rmk@armlinux.org.uk>
CC: Christoph Hellwig <hch@infradead.org>
CC: Thomas Gleixner <tglx@linutronix.de>

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/process/license-rules.rst
-- 
Cordially
Philippe Ombredanne

^ permalink raw reply	[flat|nested] 19+ messages in thread

* RE: [PATCH v5 01/11] scsi: ufs: sysfs: attribute group for existing sysfs entries.
  2018-02-12  1:06   ` Jaegeuk Kim
  2018-02-12  9:31     ` Philippe Ombredanne
@ 2018-02-12 11:06     ` Stanislav Nijnikov
  1 sibling, 0 replies; 19+ messages in thread
From: Stanislav Nijnikov @ 2018-02-12 11:06 UTC (permalink / raw)
  To: Jaegeuk Kim; +Cc: linux-scsi, linux-kernel, gregkh, Alex Lemberg



> -----Original Message-----
> From: Jaegeuk Kim [mailto:jaegeuk@kernel.org]
> Sent: Monday, February 12, 2018 3:06 AM
> To: Stanislav Nijnikov <Stanislav.Nijnikov@wdc.com>
> Cc: linux-scsi@vger.kernel.org; linux-kernel@vger.kernel.org;
> gregkh@linuxfoundation.org; Alex Lemberg <Alex.Lemberg@wdc.com>
> Subject: Re: [PATCH v5 01/11] scsi: ufs: sysfs: attribute group for existing
> sysfs entries.
> 
> On 02/06, Stanislav Nijnikov wrote:
> > This patch introduces attribute group to show existing sysfs entries.
> >
> > Signed-off-by: Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > ---
> >  drivers/scsi/ufs/Makefile    |   3 +-
> >  drivers/scsi/ufs/ufs-sysfs.c | 156
> > +++++++++++++++++++++++++++++++++++++++++++
> >  drivers/scsi/ufs/ufs-sysfs.h |  14 ++++
> >  drivers/scsi/ufs/ufshcd.c    | 156 ++-----------------------------------------
> >  drivers/scsi/ufs/ufshcd.h    |   2 +
> >  5 files changed, 178 insertions(+), 153 deletions(-)  create mode
> > 100644 drivers/scsi/ufs/ufs-sysfs.c  create mode 100644
> > drivers/scsi/ufs/ufs-sysfs.h
> >
> > diff --git a/drivers/scsi/ufs/Makefile b/drivers/scsi/ufs/Makefile
> > index 9310c6c..918f579 100644
> > --- a/drivers/scsi/ufs/Makefile
> > +++ b/drivers/scsi/ufs/Makefile
> > @@ -3,6 +3,7 @@
> >  obj-$(CONFIG_SCSI_UFS_DWC_TC_PCI) += tc-dwc-g210-pci.o ufshcd-
> dwc.o
> > tc-dwc-g210.o
> >  obj-$(CONFIG_SCSI_UFS_DWC_TC_PLATFORM) += tc-dwc-g210-pltfrm.o
> > ufshcd-dwc.o tc-dwc-g210.o
> >  obj-$(CONFIG_SCSI_UFS_QCOM) += ufs-qcom.o
> > -obj-$(CONFIG_SCSI_UFSHCD) += ufshcd.o
> > +obj-$(CONFIG_SCSI_UFSHCD) += ufshcd-core.o ufshcd-core-objs :=
> > +ufshcd.o ufs-sysfs.o
> >  obj-$(CONFIG_SCSI_UFSHCD_PCI) += ufshcd-pci.o
> >  obj-$(CONFIG_SCSI_UFSHCD_PLATFORM) += ufshcd-pltfrm.o diff --git
> > a/drivers/scsi/ufs/ufs-sysfs.c b/drivers/scsi/ufs/ufs-sysfs.c new file
> > mode 100644 index 0000000..ce8dcb6
> > --- /dev/null
> > +++ b/drivers/scsi/ufs/ufs-sysfs.c
> > @@ -0,0 +1,156 @@
> > +// SPDX-License-Identifier: GPL-2.0-only // Copyright (C) 2018
> > +Western Digital Corporation
> > +
> > +#include <linux/err.h>
> > +#include <linux/string.h>
> > +
> > +#include "ufs-sysfs.h"
> > +
> > +static const char *ufschd_uic_link_state_to_string(
> > +			enum uic_link_state state)
> > +{
> > +	switch (state) {
> > +	case UIC_LINK_OFF_STATE:	return "OFF";
> > +	case UIC_LINK_ACTIVE_STATE:	return "ACTIVE";
> > +	case UIC_LINK_HIBERN8_STATE:	return "HIBERN8";
> > +	default:			return "UNKNOWN";
> > +	}
> > +}
> > +
> > +static const char *ufschd_ufs_dev_pwr_mode_to_string(
> > +			enum ufs_dev_pwr_mode state)
> > +{
> > +	switch (state) {
> > +	case UFS_ACTIVE_PWR_MODE:	return "ACTIVE";
> > +	case UFS_SLEEP_PWR_MODE:	return "SLEEP";
> > +	case UFS_POWERDOWN_PWR_MODE:	return "POWERDOWN";
> > +	default:			return "UNKNOWN";
> > +	}
> > +}
> > +
> > +static inline ssize_t ufs_sysfs_pm_lvl_store(struct device *dev,
> > +					     struct device_attribute *attr,
> > +					     const char *buf, size_t count,
> > +					     bool rpm)
> > +{
> > +	struct ufs_hba *hba = dev_get_drvdata(dev);
> > +	unsigned long flags, value;
> > +
> > +	if (kstrtoul(buf, 0, &value))
> > +		return -EINVAL;
> > +
> > +	if (value >= UFS_PM_LVL_MAX)
> > +		return -EINVAL;
> > +
> > +	spin_lock_irqsave(hba->host->host_lock, flags);
> > +	if (rpm)
> > +		hba->rpm_lvl = value;
> > +	else
> > +		hba->spm_lvl = value;
> > +	spin_unlock_irqrestore(hba->host->host_lock, flags);
> > +	return count;
> > +}
> > +
> > +static ssize_t rpm_lvl_show(struct device *dev,
> > +		struct device_attribute *attr, char *buf) {
> > +	struct ufs_hba *hba = dev_get_drvdata(dev);
> > +	int curr_len;
> > +	u8 lvl;
> > +
> > +	curr_len = snprintf(buf, PAGE_SIZE,
> > +			    "\nCurrent Runtime PM level [%d] => dev_state
> [%s] link_state [%s]\n",
> > +			    hba->rpm_lvl,
> > +			    ufschd_ufs_dev_pwr_mode_to_string(
> > +				ufs_pm_lvl_states[hba-
> >rpm_lvl].dev_state),
> > +			    ufschd_uic_link_state_to_string(
> > +				ufs_pm_lvl_states[hba-
> >rpm_lvl].link_state));
> 
> If there is no objection regarding to backward compatibility, can we also clean
> this up by adding multiple entries having single string each, as Greg
> recommended?
> 
> For example,
> 
> /rpm_level
> 1
> 
> /rpm_dev_state
> ACTIVE
> 
> /rpm_link_state
> HIBERN8
> 
> /spm_level
> 2
> 
> /spm_dev_state
> SLEEP
> 
> /spm_link_state
> ACTIVE
> 
> /avail_dev_states
> 0:ACTIVE 1:ACTIVE 2:SLEEP 3:SLEEP 4:POWERDOWN 5:POWERDOWN
> 
> /avail_link_states
> 0:ACTIVE 1:HIBERN8 2:ACTIVE 3:HIBERN8 4:HIBERN8 5:OFF
> 
> Thanks,
> 
Hi,
We are planning to fix this in a separate patch.

Regards

> > +
> > +	curr_len += snprintf((buf + curr_len), (PAGE_SIZE - curr_len),
> > +			     "\nAll available Runtime PM levels info:\n");
> > +	for (lvl = UFS_PM_LVL_0; lvl < UFS_PM_LVL_MAX; lvl++)
> > +		curr_len += snprintf((buf + curr_len), (PAGE_SIZE - curr_len),
> > +				     "\tRuntime PM level [%d] => dev_state
> [%s] link_state [%s]\n",
> > +				    lvl,
> > +				    ufschd_ufs_dev_pwr_mode_to_string(
> > +					ufs_pm_lvl_states[lvl].dev_state),
> > +				    ufschd_uic_link_state_to_string(
> > +					ufs_pm_lvl_states[lvl].link_state));
> > +
> > +	return curr_len;
> > +}
> > +
> > +static ssize_t rpm_lvl_store(struct device *dev,
> > +		struct device_attribute *attr, const char *buf, size_t count) {
> > +	return ufs_sysfs_pm_lvl_store(dev, attr, buf, count, true); }
> > +
> > +static ssize_t spm_lvl_show(struct device *dev,
> > +		struct device_attribute *attr, char *buf) {
> > +	struct ufs_hba *hba = dev_get_drvdata(dev);
> > +	int curr_len;
> > +	u8 lvl;
> > +
> > +	curr_len = snprintf(buf, PAGE_SIZE,
> > +			    "\nCurrent System PM level [%d] => dev_state
> [%s] link_state [%s]\n",
> > +			    hba->spm_lvl,
> > +			    ufschd_ufs_dev_pwr_mode_to_string(
> > +				ufs_pm_lvl_states[hba-
> >spm_lvl].dev_state),
> > +			    ufschd_uic_link_state_to_string(
> > +				ufs_pm_lvl_states[hba-
> >spm_lvl].link_state));
> > +
> > +	curr_len += snprintf((buf + curr_len), (PAGE_SIZE - curr_len),
> > +			     "\nAll available System PM levels info:\n");
> > +	for (lvl = UFS_PM_LVL_0; lvl < UFS_PM_LVL_MAX; lvl++)
> > +		curr_len += snprintf((buf + curr_len), (PAGE_SIZE - curr_len),
> > +				     "\tSystem PM level [%d] => dev_state
> [%s] link_state [%s]\n",
> > +				    lvl,
> > +				    ufschd_ufs_dev_pwr_mode_to_string(
> > +					ufs_pm_lvl_states[lvl].dev_state),
> > +				    ufschd_uic_link_state_to_string(
> > +					ufs_pm_lvl_states[lvl].link_state));
> > +
> > +	return curr_len;
> > +}
> > +
> > +static ssize_t spm_lvl_store(struct device *dev,
> > +		struct device_attribute *attr, const char *buf, size_t count) {
> > +	return ufs_sysfs_pm_lvl_store(dev, attr, buf, count, false); }
> > +
> > +static DEVICE_ATTR_RW(rpm_lvl);
> > +static DEVICE_ATTR_RW(spm_lvl);
> > +
> > +static struct attribute *ufs_sysfs_ufshcd_attrs[] = {
> > +	&dev_attr_rpm_lvl.attr,
> > +	&dev_attr_spm_lvl.attr,
> > +	NULL
> > +};
> > +
> > +static const struct attribute_group ufs_sysfs_default_group = {
> > +	.attrs = ufs_sysfs_ufshcd_attrs,
> > +};
> > +
> > +static const struct attribute_group *ufs_sysfs_groups[] = {
> > +	&ufs_sysfs_default_group,
> > +	NULL,
> > +};
> > +
> > +void ufs_sysfs_add_nodes(struct device *dev) {
> > +	int ret;
> > +
> > +	ret = sysfs_create_groups(&dev->kobj, ufs_sysfs_groups);
> > +	if (ret)
> > +		dev_err(dev,
> > +			"%s: sysfs groups creation failed (err = %d)\n",
> > +			__func__, ret);
> > +}
> > +
> > +void ufs_sysfs_remove_nodes(struct device *dev) {
> > +	sysfs_remove_groups(&dev->kobj, ufs_sysfs_groups); }
> > diff --git a/drivers/scsi/ufs/ufs-sysfs.h
> > b/drivers/scsi/ufs/ufs-sysfs.h new file mode 100644 index
> > 0000000..4a984ca
> > --- /dev/null
> > +++ b/drivers/scsi/ufs/ufs-sysfs.h
> > @@ -0,0 +1,14 @@
> > +/* SPDX-License-Identifier: GPL-2.0-only
> > + * Copyright (C) 2018 Western Digital Corporation  */
> > +
> > +#ifndef __UFS_SYSFS_H__
> > +#define __UFS_SYSFS_H__
> > +
> > +#include <linux/sysfs.h>
> > +
> > +#include "ufshcd.h"
> > +
> > +void ufs_sysfs_add_nodes(struct device *dev); void
> > +ufs_sysfs_remove_nodes(struct device *dev); #endif
> > diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
> > index a355d98..e7621a0a 100644
> > --- a/drivers/scsi/ufs/ufshcd.c
> > +++ b/drivers/scsi/ufs/ufshcd.c
> > @@ -44,6 +44,7 @@
> >  #include "ufshcd.h"
> >  #include "ufs_quirks.h"
> >  #include "unipro.h"
> > +#include "ufs-sysfs.h"
> >
> >  #define CREATE_TRACE_POINTS
> >  #include <trace/events/ufs.h>
> > @@ -150,7 +151,7 @@ enum {
> >  #define ufshcd_is_ufs_dev_poweroff(h) \
> >  	((h)->curr_dev_pwr_mode == UFS_POWERDOWN_PWR_MODE)
> >
> > -static struct ufs_pm_lvl_states ufs_pm_lvl_states[] = {
> > +struct ufs_pm_lvl_states ufs_pm_lvl_states[] = {
> >  	{UFS_ACTIVE_PWR_MODE, UIC_LINK_ACTIVE_STATE},
> >  	{UFS_ACTIVE_PWR_MODE, UIC_LINK_HIBERN8_STATE},
> >  	{UFS_SLEEP_PWR_MODE, UIC_LINK_ACTIVE_STATE}, @@ -813,28
> +814,6 @@
> > static inline bool ufshcd_is_hba_active(struct ufs_hba *hba)
> >  		? false : true;
> >  }
> >
> > -static const char *ufschd_uic_link_state_to_string(
> > -			enum uic_link_state state)
> > -{
> > -	switch (state) {
> > -	case UIC_LINK_OFF_STATE:	return "OFF";
> > -	case UIC_LINK_ACTIVE_STATE:	return "ACTIVE";
> > -	case UIC_LINK_HIBERN8_STATE:	return "HIBERN8";
> > -	default:			return "UNKNOWN";
> > -	}
> > -}
> > -
> > -static const char *ufschd_ufs_dev_pwr_mode_to_string(
> > -			enum ufs_dev_pwr_mode state)
> > -{
> > -	switch (state) {
> > -	case UFS_ACTIVE_PWR_MODE:	return "ACTIVE";
> > -	case UFS_SLEEP_PWR_MODE:	return "SLEEP";
> > -	case UFS_POWERDOWN_PWR_MODE:	return "POWERDOWN";
> > -	default:			return "UNKNOWN";
> > -	}
> > -}
> > -
> >  u32 ufshcd_get_local_unipro_ver(struct ufs_hba *hba)  {
> >  	/* HCI version 1.0 and 1.1 supports UniPro 1.41 */ @@ -7585,133
> > +7564,6 @@ int ufshcd_runtime_idle(struct ufs_hba *hba)  }
> > EXPORT_SYMBOL(ufshcd_runtime_idle);
> >
> > -static inline ssize_t ufshcd_pm_lvl_store(struct device *dev,
> > -					   struct device_attribute *attr,
> > -					   const char *buf, size_t count,
> > -					   bool rpm)
> > -{
> > -	struct ufs_hba *hba = dev_get_drvdata(dev);
> > -	unsigned long flags, value;
> > -
> > -	if (kstrtoul(buf, 0, &value))
> > -		return -EINVAL;
> > -
> > -	if (value >= UFS_PM_LVL_MAX)
> > -		return -EINVAL;
> > -
> > -	spin_lock_irqsave(hba->host->host_lock, flags);
> > -	if (rpm)
> > -		hba->rpm_lvl = value;
> > -	else
> > -		hba->spm_lvl = value;
> > -	spin_unlock_irqrestore(hba->host->host_lock, flags);
> > -	return count;
> > -}
> > -
> > -static ssize_t ufshcd_rpm_lvl_show(struct device *dev,
> > -		struct device_attribute *attr, char *buf)
> > -{
> > -	struct ufs_hba *hba = dev_get_drvdata(dev);
> > -	int curr_len;
> > -	u8 lvl;
> > -
> > -	curr_len = snprintf(buf, PAGE_SIZE,
> > -			    "\nCurrent Runtime PM level [%d] => dev_state
> [%s] link_state [%s]\n",
> > -			    hba->rpm_lvl,
> > -			    ufschd_ufs_dev_pwr_mode_to_string(
> > -				ufs_pm_lvl_states[hba-
> >rpm_lvl].dev_state),
> > -			    ufschd_uic_link_state_to_string(
> > -				ufs_pm_lvl_states[hba-
> >rpm_lvl].link_state));
> > -
> > -	curr_len += snprintf((buf + curr_len), (PAGE_SIZE - curr_len),
> > -			     "\nAll available Runtime PM levels info:\n");
> > -	for (lvl = UFS_PM_LVL_0; lvl < UFS_PM_LVL_MAX; lvl++)
> > -		curr_len += snprintf((buf + curr_len), (PAGE_SIZE - curr_len),
> > -				     "\tRuntime PM level [%d] => dev_state
> [%s] link_state [%s]\n",
> > -				    lvl,
> > -				    ufschd_ufs_dev_pwr_mode_to_string(
> > -					ufs_pm_lvl_states[lvl].dev_state),
> > -				    ufschd_uic_link_state_to_string(
> > -					ufs_pm_lvl_states[lvl].link_state));
> > -
> > -	return curr_len;
> > -}
> > -
> > -static ssize_t ufshcd_rpm_lvl_store(struct device *dev,
> > -		struct device_attribute *attr, const char *buf, size_t count)
> > -{
> > -	return ufshcd_pm_lvl_store(dev, attr, buf, count, true);
> > -}
> > -
> > -static void ufshcd_add_rpm_lvl_sysfs_nodes(struct ufs_hba *hba) -{
> > -	hba->rpm_lvl_attr.show = ufshcd_rpm_lvl_show;
> > -	hba->rpm_lvl_attr.store = ufshcd_rpm_lvl_store;
> > -	sysfs_attr_init(&hba->rpm_lvl_attr.attr);
> > -	hba->rpm_lvl_attr.attr.name = "rpm_lvl";
> > -	hba->rpm_lvl_attr.attr.mode = 0644;
> > -	if (device_create_file(hba->dev, &hba->rpm_lvl_attr))
> > -		dev_err(hba->dev, "Failed to create sysfs for rpm_lvl\n");
> > -}
> > -
> > -static ssize_t ufshcd_spm_lvl_show(struct device *dev,
> > -		struct device_attribute *attr, char *buf)
> > -{
> > -	struct ufs_hba *hba = dev_get_drvdata(dev);
> > -	int curr_len;
> > -	u8 lvl;
> > -
> > -	curr_len = snprintf(buf, PAGE_SIZE,
> > -			    "\nCurrent System PM level [%d] => dev_state
> [%s] link_state [%s]\n",
> > -			    hba->spm_lvl,
> > -			    ufschd_ufs_dev_pwr_mode_to_string(
> > -				ufs_pm_lvl_states[hba-
> >spm_lvl].dev_state),
> > -			    ufschd_uic_link_state_to_string(
> > -				ufs_pm_lvl_states[hba-
> >spm_lvl].link_state));
> > -
> > -	curr_len += snprintf((buf + curr_len), (PAGE_SIZE - curr_len),
> > -			     "\nAll available System PM levels info:\n");
> > -	for (lvl = UFS_PM_LVL_0; lvl < UFS_PM_LVL_MAX; lvl++)
> > -		curr_len += snprintf((buf + curr_len), (PAGE_SIZE - curr_len),
> > -				     "\tSystem PM level [%d] => dev_state
> [%s] link_state [%s]\n",
> > -				    lvl,
> > -				    ufschd_ufs_dev_pwr_mode_to_string(
> > -					ufs_pm_lvl_states[lvl].dev_state),
> > -				    ufschd_uic_link_state_to_string(
> > -					ufs_pm_lvl_states[lvl].link_state));
> > -
> > -	return curr_len;
> > -}
> > -
> > -static ssize_t ufshcd_spm_lvl_store(struct device *dev,
> > -		struct device_attribute *attr, const char *buf, size_t count)
> > -{
> > -	return ufshcd_pm_lvl_store(dev, attr, buf, count, false);
> > -}
> > -
> > -static void ufshcd_add_spm_lvl_sysfs_nodes(struct ufs_hba *hba) -{
> > -	hba->spm_lvl_attr.show = ufshcd_spm_lvl_show;
> > -	hba->spm_lvl_attr.store = ufshcd_spm_lvl_store;
> > -	sysfs_attr_init(&hba->spm_lvl_attr.attr);
> > -	hba->spm_lvl_attr.attr.name = "spm_lvl";
> > -	hba->spm_lvl_attr.attr.mode = 0644;
> > -	if (device_create_file(hba->dev, &hba->spm_lvl_attr))
> > -		dev_err(hba->dev, "Failed to create sysfs for spm_lvl\n");
> > -}
> > -
> > -static inline void ufshcd_add_sysfs_nodes(struct ufs_hba *hba) -{
> > -	ufshcd_add_rpm_lvl_sysfs_nodes(hba);
> > -	ufshcd_add_spm_lvl_sysfs_nodes(hba);
> > -}
> > -
> > -static inline void ufshcd_remove_sysfs_nodes(struct ufs_hba *hba) -{
> > -	device_remove_file(hba->dev, &hba->rpm_lvl_attr);
> > -	device_remove_file(hba->dev, &hba->spm_lvl_attr);
> > -}
> > -
> >  /**
> >   * ufshcd_shutdown - shutdown routine
> >   * @hba: per adapter instance
> > @@ -7749,7 +7601,7 @@ EXPORT_SYMBOL(ufshcd_shutdown);
> >   */
> >  void ufshcd_remove(struct ufs_hba *hba)  {
> > -	ufshcd_remove_sysfs_nodes(hba);
> > +	ufs_sysfs_remove_nodes(hba->dev);
> >  	scsi_remove_host(hba->host);
> >  	/* disable interrupts */
> >  	ufshcd_disable_intr(hba, hba->intr_mask); @@ -7996,7 +7848,7 @@
> int
> > ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int
> irq)
> >  	ufshcd_set_ufs_dev_active(hba);
> >
> >  	async_schedule(ufshcd_async_scan, hba);
> > -	ufshcd_add_sysfs_nodes(hba);
> > +	ufs_sysfs_add_nodes(hba->dev);
> >
> >  	return 0;
> >
> > diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
> > index 1332e54..53e2779 100644
> > --- a/drivers/scsi/ufs/ufshcd.h
> > +++ b/drivers/scsi/ufs/ufshcd.h
> > @@ -985,4 +985,6 @@ static inline void
> ufshcd_vops_dbg_register_dump(struct ufs_hba *hba)
> >  		hba->vops->dbg_register_dump(hba);
> >  }
> >
> > +extern struct ufs_pm_lvl_states ufs_pm_lvl_states[];
> > +
> >  #endif /* End of Header */
> > --
> > 2.7.4

^ permalink raw reply	[flat|nested] 19+ messages in thread

* RE: [PATCH v5 02/11] scsi: ufs: sysfs: device descriptor
  2018-02-12  1:07   ` Jaegeuk Kim
@ 2018-02-12 11:21     ` Stanislav Nijnikov
  2018-02-12 18:00       ` Jaegeuk Kim
  0 siblings, 1 reply; 19+ messages in thread
From: Stanislav Nijnikov @ 2018-02-12 11:21 UTC (permalink / raw)
  To: Jaegeuk Kim; +Cc: linux-scsi, linux-kernel, gregkh, Alex Lemberg



> -----Original Message-----
> From: Jaegeuk Kim [mailto:jaegeuk@kernel.org]
> Sent: Monday, February 12, 2018 3:08 AM
> To: Stanislav Nijnikov <Stanislav.Nijnikov@wdc.com>
> Cc: linux-scsi@vger.kernel.org; linux-kernel@vger.kernel.org;
> gregkh@linuxfoundation.org; Alex Lemberg <Alex.Lemberg@wdc.com>
> Subject: Re: [PATCH v5 02/11] scsi: ufs: sysfs: device descriptor
> 
> On 02/06, Stanislav Nijnikov wrote:
> > This patch introduces a sysfs group entry for the UFS device
> > descriptor parameters. The group adds "device_descriptor" folder under
> > the UFS driver sysfs entry (/sys/bus/platform/drivers/ufshcd/*). The
> > parameters are shown as hexadecimal numbers. The full information
> > about the parameters could be found at UFS specifications 2.1.
> >
> > Signed-off-by: Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > ---
> >  Documentation/ABI/testing/sysfs-driver-ufs | 223
> +++++++++++++++++++++++++++++
> >  drivers/scsi/ufs/ufs-sysfs.c               | 116 +++++++++++++++
> >  drivers/scsi/ufs/ufs.h                     |   8 ++
> >  drivers/scsi/ufs/ufshcd.c                  |  12 +-
> >  drivers/scsi/ufs/ufshcd.h                  |   6 +
> >  5 files changed, 359 insertions(+), 6 deletions(-)  create mode
> > 100644 Documentation/ABI/testing/sysfs-driver-ufs
> >
> > diff --git a/Documentation/ABI/testing/sysfs-driver-ufs
> > b/Documentation/ABI/testing/sysfs-driver-ufs
> > new file mode 100644
> > index 0000000..8da7b84
> > --- /dev/null
> > +++ b/Documentation/ABI/testing/sysfs-driver-ufs
> > @@ -0,0 +1,223 @@
> > +What:
> 	/sys/bus/platform/drivers/ufshcd/*/device_descriptor/device_type
> > +Date:		February 2018
> > +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > +Description:	This file shows the device type. This is one of the UFS
> > +		device descriptor parameters. The full information about
> > +		the descriptor could be found at UFS specifications 2.1.
> > +		The file is read only.
> > +
> > +What:
> 	/sys/bus/platform/drivers/ufshcd/*/device_descriptor/device_class
> > +Date:		February 2018
> > +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > +Description:	This file shows the device class. This is one of the UFS
> > +		device descriptor parameters. The full information about
> > +		the descriptor could be found at UFS specifications 2.1.
> > +		The file is read only.
> > +
> > +What:
> 	/sys/bus/platform/drivers/ufshcd/*/device_descriptor/device_sub_
> class
> > +Date:		February 2018
> > +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > +Description:	This file shows the UFS storage subclass. This is one of
> > +		the UFS device descriptor parameters. The full information
> > +		about the descriptor could be found at UFS specifications 2.1.
> > +		The file is read only.
> > +
> > +What:
> 	/sys/bus/platform/drivers/ufshcd/*/device_descriptor/protocol
> > +Date:		February 2018
> > +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > +Description:	This file shows the protocol supported by an UFS device.
> > +		This is one of the UFS device descriptor parameters.
> > +		The full information about the descriptor could be found
> > +		at UFS specifications 2.1.
> > +		The file is read only.
> > +
> > +What:
> 	/sys/bus/platform/drivers/ufshcd/*/device_descriptor/number_of_
> luns
> > +Date:		February 2018
> > +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > +Description:	This file shows number of logical units. This is one of
> > +		the UFS device descriptor parameters. The full information
> > +		about the descriptor could be found at UFS specifications 2.1.
> > +		The file is read only.
> > +
> > +What:
> 	/sys/bus/platform/drivers/ufshcd/*/device_descriptor/number_of_
> wluns
> > +Date:		February 2018
> > +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > +Description:	This file shows number of well known logical units.
> > +		This is one of the UFS device descriptor parameters.
> > +		The full information about the descriptor could be found
> > +		at UFS specifications 2.1.
> > +		The file is read only.
> > +
> > +What:
> 	/sys/bus/platform/drivers/ufshcd/*/device_descriptor/boot_enable
> > +Date:		February 2018
> > +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > +Description:	This file shows value that indicates whether the device is
> > +		enabled for boot. This is one of the UFS device descriptor
> > +		parameters. The full information about the descriptor could
> > +		be found at UFS specifications 2.1.
> > +		The file is read only.
> > +
> > +What:
> 	/sys/bus/platform/drivers/ufshcd/*/device_descriptor/descriptor_a
> ccess_enable
> > +Date:		February 2018
> > +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > +Description:	This file shows value that indicates whether the device
> > +		descriptor could be read after partial initialization phase
> > +		of the boot sequence. This is one of the UFS device
> descriptor
> > +		parameters. The full information about the descriptor could
> > +		be found at UFS specifications 2.1.
> > +		The file is read only.
> > +
> > +What:
> 	/sys/bus/platform/drivers/ufshcd/*/device_descriptor/initial_powe
> r_mode
> > +Date:		February 2018
> > +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > +Description:	This file shows value that defines the power mode after
> > +		device initialization or hardware reset. This is one of
> > +		the UFS device descriptor parameters. The full information
> > +		about the descriptor could be found at UFS specifications 2.1.
> > +		The file is read only.
> > +
> > +What:
> 	/sys/bus/platform/drivers/ufshcd/*/device_descriptor/high_priority
> _lun
> > +Date:		February 2018
> > +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > +Description:	This file shows the high priority lun. This is one of
> > +		the UFS device descriptor parameters. The full information
> > +		about the descriptor could be found at UFS specifications 2.1.
> > +		The file is read only.
> > +
> > +What:
> 	/sys/bus/platform/drivers/ufshcd/*/device_descriptor/secure_rem
> oval_type
> > +Date:		February 2018
> > +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > +Description:	This file shows the secure removal type. This is one of
> > +		the UFS device descriptor parameters. The full information
> > +		about the descriptor could be found at UFS specifications 2.1.
> > +		The file is read only.
> > +
> > +What:
> 	/sys/bus/platform/drivers/ufshcd/*/device_descriptor/support_sec
> urity_lun
> > +Date:		February 2018
> > +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > +Description:	This file shows whether the security lun is supported.
> > +		This is one of the UFS device descriptor parameters.
> > +		The full information about the descriptor could be found
> > +		at UFS specifications 2.1.
> > +		The file is read only.
> > +
> > +What:
> 	/sys/bus/platform/drivers/ufshcd/*/device_descriptor/bkops_termi
> nation_latency
> > +Date:		February 2018
> > +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > +Description:	This file shows the background operations termination
> > +		latency. This is one of the UFS device descriptor parameters.
> > +		The full information about the descriptor could be found
> > +		at UFS specifications 2.1.
> > +		The file is read only.
> > +
> > +What:
> 	/sys/bus/platform/drivers/ufshcd/*/device_descriptor/initial_active
> _icc_level
> > +Date:		February 2018
> > +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > +Description:	This file shows the initial active ICC level. This is one
> > +		of the UFS device descriptor parameters. The full information
> > +		about the descriptor could be found at UFS specifications 2.1.
> > +		The file is read only.
> > +
> > +What:
> 	/sys/bus/platform/drivers/ufshcd/*/device_descriptor/specification
> _version
> > +Date:		February 2018
> > +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > +Description:	This file shows the specification version. This is one
> > +		of the UFS device descriptor parameters. The full information
> > +		about the descriptor could be found at UFS specifications 2.1.
> > +		The file is read only.
> > +
> > +What:
> 	/sys/bus/platform/drivers/ufshcd/*/device_descriptor/manufacturi
> ng_date
> > +Date:		February 2018
> > +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > +Description:	This file shows the manufacturing date in BCD format.
> > +		This is one of the UFS device descriptor parameters.
> > +		The full information about the descriptor could be found
> > +		at UFS specifications 2.1.
> > +		The file is read only.
> > +
> > +What:
> 	/sys/bus/platform/drivers/ufshcd/*/device_descriptor/manufacture
> r_id
> > +Date:		February 2018
> > +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > +Description:	This file shows the manufacturee ID. This is one of the
> > +		UFS device descriptor parameters. The full information about
> > +		the descriptor could be found at UFS specifications 2.1.
> > +		The file is read only.
> > +
> > +What:
> 	/sys/bus/platform/drivers/ufshcd/*/device_descriptor/rtt_capabilit
> y
> > +Date:		February 2018
> > +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > +Description:	This file shows the maximum number of outstanding RTTs
> > +		supported by the device. This is one of the UFS device
> > +		descriptor parameters. The full information about
> > +		the descriptor could be found at UFS specifications 2.1.
> > +		The file is read only.
> > +
> > +What:
> 	/sys/bus/platform/drivers/ufshcd/*/device_descriptor/rtc_update
> > +Date:		February 2018
> > +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > +Description:	This file shows the frequency and method of the realtime
> > +		clock update. This is one of the UFS device descriptor
> > +		parameters. The full information about the descriptor
> > +		could be found at UFS specifications 2.1.
> > +		The file is read only.
> > +
> > +What:
> 	/sys/bus/platform/drivers/ufshcd/*/device_descriptor/ufs_features
> > +Date:		February 2018
> > +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > +Description:	This file shows which features are supported by the device.
> > +		This is one of the UFS device descriptor parameters.
> > +		The full information about the descriptor could be
> > +		found at UFS specifications 2.1.
> > +		The file is read only.
> > +
> > +What:
> 	/sys/bus/platform/drivers/ufshcd/*/device_descriptor/ffu_timeout
> > +Date:		February 2018
> > +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > +Description:	This file shows the FFU timeout. This is one of the
> > +		UFS device descriptor parameters. The full information
> > +		about the descriptor could be found at UFS specifications 2.1.
> > +		The file is read only.
> > +
> > +What:
> 	/sys/bus/platform/drivers/ufshcd/*/device_descriptor/queue_dept
> h
> > +Date:		February 2018
> > +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > +Description:	This file shows the device queue depth. This is one of the
> > +		UFS device descriptor parameters. The full information
> > +		about the descriptor could be found at UFS specifications 2.1.
> > +		The file is read only.
> > +
> > +What:
> 	/sys/bus/platform/drivers/ufshcd/*/device_descriptor/device_versi
> on
> > +Date:		February 2018
> > +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > +Description:	This file shows the device version. This is one of the
> > +		UFS device descriptor parameters. The full information
> > +		about the descriptor could be found at UFS specifications 2.1.
> > +		The file is read only.
> > +
> > +What:
> 	/sys/bus/platform/drivers/ufshcd/*/device_descriptor/number_of_
> secure_wpa
> > +Date:		February 2018
> > +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > +Description:	This file shows number of secure write protect areas
> > +		supported by the device. This is one of the UFS device
> > +		descriptor parameters. The full information about
> > +		the descriptor could be found at UFS specifications 2.1.
> > +		The file is read only.
> > +
> > +What:
> 	/sys/bus/platform/drivers/ufshcd/*/device_descriptor/psa_max_da
> ta_size
> > +Date:		February 2018
> > +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > +Description:	This file shows the maximum amount of data that may be
> > +		written during the pre-soldering phase of the PSA flow.
> > +		This is one of the UFS device descriptor parameters.
> > +		The full information about the descriptor could be found
> > +		at UFS specifications 2.1.
> > +		The file is read only.
> > +
> > +What:
> 	/sys/bus/platform/drivers/ufshcd/*/device_descriptor/psa_state_ti
> meout
> > +Date:		February 2018
> > +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > +Description:	This file shows the command maximum timeout for a change
> > +		in PSA state. This is one of the UFS device descriptor
> > +		parameters. The full information about the descriptor could
> > +		be found at UFS specifications 2.1.
> > +		The file is read only.
> > diff --git a/drivers/scsi/ufs/ufs-sysfs.c
> > b/drivers/scsi/ufs/ufs-sysfs.c index ce8dcb6..aa2779a 100644
> > --- a/drivers/scsi/ufs/ufs-sysfs.c
> > +++ b/drivers/scsi/ufs/ufs-sysfs.c
> > @@ -3,7 +3,9 @@
> >
> >  #include <linux/err.h>
> >  #include <linux/string.h>
> > +#include <asm/unaligned.h>
> >
> > +#include "ufs.h"
> >  #include "ufs-sysfs.h"
> >
> >  static const char *ufschd_uic_link_state_to_string( @@ -134,8
> > +136,122 @@ static const struct attribute_group ufs_sysfs_default_group
> = {
> >  	.attrs = ufs_sysfs_ufshcd_attrs,
> >  };
> >
> > +static ssize_t ufs_sysfs_read_desc_param(struct ufs_hba *hba,
> > +				  enum desc_idn desc_id,
> > +				  u8 desc_index,
> > +				  u8 param_offset,
> > +				  u8 *sysfs_buf,
> > +				  u8 param_size)
> > +{
> > +	u8 desc_buf[8] = {0};
> > +	int ret;
> > +
> > +	if (param_size > 8)
> > +		return -EINVAL;
> > +
> > +	ret = ufshcd_read_desc_param(hba, desc_id, desc_index,
> > +				param_offset, desc_buf, param_size);
> > +	if (ret)
> > +		return -EINVAL;
> > +	switch (param_size) {
> > +	case 1:
> > +		ret = sprintf(sysfs_buf, "0x%02X\n", *desc_buf);
> > +		break;
> > +	case 2:
> > +		ret = sprintf(sysfs_buf, "0x%04X\n",
> > +			get_unaligned_be16(desc_buf));
> > +		break;
> > +	case 4:
> > +		ret = sprintf(sysfs_buf, "0x%08X\n",
> > +			get_unaligned_be32(desc_buf));
> > +		break;
> > +	case 8:
> > +		ret = sprintf(sysfs_buf, "0x%016llX\n",
> > +			get_unaligned_be64(desc_buf));
> > +		break;
> > +	}
> > +
> > +	return ret;
> > +}
> > +
> > +#define UFS_DESC_PARAM(_name, _puname, _duname, _size)
> 		\
> > +static ssize_t _name##_show(struct device *dev,
> 	\
> > +	struct device_attribute *attr, char *buf)			\
> > +{									\
> > +	struct ufs_hba *hba = dev_get_drvdata(dev);			\
> > +	return ufs_sysfs_read_desc_param(hba,
> QUERY_DESC_IDN_##_duname,	\
> > +		0, _duname##_DESC_PARAM##_puname, buf, _size);
> 	\
> > +}									\
> > +static DEVICE_ATTR_RO(_name)
> > +
> > +#define UFS_DEVICE_DESC_PARAM(_name, _uname, _size)
> 		\
> > +	UFS_DESC_PARAM(_name, _uname, DEVICE, _size)
> > +
> > +UFS_DEVICE_DESC_PARAM(device_type, _DEVICE_TYPE, 1);
> > +UFS_DEVICE_DESC_PARAM(device_class, _DEVICE_CLASS, 1);
> > +UFS_DEVICE_DESC_PARAM(device_sub_class, _DEVICE_SUB_CLASS, 1);
> > +UFS_DEVICE_DESC_PARAM(protocol, _PRTCL, 1);
> > +UFS_DEVICE_DESC_PARAM(number_of_luns, _NUM_LU, 1);
> > +UFS_DEVICE_DESC_PARAM(number_of_wluns, _NUM_WLU, 1);
> > +UFS_DEVICE_DESC_PARAM(boot_enable, _BOOT_ENBL, 1);
> > +UFS_DEVICE_DESC_PARAM(descriptor_access_enable,
> _DESC_ACCSS_ENBL, 1);
> > +UFS_DEVICE_DESC_PARAM(initial_power_mode, _INIT_PWR_MODE, 1);
> > +UFS_DEVICE_DESC_PARAM(high_priority_lun, _HIGH_PR_LUN, 1);
> > +UFS_DEVICE_DESC_PARAM(secure_removal_type, _SEC_RMV_TYPE, 1);
> > +UFS_DEVICE_DESC_PARAM(support_security_lun, _SEC_LU, 1);
> > +UFS_DEVICE_DESC_PARAM(bkops_termination_latency,
> _BKOP_TERM_LT, 1);
> > +UFS_DEVICE_DESC_PARAM(initial_active_icc_level, _ACTVE_ICC_LVL, 1);
> > +UFS_DEVICE_DESC_PARAM(specification_version, _SPEC_VER, 2);
> > +UFS_DEVICE_DESC_PARAM(manufacturing_date, _MANF_DATE, 2);
> > +UFS_DEVICE_DESC_PARAM(manufacturer_id, _MANF_ID, 2);
> > +UFS_DEVICE_DESC_PARAM(rtt_capability, _RTT_CAP, 1);
> > +UFS_DEVICE_DESC_PARAM(rtc_update, _FRQ_RTC, 2);
> > +UFS_DEVICE_DESC_PARAM(ufs_features, _UFS_FEAT, 1);
> > +UFS_DEVICE_DESC_PARAM(ffu_timeout, _FFU_TMT, 1);
> > +UFS_DEVICE_DESC_PARAM(queue_depth, _Q_DPTH, 1);
> > +UFS_DEVICE_DESC_PARAM(device_version, _DEV_VER, 2);
> > +UFS_DEVICE_DESC_PARAM(number_of_secure_wpa, _NUM_SEC_WPA,
> 1);
> > +UFS_DEVICE_DESC_PARAM(psa_max_data_size, _PSA_MAX_DATA, 4);
> > +UFS_DEVICE_DESC_PARAM(psa_state_timeout, _PSA_TMT, 1);
> 
> Could you add this case as well?
> 
> DEVICE_DESC_PARAM_PRDCT_REV		= 0x2A,
> 

This value was omitted intentionally. It holds an index of the string descriptor with the
product revision. There are 4 more such fields in the device descriptor:
 - DEVICE_DESC_PARAM_MANF_NAME = 0x14
 - DEVICE_DESC_PARAM_PRDCT_NAME  = 0x15,
 - DEVICE_DESC_PARAM_SN = 0x16,
 - DEVICE_DESC_PARAM_OEM_ID  = 0x17,
The indexes itself don't provide any useful information to users and the
corresponding strings are shown by the string descriptors (see "[PATCH v5 07/11] 
scsi: ufs: sysfs: string descriptors")

Regards

> > +
> > +static struct attribute *ufs_sysfs_device_descriptor[] = {
> > +	&dev_attr_device_type.attr,
> > +	&dev_attr_device_class.attr,
> > +	&dev_attr_device_sub_class.attr,
> > +	&dev_attr_protocol.attr,
> > +	&dev_attr_number_of_luns.attr,
> > +	&dev_attr_number_of_wluns.attr,
> > +	&dev_attr_boot_enable.attr,
> > +	&dev_attr_descriptor_access_enable.attr,
> > +	&dev_attr_initial_power_mode.attr,
> > +	&dev_attr_high_priority_lun.attr,
> > +	&dev_attr_secure_removal_type.attr,
> > +	&dev_attr_support_security_lun.attr,
> > +	&dev_attr_bkops_termination_latency.attr,
> > +	&dev_attr_initial_active_icc_level.attr,
> > +	&dev_attr_specification_version.attr,
> > +	&dev_attr_manufacturing_date.attr,
> > +	&dev_attr_manufacturer_id.attr,
> > +	&dev_attr_rtt_capability.attr,
> > +	&dev_attr_rtc_update.attr,
> > +	&dev_attr_ufs_features.attr,
> > +	&dev_attr_ffu_timeout.attr,
> > +	&dev_attr_queue_depth.attr,
> > +	&dev_attr_device_version.attr,
> > +	&dev_attr_number_of_secure_wpa.attr,
> > +	&dev_attr_psa_max_data_size.attr,
> > +	&dev_attr_psa_state_timeout.attr,
> > +	NULL,
> > +};
> > +
> > +static const struct attribute_group ufs_sysfs_device_descriptor_group = {
> > +	.name = "device_descriptor",
> > +	.attrs = ufs_sysfs_device_descriptor, };
> > +
> >  static const struct attribute_group *ufs_sysfs_groups[] = {
> >  	&ufs_sysfs_default_group,
> > +	&ufs_sysfs_device_descriptor_group,
> >  	NULL,
> >  };
> >
> > diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h index
> > 54deeb7..6ae1e08 100644
> > --- a/drivers/scsi/ufs/ufs.h
> > +++ b/drivers/scsi/ufs/ufs.h
> > @@ -220,6 +220,14 @@ enum device_desc_param {
> >  	DEVICE_DESC_PARAM_UD_LEN		= 0x1B,
> >  	DEVICE_DESC_PARAM_RTT_CAP		= 0x1C,
> >  	DEVICE_DESC_PARAM_FRQ_RTC		= 0x1D,
> > +	DEVICE_DESC_PARAM_UFS_FEAT		= 0x1F,
> > +	DEVICE_DESC_PARAM_FFU_TMT		= 0x20,
> > +	DEVICE_DESC_PARAM_Q_DPTH		= 0x21,
> > +	DEVICE_DESC_PARAM_DEV_VER		= 0x22,
> > +	DEVICE_DESC_PARAM_NUM_SEC_WPA		= 0x24,
> > +	DEVICE_DESC_PARAM_PSA_MAX_DATA		= 0x25,
> > +	DEVICE_DESC_PARAM_PSA_TMT		= 0x29,
> > +	DEVICE_DESC_PARAM_PRDCT_REV		= 0x2A,
> >  };
> >
> >  /*
> > diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
> > index e7621a0a..540a431 100644
> > --- a/drivers/scsi/ufs/ufshcd.c
> > +++ b/drivers/scsi/ufs/ufshcd.c
> > @@ -2989,12 +2989,12 @@
> EXPORT_SYMBOL(ufshcd_map_desc_id_to_length);
> >   *
> >   * Return 0 in case of success, non-zero otherwise
> >   */
> > -static int ufshcd_read_desc_param(struct ufs_hba *hba,
> > -				  enum desc_idn desc_id,
> > -				  int desc_index,
> > -				  u8 param_offset,
> > -				  u8 *param_read_buf,
> > -				  u8 param_size)
> > +int ufshcd_read_desc_param(struct ufs_hba *hba,
> > +			   enum desc_idn desc_id,
> > +			   int desc_index,
> > +			   u8 param_offset,
> > +			   u8 *param_read_buf,
> > +			   u8 param_size)
> >  {
> >  	int ret;
> >  	u8 *desc_buf;
> > diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
> > index 53e2779..38c307d 100644
> > --- a/drivers/scsi/ufs/ufshcd.h
> > +++ b/drivers/scsi/ufs/ufshcd.h
> > @@ -841,6 +841,12 @@ static inline bool ufshcd_is_hs_mode(struct
> > ufs_pa_layer_attr *pwr_info)  }
> >
> >  /* Expose Query-Request API */
> > +int ufshcd_read_desc_param(struct ufs_hba *hba,
> > +			   enum desc_idn desc_id,
> > +			   int desc_index,
> > +			   u8 param_offset,
> > +			   u8 *param_read_buf,
> > +			   u8 param_size);
> >  int ufshcd_query_flag(struct ufs_hba *hba, enum query_opcode opcode,
> >  	enum flag_idn idn, bool *flag_res);
> >  int ufshcd_hold(struct ufs_hba *hba, bool async);
> > --
> > 2.7.4

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v5 02/11] scsi: ufs: sysfs: device descriptor
  2018-02-12 11:21     ` Stanislav Nijnikov
@ 2018-02-12 18:00       ` Jaegeuk Kim
  0 siblings, 0 replies; 19+ messages in thread
From: Jaegeuk Kim @ 2018-02-12 18:00 UTC (permalink / raw)
  To: Stanislav Nijnikov; +Cc: linux-scsi, linux-kernel, gregkh, Alex Lemberg

On 02/12, Stanislav Nijnikov wrote:
> 
> 
> > -----Original Message-----
> > From: Jaegeuk Kim [mailto:jaegeuk@kernel.org]
> > Sent: Monday, February 12, 2018 3:08 AM
> > To: Stanislav Nijnikov <Stanislav.Nijnikov@wdc.com>
> > Cc: linux-scsi@vger.kernel.org; linux-kernel@vger.kernel.org;
> > gregkh@linuxfoundation.org; Alex Lemberg <Alex.Lemberg@wdc.com>
> > Subject: Re: [PATCH v5 02/11] scsi: ufs: sysfs: device descriptor
> > 
> > On 02/06, Stanislav Nijnikov wrote:
> > > This patch introduces a sysfs group entry for the UFS device
> > > descriptor parameters. The group adds "device_descriptor" folder under
> > > the UFS driver sysfs entry (/sys/bus/platform/drivers/ufshcd/*). The
> > > parameters are shown as hexadecimal numbers. The full information
> > > about the parameters could be found at UFS specifications 2.1.
> > >
> > > Signed-off-by: Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > > ---
> > >  Documentation/ABI/testing/sysfs-driver-ufs | 223
> > +++++++++++++++++++++++++++++
> > >  drivers/scsi/ufs/ufs-sysfs.c               | 116 +++++++++++++++
> > >  drivers/scsi/ufs/ufs.h                     |   8 ++
> > >  drivers/scsi/ufs/ufshcd.c                  |  12 +-
> > >  drivers/scsi/ufs/ufshcd.h                  |   6 +
> > >  5 files changed, 359 insertions(+), 6 deletions(-)  create mode
> > > 100644 Documentation/ABI/testing/sysfs-driver-ufs
> > >
> > > diff --git a/Documentation/ABI/testing/sysfs-driver-ufs
> > > b/Documentation/ABI/testing/sysfs-driver-ufs
> > > new file mode 100644
> > > index 0000000..8da7b84
> > > --- /dev/null
> > > +++ b/Documentation/ABI/testing/sysfs-driver-ufs
> > > @@ -0,0 +1,223 @@
> > > +What:
> > 	/sys/bus/platform/drivers/ufshcd/*/device_descriptor/device_type
> > > +Date:		February 2018
> > > +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > > +Description:	This file shows the device type. This is one of the UFS
> > > +		device descriptor parameters. The full information about
> > > +		the descriptor could be found at UFS specifications 2.1.
> > > +		The file is read only.
> > > +
> > > +What:
> > 	/sys/bus/platform/drivers/ufshcd/*/device_descriptor/device_class
> > > +Date:		February 2018
> > > +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > > +Description:	This file shows the device class. This is one of the UFS
> > > +		device descriptor parameters. The full information about
> > > +		the descriptor could be found at UFS specifications 2.1.
> > > +		The file is read only.
> > > +
> > > +What:
> > 	/sys/bus/platform/drivers/ufshcd/*/device_descriptor/device_sub_
> > class
> > > +Date:		February 2018
> > > +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > > +Description:	This file shows the UFS storage subclass. This is one of
> > > +		the UFS device descriptor parameters. The full information
> > > +		about the descriptor could be found at UFS specifications 2.1.
> > > +		The file is read only.
> > > +
> > > +What:
> > 	/sys/bus/platform/drivers/ufshcd/*/device_descriptor/protocol
> > > +Date:		February 2018
> > > +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > > +Description:	This file shows the protocol supported by an UFS device.
> > > +		This is one of the UFS device descriptor parameters.
> > > +		The full information about the descriptor could be found
> > > +		at UFS specifications 2.1.
> > > +		The file is read only.
> > > +
> > > +What:
> > 	/sys/bus/platform/drivers/ufshcd/*/device_descriptor/number_of_
> > luns
> > > +Date:		February 2018
> > > +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > > +Description:	This file shows number of logical units. This is one of
> > > +		the UFS device descriptor parameters. The full information
> > > +		about the descriptor could be found at UFS specifications 2.1.
> > > +		The file is read only.
> > > +
> > > +What:
> > 	/sys/bus/platform/drivers/ufshcd/*/device_descriptor/number_of_
> > wluns
> > > +Date:		February 2018
> > > +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > > +Description:	This file shows number of well known logical units.
> > > +		This is one of the UFS device descriptor parameters.
> > > +		The full information about the descriptor could be found
> > > +		at UFS specifications 2.1.
> > > +		The file is read only.
> > > +
> > > +What:
> > 	/sys/bus/platform/drivers/ufshcd/*/device_descriptor/boot_enable
> > > +Date:		February 2018
> > > +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > > +Description:	This file shows value that indicates whether the device is
> > > +		enabled for boot. This is one of the UFS device descriptor
> > > +		parameters. The full information about the descriptor could
> > > +		be found at UFS specifications 2.1.
> > > +		The file is read only.
> > > +
> > > +What:
> > 	/sys/bus/platform/drivers/ufshcd/*/device_descriptor/descriptor_a
> > ccess_enable
> > > +Date:		February 2018
> > > +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > > +Description:	This file shows value that indicates whether the device
> > > +		descriptor could be read after partial initialization phase
> > > +		of the boot sequence. This is one of the UFS device
> > descriptor
> > > +		parameters. The full information about the descriptor could
> > > +		be found at UFS specifications 2.1.
> > > +		The file is read only.
> > > +
> > > +What:
> > 	/sys/bus/platform/drivers/ufshcd/*/device_descriptor/initial_powe
> > r_mode
> > > +Date:		February 2018
> > > +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > > +Description:	This file shows value that defines the power mode after
> > > +		device initialization or hardware reset. This is one of
> > > +		the UFS device descriptor parameters. The full information
> > > +		about the descriptor could be found at UFS specifications 2.1.
> > > +		The file is read only.
> > > +
> > > +What:
> > 	/sys/bus/platform/drivers/ufshcd/*/device_descriptor/high_priority
> > _lun
> > > +Date:		February 2018
> > > +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > > +Description:	This file shows the high priority lun. This is one of
> > > +		the UFS device descriptor parameters. The full information
> > > +		about the descriptor could be found at UFS specifications 2.1.
> > > +		The file is read only.
> > > +
> > > +What:
> > 	/sys/bus/platform/drivers/ufshcd/*/device_descriptor/secure_rem
> > oval_type
> > > +Date:		February 2018
> > > +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > > +Description:	This file shows the secure removal type. This is one of
> > > +		the UFS device descriptor parameters. The full information
> > > +		about the descriptor could be found at UFS specifications 2.1.
> > > +		The file is read only.
> > > +
> > > +What:
> > 	/sys/bus/platform/drivers/ufshcd/*/device_descriptor/support_sec
> > urity_lun
> > > +Date:		February 2018
> > > +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > > +Description:	This file shows whether the security lun is supported.
> > > +		This is one of the UFS device descriptor parameters.
> > > +		The full information about the descriptor could be found
> > > +		at UFS specifications 2.1.
> > > +		The file is read only.
> > > +
> > > +What:
> > 	/sys/bus/platform/drivers/ufshcd/*/device_descriptor/bkops_termi
> > nation_latency
> > > +Date:		February 2018
> > > +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > > +Description:	This file shows the background operations termination
> > > +		latency. This is one of the UFS device descriptor parameters.
> > > +		The full information about the descriptor could be found
> > > +		at UFS specifications 2.1.
> > > +		The file is read only.
> > > +
> > > +What:
> > 	/sys/bus/platform/drivers/ufshcd/*/device_descriptor/initial_active
> > _icc_level
> > > +Date:		February 2018
> > > +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > > +Description:	This file shows the initial active ICC level. This is one
> > > +		of the UFS device descriptor parameters. The full information
> > > +		about the descriptor could be found at UFS specifications 2.1.
> > > +		The file is read only.
> > > +
> > > +What:
> > 	/sys/bus/platform/drivers/ufshcd/*/device_descriptor/specification
> > _version
> > > +Date:		February 2018
> > > +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > > +Description:	This file shows the specification version. This is one
> > > +		of the UFS device descriptor parameters. The full information
> > > +		about the descriptor could be found at UFS specifications 2.1.
> > > +		The file is read only.
> > > +
> > > +What:
> > 	/sys/bus/platform/drivers/ufshcd/*/device_descriptor/manufacturi
> > ng_date
> > > +Date:		February 2018
> > > +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > > +Description:	This file shows the manufacturing date in BCD format.
> > > +		This is one of the UFS device descriptor parameters.
> > > +		The full information about the descriptor could be found
> > > +		at UFS specifications 2.1.
> > > +		The file is read only.
> > > +
> > > +What:
> > 	/sys/bus/platform/drivers/ufshcd/*/device_descriptor/manufacture
> > r_id
> > > +Date:		February 2018
> > > +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > > +Description:	This file shows the manufacturee ID. This is one of the
> > > +		UFS device descriptor parameters. The full information about
> > > +		the descriptor could be found at UFS specifications 2.1.
> > > +		The file is read only.
> > > +
> > > +What:
> > 	/sys/bus/platform/drivers/ufshcd/*/device_descriptor/rtt_capabilit
> > y
> > > +Date:		February 2018
> > > +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > > +Description:	This file shows the maximum number of outstanding RTTs
> > > +		supported by the device. This is one of the UFS device
> > > +		descriptor parameters. The full information about
> > > +		the descriptor could be found at UFS specifications 2.1.
> > > +		The file is read only.
> > > +
> > > +What:
> > 	/sys/bus/platform/drivers/ufshcd/*/device_descriptor/rtc_update
> > > +Date:		February 2018
> > > +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > > +Description:	This file shows the frequency and method of the realtime
> > > +		clock update. This is one of the UFS device descriptor
> > > +		parameters. The full information about the descriptor
> > > +		could be found at UFS specifications 2.1.
> > > +		The file is read only.
> > > +
> > > +What:
> > 	/sys/bus/platform/drivers/ufshcd/*/device_descriptor/ufs_features
> > > +Date:		February 2018
> > > +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > > +Description:	This file shows which features are supported by the device.
> > > +		This is one of the UFS device descriptor parameters.
> > > +		The full information about the descriptor could be
> > > +		found at UFS specifications 2.1.
> > > +		The file is read only.
> > > +
> > > +What:
> > 	/sys/bus/platform/drivers/ufshcd/*/device_descriptor/ffu_timeout
> > > +Date:		February 2018
> > > +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > > +Description:	This file shows the FFU timeout. This is one of the
> > > +		UFS device descriptor parameters. The full information
> > > +		about the descriptor could be found at UFS specifications 2.1.
> > > +		The file is read only.
> > > +
> > > +What:
> > 	/sys/bus/platform/drivers/ufshcd/*/device_descriptor/queue_dept
> > h
> > > +Date:		February 2018
> > > +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > > +Description:	This file shows the device queue depth. This is one of the
> > > +		UFS device descriptor parameters. The full information
> > > +		about the descriptor could be found at UFS specifications 2.1.
> > > +		The file is read only.
> > > +
> > > +What:
> > 	/sys/bus/platform/drivers/ufshcd/*/device_descriptor/device_versi
> > on
> > > +Date:		February 2018
> > > +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > > +Description:	This file shows the device version. This is one of the
> > > +		UFS device descriptor parameters. The full information
> > > +		about the descriptor could be found at UFS specifications 2.1.
> > > +		The file is read only.
> > > +
> > > +What:
> > 	/sys/bus/platform/drivers/ufshcd/*/device_descriptor/number_of_
> > secure_wpa
> > > +Date:		February 2018
> > > +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > > +Description:	This file shows number of secure write protect areas
> > > +		supported by the device. This is one of the UFS device
> > > +		descriptor parameters. The full information about
> > > +		the descriptor could be found at UFS specifications 2.1.
> > > +		The file is read only.
> > > +
> > > +What:
> > 	/sys/bus/platform/drivers/ufshcd/*/device_descriptor/psa_max_da
> > ta_size
> > > +Date:		February 2018
> > > +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > > +Description:	This file shows the maximum amount of data that may be
> > > +		written during the pre-soldering phase of the PSA flow.
> > > +		This is one of the UFS device descriptor parameters.
> > > +		The full information about the descriptor could be found
> > > +		at UFS specifications 2.1.
> > > +		The file is read only.
> > > +
> > > +What:
> > 	/sys/bus/platform/drivers/ufshcd/*/device_descriptor/psa_state_ti
> > meout
> > > +Date:		February 2018
> > > +Contact:	Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
> > > +Description:	This file shows the command maximum timeout for a change
> > > +		in PSA state. This is one of the UFS device descriptor
> > > +		parameters. The full information about the descriptor could
> > > +		be found at UFS specifications 2.1.
> > > +		The file is read only.
> > > diff --git a/drivers/scsi/ufs/ufs-sysfs.c
> > > b/drivers/scsi/ufs/ufs-sysfs.c index ce8dcb6..aa2779a 100644
> > > --- a/drivers/scsi/ufs/ufs-sysfs.c
> > > +++ b/drivers/scsi/ufs/ufs-sysfs.c
> > > @@ -3,7 +3,9 @@
> > >
> > >  #include <linux/err.h>
> > >  #include <linux/string.h>
> > > +#include <asm/unaligned.h>
> > >
> > > +#include "ufs.h"
> > >  #include "ufs-sysfs.h"
> > >
> > >  static const char *ufschd_uic_link_state_to_string( @@ -134,8
> > > +136,122 @@ static const struct attribute_group ufs_sysfs_default_group
> > = {
> > >  	.attrs = ufs_sysfs_ufshcd_attrs,
> > >  };
> > >
> > > +static ssize_t ufs_sysfs_read_desc_param(struct ufs_hba *hba,
> > > +				  enum desc_idn desc_id,
> > > +				  u8 desc_index,
> > > +				  u8 param_offset,
> > > +				  u8 *sysfs_buf,
> > > +				  u8 param_size)
> > > +{
> > > +	u8 desc_buf[8] = {0};
> > > +	int ret;
> > > +
> > > +	if (param_size > 8)
> > > +		return -EINVAL;
> > > +
> > > +	ret = ufshcd_read_desc_param(hba, desc_id, desc_index,
> > > +				param_offset, desc_buf, param_size);
> > > +	if (ret)
> > > +		return -EINVAL;
> > > +	switch (param_size) {
> > > +	case 1:
> > > +		ret = sprintf(sysfs_buf, "0x%02X\n", *desc_buf);
> > > +		break;
> > > +	case 2:
> > > +		ret = sprintf(sysfs_buf, "0x%04X\n",
> > > +			get_unaligned_be16(desc_buf));
> > > +		break;
> > > +	case 4:
> > > +		ret = sprintf(sysfs_buf, "0x%08X\n",
> > > +			get_unaligned_be32(desc_buf));
> > > +		break;
> > > +	case 8:
> > > +		ret = sprintf(sysfs_buf, "0x%016llX\n",
> > > +			get_unaligned_be64(desc_buf));
> > > +		break;
> > > +	}
> > > +
> > > +	return ret;
> > > +}
> > > +
> > > +#define UFS_DESC_PARAM(_name, _puname, _duname, _size)
> > 		\
> > > +static ssize_t _name##_show(struct device *dev,
> > 	\
> > > +	struct device_attribute *attr, char *buf)			\
> > > +{									\
> > > +	struct ufs_hba *hba = dev_get_drvdata(dev);			\
> > > +	return ufs_sysfs_read_desc_param(hba,
> > QUERY_DESC_IDN_##_duname,	\
> > > +		0, _duname##_DESC_PARAM##_puname, buf, _size);
> > 	\
> > > +}									\
> > > +static DEVICE_ATTR_RO(_name)
> > > +
> > > +#define UFS_DEVICE_DESC_PARAM(_name, _uname, _size)
> > 		\
> > > +	UFS_DESC_PARAM(_name, _uname, DEVICE, _size)
> > > +
> > > +UFS_DEVICE_DESC_PARAM(device_type, _DEVICE_TYPE, 1);
> > > +UFS_DEVICE_DESC_PARAM(device_class, _DEVICE_CLASS, 1);
> > > +UFS_DEVICE_DESC_PARAM(device_sub_class, _DEVICE_SUB_CLASS, 1);
> > > +UFS_DEVICE_DESC_PARAM(protocol, _PRTCL, 1);
> > > +UFS_DEVICE_DESC_PARAM(number_of_luns, _NUM_LU, 1);
> > > +UFS_DEVICE_DESC_PARAM(number_of_wluns, _NUM_WLU, 1);
> > > +UFS_DEVICE_DESC_PARAM(boot_enable, _BOOT_ENBL, 1);
> > > +UFS_DEVICE_DESC_PARAM(descriptor_access_enable,
> > _DESC_ACCSS_ENBL, 1);
> > > +UFS_DEVICE_DESC_PARAM(initial_power_mode, _INIT_PWR_MODE, 1);
> > > +UFS_DEVICE_DESC_PARAM(high_priority_lun, _HIGH_PR_LUN, 1);
> > > +UFS_DEVICE_DESC_PARAM(secure_removal_type, _SEC_RMV_TYPE, 1);
> > > +UFS_DEVICE_DESC_PARAM(support_security_lun, _SEC_LU, 1);
> > > +UFS_DEVICE_DESC_PARAM(bkops_termination_latency,
> > _BKOP_TERM_LT, 1);
> > > +UFS_DEVICE_DESC_PARAM(initial_active_icc_level, _ACTVE_ICC_LVL, 1);
> > > +UFS_DEVICE_DESC_PARAM(specification_version, _SPEC_VER, 2);
> > > +UFS_DEVICE_DESC_PARAM(manufacturing_date, _MANF_DATE, 2);
> > > +UFS_DEVICE_DESC_PARAM(manufacturer_id, _MANF_ID, 2);
> > > +UFS_DEVICE_DESC_PARAM(rtt_capability, _RTT_CAP, 1);
> > > +UFS_DEVICE_DESC_PARAM(rtc_update, _FRQ_RTC, 2);
> > > +UFS_DEVICE_DESC_PARAM(ufs_features, _UFS_FEAT, 1);
> > > +UFS_DEVICE_DESC_PARAM(ffu_timeout, _FFU_TMT, 1);
> > > +UFS_DEVICE_DESC_PARAM(queue_depth, _Q_DPTH, 1);
> > > +UFS_DEVICE_DESC_PARAM(device_version, _DEV_VER, 2);
> > > +UFS_DEVICE_DESC_PARAM(number_of_secure_wpa, _NUM_SEC_WPA,
> > 1);
> > > +UFS_DEVICE_DESC_PARAM(psa_max_data_size, _PSA_MAX_DATA, 4);
> > > +UFS_DEVICE_DESC_PARAM(psa_state_timeout, _PSA_TMT, 1);
> > 
> > Could you add this case as well?
> > 
> > DEVICE_DESC_PARAM_PRDCT_REV		= 0x2A,
> > 
> 
> This value was omitted intentionally. It holds an index of the string descriptor with the
> product revision. There are 4 more such fields in the device descriptor:
>  - DEVICE_DESC_PARAM_MANF_NAME = 0x14
>  - DEVICE_DESC_PARAM_PRDCT_NAME  = 0x15,
>  - DEVICE_DESC_PARAM_SN = 0x16,
>  - DEVICE_DESC_PARAM_OEM_ID  = 0x17,
> The indexes itself don't provide any useful information to users and the
> corresponding strings are shown by the string descriptors (see "[PATCH v5 07/11] 
> scsi: ufs: sysfs: string descriptors")

Ah, I see, right. :)

Thanks,

> 
> Regards
> 
> > > +
> > > +static struct attribute *ufs_sysfs_device_descriptor[] = {
> > > +	&dev_attr_device_type.attr,
> > > +	&dev_attr_device_class.attr,
> > > +	&dev_attr_device_sub_class.attr,
> > > +	&dev_attr_protocol.attr,
> > > +	&dev_attr_number_of_luns.attr,
> > > +	&dev_attr_number_of_wluns.attr,
> > > +	&dev_attr_boot_enable.attr,
> > > +	&dev_attr_descriptor_access_enable.attr,
> > > +	&dev_attr_initial_power_mode.attr,
> > > +	&dev_attr_high_priority_lun.attr,
> > > +	&dev_attr_secure_removal_type.attr,
> > > +	&dev_attr_support_security_lun.attr,
> > > +	&dev_attr_bkops_termination_latency.attr,
> > > +	&dev_attr_initial_active_icc_level.attr,
> > > +	&dev_attr_specification_version.attr,
> > > +	&dev_attr_manufacturing_date.attr,
> > > +	&dev_attr_manufacturer_id.attr,
> > > +	&dev_attr_rtt_capability.attr,
> > > +	&dev_attr_rtc_update.attr,
> > > +	&dev_attr_ufs_features.attr,
> > > +	&dev_attr_ffu_timeout.attr,
> > > +	&dev_attr_queue_depth.attr,
> > > +	&dev_attr_device_version.attr,
> > > +	&dev_attr_number_of_secure_wpa.attr,
> > > +	&dev_attr_psa_max_data_size.attr,
> > > +	&dev_attr_psa_state_timeout.attr,
> > > +	NULL,
> > > +};
> > > +
> > > +static const struct attribute_group ufs_sysfs_device_descriptor_group = {
> > > +	.name = "device_descriptor",
> > > +	.attrs = ufs_sysfs_device_descriptor, };
> > > +
> > >  static const struct attribute_group *ufs_sysfs_groups[] = {
> > >  	&ufs_sysfs_default_group,
> > > +	&ufs_sysfs_device_descriptor_group,
> > >  	NULL,
> > >  };
> > >
> > > diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h index
> > > 54deeb7..6ae1e08 100644
> > > --- a/drivers/scsi/ufs/ufs.h
> > > +++ b/drivers/scsi/ufs/ufs.h
> > > @@ -220,6 +220,14 @@ enum device_desc_param {
> > >  	DEVICE_DESC_PARAM_UD_LEN		= 0x1B,
> > >  	DEVICE_DESC_PARAM_RTT_CAP		= 0x1C,
> > >  	DEVICE_DESC_PARAM_FRQ_RTC		= 0x1D,
> > > +	DEVICE_DESC_PARAM_UFS_FEAT		= 0x1F,
> > > +	DEVICE_DESC_PARAM_FFU_TMT		= 0x20,
> > > +	DEVICE_DESC_PARAM_Q_DPTH		= 0x21,
> > > +	DEVICE_DESC_PARAM_DEV_VER		= 0x22,
> > > +	DEVICE_DESC_PARAM_NUM_SEC_WPA		= 0x24,
> > > +	DEVICE_DESC_PARAM_PSA_MAX_DATA		= 0x25,
> > > +	DEVICE_DESC_PARAM_PSA_TMT		= 0x29,
> > > +	DEVICE_DESC_PARAM_PRDCT_REV		= 0x2A,
> > >  };
> > >
> > >  /*
> > > diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
> > > index e7621a0a..540a431 100644
> > > --- a/drivers/scsi/ufs/ufshcd.c
> > > +++ b/drivers/scsi/ufs/ufshcd.c
> > > @@ -2989,12 +2989,12 @@
> > EXPORT_SYMBOL(ufshcd_map_desc_id_to_length);
> > >   *
> > >   * Return 0 in case of success, non-zero otherwise
> > >   */
> > > -static int ufshcd_read_desc_param(struct ufs_hba *hba,
> > > -				  enum desc_idn desc_id,
> > > -				  int desc_index,
> > > -				  u8 param_offset,
> > > -				  u8 *param_read_buf,
> > > -				  u8 param_size)
> > > +int ufshcd_read_desc_param(struct ufs_hba *hba,
> > > +			   enum desc_idn desc_id,
> > > +			   int desc_index,
> > > +			   u8 param_offset,
> > > +			   u8 *param_read_buf,
> > > +			   u8 param_size)
> > >  {
> > >  	int ret;
> > >  	u8 *desc_buf;
> > > diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
> > > index 53e2779..38c307d 100644
> > > --- a/drivers/scsi/ufs/ufshcd.h
> > > +++ b/drivers/scsi/ufs/ufshcd.h
> > > @@ -841,6 +841,12 @@ static inline bool ufshcd_is_hs_mode(struct
> > > ufs_pa_layer_attr *pwr_info)  }
> > >
> > >  /* Expose Query-Request API */
> > > +int ufshcd_read_desc_param(struct ufs_hba *hba,
> > > +			   enum desc_idn desc_id,
> > > +			   int desc_index,
> > > +			   u8 param_offset,
> > > +			   u8 *param_read_buf,
> > > +			   u8 param_size);
> > >  int ufshcd_query_flag(struct ufs_hba *hba, enum query_opcode opcode,
> > >  	enum flag_idn idn, bool *flag_res);
> > >  int ufshcd_hold(struct ufs_hba *hba, bool async);
> > > --
> > > 2.7.4

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2018-02-12 18:00 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-02-06 16:06 [PATCH v5 00/11] ufs: sysfs: read-only access to device Stanislav Nijnikov
2018-02-06 16:06 ` [PATCH v5 01/11] scsi: ufs: sysfs: attribute group for existing sysfs entries Stanislav Nijnikov
2018-02-12  1:06   ` Jaegeuk Kim
2018-02-12  9:31     ` Philippe Ombredanne
2018-02-12 11:06     ` Stanislav Nijnikov
2018-02-06 16:06 ` [PATCH v5 02/11] scsi: ufs: sysfs: device descriptor Stanislav Nijnikov
2018-02-12  1:07   ` Jaegeuk Kim
2018-02-12 11:21     ` Stanislav Nijnikov
2018-02-12 18:00       ` Jaegeuk Kim
2018-02-06 16:06 ` [PATCH v5 03/11] scsi: ufs: sysfs: interconnect descriptor Stanislav Nijnikov
2018-02-06 16:06 ` [PATCH v5 04/11] scsi: ufs: sysfs: geometry descriptor Stanislav Nijnikov
2018-02-06 16:06 ` [PATCH v5 05/11] scsi: ufs: sysfs: health descriptor Stanislav Nijnikov
2018-02-06 16:06 ` [PATCH v5 06/11] scsi: ufs: sysfs: power descriptor Stanislav Nijnikov
2018-02-06 16:06 ` [PATCH v5 07/11] scsi: ufs: sysfs: string descriptors Stanislav Nijnikov
2018-02-06 16:06 ` [PATCH v5 08/11] scsi: host template attribute groups Stanislav Nijnikov
2018-02-06 19:06   ` Bart Van Assche
2018-02-06 16:06 ` [PATCH v5 09/11] scsi: ufs: sysfs: unit descriptor Stanislav Nijnikov
2018-02-06 16:06 ` [PATCH v5 10/11] scsi: ufs: sysfs: flags Stanislav Nijnikov
2018-02-06 16:06 ` [PATCH v5 11/11] scsi: ufs: sysfs: attributes Stanislav Nijnikov

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.