44#include "nvme.h"
55#include "plugin.h"
66#include "nvme-print.h"
7+ #include "common.h"
78
89#define CREATE_CMD
910#include "feat-nvme.h"
@@ -27,6 +28,7 @@ static const char *sel = "[0-3]: current/default/saved/supported";
2728static const char * save = "Specifies that the controller shall save the attribute" ;
2829static const char * perfc_feat = "performance characteristics feature" ;
2930static const char * hctm_feat = "host controlled thermal management feature" ;
31+ static const char * timestamp_feat = "timestamp feature" ;
3032
3133static int feat_get (struct nvme_dev * dev , const __u8 fid , __u32 cdw11 , __u8 sel , const char * feat )
3234{
@@ -312,3 +314,70 @@ static int feat_hctm(int argc, char **argv, struct command *cmd, struct plugin *
312314
313315 return err ;
314316}
317+
318+ static int timestamp_set (struct nvme_dev * dev , const __u8 fid , __u64 tstmp , bool save )
319+ {
320+ __u32 result ;
321+ int err ;
322+ struct nvme_timestamp ts ;
323+ __le64 timestamp = cpu_to_le64 (tstmp );
324+
325+ struct nvme_set_features_args args = {
326+ .args_size = sizeof (args ),
327+ .fd = dev_fd (dev ),
328+ .fid = fid ,
329+ .save = save ,
330+ .timeout = NVME_DEFAULT_IOCTL_TIMEOUT ,
331+ .result = & result ,
332+ .data = & ts ,
333+ .data_len = sizeof (ts ),
334+ };
335+
336+ memcpy (ts .timestamp , & timestamp , sizeof (ts .timestamp ));
337+
338+ err = nvme_set_features (& args );
339+
340+ nvme_show_init ();
341+
342+ if (err > 0 ) {
343+ nvme_show_status (err );
344+ } else if (err < 0 ) {
345+ nvme_show_perror ("Set %s" , timestamp_feat );
346+ } else {
347+ nvme_show_result ("Set %s: (%s)" , timestamp_feat , save ? "Save" : "Not save" );
348+ nvme_feature_show_fields (fid , args .cdw11 , args .data );
349+ }
350+
351+ nvme_show_finish ();
352+
353+ return err ;
354+ }
355+
356+ static int feat_timestamp (int argc , char * * argv , struct command * cmd , struct plugin * plugin )
357+ {
358+ const __u8 fid = NVME_FEAT_FID_TIMESTAMP ;
359+ const char * tstmp = "timestamp" ;
360+
361+ _cleanup_nvme_dev_ struct nvme_dev * dev = NULL ;
362+ int err ;
363+
364+ struct config {
365+ __u64 tstmp ;
366+ __u8 sel ;
367+ };
368+
369+ struct config cfg = { 0 };
370+
371+ FEAT_ARGS (opts , OPT_LONG ("tstmp" , 't' , & cfg .tstmp , tstmp ));
372+
373+ err = parse_and_open (& dev , argc , argv , TIMESTAMP_DESC , opts );
374+ if (err )
375+ return err ;
376+
377+ if (argconfig_parse_seen (opts , "tstmp" ))
378+ err = timestamp_set (dev , fid , cfg .tstmp , argconfig_parse_seen (opts , "save" ));
379+ else
380+ err = feat_get (dev , fid , 0 , cfg .sel , timestamp_feat );
381+
382+ return err ;
383+ }
0 commit comments