@@ -87,6 +87,23 @@ static const char *ufs_wb_resize_status_to_string(enum wb_resize_status status)
8787 }
8888}
8989
90+ static const char * const ufs_hid_states [] = {
91+ [HID_IDLE ] = "idle" ,
92+ [ANALYSIS_IN_PROGRESS ] = "analysis_in_progress" ,
93+ [DEFRAG_REQUIRED ] = "defrag_required" ,
94+ [DEFRAG_IN_PROGRESS ] = "defrag_in_progress" ,
95+ [DEFRAG_COMPLETED ] = "defrag_completed" ,
96+ [DEFRAG_NOT_REQUIRED ] = "defrag_not_required" ,
97+ };
98+
99+ static const char * ufs_hid_state_to_string (enum ufs_hid_state state )
100+ {
101+ if (state < NUM_UFS_HID_STATES )
102+ return ufs_hid_states [state ];
103+
104+ return "unknown" ;
105+ }
106+
90107static const char * ufshcd_uic_link_state_to_string (
91108 enum uic_link_state state )
92109{
@@ -1763,6 +1780,178 @@ static const struct attribute_group ufs_sysfs_attributes_group = {
17631780 .attrs = ufs_sysfs_attributes ,
17641781};
17651782
1783+ static int hid_query_attr (struct ufs_hba * hba , enum query_opcode opcode ,
1784+ enum attr_idn idn , u32 * attr_val )
1785+ {
1786+ int ret ;
1787+
1788+ down (& hba -> host_sem );
1789+ if (!ufshcd_is_user_access_allowed (hba )) {
1790+ up (& hba -> host_sem );
1791+ return - EBUSY ;
1792+ }
1793+
1794+ ufshcd_rpm_get_sync (hba );
1795+ ret = ufshcd_query_attr (hba , opcode , idn , 0 , 0 , attr_val );
1796+ ufshcd_rpm_put_sync (hba );
1797+
1798+ up (& hba -> host_sem );
1799+ return ret ;
1800+ }
1801+
1802+ static ssize_t analysis_trigger_store (struct device * dev ,
1803+ struct device_attribute * attr , const char * buf , size_t count )
1804+ {
1805+ struct ufs_hba * hba = dev_get_drvdata (dev );
1806+ int mode ;
1807+ int ret ;
1808+
1809+ if (sysfs_streq (buf , "enable" ))
1810+ mode = HID_ANALYSIS_ENABLE ;
1811+ else if (sysfs_streq (buf , "disable" ))
1812+ mode = HID_ANALYSIS_AND_DEFRAG_DISABLE ;
1813+ else
1814+ return - EINVAL ;
1815+
1816+ ret = hid_query_attr (hba , UPIU_QUERY_OPCODE_WRITE_ATTR ,
1817+ QUERY_ATTR_IDN_HID_DEFRAG_OPERATION , & mode );
1818+
1819+ return ret < 0 ? ret : count ;
1820+ }
1821+
1822+ static DEVICE_ATTR_WO (analysis_trigger );
1823+
1824+ static ssize_t defrag_trigger_store (struct device * dev ,
1825+ struct device_attribute * attr , const char * buf , size_t count )
1826+ {
1827+ struct ufs_hba * hba = dev_get_drvdata (dev );
1828+ int mode ;
1829+ int ret ;
1830+
1831+ if (sysfs_streq (buf , "enable" ))
1832+ mode = HID_ANALYSIS_AND_DEFRAG_ENABLE ;
1833+ else if (sysfs_streq (buf , "disable" ))
1834+ mode = HID_ANALYSIS_AND_DEFRAG_DISABLE ;
1835+ else
1836+ return - EINVAL ;
1837+
1838+ ret = hid_query_attr (hba , UPIU_QUERY_OPCODE_WRITE_ATTR ,
1839+ QUERY_ATTR_IDN_HID_DEFRAG_OPERATION , & mode );
1840+
1841+ return ret < 0 ? ret : count ;
1842+ }
1843+
1844+ static DEVICE_ATTR_WO (defrag_trigger );
1845+
1846+ static ssize_t fragmented_size_show (struct device * dev ,
1847+ struct device_attribute * attr , char * buf )
1848+ {
1849+ struct ufs_hba * hba = dev_get_drvdata (dev );
1850+ u32 value ;
1851+ int ret ;
1852+
1853+ ret = hid_query_attr (hba , UPIU_QUERY_OPCODE_READ_ATTR ,
1854+ QUERY_ATTR_IDN_HID_AVAILABLE_SIZE , & value );
1855+ if (ret )
1856+ return ret ;
1857+
1858+ return sysfs_emit (buf , "%u\n" , value );
1859+ }
1860+
1861+ static DEVICE_ATTR_RO (fragmented_size );
1862+
1863+ static ssize_t defrag_size_show (struct device * dev ,
1864+ struct device_attribute * attr , char * buf )
1865+ {
1866+ struct ufs_hba * hba = dev_get_drvdata (dev );
1867+ u32 value ;
1868+ int ret ;
1869+
1870+ ret = hid_query_attr (hba , UPIU_QUERY_OPCODE_READ_ATTR ,
1871+ QUERY_ATTR_IDN_HID_SIZE , & value );
1872+ if (ret )
1873+ return ret ;
1874+
1875+ return sysfs_emit (buf , "%u\n" , value );
1876+ }
1877+
1878+ static ssize_t defrag_size_store (struct device * dev ,
1879+ struct device_attribute * attr , const char * buf , size_t count )
1880+ {
1881+ struct ufs_hba * hba = dev_get_drvdata (dev );
1882+ u32 value ;
1883+ int ret ;
1884+
1885+ if (kstrtou32 (buf , 0 , & value ))
1886+ return - EINVAL ;
1887+
1888+ ret = hid_query_attr (hba , UPIU_QUERY_OPCODE_WRITE_ATTR ,
1889+ QUERY_ATTR_IDN_HID_SIZE , & value );
1890+
1891+ return ret < 0 ? ret : count ;
1892+ }
1893+
1894+ static DEVICE_ATTR_RW (defrag_size );
1895+
1896+ static ssize_t progress_ratio_show (struct device * dev ,
1897+ struct device_attribute * attr , char * buf )
1898+ {
1899+ struct ufs_hba * hba = dev_get_drvdata (dev );
1900+ u32 value ;
1901+ int ret ;
1902+
1903+ ret = hid_query_attr (hba , UPIU_QUERY_OPCODE_READ_ATTR ,
1904+ QUERY_ATTR_IDN_HID_PROGRESS_RATIO , & value );
1905+ if (ret )
1906+ return ret ;
1907+
1908+ return sysfs_emit (buf , "%u\n" , value );
1909+ }
1910+
1911+ static DEVICE_ATTR_RO (progress_ratio );
1912+
1913+ static ssize_t state_show (struct device * dev ,
1914+ struct device_attribute * attr , char * buf )
1915+ {
1916+ struct ufs_hba * hba = dev_get_drvdata (dev );
1917+ u32 value ;
1918+ int ret ;
1919+
1920+ ret = hid_query_attr (hba , UPIU_QUERY_OPCODE_READ_ATTR ,
1921+ QUERY_ATTR_IDN_HID_STATE , & value );
1922+ if (ret )
1923+ return ret ;
1924+
1925+ return sysfs_emit (buf , "%s\n" , ufs_hid_state_to_string (value ));
1926+ }
1927+
1928+ static DEVICE_ATTR_RO (state );
1929+
1930+ static struct attribute * ufs_sysfs_hid [] = {
1931+ & dev_attr_analysis_trigger .attr ,
1932+ & dev_attr_defrag_trigger .attr ,
1933+ & dev_attr_fragmented_size .attr ,
1934+ & dev_attr_defrag_size .attr ,
1935+ & dev_attr_progress_ratio .attr ,
1936+ & dev_attr_state .attr ,
1937+ NULL ,
1938+ };
1939+
1940+ static umode_t ufs_sysfs_hid_is_visible (struct kobject * kobj ,
1941+ struct attribute * attr , int n )
1942+ {
1943+ struct device * dev = container_of (kobj , struct device , kobj );
1944+ struct ufs_hba * hba = dev_get_drvdata (dev );
1945+
1946+ return hba -> dev_info .hid_sup ? attr -> mode : 0 ;
1947+ }
1948+
1949+ static const struct attribute_group ufs_sysfs_hid_group = {
1950+ .name = "hid" ,
1951+ .attrs = ufs_sysfs_hid ,
1952+ .is_visible = ufs_sysfs_hid_is_visible ,
1953+ };
1954+
17661955static const struct attribute_group * ufs_sysfs_groups [] = {
17671956 & ufs_sysfs_default_group ,
17681957 & ufs_sysfs_capabilities_group ,
@@ -1777,6 +1966,7 @@ static const struct attribute_group *ufs_sysfs_groups[] = {
17771966 & ufs_sysfs_string_descriptors_group ,
17781967 & ufs_sysfs_flags_group ,
17791968 & ufs_sysfs_attributes_group ,
1969+ & ufs_sysfs_hid_group ,
17801970 NULL ,
17811971};
17821972
0 commit comments