@@ -1204,10 +1204,15 @@ int parse_statistic(struct nvme_ocp_telemetry_statistic_descriptor *pstatistic_e
12041204 struct json_object * pstats_array , FILE * fp )
12051205{
12061206 if (pstatistic_entry == NULL ) {
1207- nvme_show_error ("Input buffer was NULL" );
1207+ nvme_show_error ("Statistics Input buffer was NULL" );
12081208 return -1 ;
12091209 }
12101210
1211+ if (pstatistic_entry -> statistic_id == STATISTICS_RESERVED_ID )
1212+ /* End of statistics entries, return -1 to stop processing the buffer */
1213+ return -1 ;
1214+
1215+
12111216 unsigned int data_size = pstatistic_entry -> statistic_data_size * SIZE_OF_DWORD ;
12121217 __u8 * pdata = (__u8 * )pstatistic_entry +
12131218 sizeof (struct nvme_ocp_telemetry_statistic_descriptor );
@@ -1236,8 +1241,33 @@ int parse_statistic(struct nvme_ocp_telemetry_statistic_descriptor *pstatistic_e
12361241 pstatistic_entry -> statistic_data_size );
12371242 json_add_formatted_u32_str (pstatistics_object , STR_RESERVED ,
12381243 pstatistic_entry -> reserved );
1239- json_add_formatted_var_size_str (pstatistics_object , STR_STATISTICS_SPECIFIC_DATA ,
1240- pdata , data_size );
1244+ if (pstatistic_entry -> statistic_id == MAX_DIE_BAD_BLOCK_ID ) {
1245+ json_add_formatted_u32_str (pstatistics_object ,
1246+ STR_STATISTICS_WORST_DIE_PERCENT ,
1247+ pdata [0 ]);
1248+ json_add_formatted_u32_str (pstatistics_object ,
1249+ STR_STATISTICS_WORST_DIE_RAW ,
1250+ * (__u16 * )& pdata [2 ]);
1251+ } else if (pstatistic_entry -> statistic_id == MAX_NAND_CHANNEL_BAD_BLOCK_ID ) {
1252+ json_add_formatted_u32_str (pstatistics_object ,
1253+ STR_STATISTICS_WORST_NAND_CHANNEL_PERCENT ,
1254+ pdata [0 ]);
1255+ json_add_formatted_u32_str (pstatistics_object ,
1256+ STR_STATISTICS_WORST_NAND_CHANNEL_RAW ,
1257+ * (__u16 * )& pdata [2 ]);
1258+ } else if (pstatistic_entry -> statistic_id == MIN_NAND_CHANNEL_BAD_BLOCK_ID ) {
1259+ json_add_formatted_u32_str (pstatistics_object ,
1260+ STR_STATISTICS_BEST_NAND_CHANNEL_PERCENT ,
1261+ pdata [0 ]);
1262+ json_add_formatted_u32_str (pstatistics_object ,
1263+ STR_STATISTICS_BEST_NAND_CHANNEL_RAW ,
1264+ * (__u16 * )& pdata [2 ]);
1265+ } else {
1266+ json_add_formatted_var_size_str (pstatistics_object ,
1267+ STR_STATISTICS_SPECIFIC_DATA ,
1268+ pdata ,
1269+ data_size );
1270+ }
12411271
12421272 if (pstatistics_object != NULL )
12431273 json_array_add_value_object (pstats_array , pstatistics_object );
@@ -1257,8 +1287,33 @@ int parse_statistic(struct nvme_ocp_telemetry_statistic_descriptor *pstatistic_e
12571287 fprintf (fp , "%s: 0x%x\n" , STR_STATISTICS_DATA_SIZE ,
12581288 pstatistic_entry -> statistic_data_size );
12591289 fprintf (fp , "%s: 0x%x\n" , STR_RESERVED , pstatistic_entry -> reserved );
1260- print_formatted_var_size_str (STR_STATISTICS_SPECIFIC_DATA , pdata ,
1261- data_size , fp );
1290+ if (pstatistic_entry -> statistic_id == MAX_DIE_BAD_BLOCK_ID ) {
1291+ fprintf (fp , "%s: 0x%02x\n" , STR_STATISTICS_WORST_DIE_PERCENT ,
1292+ pdata [0 ]);
1293+ fprintf (fp , "%s: 0x%04x\n" , STR_STATISTICS_WORST_DIE_RAW ,
1294+ * (__u16 * )& pdata [2 ]);
1295+ } else if (pstatistic_entry -> statistic_id ==
1296+ MAX_NAND_CHANNEL_BAD_BLOCK_ID ) {
1297+ fprintf (fp , "%s: 0x%02x\n" ,
1298+ STR_STATISTICS_WORST_NAND_CHANNEL_PERCENT ,
1299+ pdata [0 ]);
1300+ fprintf (fp , "%s: 0x%04x\n" ,
1301+ STR_STATISTICS_WORST_NAND_CHANNEL_RAW ,
1302+ * (__u16 * )& pdata [2 ]);
1303+ } else if (pstatistic_entry -> statistic_id ==
1304+ MIN_NAND_CHANNEL_BAD_BLOCK_ID ) {
1305+ fprintf (fp , "%s: 0x%02x\n" ,
1306+ STR_STATISTICS_BEST_NAND_CHANNEL_PERCENT ,
1307+ pdata [0 ]);
1308+ fprintf (fp , "%s: 0x%04x\n" ,
1309+ STR_STATISTICS_BEST_NAND_CHANNEL_RAW ,
1310+ * (__u16 * )& pdata [2 ]);
1311+ } else {
1312+ print_formatted_var_size_str (STR_STATISTICS_SPECIFIC_DATA ,
1313+ pdata ,
1314+ data_size ,
1315+ fp );
1316+ }
12621317 fprintf (fp , STR_LINE2 );
12631318 } else {
12641319 printf ("%s: 0x%x\n" , STR_STATISTICS_IDENTIFIER ,
@@ -1275,8 +1330,33 @@ int parse_statistic(struct nvme_ocp_telemetry_statistic_descriptor *pstatistic_e
12751330 printf ("%s: 0x%x\n" , STR_STATISTICS_DATA_SIZE ,
12761331 pstatistic_entry -> statistic_data_size );
12771332 printf ("%s: 0x%x\n" , STR_RESERVED , pstatistic_entry -> reserved );
1278- print_formatted_var_size_str (STR_STATISTICS_SPECIFIC_DATA , pdata ,
1279- data_size , fp );
1333+ if (pstatistic_entry -> statistic_id == MAX_DIE_BAD_BLOCK_ID ) {
1334+ printf ("%s: 0x%02x\n" , STR_STATISTICS_WORST_DIE_PERCENT ,
1335+ pdata [0 ]);
1336+ printf ("%s: 0x%04x\n" , STR_STATISTICS_WORST_DIE_RAW ,
1337+ * (__u16 * )& pdata [2 ]);
1338+ } else if (pstatistic_entry -> statistic_id ==
1339+ MAX_NAND_CHANNEL_BAD_BLOCK_ID ) {
1340+ printf ("%s: 0x%02x\n" ,
1341+ STR_STATISTICS_WORST_NAND_CHANNEL_PERCENT ,
1342+ pdata [0 ]);
1343+ printf ("%s: 0x%04x\n" ,
1344+ STR_STATISTICS_WORST_NAND_CHANNEL_RAW ,
1345+ * (__u16 * )& pdata [2 ]);
1346+ } else if (pstatistic_entry -> statistic_id ==
1347+ MIN_NAND_CHANNEL_BAD_BLOCK_ID ) {
1348+ printf ("%s: 0x%02x\n" ,
1349+ STR_STATISTICS_BEST_NAND_CHANNEL_PERCENT ,
1350+ pdata [0 ]);
1351+ printf ("%s: 0x%04x\n" ,
1352+ STR_STATISTICS_BEST_NAND_CHANNEL_RAW ,
1353+ * (__u16 * )& pdata [2 ]);
1354+ } else {
1355+ print_formatted_var_size_str (STR_STATISTICS_SPECIFIC_DATA ,
1356+ pdata ,
1357+ data_size ,
1358+ fp );
1359+ }
12801360 printf (STR_LINE2 );
12811361 }
12821362 }
@@ -1297,6 +1377,7 @@ int parse_statistics(struct json_object *root, struct nvme_ocp_telemetry_offsets
12971377 __u32 stats_da_1_start_dw = 0 , stats_da_1_size_dw = 0 ;
12981378 __u32 stats_da_2_start_dw = 0 , stats_da_2_size_dw = 0 ;
12991379 __u8 * pstats_offset = NULL ;
1380+ int parse_rc = 0 ;
13001381
13011382 if (poffsets -> data_area == 1 ) {
13021383 __u32 stats_da_1_start = * (__u32 * )(pda1_ocp_header_offset +
@@ -1336,7 +1417,11 @@ int parse_statistics(struct json_object *root, struct nvme_ocp_telemetry_offsets
13361417 (struct nvme_ocp_telemetry_statistic_descriptor * )
13371418 (pstats_offset + offset_to_move );
13381419
1339- parse_statistic (pstatistic_entry , pstats_array , fp );
1420+ parse_rc = parse_statistic (pstatistic_entry , pstats_array , fp );
1421+ if (parse_rc < 0 )
1422+ /* end of stats entries or null pointer, so break */
1423+ break ;
1424+
13401425 offset_to_move += (pstatistic_entry -> statistic_data_size * SIZE_OF_DWORD +
13411426 stat_des_size );
13421427 }
0 commit comments