@@ -28,28 +28,45 @@ static const char *save = "Specifies that the controller shall save the attribut
2828static const char * perfc_feat = "performance characteristics feature" ;
2929static const char * hctm_feat = "host controlled thermal management feature" ;
3030
31- static int power_mgmt_get (struct nvme_dev * dev , const __u8 fid , __u8 sel )
31+ static int feat_get (struct nvme_dev * dev , const __u8 fid , __u32 cdw11 , __u8 sel , const char * feat )
3232{
3333 __u32 result ;
3434 int err ;
35+ __u32 len = 0 ;
36+
37+ _cleanup_free_ void * buf = NULL ;
38+
39+ if (!NVME_CHECK (sel , GET_FEATURES_SEL , SUPPORTED ))
40+ nvme_get_feature_length (fid , cdw11 , & len );
41+
42+ if (len ) {
43+ buf = nvme_alloc (len - 1 );
44+ if (!buf )
45+ return - ENOMEM ;
46+ }
3547
3648 struct nvme_get_features_args args = {
37- .args_size = sizeof (args ),
38- .fd = dev_fd (dev ),
39- .fid = fid ,
40- .sel = sel ,
41- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT ,
42- .result = & result ,
49+ .args_size = sizeof (args ),
50+ .fd = dev_fd (dev ),
51+ .fid = fid ,
52+ .sel = sel ,
53+ .timeout = NVME_DEFAULT_IOCTL_TIMEOUT ,
54+ .result = & result ,
55+ .cdw11 = cdw11 ,
56+ .data = buf ,
57+ .data_len = len ,
4358 };
4459
4560 err = nvme_get_features (& args );
4661 if (!err ) {
4762 if (NVME_CHECK (sel , GET_FEATURES_SEL , SUPPORTED ))
4863 nvme_show_select_result (fid , result );
4964 else
50- nvme_feature_show_fields (fid , result , NULL );
65+ nvme_feature_show_fields (fid , result , buf );
66+ } else if (err > 0 ) {
67+ nvme_show_status (err );
5168 } else {
52- nvme_show_error ("Get %s" , power_mgmt_feat );
69+ nvme_show_error ("Get %s: %s " , feat , nvme_strerror ( errno ) );
5370 }
5471
5572 return err ;
@@ -117,41 +134,12 @@ static int feat_power_mgmt(int argc, char **argv, struct command *cmd, struct pl
117134 if (argconfig_parse_seen (opts , "ps" ))
118135 err = power_mgmt_set (dev , fid , cfg .ps , cfg .wh , argconfig_parse_seen (opts , "save" ));
119136 else
120- err = power_mgmt_get (dev , fid , cfg .sel );
137+ err = feat_get (dev , fid , 0 , cfg .sel , power_mgmt_feat );
121138
122139 return err ;
123140}
124141
125- static int perfc_get (struct nvme_dev * dev , struct perfc_config * cfg )
126- {
127- __u32 result ;
128- int err ;
129-
130- struct nvme_get_features_args args = {
131- .args_size = sizeof (args ),
132- .fd = dev_fd (dev ),
133- .fid = NVME_FEAT_FID_PERF_CHARACTERISTICS ,
134- .cdw11 = NVME_SET (cfg -> attri , FEAT_PERFC_ATTRI ) |
135- NVME_SET (cfg -> rvspa , FEAT_PERFC_RVSPA ),
136- .sel = cfg -> sel ,
137- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT ,
138- .result = & result ,
139- };
140-
141- err = nvme_get_features (& args );
142- if (!err ) {
143- if (NVME_CHECK (args .sel , GET_FEATURES_SEL , SUPPORTED ))
144- nvme_show_select_result (args .fid , result );
145- else
146- nvme_feature_show_fields (args .fid , result , NULL );
147- } else {
148- nvme_show_error ("Get %s" , perfc_feat );
149- }
150-
151- return err ;
152- }
153-
154- static int perfc_set (struct nvme_dev * dev , struct perfc_config * cfg )
142+ static int perfc_set (struct nvme_dev * dev , __u8 fid , __u32 cdw11 , struct perfc_config * cfg )
155143{
156144 __u32 result ;
157145 int err ;
@@ -165,9 +153,8 @@ static int perfc_set(struct nvme_dev *dev, struct perfc_config *cfg)
165153 struct nvme_set_features_args args = {
166154 .args_size = sizeof (args ),
167155 .fd = dev_fd (dev ),
168- .fid = NVME_FEAT_FID_PERF_CHARACTERISTICS ,
169- .cdw11 = NVME_SET (cfg -> attri , FEAT_PERFC_ATTRI ) |
170- NVME_SET (cfg -> rvspa , FEAT_PERFC_RVSPA ),
156+ .fid = fid ,
157+ .cdw11 = cdw11 ,
171158 .save = save ,
172159 .timeout = NVME_DEFAULT_IOCTL_TIMEOUT ,
173160 .result = & result ,
@@ -232,6 +219,8 @@ static int feat_perfc(int argc, char **argv, struct command *cmd, struct plugin
232219
233220 _cleanup_nvme_dev_ struct nvme_dev * dev = NULL ;
234221 int err ;
222+ __u8 fid = NVME_FEAT_FID_PERF_CHARACTERISTICS ;
223+ __u32 cdw11 ;
235224
236225 struct perfc_config cfg = { 0 };
237226
@@ -248,38 +237,13 @@ static int feat_perfc(int argc, char **argv, struct command *cmd, struct plugin
248237 if (err )
249238 return err ;
250239
240+ cdw11 = NVME_SET (cfg .attri , FEAT_PERFC_ATTRI ) | NVME_SET (cfg .rvspa , FEAT_PERFC_RVSPA );
241+
251242 if (argconfig_parse_seen (opts , "rvspa" ) || argconfig_parse_seen (opts , "r4karl" ) ||
252243 argconfig_parse_seen (opts , "paid" ))
253- err = perfc_set (dev , & cfg );
244+ err = perfc_set (dev , fid , cdw11 , & cfg );
254245 else
255- err = perfc_get (dev , & cfg );
256-
257- return err ;
258- }
259-
260- static int hctm_get (struct nvme_dev * dev , const __u8 fid , __u8 sel )
261- {
262- __u32 result ;
263- int err ;
264-
265- struct nvme_get_features_args args = {
266- .args_size = sizeof (args ),
267- .fd = dev_fd (dev ),
268- .fid = fid ,
269- .sel = sel ,
270- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT ,
271- .result = & result ,
272- };
273-
274- err = nvme_get_features (& args );
275- if (!err ) {
276- if (NVME_CHECK (sel , GET_FEATURES_SEL , SUPPORTED ))
277- nvme_show_select_result (fid , result );
278- else
279- nvme_feature_show_fields (fid , result , NULL );
280- } else {
281- nvme_show_error ("Get %s" , hctm_feat );
282- }
246+ err = feat_get (dev , fid , cdw11 , cfg .sel , perfc_feat );
283247
284248 return err ;
285249}
@@ -344,7 +308,7 @@ static int feat_hctm(int argc, char **argv, struct command *cmd, struct plugin *
344308 if (argconfig_parse_seen (opts , "tmt1" ) || argconfig_parse_seen (opts , "tmt2" ))
345309 err = hctm_set (dev , fid , cfg .tmt1 , cfg .tmt2 , argconfig_parse_seen (opts , "save" ));
346310 else
347- err = hctm_get (dev , fid , cfg .sel );
311+ err = feat_get (dev , fid , 0 , cfg .sel , hctm_feat );
348312
349313 return err ;
350314}
0 commit comments