summaryrefslogtreecommitdiff
path: root/drivers/scsi/ufs/ufs-sysfs.c
diff options
context:
space:
mode:
authorStanislav Nijnikov <stanislav.nijnikov@wdc.com>2018-02-15 14:14:07 +0200
committerMartin K. Petersen <martin.petersen@oracle.com>2018-02-15 18:34:25 -0500
commit2238d31cdeabc585de5869efd11856815aa4dd13 (patch)
treeae44b7db8de163a1404b71b1b387aaceaeda765d /drivers/scsi/ufs/ufs-sysfs.c
parentc2e6e283c52f3a2c4a99774b36bcc88e7cbd5eb7 (diff)
scsi: ufs: sysfs: string descriptors
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> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/ufs/ufs-sysfs.c')
-rw-r--r--drivers/scsi/ufs/ufs-sysfs.c56
1 files changed, 56 insertions, 0 deletions
diff --git a/drivers/scsi/ufs/ufs-sysfs.c b/drivers/scsi/ufs/ufs-sysfs.c
index 16e357a95b6b..c1aeb8aa3160 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,
};