@@ -29,28 +29,42 @@ 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+ _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+ }
3647
3748 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 ,
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 ,
4458 };
4559
4660 err = nvme_get_features (& args );
4761 if (!err ) {
4862 if (NVME_CHECK (sel , GET_FEATURES_SEL , SUPPORTED ))
4963 nvme_show_select_result (fid , result );
5064 else
51- nvme_feature_show_fields (fid , result , NULL );
65+ nvme_feature_show_fields (fid , result , buf );
5266 } else {
53- nvme_show_error ("Get %s" , power_mgmt_feat );
67+ nvme_show_error ("Get %s" , feat );
5468 }
5569
5670 return err ;
@@ -121,41 +135,12 @@ static int feat_power_mgmt(int argc, char **argv, struct command *cmd, struct pl
121135 if (argconfig_parse_seen (opts , "ps" ))
122136 err = power_mgmt_set (dev , fid , cfg .ps , cfg .wh , cfg .save );
123137 else
124- err = power_mgmt_get (dev , fid , cfg .sel );
138+ err = feat_get (dev , fid , 0 , cfg .sel , power_mgmt_feat );
125139
126140 return err ;
127141}
128142
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 )
143+ static int perfc_set (struct nvme_dev * dev , __u8 fid , __u32 cdw11 , struct perfc_config * cfg )
159144{
160145 __u32 result ;
161146 int err ;
@@ -169,9 +154,8 @@ static int perfc_set(struct nvme_dev *dev, struct perfc_config *cfg)
169154 struct nvme_set_features_args args = {
170155 .args_size = sizeof (args ),
171156 .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 ),
157+ .fid = fid ,
158+ .cdw11 = cdw11 ,
175159 .save = save ,
176160 .timeout = NVME_DEFAULT_IOCTL_TIMEOUT ,
177161 .result = & result ,
@@ -236,6 +220,8 @@ static int feat_perfc(int argc, char **argv, struct command *cmd, struct plugin
236220
237221 _cleanup_nvme_dev_ struct nvme_dev * dev = NULL ;
238222 int err ;
223+ __u8 fid = NVME_FEAT_FID_PERF_CHARACTERISTICS ;
224+ __u32 cdw11 ;
239225
240226 struct perfc_config cfg = { 0 };
241227
@@ -254,38 +240,13 @@ static int feat_perfc(int argc, char **argv, struct command *cmd, struct plugin
254240 if (err )
255241 return err ;
256242
243+ cdw11 = NVME_SET (cfg .attri , FEAT_PERFC_ATTRI ) | NVME_SET (cfg .rvspa , FEAT_PERFC_RVSPA );
244+
257245 if (argconfig_parse_seen (opts , "rvspa" ) || argconfig_parse_seen (opts , "r4karl" ) ||
258246 argconfig_parse_seen (opts , "paid" ))
259- err = perfc_set (dev , & cfg );
247+ err = perfc_set (dev , fid , cdw11 , & cfg );
260248 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- }
249+ err = feat_get (dev , fid , cdw11 , cfg .sel , perfc_feat );
289250
290251 return err ;
291252}
@@ -353,7 +314,7 @@ static int feat_hctm(int argc, char **argv, struct command *cmd, struct plugin *
353314 if (argconfig_parse_seen (opts , "tmt1" ) || argconfig_parse_seen (opts , "tmt2" ))
354315 err = hctm_set (dev , fid , cfg .tmt1 , cfg .tmt2 , cfg .save );
355316 else
356- err = hctm_get (dev , fid , cfg .sel );
317+ err = feat_get (dev , fid , 0 , cfg .sel , hctm_feat );
357318
358319 return err ;
359320}
0 commit comments