summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/ufs
diff options
context:
space:
mode:
authorStanislav Nijnikov <stanislav.nijnikov@wdc.com>2018-02-15 14:14:05 +0200
committerMartin K. Petersen <martin.petersen@oracle.com>2018-02-15 18:34:24 -0500
commitc648c2d27f168ae4faeb43f8c3074226aae3862c (patch)
tree11f41b8d2d1f64c8fcc512950f47e55b20698374 /drivers/scsi/ufs
parentc720c091222e26d46c0fd9c70144a0f916bf3993 (diff)
downloadlinux-c648c2d27f168ae4faeb43f8c3074226aae3862c.tar.bz2
scsi: ufs: sysfs: health descriptor
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> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/ufs')
-rw-r--r--drivers/scsi/ufs/ufs-sysfs.c20
-rw-r--r--drivers/scsi/ufs/ufs.h11
-rw-r--r--drivers/scsi/ufs/ufshcd.c8
-rw-r--r--drivers/scsi/ufs/ufshcd.h1
4 files changed, 40 insertions, 0 deletions
diff --git a/drivers/scsi/ufs/ufs-sysfs.c b/drivers/scsi/ufs/ufs-sysfs.c
index ecd3dcb05f67..c4f18b0970db 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 04d41c8d3dc1..6bfeedb934f1 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 540a431e38ce..b88fcf7be47b 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 38c307d053c7..515c6e6244be 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;
};
/**