diff --git a/nvme-print-json.c b/nvme-print-json.c index 1766cae882..cef69a1b0a 100644 --- a/nvme-print-json.c +++ b/nvme-print-json.c @@ -2124,23 +2124,60 @@ static char *json_eom_printable_eye(struct nvme_eom_lane_desc *lane, struct json_object *r) { char *eye = (char *)lane->eye_desc; - char *printable = malloc(lane->nrows * lane->ncols + lane->ncols); - char *printable_start = printable; - int i, j; + uint16_t nrows = le16_to_cpu(lane->nrows); + uint16_t ncols = le16_to_cpu(lane->ncols); + struct json_object *eye_array = NULL; + char *printable_start = NULL; + char *printable = NULL; + + if (nrows == 0 || ncols == 0) + return NULL; + + eye_array = json_create_array(); + if (!eye_array) + return NULL; + + /* + * Allocate buffer for full printable string (with newlines) + * +1 for null terminator + */ + printable = malloc(nrows * ncols + nrows + 1); + printable_start = printable; if (!printable) - goto exit; + goto fail_free_eye_array; - for (i = 0; i < lane->nrows; i++) { - for (j = 0; j < lane->ncols; j++, printable++) - sprintf(printable, "%c", eye[i * lane->ncols + j]); - sprintf(printable++, "\n"); + for (int i = 0; i < nrows; i++) { + char *row = malloc(ncols + 1); + + if (!row) + goto fail_free_eye_printable; + + for (int j = 0; j < ncols; j++) { + char ch = eye[i * ncols + j]; + *printable++ = ch; + row[j] = ch; + } + + *printable++ = '\n'; + row[ncols] = '\0'; + + array_add_str(eye_array, row); + free(row); } - obj_add_str(r, "printable_eye", printable_start); + *printable = '\0'; + + obj_add_array(r, "printable_eye", eye_array); -exit: return printable_start; + +fail_free_eye_printable: + free(printable); +fail_free_eye_array: + json_free_object(eye_array); + + return NULL; } static void json_phy_rx_eom_descs(struct nvme_phy_rx_eom_log *log, @@ -2155,7 +2192,20 @@ static void json_phy_rx_eom_descs(struct nvme_phy_rx_eom_log *log, for (i = 0; i < num_descs; i++) { struct nvme_eom_lane_desc *desc = p; - struct json_object *jdesc = json_create_object(); + _cleanup_free_ char *hexstr = NULL; + unsigned char *vsdata = NULL; + unsigned int vsdataoffset = 0; + uint16_t nrows, ncols, edlen; + struct json_object *jdesc; + char *hexdata; + + jdesc = json_create_object(); + if (!desc) + return; + + nrows = le16_to_cpu(desc->nrows); + ncols = le16_to_cpu(desc->ncols); + edlen = le16_to_cpu(desc->edlen); obj_add_uint(jdesc, "lid", desc->mstatus); obj_add_uint(jdesc, "lane", desc->lane); @@ -2164,14 +2214,36 @@ static void json_phy_rx_eom_descs(struct nvme_phy_rx_eom_log *log, obj_add_uint(jdesc, "bottom", le16_to_cpu(desc->bottom)); obj_add_uint(jdesc, "left", le16_to_cpu(desc->left)); obj_add_uint(jdesc, "right", le16_to_cpu(desc->right)); - obj_add_uint(jdesc, "nrows", le16_to_cpu(desc->nrows)); - obj_add_uint(jdesc, "ncols", le16_to_cpu(desc->ncols)); - obj_add_uint(jdesc, "edlen", le16_to_cpu(desc->edlen)); + obj_add_uint(jdesc, "nrows", nrows); + obj_add_uint(jdesc, "ncols", ncols); + obj_add_uint(jdesc, "edlen", edlen); if (NVME_EOM_ODP_PEFP(log->odp)) - allocated_eyes[i] = json_eom_printable_eye(desc, r); + allocated_eyes[i] = json_eom_printable_eye(desc, jdesc); + + if (edlen == 0) + continue; + + /* 2 hex chars + space per byte */ + hexstr = malloc(edlen * 3 + 1); + + if (!hexstr) { + json_free_object(jdesc); + return; + } + + /* Hex dump Vendor Specific Eye Data */ + vsdataoffset = (nrows * ncols) + sizeof(struct nvme_eom_lane_desc); + vsdata = (unsigned char *)((unsigned char *)desc + vsdataoffset); + + hexdata = hexstr; + + for (int offset = 0; offset < edlen; offset++) + hexdata += sprintf(hexdata, "%02X ", vsdata[offset]); + /* remove trailing space */ + *(hexdata - 1) = '\0'; - /* Eye Data field is vendor specific, doesn't map to JSON */ + obj_add_str(jdesc, "vsdata_hex", hexstr); array_add_obj(descs, jdesc); diff --git a/nvme-print-stdout.c b/nvme-print-stdout.c index 1852beaf0c..120fa9ff6d 100644 --- a/nvme-print-stdout.c +++ b/nvme-print-stdout.c @@ -776,9 +776,9 @@ static void stdout_eom_printable_eye(struct nvme_eom_lane_desc *lane) char *eye = (char *)lane->eye_desc; int i, j; - for (i = 0; i < lane->nrows; i++) { - for (j = 0; j < lane->ncols; j++) - printf("%c", eye[i * lane->ncols + j]); + for (i = 0; i < le16_to_cpu(lane->nrows); i++) { + for (j = 0; j < le16_to_cpu(lane->ncols); j++) + printf("%c", eye[i * le16_to_cpu(lane->ncols) + j]); printf("\n"); } } @@ -790,6 +790,13 @@ static void stdout_phy_rx_eom_descs(struct nvme_phy_rx_eom_log *log) for (i = 0; i < log->nd; i++) { struct nvme_eom_lane_desc *desc = p; + unsigned char *vsdata = NULL; + unsigned int vsdataoffset = 0; + uint16_t nrows, ncols, edlen; + + nrows = le16_to_cpu(desc->nrows); + ncols = le16_to_cpu(desc->ncols); + edlen = le16_to_cpu(desc->edlen); printf("Measurement Status: %s\n", desc->mstatus ? "Successful" : "Not Successful"); @@ -799,14 +806,28 @@ static void stdout_phy_rx_eom_descs(struct nvme_phy_rx_eom_log *log) printf("Bottom: %u\n", le16_to_cpu(desc->bottom)); printf("Left: %u\n", le16_to_cpu(desc->left)); printf("Right: %u\n", le16_to_cpu(desc->right)); - printf("Number of Rows: %u\n", le16_to_cpu(desc->nrows)); - printf("Number of Columns: %u\n", le16_to_cpu(desc->ncols)); - printf("Eye Data Length: %u\n", le16_to_cpu(desc->edlen)); + printf("Number of Rows: %u\n", nrows); + printf("Number of Columns: %u\n", ncols); + printf("Eye Data Length: %u\n", desc->edlen); if (NVME_EOM_ODP_PEFP(log->odp)) stdout_eom_printable_eye(desc); /* Eye Data field is vendor specific */ + if (edlen == 0) + continue; + + /* Hex dump Vendor Specific Eye Data */ + vsdata = malloc(edlen); + if (!vsdata) + return; + + vsdataoffset = (nrows * ncols) + sizeof(struct nvme_eom_lane_desc); + vsdata = (unsigned char *)((unsigned char *)desc + vsdataoffset); + printf("Eye Data:\n"); + d(vsdata, edlen, 16, 1); + printf("\n"); + free(vsdata); p += log->dsize; } diff --git a/plugins/micron/micron-nvme.c b/plugins/micron/micron-nvme.c index 371bc56d59..cc20a1cb52 100644 --- a/plugins/micron/micron-nvme.c +++ b/plugins/micron/micron-nvme.c @@ -4,7 +4,9 @@ * * @file: micron-nvme.c * @brief: This module contains all the constructs needed for micron nvme-cli plugin. - * @authors:Chaithanya Shoba , + * @authors:Hanumanthu H + * Chaithanya Shoba + * Sivaprasad Gutha */ #include diff --git a/plugins/micron/micron-nvme.h b/plugins/micron/micron-nvme.h index 967909ac4a..c6b3b37dda 100644 --- a/plugins/micron/micron-nvme.h +++ b/plugins/micron/micron-nvme.h @@ -3,7 +3,9 @@ * * @file: micron-nvme.h * @brief: This module contains all the constructs needed for micron nvme-cli plugin. - * @authors:Chaithanya Shoba , + * @authors:Hanumanthu H + * Chaithanya Shoba + * Sivaprasad Gutha */ #undef CMD_INC_FILE