@@ -108,7 +108,7 @@ static int open_dev(char *dev)
108108 return - ENODEV ;
109109 }
110110 return fd ;
111- perror :
111+ perror :
112112 perror (dev );
113113 return err ;
114114}
@@ -4656,6 +4656,95 @@ static int write_cmd(int argc, char **argv, struct command *cmd, struct plugin *
46564656 return submit_io (nvme_cmd_write , "write" , desc , argc , argv );
46574657}
46584658
4659+ static int verify_cmd (int argc , char * * argv , struct command * cmd , struct plugin * plugin )
4660+ {
4661+ int err , fd ;
4662+ __u16 control = 0 ;
4663+ const char * desc = "Verify specified logical blocks on the given device." ;
4664+ const char * namespace_id = "desired namespace" ;
4665+ const char * start_block = "64-bit LBA of first block to access" ;
4666+ const char * block_count = "number of blocks (zeroes based) on device to access" ;
4667+ const char * limited_retry = "limit media access attempts" ;
4668+ const char * force = "force device to commit cached data before performing the verify operation" ;
4669+ const char * prinfo = "PI and check field" ;
4670+ const char * ref_tag = "reference tag (for end to end PI)" ;
4671+ const char * app_tag_mask = "app tag mask (for end to end PI)" ;
4672+ const char * app_tag = "app tag (for end to end PI)" ;
4673+
4674+ struct config {
4675+ __u64 start_block ;
4676+ __u32 namespace_id ;
4677+ __u32 ref_tag ;
4678+ __u16 app_tag ;
4679+ __u16 app_tag_mask ;
4680+ __u16 block_count ;
4681+ __u8 prinfo ;
4682+ int limited_retry ;
4683+ int force_unit_access ;
4684+ };
4685+
4686+ struct config cfg = {
4687+ .namespace_id = 0 ,
4688+ .start_block = 0 ,
4689+ .block_count = 0 ,
4690+ .prinfo = 0 ,
4691+ .ref_tag = 0 ,
4692+ .app_tag = 0 ,
4693+ .app_tag_mask = 0 ,
4694+ .limited_retry = 0 ,
4695+ .force_unit_access = 0 ,
4696+ };
4697+
4698+ const struct argconfig_commandline_options command_line_options [] = {
4699+ {"namespace-id" , 'n' , "NUM" , CFG_POSITIVE , & cfg .namespace_id , required_argument , namespace_id },
4700+ {"start-block" , 's' , "NUM" , CFG_LONG_SUFFIX , & cfg .start_block , required_argument , start_block },
4701+ {"block-count" , 'c' , "NUM" , CFG_SHORT , & cfg .block_count , required_argument , block_count },
4702+ {"limited-retry" , 'l' , "" , CFG_NONE , & cfg .limited_retry , no_argument , limited_retry },
4703+ {"force-unit-access" , 'f' , "" , CFG_NONE , & cfg .force_unit_access , no_argument , force },
4704+ {"prinfo" , 'p' , "NUM" , CFG_BYTE , & cfg .prinfo , required_argument , prinfo },
4705+ {"ref-tag" , 'r' , "NUM" , CFG_POSITIVE , & cfg .ref_tag , required_argument , ref_tag },
4706+ {"app-tag" , 'a' , "NUM" , CFG_SHORT , & cfg .app_tag , required_argument , app_tag },
4707+ {"app-tag-mask" , 'm' , "NUM" , CFG_SHORT , & cfg .app_tag_mask , required_argument , app_tag_mask },
4708+ {NULL }
4709+ };
4710+
4711+ fd = parse_and_open (argc , argv , desc , command_line_options , & cfg , sizeof (cfg ));
4712+ if (fd < 0 )
4713+ return fd ;
4714+
4715+ if (cfg .prinfo > 0xf ) {
4716+ err = EINVAL ;
4717+ goto close_fd ;
4718+ }
4719+
4720+ control |= (cfg .prinfo << 10 );
4721+ if (cfg .limited_retry )
4722+ control |= NVME_RW_LR ;
4723+ if (cfg .force_unit_access )
4724+ control |= NVME_RW_FUA ;
4725+
4726+ if (!cfg .namespace_id ) {
4727+ cfg .namespace_id = get_nsid (fd );
4728+ if (cfg .namespace_id == 0 ) {
4729+ err = EINVAL ;
4730+ goto close_fd ;
4731+ }
4732+ }
4733+
4734+ err = nvme_verify (fd , cfg .namespace_id , cfg .start_block , cfg .block_count ,
4735+ control , cfg .ref_tag , cfg .app_tag , cfg .app_tag_mask );
4736+ if (err < 0 )
4737+ perror ("verify" );
4738+ else if (err != 0 )
4739+ show_nvme_status (err );
4740+ else
4741+ printf ("NVME Verify Success\n" );
4742+
4743+ close_fd :
4744+ close (fd );
4745+ return err ;
4746+ }
4747+
46594748static int sec_recv (int argc , char * * argv , struct command * cmd , struct plugin * plugin )
46604749{
46614750 const char * desc = "Obtain results of one or more " \
0 commit comments