Skip to content

Commit f45b402

Browse files
nvme: plot eye chart data and hex dumping VS eye data
- Fixed segmentation fault issue in JSON output format for VS Eye data. - Added support to hex dump VS Eye data in both normal and JSON formats. - This enables customers to decode the raw eye chart data if needed. - Ensured compatibility with existing d() and obj_d() hex dump utilities. Signed-off-by: Sivaprasad Gutha <[email protected]>
1 parent cba763f commit f45b402

2 files changed

Lines changed: 70 additions & 12 deletions

File tree

nvme-print-json.c

Lines changed: 56 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2121,25 +2121,47 @@ static void json_boot_part_log(void *bp_log, const char *devname,
21212121

21222122
/* Printable Eye string is allocated and returned, caller must free */
21232123
static char *json_eom_printable_eye(struct nvme_eom_lane_desc *lane,
2124-
struct json_object *r)
2124+
struct json_object *r)
21252125
{
21262126
char *eye = (char *)lane->eye_desc;
2127-
char *printable = malloc(lane->nrows * lane->ncols + lane->ncols);
2127+
uint16_t nrows = lane->nrows;
2128+
uint16_t ncols = lane->ncols;
2129+
2130+
if (nrows == 0 || ncols == 0)
2131+
return NULL;
2132+
2133+
// Allocate buffer for full printable string (with newlines)
2134+
char *printable = malloc(nrows * ncols + nrows + 1); // +1 for null terminator
21282135
char *printable_start = printable;
2129-
int i, j;
21302136

21312137
if (!printable)
2132-
goto exit;
2138+
return NULL;
2139+
2140+
struct json_object *eye_array = json_create_array();
2141+
2142+
for (int i = 0; i < nrows; i++) {
2143+
char *row = malloc(ncols + 1);
2144+
2145+
if (!row)
2146+
continue;
21332147

2134-
for (i = 0; i < lane->nrows; i++) {
2135-
for (j = 0; j < lane->ncols; j++, printable++)
2136-
sprintf(printable, "%c", eye[i * lane->ncols + j]);
2137-
sprintf(printable++, "\n");
2148+
for (int j = 0; j < ncols; j++) {
2149+
char ch = eye[i * ncols + j];
2150+
*printable++ = ch;
2151+
row[j] = ch;
2152+
}
2153+
2154+
*printable++ = '\n';
2155+
row[ncols] = '\0';
2156+
2157+
array_add_str(eye_array, row);
2158+
free(row);
21382159
}
21392160

2140-
obj_add_str(r, "printable_eye", printable_start);
2161+
*printable = '\0';
2162+
2163+
obj_add_array(r, "printable_eye_rows", eye_array);
21412164

2142-
exit:
21432165
return printable_start;
21442166
}
21452167

@@ -2155,6 +2177,8 @@ static void json_phy_rx_eom_descs(struct nvme_phy_rx_eom_log *log,
21552177

21562178
for (i = 0; i < num_descs; i++) {
21572179
struct nvme_eom_lane_desc *desc = p;
2180+
unsigned char *vsdata = NULL;
2181+
unsigned int vsdataoffset = 0;
21582182
struct json_object *jdesc = json_create_object();
21592183

21602184
obj_add_uint(jdesc, "lid", desc->mstatus);
@@ -2169,10 +2193,30 @@ static void json_phy_rx_eom_descs(struct nvme_phy_rx_eom_log *log,
21692193
obj_add_uint(jdesc, "edlen", le16_to_cpu(desc->edlen));
21702194

21712195
if (NVME_EOM_ODP_PEFP(log->odp))
2172-
allocated_eyes[i] = json_eom_printable_eye(desc, r);
2196+
allocated_eyes[i] = json_eom_printable_eye(desc, jdesc);
21732197

2174-
/* Eye Data field is vendor specific, doesn't map to JSON */
2198+
if (desc->edlen == 0)
2199+
continue;
2200+
else {
2201+
/* Hex dump Vendor Specific Eye Data*/
2202+
vsdata = (unsigned char *)malloc(desc->edlen);
2203+
vsdataoffset = (desc->nrows * desc->ncols) +
2204+
sizeof(struct nvme_eom_lane_desc);
2205+
vsdata = (unsigned char *)((unsigned char *)desc + vsdataoffset);
2206+
char *hexstr = malloc(desc->edlen * 3 + 1); // 2 hex chars + space per byte
21752207

2208+
if (!hexstr)
2209+
return;
2210+
2211+
char *p = hexstr;
2212+
2213+
for (int offset = 0; offset < desc->edlen; offset++)
2214+
p += sprintf(p, "%02X ", vsdata[offset]);
2215+
*(p - 1) = '\0'; // remove trailing space
2216+
2217+
obj_add_str(jdesc, "vsdata_hex", hexstr);
2218+
free(hexstr);
2219+
}
21762220
array_add_obj(descs, jdesc);
21772221

21782222
p += log->dsize;

nvme-print-stdout.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -790,6 +790,8 @@ static void stdout_phy_rx_eom_descs(struct nvme_phy_rx_eom_log *log)
790790

791791
for (i = 0; i < log->nd; i++) {
792792
struct nvme_eom_lane_desc *desc = p;
793+
unsigned char *vsdata = NULL;
794+
unsigned int vsdataoffset = 0;
793795

794796
printf("Measurement Status: %s\n",
795797
desc->mstatus ? "Successful" : "Not Successful");
@@ -807,6 +809,18 @@ static void stdout_phy_rx_eom_descs(struct nvme_phy_rx_eom_log *log)
807809
stdout_eom_printable_eye(desc);
808810

809811
/* Eye Data field is vendor specific */
812+
if (desc->edlen == 0)
813+
continue;
814+
else {
815+
/* Hex dump Vendor Specific Eye Data */
816+
vsdata = (unsigned char *)malloc(desc->edlen);
817+
vsdataoffset = (desc->nrows * desc->ncols) +
818+
sizeof(struct nvme_eom_lane_desc);
819+
vsdata = (unsigned char *)((unsigned char *)desc + vsdataoffset);
820+
printf("Eye Data:\n");
821+
d(vsdata, desc->edlen, 16, 1);
822+
printf("\n");
823+
}
810824

811825
p += log->dsize;
812826
}

0 commit comments

Comments
 (0)