From 3e94c44bed01fea4162ee08daef9481c507f7412 Mon Sep 17 00:00:00 2001 From: Steven Seungcheol Lee Date: Thu, 5 Dec 2024 09:20:31 +0900 Subject: [PATCH] nvme: Host-init telemetry log mcda field added Maximum Created Data Area for Telemetry Host-Initiated Log creation This will ignored by contorller when MCDAS bit is 0 from supported log Signed-off-by: Steven Seungcheol Lee --- nvme-wrap.c | 5 +++-- nvme-wrap.h | 3 ++- nvme.c | 50 +++++++++++++++++++++++++++++++++++++------------- 3 files changed, 42 insertions(+), 16 deletions(-) diff --git a/nvme-wrap.c b/nvme-wrap.c index 2a18d4df..5c473f9f 100644 --- a/nvme-wrap.c +++ b/nvme-wrap.c @@ -221,10 +221,11 @@ int nvme_cli_get_log_device_self_test(struct nvme_dev *dev, return do_admin_op(get_log_device_self_test, dev, log); } -int nvme_cli_get_log_create_telemetry_host(struct nvme_dev *dev, +int nvme_cli_get_log_create_telemetry_host_mcda(struct nvme_dev *dev, + enum nvme_telemetry_da mcda, struct nvme_telemetry_log *log) { - return do_admin_op(get_log_create_telemetry_host, dev, log); + return do_admin_op(get_log_create_telemetry_host_mcda, dev, mcda, log); } int nvme_cli_get_log_telemetry_host(struct nvme_dev *dev, __u64 offset, diff --git a/nvme-wrap.h b/nvme-wrap.h index 67807b03..bbdbe65f 100644 --- a/nvme-wrap.h +++ b/nvme-wrap.h @@ -75,7 +75,8 @@ int nvme_cli_get_log_cmd_effects(struct nvme_dev *dev, enum nvme_csi csi, struct nvme_cmd_effects_log *effects_log); int nvme_cli_get_log_device_self_test(struct nvme_dev *dev, struct nvme_self_test_log *log); -int nvme_cli_get_log_create_telemetry_host(struct nvme_dev *dev, +int nvme_cli_get_log_create_telemetry_host_mcda(struct nvme_dev *dev, + enum nvme_telemetry_da mcda, struct nvme_telemetry_log *log); int nvme_cli_get_log_telemetry_host(struct nvme_dev *dev, __u64 offset, __u32 len, void *log); diff --git a/nvme.c b/nvme.c index 68d992c3..4db3cd63 100644 --- a/nvme.c +++ b/nvme.c @@ -655,31 +655,41 @@ static int parse_telemetry_da(struct nvme_dev *dev, { _cleanup_free_ struct nvme_id_ctrl *id_ctrl = NULL; - size_t dalb = 0; + size_t dalb, da1lb = le16_to_cpu(telem->dalb1), da2lb = le16_to_cpu(telem->dalb2), + da3lb = le16_to_cpu(telem->dalb3), da4lb = le32_to_cpu(telem->dalb4); + bool data_area_4_support; id_ctrl = nvme_alloc(sizeof(*id_ctrl)); if (!id_ctrl) return -ENOMEM; + if (nvme_cli_identify_ctrl(dev, id_ctrl)) { + perror("identify-ctrl"); + return -errno; + } + + data_area_4_support = id_ctrl->lpa & 0x40; + switch (da) { + case NVME_TELEMETRY_DA_CTRL_DETERMINE: + if (data_area_4_support) + dalb = da4lb; + else + dalb = da3lb; + break; case NVME_TELEMETRY_DA_1: - dalb = le16_to_cpu(telem->dalb1); + dalb = da1lb; break; case NVME_TELEMETRY_DA_2: - dalb = le16_to_cpu(telem->dalb2); + dalb = da2lb; break; case NVME_TELEMETRY_DA_3: /* dalb3 >= dalb2 >= dalb1 */ - dalb = le16_to_cpu(telem->dalb3); + dalb = da3lb; break; case NVME_TELEMETRY_DA_4: - if (nvme_cli_identify_ctrl(dev, id_ctrl)) { - perror("identify-ctrl"); - return -errno; - } - - if (id_ctrl->lpa & 0x40) { - dalb = le32_to_cpu(telem->dalb4); + if (data_area_4_support) { + dalb = da4lb; } else { nvme_show_error( "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, if (!log) return -ENOMEM; - err = nvme_cli_get_log_create_telemetry_host(dev, log); + err = nvme_cli_get_log_create_telemetry_host_mcda(dev, da, log); if (err) { if (errno) return -errno; @@ -854,6 +864,8 @@ static int get_telemetry_log(int argc, char **argv, struct command *cmd, const char *hgen = "Have the host tell the controller to generate the report"; const char *cgen = "Gather report generated by the controller."; 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."; + const char *mcda = "Host-init Maximum Created Data Area. Valid options are 0 ~ 4 " + "If given, This option will override dgen. 0 : controller determines data area"; _cleanup_free_ struct nvme_telemetry_log *log = NULL; _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; @@ -869,6 +881,7 @@ static int get_telemetry_log(int argc, char **argv, struct command *cmd, bool ctrl_init; int data_area; bool rae; + __u8 mcda; }; struct config cfg = { .file_name = NULL, @@ -876,6 +889,7 @@ static int get_telemetry_log(int argc, char **argv, struct command *cmd, .ctrl_init = false, .data_area = 3, .rae = false, + .mcda = 0xff, }; NVME_ARGS(opts, @@ -883,7 +897,8 @@ static int get_telemetry_log(int argc, char **argv, struct command *cmd, OPT_UINT("host-generate", 'g', &cfg.host_gen, hgen), OPT_FLAG("controller-init", 'c', &cfg.ctrl_init, cgen), OPT_UINT("data-area", 'd', &cfg.data_area, dgen), - OPT_FLAG("rae", 'r', &cfg.rae, rae)); + OPT_FLAG("rae", 'r', &cfg.rae, rae), + OPT_BYTE("mcda", 'm', &cfg.mcda, mcda)); err = parse_and_open(&dev, argc, argv, desc, opts); if (err) @@ -895,6 +910,15 @@ static int get_telemetry_log(int argc, char **argv, struct command *cmd, } cfg.host_gen = !!cfg.host_gen; + + if (cfg.mcda != 0xff) { + if (cfg.ctrl_init || !cfg.host_gen) { + nvme_show_error("mcda allowed for Host-init Creation!"); + return -EINVAL; + } + cfg.data_area = cfg.mcda; + } + output = open(cfg.file_name, O_WRONLY | O_CREAT | O_TRUNC, 0666); if (output < 0) { nvme_show_error("Failed to open output file %s: %s!", -- 2.50.1