@@ -24,6 +24,14 @@ 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+ __u8 sel ;
33+ };
34+
2735static const char * power_mgmt_feat = "power management feature" ;
2836static const char * sel = "[0-3]: current/default/saved/supported" ;
2937static const char * save = "Specifies that the controller shall save the attribute" ;
@@ -394,3 +402,83 @@ static int feat_timestamp(int argc, char **argv, struct command *cmd, struct plu
394402
395403 return err ;
396404}
405+
406+ static int temp_thresh_set (int fd , const __u8 fid , struct argconfig_commandline_options * opts ,
407+ struct temp_thresh_config * cfg )
408+ {
409+ __u32 result ;
410+ int err ;
411+ enum nvme_get_features_sel sel = NVME_GET_FEATURES_SEL_CURRENT ;
412+ __u16 tmpth ;
413+ __u8 tmpsel ;
414+ __u8 thsel ;
415+ __u8 tmpthh ;
416+ bool save = argconfig_parse_seen (opts , "save" );
417+
418+ if (save )
419+ sel = NVME_GET_FEATURES_SEL_SAVED ;
420+
421+ err = nvme_get_features_temp_thresh (fd , sel , cfg -> tmpsel , cfg -> thsel , & result );
422+ if (!err ) {
423+ nvme_feature_decode_temp_threshold (result , & tmpth , & tmpsel , & thsel , & tmpthh );
424+ if (!argconfig_parse_seen (opts , "tmpth" ))
425+ cfg -> tmpth = tmpth ;
426+ if (!argconfig_parse_seen (opts , "tmpthh" ))
427+ cfg -> tmpthh = tmpthh ;
428+ }
429+
430+ err = nvme_set_features_temp_thresh (fd , cfg -> tmpth , cfg -> tmpsel , cfg -> thsel , cfg -> tmpthh ,
431+ save , & result );
432+
433+ nvme_show_init ();
434+
435+ if (err > 0 ) {
436+ nvme_show_status (err );
437+ } else if (err < 0 ) {
438+ nvme_show_perror ("Set %s" , timestamp_feat );
439+ } else {
440+ nvme_show_result ("Set %s: (%s)" , timestamp_feat , save ? "Save" : "Not save" );
441+ nvme_feature_show_fields (fid , NVME_SET (cfg -> tmpth , FEAT_TT_TMPTH ) |
442+ NVME_SET (cfg -> tmpsel , FEAT_TT_TMPSEL ) |
443+ NVME_SET (cfg -> thsel , FEAT_TT_THSEL ) |
444+ NVME_SET (cfg -> tmpthh , FEAT_TT_TMPTHH ), NULL );
445+ }
446+
447+ nvme_show_finish ();
448+
449+ return err ;
450+ }
451+
452+ static int feat_temp_thresh (int argc , char * * argv , struct command * cmd , struct plugin * plugin )
453+ {
454+ const __u8 fid = NVME_FEAT_FID_TEMP_THRESH ;
455+ const char * tmpth = "temperature threshold" ;
456+ const char * tmpsel = "threshold temperature select" ;
457+ const char * thsel = "threshold type select" ;
458+ const char * tmpthh = "temperature threshold hysteresis" ;
459+
460+ _cleanup_nvme_dev_ struct nvme_dev * dev = NULL ;
461+ int err ;
462+
463+ struct temp_thresh_config cfg = { 0 };
464+
465+ NVME_ARGS (opts ,
466+ OPT_SHRT ("tmpth" , 'T' , & cfg .tmpth , tmpth ),
467+ OPT_BYTE ("tmpsel" , 'm' , & cfg .tmpsel , tmpsel ),
468+ OPT_BYTE ("thsel" , 'H' , & cfg .thsel , thsel ),
469+ OPT_BYTE ("tmpthh" , 'M' , & cfg .tmpthh , tmpthh ),
470+ OPT_FLAG ("save" , 's' , NULL , save ),
471+ OPT_BYTE ("sel" , 'S' , & cfg .sel , sel ));
472+
473+ err = parse_and_open (& dev , argc , argv , TEMP_THRESH_DESC , opts );
474+ if (err )
475+ return err ;
476+
477+ if (argconfig_parse_seen (opts , "tmpth" ) || argconfig_parse_seen (opts , "tmpthh" ))
478+ err = temp_thresh_set (dev_fd (dev ), fid , opts , & cfg );
479+ else
480+ err = feat_get (dev , fid , NVME_SET (cfg .tmpsel , FEAT_TT_TMPSEL ) |
481+ NVME_SET (cfg .thsel , FEAT_TT_THSEL ), cfg .sel , timestamp_feat );
482+
483+ return err ;
484+ }
0 commit comments