@@ -655,31 +655,41 @@ static int parse_telemetry_da(struct nvme_dev *dev,
655655
656656{
657657 _cleanup_free_ struct nvme_id_ctrl * id_ctrl = NULL ;
658- size_t dalb = 0 ;
658+ size_t dalb , da1lb = le16_to_cpu (telem -> dalb1 ), da2lb = le16_to_cpu (telem -> dalb2 ),
659+ da3lb = le16_to_cpu (telem -> dalb3 ), da4lb = le32_to_cpu (telem -> dalb4 );
660+ bool data_area_4_support ;
659661
660662 id_ctrl = nvme_alloc (sizeof (* id_ctrl ));
661663 if (!id_ctrl )
662664 return - ENOMEM ;
663665
666+ if (nvme_cli_identify_ctrl (dev , id_ctrl )) {
667+ perror ("identify-ctrl" );
668+ return - errno ;
669+ }
670+
671+ data_area_4_support = id_ctrl -> lpa & 0x40 ;
672+
664673 switch (da ) {
674+ case NVME_TELEMETRY_DA_CTRL_DETERMINE :
675+ if (data_area_4_support )
676+ dalb = da4lb ;
677+ else
678+ dalb = da3lb ;
679+ break ;
665680 case NVME_TELEMETRY_DA_1 :
666- dalb = le16_to_cpu ( telem -> dalb1 ) ;
681+ dalb = da1lb ;
667682 break ;
668683 case NVME_TELEMETRY_DA_2 :
669- dalb = le16_to_cpu ( telem -> dalb2 ) ;
684+ dalb = da2lb ;
670685 break ;
671686 case NVME_TELEMETRY_DA_3 :
672687 /* dalb3 >= dalb2 >= dalb1 */
673- dalb = le16_to_cpu ( telem -> dalb3 ) ;
688+ dalb = da3lb ;
674689 break ;
675690 case NVME_TELEMETRY_DA_4 :
676- if (nvme_cli_identify_ctrl (dev , id_ctrl )) {
677- perror ("identify-ctrl" );
678- return - errno ;
679- }
680-
681- if (id_ctrl -> lpa & 0x40 ) {
682- dalb = le32_to_cpu (telem -> dalb4 );
691+ if (data_area_4_support ) {
692+ dalb = da4lb ;
683693 } else {
684694 nvme_show_error (
685695 "Data area 4 unsupported, bit 6 of Log Page Attributes not set" );
@@ -757,7 +767,7 @@ static int __create_telemetry_log_host(struct nvme_dev *dev,
757767 if (!log )
758768 return - ENOMEM ;
759769
760- err = nvme_cli_get_log_create_telemetry_host (dev , log );
770+ err = nvme_cli_get_log_create_telemetry_host_mcda (dev , da , log );
761771 if (err ) {
762772 if (errno )
763773 return - errno ;
@@ -854,6 +864,8 @@ static int get_telemetry_log(int argc, char **argv, struct command *cmd,
854864 const char * hgen = "Have the host tell the controller to generate the report" ;
855865 const char * cgen = "Gather report generated by the controller." ;
856866 const char * dgen = "Pick which telemetry data area to report. Default is 3 to fetch areas 1-3. Valid options are 1, 2, 3, 4." ;
867+ const char * mcda = "Host-init Maximum Created Data Area. Valid options are 0 ~ 4 "
868+ "If given, This option will override dgen. 0 : controller determines data area" ;
857869
858870 _cleanup_free_ struct nvme_telemetry_log * log = NULL ;
859871 _cleanup_nvme_dev_ struct nvme_dev * dev = NULL ;
@@ -869,21 +881,24 @@ static int get_telemetry_log(int argc, char **argv, struct command *cmd,
869881 bool ctrl_init ;
870882 int data_area ;
871883 bool rae ;
884+ __u8 mcda ;
872885 };
873886 struct config cfg = {
874887 .file_name = NULL ,
875888 .host_gen = 1 ,
876889 .ctrl_init = false,
877890 .data_area = 3 ,
878891 .rae = false,
892+ .mcda = 0xff ,
879893 };
880894
881895 NVME_ARGS (opts ,
882896 OPT_FILE ("output-file" , 'O' , & cfg .file_name , fname ),
883897 OPT_UINT ("host-generate" , 'g' , & cfg .host_gen , hgen ),
884898 OPT_FLAG ("controller-init" , 'c' , & cfg .ctrl_init , cgen ),
885899 OPT_UINT ("data-area" , 'd' , & cfg .data_area , dgen ),
886- OPT_FLAG ("rae" , 'r' , & cfg .rae , rae ));
900+ OPT_FLAG ("rae" , 'r' , & cfg .rae , rae ),
901+ OPT_BYTE ("mcda" , 'm' , & cfg .mcda , mcda ));
887902
888903 err = parse_and_open (& dev , argc , argv , desc , opts );
889904 if (err )
@@ -895,6 +910,15 @@ static int get_telemetry_log(int argc, char **argv, struct command *cmd,
895910 }
896911
897912 cfg .host_gen = !!cfg .host_gen ;
913+
914+ if (cfg .mcda != 0xff ) {
915+ if (cfg .ctrl_init || !cfg .host_gen ) {
916+ nvme_show_error ("mcda allowed for Host-init Creation!" );
917+ return - EINVAL ;
918+ }
919+ cfg .data_area = cfg .mcda ;
920+ }
921+
898922 output = open (cfg .file_name , O_WRONLY | O_CREAT | O_TRUNC , 0666 );
899923 if (output < 0 ) {
900924 nvme_show_error ("Failed to open output file %s: %s!" ,
0 commit comments