@@ -24,6 +24,15 @@ struct perfc_config {
2424 __u8 sel ;
2525};
2626
27+ struct temp_thresh_config {
28+ __u16 tmpth ;
29+ __u8 tmpsel ;
30+ __u8 thsel ;
31+ __u8 tmpthh ;
32+ bool save ;
33+ __u8 sel ;
34+ };
35+
2736static const char * power_mgmt_feat = "power management feature" ;
2837static const char * sel = "[0-3]: current/default/saved/supported" ;
2938static const char * save = "Specifies that the controller shall save the attribute" ;
@@ -385,3 +394,81 @@ static int feat_timestamp(int argc, char **argv, struct command *cmd, struct plu
385394
386395 return err ;
387396}
397+
398+ static int temp_thresh_set (int fd , const __u8 fid , struct argconfig_commandline_options * opts ,
399+ struct temp_thresh_config * cfg )
400+ {
401+ __u32 result ;
402+ int err ;
403+ enum nvme_get_features_sel sel = NVME_GET_FEATURES_SEL_CURRENT ;
404+ __u16 tmpth ;
405+ __u8 tmpsel ;
406+ __u8 thsel ;
407+ __u8 tmpthh ;
408+ bool save = argconfig_parse_seen (opts , "save" );
409+
410+ if (save )
411+ sel = NVME_GET_FEATURES_SEL_SAVED ;
412+
413+ err = nvme_get_features_temp_thresh (fd , sel , cfg -> tmpsel , cfg -> thsel , & result );
414+ if (!err ) {
415+ nvme_feature_decode_temp_threshold (result , & tmpth , & tmpsel , & thsel , & tmpthh );
416+ if (!argconfig_parse_seen (opts , "tmpth" ))
417+ cfg -> tmpth = tmpth ;
418+ if (!argconfig_parse_seen (opts , "tmpthh" ))
419+ cfg -> tmpthh = tmpthh ;
420+ }
421+
422+ err = nvme_set_features_temp_thresh (fd , cfg -> tmpth , cfg -> tmpsel , cfg -> thsel , cfg -> tmpthh ,
423+ save , & result );
424+
425+ nvme_show_init ();
426+
427+ if (err > 0 ) {
428+ nvme_show_status (err );
429+ } else if (err < 0 ) {
430+ nvme_show_perror ("Set %s" , timestamp_feat );
431+ } else {
432+ nvme_show_result ("Set %s: (%s)" , timestamp_feat , save ? "Save" : "Not save" );
433+ nvme_feature_show_fields (fid , NVME_SET (cfg -> tmpth , FEAT_TT_TMPTH ) |
434+ NVME_SET (cfg -> tmpsel , FEAT_TT_TMPSEL ) |
435+ NVME_SET (cfg -> thsel , FEAT_TT_THSEL ) |
436+ NVME_SET (cfg -> tmpthh , FEAT_TT_TMPTHH ), NULL );
437+ }
438+
439+ nvme_show_finish ();
440+
441+ return err ;
442+ }
443+
444+ static int feat_temp_thresh (int argc , char * * argv , struct command * cmd , struct plugin * plugin )
445+ {
446+ const __u8 fid = NVME_FEAT_FID_TEMP_THRESH ;
447+ const char * tmpth = "temperature threshold" ;
448+ const char * tmpsel = "threshold temperature select" ;
449+ const char * thsel = "threshold type select" ;
450+ const char * tmpthh = "temperature threshold hysteresis" ;
451+
452+ _cleanup_nvme_dev_ struct nvme_dev * dev = NULL ;
453+ int err ;
454+
455+ struct temp_thresh_config cfg = { 0 };
456+
457+ FEAT_ARGS (opts ,
458+ OPT_SHRT ("tmpth" , 'T' , & cfg .tmpth , tmpth ),
459+ OPT_BYTE ("tmpsel" , 'm' , & cfg .tmpsel , tmpsel ),
460+ OPT_BYTE ("thsel" , 'H' , & cfg .thsel , thsel ),
461+ OPT_BYTE ("tmpthh" , 'M' , & cfg .tmpthh , tmpthh ));
462+
463+ err = parse_and_open (& dev , argc , argv , TEMP_THRESH_DESC , opts );
464+ if (err )
465+ return err ;
466+
467+ if (argconfig_parse_seen (opts , "tmpth" ) || argconfig_parse_seen (opts , "tmpthh" ))
468+ err = temp_thresh_set (dev_fd (dev ), fid , opts , & cfg );
469+ else
470+ err = feat_get (dev , fid , NVME_SET (cfg .tmpsel , FEAT_TT_TMPSEL ) |
471+ NVME_SET (cfg .thsel , FEAT_TT_THSEL ), cfg .sel , timestamp_feat );
472+
473+ return err ;
474+ }
0 commit comments