@@ -29,28 +29,45 @@ static const char *save = "Specifies that the controller shall save the attribut
2929static const char * perfc_feat = "performance characteristics feature" ;
3030static const char * hctm_feat = "host controlled thermal management feature" ;
3131
32- static int power_mgmt_get (struct nvme_dev * dev , const __u8 fid , __u8 sel )
32+ static int feat_get (struct nvme_dev * dev , const __u8 fid , __u32 cdw11 , __u8 sel , const char * feat )
3333{
3434 __u32 result ;
3535 int err ;
36+ __u32 len = 0 ;
37+
38+ _cleanup_free_ void * buf = NULL ;
39+
40+ if (!NVME_CHECK (sel , GET_FEATURES_SEL , SUPPORTED ))
41+ nvme_get_feature_length (fid , cdw11 , & len );
42+
43+ if (len ) {
44+ buf = nvme_alloc (len - 1 );
45+ if (!buf )
46+ return - ENOMEM ;
47+ }
3648
3749 struct nvme_get_features_args args = {
38- .args_size = sizeof (args ),
39- .fd = dev_fd (dev ),
40- .fid = fid ,
41- .sel = sel ,
42- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT ,
43- .result = & result ,
50+ .args_size = sizeof (args ),
51+ .fd = dev_fd (dev ),
52+ .fid = fid ,
53+ .sel = sel ,
54+ .timeout = NVME_DEFAULT_IOCTL_TIMEOUT ,
55+ .result = & result ,
56+ .cdw11 = cdw11 ,
57+ .data = buf ,
58+ .data_len = len ,
4459 };
4560
4661 err = nvme_get_features (& args );
4762 if (!err ) {
4863 if (NVME_CHECK (sel , GET_FEATURES_SEL , SUPPORTED ))
4964 nvme_show_select_result (fid , result );
5065 else
51- nvme_feature_show_fields (fid , result , NULL );
66+ nvme_feature_show_fields (fid , result , buf );
67+ } else if (err > 0 ) {
68+ nvme_show_status (err );
5269 } else {
53- nvme_show_error ("Get %s" , power_mgmt_feat );
70+ nvme_show_error ("Get %s: %s " , feat , nvme_strerror ( errno ) );
5471 }
5572
5673 return err ;
@@ -119,41 +136,12 @@ static int feat_power_mgmt(int argc, char **argv, struct command *cmd, struct pl
119136 if (argconfig_parse_seen (opts , "ps" ))
120137 err = power_mgmt_set (dev , fid , cfg .ps , cfg .wh , cfg .save );
121138 else
122- err = power_mgmt_get (dev , fid , cfg .sel );
139+ err = feat_get (dev , fid , 0 , cfg .sel , power_mgmt_feat );
123140
124141 return err ;
125142}
126143
127- static int perfc_get (struct nvme_dev * dev , struct perfc_config * cfg )
128- {
129- __u32 result ;
130- int err ;
131-
132- struct nvme_get_features_args args = {
133- .args_size = sizeof (args ),
134- .fd = dev_fd (dev ),
135- .fid = NVME_FEAT_FID_PERF_CHARACTERISTICS ,
136- .cdw11 = NVME_SET (cfg -> attri , FEAT_PERFC_ATTRI ) |
137- NVME_SET (cfg -> rvspa , FEAT_PERFC_RVSPA ),
138- .sel = cfg -> sel ,
139- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT ,
140- .result = & result ,
141- };
142-
143- err = nvme_get_features (& args );
144- if (!err ) {
145- if (NVME_CHECK (args .sel , GET_FEATURES_SEL , SUPPORTED ))
146- nvme_show_select_result (args .fid , result );
147- else
148- nvme_feature_show_fields (args .fid , result , NULL );
149- } else {
150- nvme_show_error ("Get %s" , perfc_feat );
151- }
152-
153- return err ;
154- }
155-
156- static int perfc_set (struct nvme_dev * dev , struct perfc_config * cfg )
144+ static int perfc_set (struct nvme_dev * dev , __u8 fid , __u32 cdw11 , struct perfc_config * cfg )
157145{
158146 __u32 result ;
159147 int err ;
@@ -167,9 +155,8 @@ static int perfc_set(struct nvme_dev *dev, struct perfc_config *cfg)
167155 struct nvme_set_features_args args = {
168156 .args_size = sizeof (args ),
169157 .fd = dev_fd (dev ),
170- .fid = NVME_FEAT_FID_PERF_CHARACTERISTICS ,
171- .cdw11 = NVME_SET (cfg -> attri , FEAT_PERFC_ATTRI ) |
172- NVME_SET (cfg -> rvspa , FEAT_PERFC_RVSPA ),
158+ .fid = fid ,
159+ .cdw11 = cdw11 ,
173160 .save = save ,
174161 .timeout = NVME_DEFAULT_IOCTL_TIMEOUT ,
175162 .result = & result ,
@@ -234,6 +221,8 @@ static int feat_perfc(int argc, char **argv, struct command *cmd, struct plugin
234221
235222 _cleanup_nvme_dev_ struct nvme_dev * dev = NULL ;
236223 int err ;
224+ __u8 fid = NVME_FEAT_FID_PERF_CHARACTERISTICS ;
225+ __u32 cdw11 ;
237226
238227 struct perfc_config cfg = { 0 };
239228
@@ -250,38 +239,13 @@ static int feat_perfc(int argc, char **argv, struct command *cmd, struct plugin
250239 if (err )
251240 return err ;
252241
242+ cdw11 = NVME_SET (cfg .attri , FEAT_PERFC_ATTRI ) | NVME_SET (cfg .rvspa , FEAT_PERFC_RVSPA );
243+
253244 if (argconfig_parse_seen (opts , "rvspa" ) || argconfig_parse_seen (opts , "r4karl" ) ||
254245 argconfig_parse_seen (opts , "paid" ))
255- err = perfc_set (dev , & cfg );
246+ err = perfc_set (dev , fid , cdw11 , & cfg );
256247 else
257- err = perfc_get (dev , & cfg );
258-
259- return err ;
260- }
261-
262- static int hctm_get (struct nvme_dev * dev , const __u8 fid , __u8 sel )
263- {
264- __u32 result ;
265- int err ;
266-
267- struct nvme_get_features_args args = {
268- .args_size = sizeof (args ),
269- .fd = dev_fd (dev ),
270- .fid = fid ,
271- .sel = sel ,
272- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT ,
273- .result = & result ,
274- };
275-
276- err = nvme_get_features (& args );
277- if (!err ) {
278- if (NVME_CHECK (sel , GET_FEATURES_SEL , SUPPORTED ))
279- nvme_show_select_result (fid , result );
280- else
281- nvme_feature_show_fields (fid , result , NULL );
282- } else {
283- nvme_show_error ("Get %s" , hctm_feat );
284- }
248+ err = feat_get (dev , fid , cdw11 , cfg .sel , perfc_feat );
285249
286250 return err ;
287251}
@@ -347,7 +311,7 @@ static int feat_hctm(int argc, char **argv, struct command *cmd, struct plugin *
347311 if (argconfig_parse_seen (opts , "tmt1" ) || argconfig_parse_seen (opts , "tmt2" ))
348312 err = hctm_set (dev , fid , cfg .tmt1 , cfg .tmt2 , cfg .save );
349313 else
350- err = hctm_get (dev , fid , cfg .sel );
314+ err = feat_get (dev , fid , 0 , cfg .sel , hctm_feat );
351315
352316 return err ;
353317}
0 commit comments