]> www.infradead.org Git - users/sagi/nvme-cli.git/commitdiff
Micron plugin version 1.0.6
authorHanumanthu H <hanumanthuh@micron.com>
Thu, 13 May 2021 08:06:40 +0000 (13:36 +0530)
committerKeith Busch <kbusch@kernel.org>
Thu, 13 May 2021 15:52:11 +0000 (09:52 -0600)
plugins/micron/micron-nvme.c

index f76c0156fc975c3b3c2d77dc27bd43338f29027c..8e4b7cff34f7b5f29d9cd0a758d3385ef0ad4fc2 100644 (file)
@@ -38,7 +38,7 @@
 /* Plugin version major_number.minor_number.patch */
 static const char *__version_major = "1";
 static const char *__version_minor = "0";
-static const char *__version_patch = "5";
+static const char *__version_patch = "6";
 
 /* supported models of micron plugin; new models should be added at the end
  * before UNKNOWN_MODEL. Make sure M5410 is first in the list !
@@ -1056,11 +1056,12 @@ static void init_d0_log_page(__u8 *buf, __u8 nsze)
 /* OCP and Vendor specific log data format */
 struct micron_vs_logpage {
     char *field;
-    int  size;
+    int  size;  /* FB client spec version 1.0 sizes - M5410 models */
+    int  size2; /* FB client spec version 0.7 sizes - M5407 models */
 }
-/* Smart Health Log information as per OCP spec */
+/* Smart Health Log information as per OCP spec M51CX models */
 ocp_c0_log_page[] = {
-    { "Physical Media Units Written", 16 },
+    { "Physical Media Units Written", 16},
     { "Physical Media Units Read", 16 },
     { "Raw Bad User NAND Block Count", 6},
     { "Normalized Bad User NAND Block Count", 2},
@@ -1096,43 +1097,56 @@ ocp_c0_log_page[] = {
 },
 /* Vendor Specific Health Log information */
 fb_log_page[] = {
-    { "Physical Media Units Written - TLC", 16 },
-    { "Physical Media Units Written - SLC", 16 },
-    { "Normalized Bad User NAND Block Count", 2},
-    { "Raw Bad User NAND Block Count", 6},
-    { "XOR Recovery Count", 8},
-    { "Uncorrectable Read Error Count", 8},
-    { "SSD End to End Corrected Errors", 8},
-    { "SSD End to End Detected Counts", 4},
-    { "SSD End to End Uncorrected Counts", 4},
-    { "System data % life-used", 1},
-    { "Minimum User Data Erase Count - TLC", 8},
-    { "Maximum User Data Erase Count - TLC", 8},
-    { "Minimum User Data Erase Count - SLC", 8},
-    { "Maximum User Data Erase Count - SLC", 8},
-    { "Normalized Program Fail Count", 2},
-    { "Raw Program Fail Count", 6},
-    { "Normalized Erase Fail Count", 2},
-    { "Raw Erase Fail Count", 6},
-    { "Pcie Correctable Error Count", 8},
-    { "% Free Blocks (User)", 1},
-    { "Security Version Number", 8},
-    { "% Free Blocks (System)", 1},
-    { "Dataset Management (Deallocate) Commands", 16},
-    { "Incomplete TRIM Data", 8},
-    { "% Age of Completed TRIM", 1},
-    { "Background Back-Pressure Gauge", 1},
-    { "Soft ECC Error Count", 8},
-    { "Refresh Count", 8},
-    { "Normalized Bad System NAND Block Count", 2},
-    { "Raw Bad System NAND Block Count", 6},
-    { "Endurance Estimate", 16},
-    { "Thermal Throttling Count", 1},
-    { "Thermal Throttling Status", 1},
-    { "Unaligned I/O", 8},
-    { "Physical Media Units Read", 16},
-    { "Reserved", 279},
-    { "Log Page Version", 2}
+    { "Physical Media Units Written - TLC",  16, 16 },
+    { "Physical Media Units Written - SLC",  16, 16 },
+    { "Normalized Bad User NAND Block Count", 2, 2},
+    { "Raw Bad User NAND Block Count", 6, 6},
+    { "XOR Recovery Count", 8, 8},
+    { "Uncorrectable Read Error Count", 8, 8},
+    { "SSD End to End Corrected Errors", 8, 8},
+    { "SSD End to End Detected Counts", 4, 8},
+    { "SSD End to End Uncorrected Counts", 4, 8},
+    { "System data % life-used", 1, 1},
+    { "Reserved", 0, 3},
+    { "Minimum User Data Erase Count - TLC", 8, 8},
+    { "Maximum User Data Erase Count - TLC", 8, 8},
+    { "Average User Data Erase Count - TLC", 0, 8},
+    { "Minimum User Data Erase Count - SLC", 8, 8},
+    { "Maximum User Data Erase Count - SLC", 8, 8},
+    { "Average User Data Erase Count - SLC", 0, 8},
+    { "Normalized Program Fail Count", 2, 2},
+    { "Raw Program Fail Count", 6, 6},
+    { "Normalized Erase Fail Count", 2, 2},
+    { "Raw Erase Fail Count", 6, 6},
+    { "Pcie Correctable Error Count", 8, 8},
+    { "% Free Blocks (User)", 1, 1},
+    { "Reserved", 0, 3},
+    { "Security Version Number", 8, 8},
+    { "% Free Blocks (System)", 1, 1},
+    { "Reserved", 0, 3},
+    { "Dataset Management (Deallocate) Commands", 16, 16},
+    { "Incomplete TRIM Data", 8, 8},
+    { "% Age of Completed TRIM", 1, 2},
+    { "Background Back-Pressure Gauge", 1, 1},
+    { "Reserved", 0, 3},
+    { "Soft ECC Error Count", 8, 8},
+    { "Refresh Count", 8, 8},
+    { "Normalized Bad System NAND Block Count", 2, 2},
+    { "Raw Bad System NAND Block Count", 6, 6},
+    { "Endurance Estimate", 16, 16},
+    { "Thermal Throttling Count", 1, 1},
+    { "Thermal Throttling Status", 1, 1},
+    { "Unaligned I/O", 8, 8},
+    { "Physical Media Units Read", 16, 16},
+    { "Reserved", 279, 0},
+    { "Log Page Version", 2, 0},
+    { "READ CMDs exceeding threshold", 0, 4},
+    { "WRITE CMDs exceeding threshold", 0, 4},
+    { "TRIMs CMDs exceeding threshold", 0, 4},
+    { "Reserved", 0, 4},
+    { "Reserved", 0, 210},
+    { "Log Page Version", 0, 2},
+    { "Log Page GUID", 0, 16},
 };
 
 /* Common function to print Micron VS log pages */
@@ -1140,66 +1154,70 @@ static void print_micron_vs_logs(
     __u8                     *buf,             /* raw log data */
     struct micron_vs_logpage *log_page,        /* format of the data */
     int                      field_count,      /* log field count */
-    struct json_object       *stats            /* json object to add fields */
+    struct json_object       *stats,           /* json object to add fields */
+    __u8                     spec              /* ocp spec index */
 )
 {
     __u64 lval_lo, lval_hi;
     __u32 ival;
     __u16 sval;
     __u8  cval, lval[8] = { 0 };
-    int field, guid_index;
+    int field;
     int offset = 0;
 
     for (field = 0; field < field_count; field++) {
         char datastr[1024] = { 0 };
-        if (log_page[field].size == 16) {
-            if (strstr(log_page[field].field, "GUID")) {
-                char *tmpstr = datastr;
-                tmpstr += sprintf(datastr, "0x");
-                for(guid_index = 0; guid_index < 16; guid_index++)
-                    tmpstr += sprintf(tmpstr, "%01X", buf[offset + guid_index]);
+        char *sfield = NULL;
+        int size = (spec == 0) ? log_page[field].size : log_page[field].size2;
+        if (size == 0) continue;
+        sfield = log_page[field].field;
+        if (size == 16) {
+            if (strstr(sfield, "GUID")) {
+                sprintf(datastr, "0x%lX%lX",
+                        (uint64_t)le64_to_cpu(*(uint64_t *)(&buf[offset + 8])),
+                        (uint64_t)le64_to_cpu(*(uint64_t *)(&buf[offset])));
             } else {
                 lval_lo = *((__u64 *)(&buf[offset]));
                 lval_hi = *((__u64 *)(&buf[offset + 8]));
                 if (lval_hi)
-                    sprintf(datastr, "0x%"PRIx64"_%"PRIx64"",
+                    sprintf(datastr, "0x%"PRIx64"%016"PRIx64"",
                             le64_to_cpu(lval_hi), le64_to_cpu(lval_lo));
                 else
                     sprintf(datastr, "0x%"PRIx64"", le64_to_cpu(lval_lo));
             }
-        } else if (log_page[field].size == 8) {
+        } else if (size == 8) {
             lval_lo = *((__u64 *)(&buf[offset]));
             sprintf(datastr, "0x%"PRIx64"", le64_to_cpu(lval_lo));
-        } else if (log_page[field].size == 7) {
+        } else if (size == 7) {
             /* 7 bytes will be in little-endian format, with last byte as MSB */
             memcpy(&lval[0], &buf[offset], 7);
             memcpy((void *)&lval_lo, lval, 8);
             sprintf(datastr, "0x%"PRIx64"", le64_to_cpu(lval_lo));
-        } else if (log_page[field].size == 6) {
+        } else if (size == 6) {
             ival    = *((__u32 *)(&buf[offset]));
             sval    = *((__u16 *)(&buf[offset + 4]));
             lval_lo = (((__u64)sval << 32) | ival);
             sprintf(datastr, "0x%"PRIx64"", le64_to_cpu(lval_lo));
-        } else if (log_page[field].size == 4) {
+        } else if (size == 4) {
             ival    = *((__u32 *)(&buf[offset]));
             sprintf(datastr, "0x%x", le32_to_cpu(ival));
-        } else if (log_page[field].size == 2) {
+        } else if (size == 2) {
             sval = *((__u16 *)(&buf[offset]));
             sprintf(datastr, "0x%04x", le16_to_cpu(sval));
-        } else if (log_page[field].size == 1) {
+        } else if (size == 1) {
             cval = buf[offset];
             sprintf(datastr, "0x%02x", cval);
         } else {
             sprintf(datastr, "0");
         }
-        offset += log_page[field].size;
+        offset += size;
         /* do not print reserved values */
-        if (strstr(log_page[field].field, "Reserved"))
+        if (strstr(sfield, "Reserved"))
             continue;
         if (stats != NULL) {
-            json_object_add_value_string(stats, log_page[field].field, datastr);
+            json_object_add_value_string(stats, sfield, datastr);
         } else {
-            printf("%-40s : %-4s\n", log_page[field].field, datastr);
+            printf("%-40s : %-4s\n", sfield, datastr);
         }
     }
 }
@@ -1219,7 +1237,7 @@ static void print_smart_cloud_health_log(__u8 *buf, bool is_json)
                                     logPages);
     }
 
-    print_micron_vs_logs(buf, ocp_c0_log_page, field_count, stats);
+    print_micron_vs_logs(buf, ocp_c0_log_page, field_count, stats, 0);
 
     if (is_json) {
         json_array_add_value_object(logPages, stats);
@@ -1229,7 +1247,7 @@ static void print_smart_cloud_health_log(__u8 *buf, bool is_json)
     }
 }
 
-static void print_nand_stats_fb(__u8 *buf, __u8 *buf2, __u8 nsze, bool is_json)
+static void print_nand_stats_fb(__u8 *buf, __u8 *buf2, __u8 nsze, bool is_json, __u8 spec)
 {
     struct json_object *root;
     struct json_object *logPages;
@@ -1244,7 +1262,7 @@ static void print_nand_stats_fb(__u8 *buf, __u8 *buf2, __u8 nsze, bool is_json)
                                     logPages);
     }
 
-    print_micron_vs_logs(buf, fb_log_page, field_count, stats);
+    print_micron_vs_logs(buf, fb_log_page, field_count, stats, spec);
 
     /* print last three entries from D0 log page */
     init_d0_log_page(buf2, nsze);
@@ -1363,11 +1381,12 @@ static int micron_nand_stats(int argc, char **argv,
     if (nsze == 0 && nsze_from_oacs)
         nsze = ((ctrl.oacs >> 3) & 0x1);
     err = 0;
-    if (has_fb_log)
-        print_nand_stats_fb((__u8 *)logFB, (__u8 *)extSmartLog, nsze, is_json);
-    else if (has_d0_log)
+    if (has_fb_log) {
+        __u8 spec = (eModel == M5410) ? 0 : 1;  /* FB spec version */
+        print_nand_stats_fb((__u8 *)logFB, (__u8 *)extSmartLog, nsze, is_json, spec);
+    } else if (has_d0_log) {
         print_nand_stats_d0((__u8 *)extSmartLog, nsze, is_json);
-    else {
+    else {
         printf("Unable to retrieve extended smart log for the drive\n");
         err = -ENOTTY;
     }
@@ -1483,6 +1502,62 @@ static void GetErrorlogData(int fd, int entries, const char *dir)
     free(error_log);
 }
 
+static void GetGenericLogs(int fd, const char *dir)
+{
+    struct nvme_self_test_log self_test_log;
+    struct nvme_firmware_log_page fw_log;
+    struct nvme_effects_log_page effects;
+    struct nvme_persistent_event_log_head pevent_log_head;
+    void *pevent_log_info = NULL;
+    __u32 log_len = 0;
+    int err = 0 ;
+    bool huge = false;
+
+    /* get self test log */
+    if (nvme_self_test_log(fd, sizeof(self_test_log), &self_test_log) == 0) {
+        WriteData((__u8*)&self_test_log, sizeof(self_test_log), dir,
+                  "drive_self_test.bin", "self test log");
+    }
+
+    /* get fw slot info log */
+    if (nvme_fw_log(fd, &fw_log) == 0) {
+        WriteData((__u8*)&fw_log, sizeof(fw_log), dir,
+                  "firmware_slot_info_log.bin", "firmware log");
+    }
+
+    /* get effects log */
+    if (nvme_effects_log(fd, &effects) == 0) {
+        WriteData((__u8*)&effects, sizeof(effects), dir,
+                  "command_effects_log.bin", "effects log");
+    }
+    
+    /* get persistent event log */
+    (void)nvme_persistent_event_log(fd, NVME_PEVENT_LOG_RELEASE_CTX,
+                                    sizeof(pevent_log_head), &pevent_log_head);
+    memset(&pevent_log_head, 0, sizeof(pevent_log_head));
+    err = nvme_persistent_event_log(fd, NVME_PEVENT_LOG_EST_CTX_AND_READ, 
+                        sizeof(pevent_log_head), &pevent_log_head);
+    if (err) {
+        fprintf(stderr, "Failed to set persistent event log read context");
+        return;
+    }
+
+    log_len = le64_to_cpu(pevent_log_head.tll);
+    pevent_log_info = nvme_alloc(log_len, &huge);
+    if (!pevent_log_info) {
+        perror("could not alloc buffer for persistent event log page\n");
+        return;
+    }
+    err = nvme_persistent_event_log(fd, NVME_PEVENT_LOG_READ,
+                                    log_len, pevent_log_info);
+    if (err == 0) {
+        WriteData((__u8*)pevent_log_info, log_len, dir,
+                  "persistent_event_log.bin", "persistent event log");
+    }
+    nvme_free(pevent_log_info, huge);
+    return;
+}
+
 static void GetNSIDDInfo(int fd, const char *dir, int nsid)
 {
     char file[PATH_MAX] = { 0 };
@@ -1537,14 +1612,14 @@ static void GetOSConfig(const char *strOSDirName)
 static int micron_telemetry_log(int fd, __u8 gen, __u8 type, __u8 **data,
                                 int *logSize, int da)
 {
-    int err;
+    int err, bs = 512, offset = bs;
     unsigned short data_area[4];
     unsigned char  ctrl_init = (type == 0x8);
 
-    __u8 *buffer = (unsigned char *)calloc(512, 1);
+    __u8 *buffer = (unsigned char *)calloc(bs, 1);
     if (buffer == NULL)
         return -1;
-    err = nvme_get_telemetry_log(fd, buffer, gen, ctrl_init, 512, 0);
+    err = nvme_get_telemetry_log(fd, buffer, gen, ctrl_init, bs, 0);
     if (err != 0) {
         fprintf(stderr, "Failed to get telemetry log header for 0x%X\n", type);
         if (buffer != NULL) {
@@ -1553,10 +1628,10 @@ static int micron_telemetry_log(int fd, __u8 gen, __u8 type, __u8 **data,
         return err;
     }
 
-    // compute size of the log
-    data_area[1] = buffer[9] << 16 | buffer[8];
-    data_area[2] = buffer[11] << 16 | buffer[10];
-    data_area[3] = buffer[13] << 16 | buffer[12];
+    /* compute size of the log */
+    data_area[1] = buffer[9]  << 8 | buffer[8];
+    data_area[2] = buffer[11] << 8 | buffer[10];
+    data_area[3] = buffer[13] << 8 | buffer[12];
     data_area[0] = data_area[1] > data_area[2] ? data_area[1] : data_area[2];
     data_area[0] = data_area[3] > data_area[0] ? data_area[3] : data_area[0];
 
@@ -1569,9 +1644,14 @@ static int micron_telemetry_log(int fd, __u8 gen, __u8 type, __u8 **data,
         return -1;
     }
 
-    *logSize = data_area[da] * 512;
+    *logSize = data_area[da] * bs;
+    offset = bs;
+    err = 0;
     if ((buffer = (unsigned char *)realloc(buffer, (size_t)(*logSize))) != NULL) {
-        err = nvme_get_telemetry_log(fd, buffer, gen, ctrl_init, *logSize, 0);
+        while (err == 0 && offset != *logSize) {
+           err = nvme_get_telemetry_log(fd, buffer + offset, gen, ctrl_init, bs, offset);
+           offset += bs;
+        }
     }
 
     if (err == 0 && buffer != NULL) {
@@ -1594,12 +1674,13 @@ static int GetTelemetryData(int fd, const char *dir)
         __u8 log;
         char *file;
     } tmap[] = {
-        {0x07, "nvme_host_telemetry.bin"},
-        {0x08, "nvme_cntrl_telemetry.bin"},
+        {0x07, "nvmetelemetrylog.bin"},
+        {0x08, "nvmetelemetrylog.bin"},
     };
 
     for(i = 0; i < (int)(sizeof(tmap)/sizeof(tmap[0])); i++) {
-        err = micron_telemetry_log(fd, 0, tmap[i].log, &buffer, &logSize, 0);
+        err = micron_telemetry_log(fd, (tmap[i].log == 0x07),
+                                   tmap[i].log, &buffer, &logSize, 0);
         if (err == 0 && logSize > 0 && buffer != NULL) {
             sprintf(msg, "telemetry log: 0x%X", tmap[i].log);
             WriteData(buffer, logSize, dir, tmap[i].file, msg);
@@ -1667,20 +1748,56 @@ static int micron_drive_info(int argc, char **argv, struct command *cmd,
     const char *desc = "Get drive HW information";
     int fd, err = 0;
     struct nvme_id_ctrl ctrl =  { 0 };
+    struct nvme_admin_cmd admin_cmd = { 0 };
+    struct fb_drive_info {
+        unsigned char hw_ver_major;
+        unsigned char hw_ver_minor;
+        unsigned char ftl_unit_size;
+        unsigned char bs_ver_major;
+        unsigned char bs_ver_minor;
+    } dinfo = { 0 };
+    eDriveModel model = UNKNOWN_MODEL;
     OPT_ARGS(opts) = {
         OPT_END()
     };
 
-    if ((fd = micron_parse_options(argc, argv, desc, opts, NULL)) < 0)
+    if ((fd = micron_parse_options(argc, argv, desc, opts, &model)) < 0)
         return err;
 
-    err = nvme_identify_ctrl(fd, &ctrl);
-    if (err) {
-        fprintf(stderr, "ERROR : nvme_identify_ctrl() failed with 0x%x\n", err);
+    if (model == UNKNOWN_MODEL) {
+        fprintf(stderr, "ERROR : Unsupported drive for vs-drive-info cmd");
         return -1;
     }
 
-    printf("%u.%u\n", ctrl.vs[820], ctrl.vs[821]);
+    if (model == M5407) {
+        admin_cmd.opcode = 0xD4,
+        admin_cmd.addr = (__u64) (uintptr_t) &dinfo;
+        admin_cmd.data_len = (__u32)sizeof(dinfo);
+        admin_cmd.cdw12 = 3;
+        err = ioctl(fd, NVME_IOCTL_ADMIN_CMD, &admin_cmd);
+        if (err) {
+            fprintf(stderr, "ERROR : drive-info opcode failed with 0x%x\n", err);
+            return -1;
+        }
+        printf("Drive Hardware Version: %hhu.%hhu\n",
+                dinfo.hw_ver_major, dinfo.hw_ver_minor);
+
+        if (dinfo.ftl_unit_size)
+            printf("FTL_unit_size: %hhu KB\n", dinfo.ftl_unit_size);
+
+        if (dinfo.bs_ver_major != 0 || dinfo.bs_ver_minor != 0) {
+            printf("Boot  Spec.Version: %hhu.%hhu\n",
+                    dinfo.bs_ver_major, dinfo.bs_ver_minor);
+        }
+    } else {
+        err = nvme_identify_ctrl(fd, &ctrl);
+        if (err) {
+            fprintf(stderr, "ERROR : identify_ctrl() failed with 0x%x\n", err);
+            return -1;
+        }
+        printf("Drive Hardware Version: %hhu.%hhu\n", ctrl.vs[820], ctrl.vs[821]);
+    }
+
     return 0;
 }
 
@@ -1825,8 +1942,7 @@ static int micron_fw_activation_history(int argc, char **argv, struct command *c
     int count = 0;
     unsigned int logC2[C2_log_size/sizeof(int)] = { 0 };
     eDriveModel eModel = UNKNOWN_MODEL;
-    struct nvme_id_ctrl ctrl;
-    int fd, err, ctrlIdx;
+    int fd, err;
     struct format {
         char *fmt;
     };
@@ -1841,9 +1957,7 @@ static int micron_fw_activation_history(int argc, char **argv, struct command *c
         OPT_END()
     };
 
-    fd = parse_and_open(argc, argv, desc, opts);
-    if (fd < 0) {
-        printf("\nDevice not found \n");;
+    if ((fd = micron_parse_options(argc, argv, desc, opts, &eModel)) < 0) {
         return -1;
     }
 
@@ -1853,16 +1967,8 @@ static int micron_fw_activation_history(int argc, char **argv, struct command *c
         return -1;
     }
 
-    err = nvme_identify_ctrl(fd, &ctrl);
-    if (err) {
-        fprintf(stderr, "failed get device identification data, error: %x\n", err);
-        goto out;
-    }
-
     /* check if product supports fw_history log */
     err = -EINVAL;
-    sscanf(argv[optind], "/dev/nvme%d", &ctrlIdx);
-    eModel = GetDriveModel(ctrlIdx);
     if (eModel != M51CX) {
         fprintf(stderr, "Unsupported drive model for vs-fw-activate-history command\n");
         goto out;
@@ -1919,8 +2025,7 @@ static int micron_ocp_smart_health_logs(int argc, char **argv, struct command *c
     const char *desc = "Retrieve Micron OCP Smart Health log for the given device ";
     unsigned int logC0[C0_log_size/sizeof(int)] = { 0 };
     eDriveModel eModel = UNKNOWN_MODEL;
-    struct nvme_id_ctrl ctrl;
-    int fd, err, ctrlIdx;
+    int fd, err;
     bool is_json = false;
     struct format {
         char *fmt;
@@ -1935,32 +2040,23 @@ static int micron_ocp_smart_health_logs(int argc, char **argv, struct command *c
         OPT_END()
     };
 
-    fd = parse_and_open(argc, argv, desc, opts);
-    if (fd < 0) {
-        printf("\nDevice not found \n");;
+    if ((fd = micron_parse_options(argc, argv, desc, opts, &eModel)) < 0) {
         return -1;
     }
 
-    if (strcmp(cfg.fmt, "json") == 0)
-        is_json = true;
-
-    err = nvme_identify_ctrl(fd, &ctrl);
-    if (err)
-        goto out;
-
-    /* pull log details based on the model name */
-    sscanf(argv[optind], "/dev/nvme%d", &ctrlIdx);
-    if ((eModel = GetDriveModel(ctrlIdx)) == UNKNOWN_MODEL) {
+    err = -EINVAL;
+    /* check for models that support 0xC0 log */
+    if (eModel != M51CX) {
         printf ("Unsupported drive model for vs-smart-add-log commmand\n");
         close(fd);
         goto out;
     }
 
-    /* should check for firmware version if this log is supported or not */
-    if (eModel == M5407 || eModel == M5410) {
-        err = nvme_get_log(fd, NVME_NSID_ALL, 0xC0, false, NVME_NO_LOG_LSP,
-                           C0_log_size, logC0);
-    }
+    if (strcmp(cfg.fmt, "json") == 0)
+        is_json = true;
+
+    err = nvme_get_log(fd, NVME_NSID_ALL, 0xC0, false, NVME_NO_LOG_LSP,
+                       C0_log_size, logC0);
     if (err < 0) {
         printf("Unable to retrieve extended smart log for the drive\n");
         err = -ENOTTY;
@@ -2249,6 +2345,7 @@ static int micron_internal_logs(int argc, char **argv, struct command *cmd,
 
     GetSmartlogData(fd, strCtrlDirName);
     GetErrorlogData(fd, ctrl.elpe, strCtrlDirName);
+    GetGenericLogs(fd, strCtrlDirName);
 
     // pull if telemetry log data is supported
     if ((ctrl.lpa & 0x8) == 0x8)
@@ -2256,7 +2353,7 @@ static int micron_internal_logs(int argc, char **argv, struct command *cmd,
 
     GetFeatureSettings(fd, strCtrlDirName);
 
-    if (eModel != M5410) {
+    if (eModel != M5410 && eModel != M5407) {
         memcpy(aVendorLogs, aM51XXLogs, sizeof(aM51XXLogs));
         if (eModel == M51AX)
             memcpy((char *)aVendorLogs + sizeof(aM51XXLogs), aM51AXLogs, sizeof(aM51AXLogs));