@@ -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 ;
@@ -121,41 +138,12 @@ static int feat_power_mgmt(int argc, char **argv, struct command *cmd, struct pl
121138 if (argconfig_parse_seen (opts , "ps" ))
122139 err = power_mgmt_set (dev , fid , cfg .ps , cfg .wh , cfg .save );
123140 else
124- err = power_mgmt_get (dev , fid , cfg .sel );
141+ err = feat_get (dev , fid , 0 , cfg .sel , power_mgmt_feat );
125142
126143 return err ;
127144}
128145
129- static int perfc_get (struct nvme_dev * dev , struct perfc_config * cfg )
130- {
131- __u32 result ;
132- int err ;
133-
134- struct nvme_get_features_args args = {
135- .args_size = sizeof (args ),
136- .fd = dev_fd (dev ),
137- .fid = NVME_FEAT_FID_PERF_CHARACTERISTICS ,
138- .cdw11 = NVME_SET (cfg -> attri , FEAT_PERFC_ATTRI ) |
139- NVME_SET (cfg -> rvspa , FEAT_PERFC_RVSPA ),
140- .sel = cfg -> sel ,
141- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT ,
142- .result = & result ,
143- };
144-
145- err = nvme_get_features (& args );
146- if (!err ) {
147- if (NVME_CHECK (args .sel , GET_FEATURES_SEL , SUPPORTED ))
148- nvme_show_select_result (args .fid , result );
149- else
150- nvme_feature_show_fields (args .fid , result , NULL );
151- } else {
152- nvme_show_error ("Get %s" , perfc_feat );
153- }
154-
155- return err ;
156- }
157-
158- static int perfc_set (struct nvme_dev * dev , struct perfc_config * cfg )
146+ static int perfc_set (struct nvme_dev * dev , __u8 fid , __u32 cdw11 , struct perfc_config * cfg )
159147{
160148 __u32 result ;
161149 int err ;
@@ -169,9 +157,8 @@ static int perfc_set(struct nvme_dev *dev, struct perfc_config *cfg)
169157 struct nvme_set_features_args args = {
170158 .args_size = sizeof (args ),
171159 .fd = dev_fd (dev ),
172- .fid = NVME_FEAT_FID_PERF_CHARACTERISTICS ,
173- .cdw11 = NVME_SET (cfg -> attri , FEAT_PERFC_ATTRI ) |
174- NVME_SET (cfg -> rvspa , FEAT_PERFC_RVSPA ),
160+ .fid = fid ,
161+ .cdw11 = cdw11 ,
175162 .save = save ,
176163 .timeout = NVME_DEFAULT_IOCTL_TIMEOUT ,
177164 .result = & result ,
@@ -236,6 +223,8 @@ static int feat_perfc(int argc, char **argv, struct command *cmd, struct plugin
236223
237224 _cleanup_nvme_dev_ struct nvme_dev * dev = NULL ;
238225 int err ;
226+ __u8 fid = NVME_FEAT_FID_PERF_CHARACTERISTICS ;
227+ __u32 cdw11 ;
239228
240229 struct perfc_config cfg = { 0 };
241230
@@ -254,38 +243,13 @@ static int feat_perfc(int argc, char **argv, struct command *cmd, struct plugin
254243 if (err )
255244 return err ;
256245
246+ cdw11 = NVME_SET (cfg .attri , FEAT_PERFC_ATTRI ) | NVME_SET (cfg .rvspa , FEAT_PERFC_RVSPA );
247+
257248 if (argconfig_parse_seen (opts , "rvspa" ) || argconfig_parse_seen (opts , "r4karl" ) ||
258249 argconfig_parse_seen (opts , "paid" ))
259- err = perfc_set (dev , & cfg );
250+ err = perfc_set (dev , fid , cdw11 , & cfg );
260251 else
261- err = perfc_get (dev , & cfg );
262-
263- return err ;
264- }
265-
266- static int hctm_get (struct nvme_dev * dev , const __u8 fid , __u8 sel )
267- {
268- __u32 result ;
269- int err ;
270-
271- struct nvme_get_features_args args = {
272- .args_size = sizeof (args ),
273- .fd = dev_fd (dev ),
274- .fid = fid ,
275- .sel = sel ,
276- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT ,
277- .result = & result ,
278- };
279-
280- err = nvme_get_features (& args );
281- if (!err ) {
282- if (NVME_CHECK (sel , GET_FEATURES_SEL , SUPPORTED ))
283- nvme_show_select_result (fid , result );
284- else
285- nvme_feature_show_fields (fid , result , NULL );
286- } else {
287- nvme_show_error ("Get %s" , hctm_feat );
288- }
252+ err = feat_get (dev , fid , cdw11 , cfg .sel , perfc_feat );
289253
290254 return err ;
291255}
@@ -353,7 +317,7 @@ static int feat_hctm(int argc, char **argv, struct command *cmd, struct plugin *
353317 if (argconfig_parse_seen (opts , "tmt1" ) || argconfig_parse_seen (opts , "tmt2" ))
354318 err = hctm_set (dev , fid , cfg .tmt1 , cfg .tmt2 , cfg .save );
355319 else
356- err = hctm_get (dev , fid , cfg .sel );
320+ err = feat_get (dev , fid , 0 , cfg .sel , hctm_feat );
357321
358322 return err ;
359323}
0 commit comments