]> www.infradead.org Git - users/sagi/nvme-cli.git/commitdiff
nvme: Host-init telemetry log mcda field added
authorSteven Seungcheol Lee <sc108.lee@samsung.com>
Thu, 5 Dec 2024 00:20:31 +0000 (09:20 +0900)
committerDaniel Wagner <wagi@monom.org>
Thu, 5 Dec 2024 09:34:10 +0000 (10:34 +0100)
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 <sc108.lee@samsung.com>
nvme-wrap.c
nvme-wrap.h
nvme.c

index 2a18d4df1a05529abe2a5fc8947f0c6dcadd615d..5c473f9fd3d96897f018760dcbe9af40bb081e33 100644 (file)
@@ -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,
index 67807b03dee97c3dc07ec359d86f6ff531129479..bbdbe65f7dcc062e7bb4f2df1b132e96e0f6486f 100644 (file)
@@ -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 68d992c31971103981c3887212059ffad747790a..4db3cd638a0477de3007987dadc7cb654aa6b83e 100644 (file)
--- 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!",