scsi: ufs: sysfs: unit descriptor
authorStanislav Nijnikov <stanislav.nijnikov@wdc.com>
Thu, 15 Feb 2018 12:14:09 +0000 (14:14 +0200)
committerMartin K. Petersen <martin.petersen@oracle.com>
Thu, 15 Feb 2018 23:35:04 +0000 (18:35 -0500)
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>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Documentation/ABI/testing/sysfs-driver-ufs
drivers/scsi/ufs/ufs-sysfs.c
drivers/scsi/ufs/ufs-sysfs.h
drivers/scsi/ufs/ufs.h
drivers/scsi/ufs/ufshcd.c
drivers/scsi/ufs/ufshcd.h

index c17a9685048b4964fe8cf3774d23119bd685fdfc..57c6a9028108287e31a56196622bde2db82ed8ed 100644 (file)
@@ -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.
index c1aeb8aa3160de32c3b2b7107303c728f44163c8..cd4d9d039ee98f614c4d8978c223a96d985dd0ab 100644 (file)
@@ -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;
index ce58861f548a1ccd01c97f829423b50a73272962..2afce169a9f0486ffd506722c9665953cdd116de 100644 (file)
@@ -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
index 6bfeedb934f13ee245321b77610f05828124c3c2..73870597e34ce1ab099850687fb3a439dda68a00 100644 (file)
@@ -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 */
index 9cfdd8ed198afc65e08bd17b355da26beb7a6feb..ace3acdc9a5bc63a3c2c6791de967431f2473b45 100644 (file)
@@ -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,
index 2dad9dada86a6a31edee45915e7be6439be811e8..f4cb31b23728214d455cf1b0238f15258e0261be 100644 (file)
@@ -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 */