@@ -715,28 +715,16 @@ static int get_ana_log(int argc, char **argv, struct command *cmd,
715715static int parse_telemetry_da (struct nvme_dev * dev ,
716716 enum nvme_telemetry_da da ,
717717 struct nvme_telemetry_log * telem ,
718- size_t * size )
718+ size_t * size ,
719+ bool da4_support )
719720
720721{
721- _cleanup_free_ struct nvme_id_ctrl * id_ctrl = NULL ;
722722 size_t dalb , da1lb = le16_to_cpu (telem -> dalb1 ), da2lb = le16_to_cpu (telem -> dalb2 ),
723723 da3lb = le16_to_cpu (telem -> dalb3 ), da4lb = le32_to_cpu (telem -> dalb4 );
724- bool data_area_4_support ;
725-
726- id_ctrl = nvme_alloc (sizeof (* id_ctrl ));
727- if (!id_ctrl )
728- return - ENOMEM ;
729-
730- if (nvme_cli_identify_ctrl (dev , id_ctrl )) {
731- perror ("identify-ctrl" );
732- return - errno ;
733- }
734-
735- data_area_4_support = id_ctrl -> lpa & 0x40 ;
736724
737725 switch (da ) {
738726 case NVME_TELEMETRY_DA_CTRL_DETERMINE :
739- if (data_area_4_support )
727+ if (da4_support )
740728 dalb = da4lb ;
741729 else
742730 dalb = da3lb ;
@@ -752,7 +740,7 @@ static int parse_telemetry_da(struct nvme_dev *dev,
752740 dalb = da3lb ;
753741 break ;
754742 case NVME_TELEMETRY_DA_4 :
755- if (data_area_4_support ) {
743+ if (da4_support ) {
756744 dalb = da4lb ;
757745 } else {
758746 nvme_show_error (
@@ -822,7 +810,8 @@ static int get_log_telemetry_host(struct nvme_dev *dev, size_t size,
822810static int __create_telemetry_log_host (struct nvme_dev * dev ,
823811 enum nvme_telemetry_da da ,
824812 size_t * size ,
825- struct nvme_telemetry_log * * buf )
813+ struct nvme_telemetry_log * * buf ,
814+ bool da4_support )
826815{
827816 _cleanup_free_ struct nvme_telemetry_log * log = NULL ;
828817 int err ;
@@ -839,7 +828,7 @@ static int __create_telemetry_log_host(struct nvme_dev *dev,
839828 return err ;
840829 }
841830
842- err = parse_telemetry_da (dev , da , log , size );
831+ err = parse_telemetry_da (dev , da , log , size , da4_support );
843832 if (err )
844833 return err ;
845834
@@ -850,7 +839,8 @@ static int __get_telemetry_log_ctrl(struct nvme_dev *dev,
850839 bool rae ,
851840 enum nvme_telemetry_da da ,
852841 size_t * size ,
853- struct nvme_telemetry_log * * buf )
842+ struct nvme_telemetry_log * * buf ,
843+ bool da4_support )
854844{
855845 struct nvme_telemetry_log * log ;
856846 int err ;
@@ -884,7 +874,7 @@ static int __get_telemetry_log_ctrl(struct nvme_dev *dev,
884874 return 0 ;
885875 }
886876
887- err = parse_telemetry_da (dev , da , log , size );
877+ err = parse_telemetry_da (dev , da , log , size , da4_support );
888878 if (err )
889879 goto free ;
890880
@@ -898,7 +888,8 @@ static int __get_telemetry_log_ctrl(struct nvme_dev *dev,
898888static int __get_telemetry_log_host (struct nvme_dev * dev ,
899889 enum nvme_telemetry_da da ,
900890 size_t * size ,
901- struct nvme_telemetry_log * * buf )
891+ struct nvme_telemetry_log * * buf ,
892+ bool da4_support )
902893{
903894 _cleanup_free_ struct nvme_telemetry_log * log = NULL ;
904895 int err ;
@@ -913,7 +904,7 @@ static int __get_telemetry_log_host(struct nvme_dev *dev,
913904 if (err )
914905 return err ;
915906
916- err = parse_telemetry_da (dev , da , log , size );
907+ err = parse_telemetry_da (dev , da , log , size , da4_support );
917908 if (err )
918909 return err ;
919910
@@ -932,13 +923,16 @@ static int get_telemetry_log(int argc, char **argv, struct command *cmd,
932923 "If given, This option will override dgen. 0 : controller determines data area" ;
933924
934925 _cleanup_free_ struct nvme_telemetry_log * log = NULL ;
926+ _cleanup_free_ struct nvme_id_ctrl * id_ctrl = NULL ;
935927 _cleanup_nvme_dev_ struct nvme_dev * dev = NULL ;
936928 _cleanup_fd_ int output = -1 ;
937929 int err = 0 ;
938- size_t total_size ;
930+ size_t total_size = 0 ;
939931 __u8 * data_ptr = NULL ;
940932 int data_written = 0 , data_remaining = 0 ;
941933 nvme_print_flags_t flags ;
934+ bool da4_support = false,
935+ host_behavior_changed = false;
942936
943937 struct config {
944938 char * file_name ;
@@ -990,6 +984,31 @@ static int get_telemetry_log(int argc, char **argv, struct command *cmd,
990984 cfg .data_area = cfg .mcda ;
991985 }
992986
987+ if (cfg .data_area == 4 ) {
988+ id_ctrl = nvme_alloc (sizeof (* id_ctrl ));
989+ if (!id_ctrl )
990+ return - ENOMEM ;
991+
992+ if (nvme_cli_identify_ctrl (dev , id_ctrl )) {
993+ perror ("identify-ctrl" );
994+ return - errno ;
995+ }
996+
997+ da4_support = id_ctrl -> lpa & 0x40 ;
998+
999+ if (!da4_support ) {
1000+ fprintf (stderr , "%s: Telemetry data area 4 not supported by device\n" ,
1001+ __func__ );
1002+ return - EINVAL ;
1003+ }
1004+
1005+ err = nvme_set_etdas (dev_fd (dev ), & host_behavior_changed );
1006+ if (err ) {
1007+ fprintf (stderr , "%s: Failed to set ETDAS bit\n" , __func__ );
1008+ return err ;
1009+ }
1010+ }
1011+
9931012 output = open (cfg .file_name , O_WRONLY | O_CREAT | O_TRUNC , 0666 );
9941013 if (output < 0 ) {
9951014 nvme_show_error ("Failed to open output file %s: %s!" ,
@@ -1003,13 +1022,13 @@ static int get_telemetry_log(int argc, char **argv, struct command *cmd,
10031022
10041023 if (cfg .ctrl_init )
10051024 err = __get_telemetry_log_ctrl (dev , cfg .rae , cfg .data_area ,
1006- & total_size , & log );
1025+ & total_size , & log , da4_support );
10071026 else if (cfg .host_gen )
10081027 err = __create_telemetry_log_host (dev , cfg .data_area ,
1009- & total_size , & log );
1028+ & total_size , & log , da4_support );
10101029 else
10111030 err = __get_telemetry_log_host (dev , cfg .data_area ,
1012- & total_size , & log );
1031+ & total_size , & log , da4_support );
10131032
10141033 if (err < 0 ) {
10151034 nvme_show_error ("get-telemetry-log: %s" , nvme_strerror (errno ));
@@ -1048,6 +1067,15 @@ static int get_telemetry_log(int argc, char **argv, struct command *cmd,
10481067 return -1 ;
10491068 }
10501069
1070+ if (host_behavior_changed ) {
1071+ host_behavior_changed = false;
1072+ err = nvme_clear_etdas (dev_fd (dev ), & host_behavior_changed );
1073+ if (err ) {
1074+ fprintf (stderr , "%s: Failed to clear ETDAS bit\n" , __func__ );
1075+ return err ;
1076+ }
1077+ }
1078+
10511079 return err ;
10521080}
10531081
0 commit comments