Commit ec92b59c authored by Stanislav Nijnikov's avatar Stanislav Nijnikov Committed by Martin K. Petersen

scsi: ufs: sysfs: attributes

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: default avatarStanislav Nijnikov <stanislav.nijnikov@wdc.com>
Reviewed-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent d10b2a8e
...@@ -663,3 +663,142 @@ Description: This file shows whether the device FW update is permanently ...@@ -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 disabled. The full information about the flag could be found
at UFS specifications 2.1. at UFS specifications 2.1.
The file is read only. 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.
...@@ -577,6 +577,61 @@ static const struct attribute_group ufs_sysfs_flags_group = { ...@@ -577,6 +577,61 @@ static const struct attribute_group ufs_sysfs_flags_group = {
.attrs = ufs_sysfs_device_flags, .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[] = { static const struct attribute_group *ufs_sysfs_groups[] = {
&ufs_sysfs_default_group, &ufs_sysfs_default_group,
&ufs_sysfs_device_descriptor_group, &ufs_sysfs_device_descriptor_group,
...@@ -586,6 +641,7 @@ static const struct attribute_group *ufs_sysfs_groups[] = { ...@@ -586,6 +641,7 @@ static const struct attribute_group *ufs_sysfs_groups[] = {
&ufs_sysfs_power_descriptor_group, &ufs_sysfs_power_descriptor_group,
&ufs_sysfs_string_descriptors_group, &ufs_sysfs_string_descriptors_group,
&ufs_sysfs_flags_group, &ufs_sysfs_flags_group,
&ufs_sysfs_attributes_group,
NULL, NULL,
}; };
...@@ -642,6 +698,30 @@ const struct attribute_group ufs_sysfs_unit_descriptor_group = { ...@@ -642,6 +698,30 @@ const struct attribute_group ufs_sysfs_unit_descriptor_group = {
.attrs = ufs_sysfs_unit_descriptor, .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) void ufs_sysfs_add_nodes(struct device *dev)
{ {
int ret; int ret;
......
...@@ -13,4 +13,5 @@ void ufs_sysfs_add_nodes(struct device *dev); ...@@ -13,4 +13,5 @@ void ufs_sysfs_add_nodes(struct device *dev);
void ufs_sysfs_remove_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_unit_descriptor_group;
extern const struct attribute_group ufs_sysfs_lun_attributes_group;
#endif #endif
...@@ -145,10 +145,29 @@ enum flag_idn { ...@@ -145,10 +145,29 @@ enum flag_idn {
/* Attribute idn for Query requests */ /* Attribute idn for Query requests */
enum attr_idn { enum attr_idn {
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_ACTIVE_ICC_LVL = 0x03,
QUERY_ATTR_IDN_OOO_DATA_EN = 0x04,
QUERY_ATTR_IDN_BKOPS_STATUS = 0x05, 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_CONTROL = 0x0D,
QUERY_ATTR_IDN_EE_STATUS = 0x0E, 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 */ /* Descriptor idn for Query requests */
......
...@@ -2689,7 +2689,7 @@ int ufshcd_query_flag(struct ufs_hba *hba, enum query_opcode opcode, ...@@ -2689,7 +2689,7 @@ int ufshcd_query_flag(struct ufs_hba *hba, enum query_opcode opcode,
* *
* Returns 0 for success, non-zero in case of failure * Returns 0 for success, non-zero in case of failure
*/ */
static int ufshcd_query_attr(struct ufs_hba *hba, enum query_opcode opcode, int ufshcd_query_attr(struct ufs_hba *hba, enum query_opcode opcode,
enum attr_idn idn, u8 index, u8 selector, u32 *attr_val) enum attr_idn idn, u8 index, u8 selector, u32 *attr_val)
{ {
struct ufs_query_req *request = NULL; struct ufs_query_req *request = NULL;
...@@ -6468,6 +6468,7 @@ static enum blk_eh_timer_return ufshcd_eh_timed_out(struct scsi_cmnd *scmd) ...@@ -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[] = { static const struct attribute_group *ufshcd_driver_groups[] = {
&ufs_sysfs_unit_descriptor_group, &ufs_sysfs_unit_descriptor_group,
&ufs_sysfs_lun_attributes_group,
NULL, NULL,
}; };
......
...@@ -847,13 +847,14 @@ int ufshcd_query_descriptor_retry(struct ufs_hba *hba, ...@@ -847,13 +847,14 @@ int ufshcd_query_descriptor_retry(struct ufs_hba *hba,
enum desc_idn idn, u8 index, enum desc_idn idn, u8 index,
u8 selector, u8 selector,
u8 *desc_buf, int *buf_len); u8 *desc_buf, int *buf_len);
int ufshcd_read_desc_param(struct ufs_hba *hba, int ufshcd_read_desc_param(struct ufs_hba *hba,
enum desc_idn desc_id, enum desc_idn desc_id,
int desc_index, int desc_index,
u8 param_offset, u8 param_offset,
u8 *param_read_buf, u8 *param_read_buf,
u8 param_size); 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, int ufshcd_query_flag(struct ufs_hba *hba, enum query_opcode opcode,
enum flag_idn idn, bool *flag_res); enum flag_idn idn, bool *flag_res);
int ufshcd_read_string_desc(struct ufs_hba *hba, int desc_index, int ufshcd_read_string_desc(struct ufs_hba *hba, int desc_index,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment