@@ -50,6 +50,7 @@ static const char *arbitration_feat = "arbitration feature";
5050static const char * volatile_wc_feat = "volatile write cache feature" ;
5151static const char * power_limit_feat = "power limit feature" ;
5252static const char * power_thresh_feat = "power threshold feature" ;
53+ static const char * power_meas_feat = "power measurement feature" ;
5354
5455static int feat_get (struct nvme_transport_handle * hdl , const __u8 fid ,
5556 __u32 cdw11 , __u8 sel , __u8 uidx , const char * feat )
@@ -753,3 +754,78 @@ static int feat_power_thresh(int argc, char **argv, struct command *acmd,
753754
754755 return err ;
755756}
757+
758+ static int power_meas_set (struct nvme_transport_handle * hdl , const __u8 fid ,
759+ __u8 action , __u8 pmts , __u16 smt , __u8 uidx , bool sv )
760+ {
761+ __u32 cdw11 = NVME_SET (action , FEAT_POWER_MEAS_ACT ) |
762+ NVME_SET (pmts , FEAT_POWER_MEAS_PMTS ) |
763+ NVME_SET (smt , FEAT_POWER_MEAS_SMT );
764+ __u64 result ;
765+ int err ;
766+
767+ err = nvme_set_features (hdl , 0 , fid , sv , cdw11 , 0 , 0 , uidx , 0 , NULL , 0 ,
768+ & result );
769+
770+ nvme_show_init ();
771+
772+ if (err > 0 ) {
773+ nvme_show_status (err );
774+ } else if (err < 0 ) {
775+ nvme_show_perror ("Set %s" , power_meas_feat );
776+ } else {
777+ nvme_show_result ("Set %s: 0x%04x (%s)" , power_meas_feat , cdw11 ,
778+ sv ? "Save" : "Not save" );
779+ nvme_feature_show_fields (fid , cdw11 , NULL );
780+ }
781+
782+ nvme_show_finish ();
783+
784+ return err ;
785+ }
786+
787+ static int feat_power_meas (int argc , char * * argv , struct command * cmd ,
788+ struct plugin * plugin )
789+ {
790+ const char * action = "action [0-1]: stop|start" ;
791+ const char * pmts = "power measurement type select" ;
792+ const char * smt = "stop measurement time" ;
793+ const __u8 fid = NVME_FEAT_FID_POWER_MEASUREMENT ;
794+
795+ _cleanup_nvme_global_ctx_ struct nvme_global_ctx * ctx = NULL ;
796+
797+ _cleanup_nvme_transport_handle_ struct nvme_transport_handle * hdl =
798+ NULL ;
799+ int err ;
800+
801+ struct config {
802+ __u8 act ;
803+ __u8 pmts ;
804+ __u16 smt ;
805+ __u8 uidx ;
806+ __u8 sel ;
807+ };
808+
809+ struct config cfg = { 0 };
810+
811+ FEAT_ARGS (opts ,
812+ OPT_BYTE ("act" , 0 , & cfg .act , action ),
813+ OPT_BYTE ("pmts" , 0 , & cfg .pmts , pmts ),
814+ OPT_SHRT ("smt" , 0 , & cfg .smt , smt ),
815+ OPT_BYTE ("uuid-index" , 'u' , & cfg .uidx , uuid_index ));
816+
817+ err = parse_and_open (& ctx , & hdl , argc , argv , POWER_MEAS_DESC , opts );
818+ if (err )
819+ return err ;
820+
821+ if (argconfig_parse_seen (opts , "act" ) ||
822+ argconfig_parse_seen (opts , "pmts" ) ||
823+ argconfig_parse_seen (opts , "smt" ))
824+ err = power_meas_set (hdl , fid , cfg .act , cfg .pmts , cfg .smt ,
825+ cfg .uidx ,
826+ argconfig_parse_seen (opts , "save" ));
827+ else
828+ err = feat_get (hdl , fid , 0 , cfg .sel , 0 , power_meas_feat );
829+
830+ return err ;
831+ }
0 commit comments