Skip to content

Commit e6deb5e

Browse files
jeff-lien-sndkigaw
authored andcommitted
nvme: Enable retrieving telemetry log data area 4
When retrieving telemetry log data area 4, the etdas bit in the host behavior changed feature must be set. This commit will change the code to use new functions added to libnvme to set and clear that bit before and after retrieving data area 4. Reviewed-by: brandon-paupore-sndk <[email protected]> Signed-off-by: jeff-lien-sndk <[email protected]>
1 parent 8e08cd8 commit e6deb5e

File tree

1 file changed

+54
-26
lines changed

1 file changed

+54
-26
lines changed

nvme.c

Lines changed: 54 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -715,28 +715,16 @@ static int get_ana_log(int argc, char **argv, struct command *cmd,
715715
static 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,
822810
static 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,
898888
static 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

Comments
 (0)