6161#define CREATE_CMD
6262#include "nvme-builtin.h"
6363
64+ struct feat_cfg {
65+ enum nvme_features_id feature_id ;
66+ __u32 namespace_id ;
67+ enum nvme_get_features_sel sel ;
68+ __u32 cdw11 ;
69+ __u8 uuid_index ;
70+ __u32 data_len ;
71+ int raw_binary ;
72+ int human_readable ;
73+ };
74+
6475static struct stat nvme_stat ;
6576const char * devicename ;
6677
@@ -2703,6 +2714,60 @@ static int self_test_log(int argc, char **argv, struct command *cmd, struct plug
27032714 return nvme_status_to_errno (err , false);
27042715}
27052716
2717+ static int get_feature_id (int fd , struct feat_cfg cfg )
2718+ {
2719+ int err ;
2720+ __u32 result ;
2721+ void * buf = NULL ;
2722+
2723+ nvme_get_feature_length (cfg .feature_id , cfg .cdw11 , & cfg .data_len );
2724+
2725+ /* check for Extended Host Identifier */
2726+ if (cfg .feature_id == NVME_FEAT_FID_HOST_ID && (cfg .cdw11 & 0x1 ))
2727+ cfg .data_len = 16 ;
2728+
2729+ if (cfg .sel == 3 )
2730+ cfg .data_len = 0 ;
2731+
2732+ if (cfg .data_len ) {
2733+ if (posix_memalign (& buf , getpagesize (), cfg .data_len )) {
2734+ fprintf (stderr , "can not allocate feature payload\n" );
2735+ errno = ENOMEM ;
2736+ return -1 ;
2737+ }
2738+ memset (buf , 0 , cfg .data_len );
2739+ }
2740+
2741+ err = nvme_get_features (fd , cfg .feature_id , cfg .namespace_id , cfg .sel ,
2742+ cfg .cdw11 , cfg .uuid_index , cfg .data_len , buf ,
2743+ & result );
2744+ if (!err ) {
2745+ if (!cfg .raw_binary || !buf ) {
2746+ printf ("get-feature:%#0*x (%s), %s value:%#0*x\n" ,
2747+ cfg .feature_id ? 4 : 2 , cfg .feature_id ,
2748+ nvme_feature_to_string (cfg .feature_id ),
2749+ nvme_select_to_string (cfg .sel ), result ? 10 : 8 ,
2750+ result );
2751+ if (cfg .sel == 3 )
2752+ nvme_show_select_result (result );
2753+ else if (cfg .human_readable )
2754+ nvme_feature_show_fields (cfg .feature_id , result ,
2755+ buf );
2756+ else if (buf )
2757+ d (buf , cfg .data_len , 16 , 1 );
2758+ } else if (buf )
2759+ d_raw (buf , cfg .data_len );
2760+ } else if (err > 0 ) {
2761+ nvme_show_status (err );
2762+ } else {
2763+ perror ("get-feature" );
2764+ }
2765+
2766+ free (buf );
2767+
2768+ return err ;
2769+ }
2770+
27062771static int get_feature (int argc , char * * argv , struct command * cmd , struct plugin * plugin )
27072772{
27082773 const char * desc = "Read operating parameters of the " \
@@ -2715,40 +2780,28 @@ static int get_feature(int argc, char **argv, struct command *cmd, struct plugin
27152780 "are vendor-specific and not changeable. Use set-feature to " \
27162781 "change saveable Features." ;
27172782 const char * raw = "show feature in binary format" ;
2718- const char * namespace_id = "identifier of desired namespace" ;
27192783 const char * feature_id = "feature identifier" ;
2784+ const char * namespace_id = "identifier of desired namespace" ;
27202785 const char * sel = "[0-3]: current/default/saved/supported" ;
27212786 const char * data_len = "buffer len if data is returned through host memory buffer" ;
27222787 const char * cdw11 = "dword 11 for interrupt vector config" ;
27232788 const char * human_readable = "show feature in readable format" ;
27242789 const char * uuid_index = "specify uuid index" ;
2725- int err , fd ;
2726- __u32 result ;
2727- void * buf = NULL ;
2728-
2729- struct config {
2730- __u32 namespace_id ;
2731- __u8 feature_id ;
2732- __u8 sel ;
2733- __u32 cdw11 ;
2734- __u8 uuid_index ;
2735- __u32 data_len ;
2736- int raw_binary ;
2737- int human_readable ;
2738- };
2790+ int err ;
2791+ int fd ;
27392792
2740- struct config cfg = {
2741- .namespace_id = 0 ,
2793+ struct feat_cfg cfg = {
27422794 .feature_id = 0 ,
2795+ .namespace_id = 0 ,
27432796 .sel = 0 ,
27442797 .cdw11 = 0 ,
27452798 .uuid_index = 0 ,
27462799 .data_len = 0 ,
27472800 };
27482801
27492802 OPT_ARGS (opts ) = {
2750- OPT_UINT ("namespace-id" , 'n' , & cfg .namespace_id , namespace_id ),
27512803 OPT_BYTE ("feature-id" , 'f' , & cfg .feature_id , feature_id ),
2804+ OPT_UINT ("namespace-id" , 'n' , & cfg .namespace_id , namespace_id ),
27522805 OPT_BYTE ("sel" , 's' , & cfg .sel , sel ),
27532806 OPT_UINT ("data-len" , 'l' , & cfg .data_len , data_len ),
27542807 OPT_FLAG ("raw-binary" , 'b' , & cfg .raw_binary , raw ),
@@ -2779,6 +2832,7 @@ static int get_feature(int argc, char **argv, struct command *cmd, struct plugin
27792832 err = - EINVAL ;
27802833 goto close_fd ;
27812834 }
2835+
27822836 if (!cfg .feature_id ) {
27832837 fprintf (stderr , "feature-id required param\n" );
27842838 err = - EINVAL ;
@@ -2792,44 +2846,7 @@ static int get_feature(int argc, char **argv, struct command *cmd, struct plugin
27922846 goto close_fd ;
27932847 }
27942848
2795- nvme_get_feature_length (cfg .feature_id , cfg .cdw11 , & cfg .data_len );
2796-
2797- if (cfg .sel == 3 )
2798- cfg .data_len = 0 ;
2799-
2800- if (cfg .data_len ) {
2801- if (posix_memalign (& buf , getpagesize (), cfg .data_len )) {
2802- fprintf (stderr , "can not allocate feature payload\n" );
2803- err = - ENOMEM ;
2804- goto close_fd ;
2805- }
2806- memset (buf , 0 , cfg .data_len );
2807- }
2808-
2809- err = nvme_get_features (fd , cfg .feature_id , cfg .namespace_id , cfg .sel ,
2810- cfg .cdw11 , cfg .uuid_index , cfg .data_len ,
2811- buf , & result );
2812- if (!err ) {
2813- if (!cfg .raw_binary || !buf ) {
2814- printf ("get-feature:%#0*x (%s), %s value:%#0*x\n" ,
2815- cfg .feature_id ? 4 : 2 , cfg .feature_id ,
2816- nvme_feature_to_string (cfg .feature_id ),
2817- nvme_select_to_string (cfg .sel ), result ? 10 : 8 ,
2818- result );
2819- if (cfg .sel == 3 )
2820- nvme_show_select_result (result );
2821- else if (cfg .human_readable )
2822- nvme_feature_show_fields (cfg .feature_id , result , buf );
2823- else if (buf )
2824- d (buf , cfg .data_len , 16 , 1 );
2825- } else if (buf )
2826- d_raw (buf , cfg .data_len );
2827- } else if (err > 0 ) {
2828- nvme_show_status (err );
2829- } else
2830- perror ("get-feature" );
2831-
2832- free (buf );
2849+ err = get_feature_id (fd , cfg );
28332850
28342851close_fd :
28352852 close (fd );
0 commit comments