@@ -47,6 +47,15 @@ struct err_recovery_config {
4747 __u8 sel ;
4848};
4949
50+ struct host_behavior_config {
51+ __u8 acre ;
52+ __u8 etdas ;
53+ __u8 lbafee ;
54+ __u8 hdisns ;
55+ __u16 cdfe ;
56+ __u8 sel ;
57+ };
58+
5059static const char * power_mgmt_feat = "power management feature" ;
5160static const char * sel = "[0-3]: current/default/saved/supported" ;
5261static const char * save = "Specifies that the controller shall save the attribute" ;
@@ -61,6 +70,7 @@ static const char *power_thresh_feat = "power threshold feature";
6170static const char * power_meas_feat = "power measurement feature" ;
6271static const char * err_recovery_feat = "error recovery feature" ;
6372static const char * num_queues_feat = "number of queues feature" ;
73+ static const char * host_behavior_feat = "host behavior support feature" ;
6474
6575static int feat_get_nsid (struct libnvme_transport_handle * hdl , __u32 nsid ,
6676 const __u8 fid , __u32 cdw11 , __u8 sel , __u8 uidx ,
@@ -975,3 +985,91 @@ static int feat_num_queues(int argc, char **argv, struct command *acmd,
975985
976986 return err ;
977987}
988+
989+ static int host_behavior_set (struct libnvme_transport_handle * hdl , __u8 fid ,
990+ struct argconfig_commandline_options * opts ,
991+ struct host_behavior_config * cfg , bool sv )
992+ {
993+ enum nvme_get_features_sel gsel = NVME_GET_FEATURES_SEL_CURRENT ;
994+ struct libnvme_passthru_cmd cmd ;
995+ struct nvme_feat_host_behavior data = { 0 };
996+ int err ;
997+
998+ if (sv )
999+ gsel = NVME_GET_FEATURES_SEL_SAVED ;
1000+
1001+ nvme_init_get_features_host_behavior (& cmd , gsel , & data );
1002+ err = libnvme_submit_admin_passthru (hdl , & cmd );
1003+ if (err ) {
1004+ nvme_show_err (err , "Get %s" , host_behavior_feat );
1005+ return err ;
1006+ }
1007+
1008+ if (argconfig_parse_seen (opts , "acre" ))
1009+ data .acre = cfg -> acre ;
1010+ if (argconfig_parse_seen (opts , "etdas" ))
1011+ data .etdas = cfg -> etdas ;
1012+ if (argconfig_parse_seen (opts , "lbafee" ))
1013+ data .lbafee = cfg -> lbafee ;
1014+ if (argconfig_parse_seen (opts , "hdisns" ))
1015+ data .hdisns = cfg -> hdisns ;
1016+ if (argconfig_parse_seen (opts , "cdfe" ))
1017+ data .cdfe = cpu_to_le16 (cfg -> cdfe );
1018+
1019+ nvme_init_set_features_host_behavior (& cmd , sv , & data );
1020+ err = libnvme_submit_admin_passthru (hdl , & cmd );
1021+ if (err ) {
1022+ nvme_show_err (err , "Set %s" , host_behavior_feat );
1023+ return err ;
1024+ }
1025+
1026+ nvme_show_init ();
1027+
1028+ nvme_show_result ("Set %s: (%s)" , host_behavior_feat ,
1029+ sv ? "Save" : "Not save" );
1030+ nvme_feature_show_fields (fid , 0 , (unsigned char * )& data );
1031+
1032+ nvme_show_finish ();
1033+
1034+ return err ;
1035+ }
1036+
1037+ static int feat_host_behavior_support (int argc , char * * argv , struct command * acmd ,
1038+ struct plugin * plugin )
1039+ {
1040+ const char * acre_desc = "Advanced Command Retry Enable (0 or 1)" ;
1041+ const char * etdas_desc = "Extended Telemetry Data Area 4 Supported (0 or 1)" ;
1042+ const char * lbafee_desc = "LBA Format Extension Enable (0 or 1)" ;
1043+ const char * hdisns_desc = "Host Dispersed Namespace Support (0 or 1)" ;
1044+ const char * cdfe_desc = "Copy Descriptor Formats Enable bitmask" ;
1045+ const __u8 fid = NVME_FEAT_FID_HOST_BEHAVIOR ;
1046+
1047+ __cleanup_nvme_global_ctx struct libnvme_global_ctx * ctx = NULL ;
1048+ __cleanup_nvme_transport_handle struct libnvme_transport_handle * hdl = NULL ;
1049+ int err ;
1050+
1051+ struct host_behavior_config cfg = { 0 };
1052+
1053+ FEAT_ARGS (opts ,
1054+ OPT_BYTE ("acre" , 'a' , & cfg .acre , acre_desc ),
1055+ OPT_BYTE ("etdas" , 'e' , & cfg .etdas , etdas_desc ),
1056+ OPT_BYTE ("lbafee" , 'l' , & cfg .lbafee , lbafee_desc ),
1057+ OPT_BYTE ("hdisns" , 'H' , & cfg .hdisns , hdisns_desc ),
1058+ OPT_SHRT ("cdfe" , 'c' , & cfg .cdfe , cdfe_desc ));
1059+
1060+ err = parse_and_open (& ctx , & hdl , argc , argv , HOST_BEHAVIOR_DESC , opts );
1061+ if (err )
1062+ return err ;
1063+
1064+ if (argconfig_parse_seen (opts , "acre" ) ||
1065+ argconfig_parse_seen (opts , "etdas" ) ||
1066+ argconfig_parse_seen (opts , "lbafee" ) ||
1067+ argconfig_parse_seen (opts , "hdisns" ) ||
1068+ argconfig_parse_seen (opts , "cdfe" ))
1069+ err = host_behavior_set (hdl , fid , opts , & cfg ,
1070+ argconfig_parse_seen (opts , "save" ));
1071+ else
1072+ err = feat_get (hdl , fid , 0 , cfg .sel , 0 , host_behavior_feat );
1073+
1074+ return err ;
1075+ }
0 commit comments