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"
@@ -28,6 +29,7 @@ static const char *sel = "[0-3]: current/default/saved/supported";
2829static const char * save = "Specifies that the controller shall save the attribute" ;
2930static const char * perfc_feat = "performance characteristics feature" ;
3031static const char * hctm_feat = "host controlled thermal management feature" ;
32+ static const char * timestamp_feat = "timestamp feature" ;
3133
3234static int feat_get (struct nvme_dev * dev , const __u8 fid , __u32 cdw11 , __u8 sel , const char * feat )
3335{
@@ -321,3 +323,74 @@ static int feat_hctm(int argc, char **argv, struct command *cmd, struct plugin *
321323
322324 return err ;
323325}
326+
327+ static int timestamp_set (struct nvme_dev * dev , const __u8 fid , __u64 tstmp , bool save )
328+ {
329+ __u32 result ;
330+ int err ;
331+ struct nvme_timestamp ts ;
332+ __le64 timestamp = cpu_to_le64 (tstmp );
333+
334+ struct nvme_set_features_args args = {
335+ .args_size = sizeof (args ),
336+ .fd = dev_fd (dev ),
337+ .fid = fid ,
338+ .save = save ,
339+ .timeout = NVME_DEFAULT_IOCTL_TIMEOUT ,
340+ .result = & result ,
341+ .data = & ts ,
342+ .data_len = sizeof (ts ),
343+ };
344+
345+ memcpy (ts .timestamp , & timestamp , sizeof (ts .timestamp ));
346+
347+ err = nvme_set_features (& args );
348+
349+ nvme_show_init ();
350+
351+ if (err > 0 ) {
352+ nvme_show_status (err );
353+ } else if (err < 0 ) {
354+ nvme_show_perror ("Set %s" , timestamp_feat );
355+ } else {
356+ nvme_show_result ("Set %s: (%s)" , timestamp_feat , save ? "Save" : "Not save" );
357+ nvme_feature_show_fields (fid , args .cdw11 , args .data );
358+ }
359+
360+ nvme_show_finish ();
361+
362+ return err ;
363+ }
364+
365+ static int feat_timestamp (int argc , char * * argv , struct command * cmd , struct plugin * plugin )
366+ {
367+ const __u8 fid = NVME_FEAT_FID_TIMESTAMP ;
368+ const char * tstmp = "timestamp" ;
369+
370+ _cleanup_nvme_dev_ struct nvme_dev * dev = NULL ;
371+ int err ;
372+
373+ struct config {
374+ __u64 tstmp ;
375+ bool save ;
376+ __u8 sel ;
377+ };
378+
379+ struct config cfg = { 0 };
380+
381+ NVME_ARGS (opts ,
382+ OPT_LONG ("tstmp" , 't' , & cfg .tstmp , tstmp ),
383+ OPT_FLAG ("save" , 's' , & cfg .save , save ),
384+ OPT_BYTE ("sel" , 'S' , & cfg .sel , sel ));
385+
386+ err = parse_and_open (& dev , argc , argv , TIMESTAMP_DESC , opts );
387+ if (err )
388+ return err ;
389+
390+ if (argconfig_parse_seen (opts , "tstmp" ))
391+ err = timestamp_set (dev , fid , cfg .tstmp , cfg .save );
392+ else
393+ err = feat_get (dev , fid , 0 , cfg .sel , timestamp_feat );
394+
395+ return err ;
396+ }
0 commit comments