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