diff --git a/nvme-print-json.c b/nvme-print-json.c index 09d37dce19..35a1aa1c7e 100644 --- a/nvme-print-json.c +++ b/nvme-print-json.c @@ -28,6 +28,13 @@ #define obj_add_uint json_object_add_value_uint #define obj_add_uint128 json_object_add_value_uint128 #define obj_add_uint64 json_object_add_value_uint64 +#define obj_add_str json_object_add_value_string +#define obj_add_uint_02x json_object_add_uint_02x +#define obj_add_uint_0x json_object_add_uint_0x +#define obj_add_byte_array json_object_add_byte_array +#define obj_add_nprix64 json_object_add_nprix64 +#define obj_add_uint_0nx json_object_add_uint_0nx +#define obj_add_0nprix64 json_object_add_0nprix64 static const uint8_t zero_uuid[16] = { 0 }; static struct print_ops json_print_ops; @@ -74,27 +81,6 @@ static void obj_add_uint_x(struct json_object *o, const char *k, __u32 v) obj_add_str(o, k, str); } -void obj_add_uint_0x(struct json_object *o, const char *k, __u32 v) -{ - char str[STR_LEN]; - - sprintf(str, "0x%x", v); - obj_add_str(o, k, str); -} - -void obj_add_uint_0nx(struct json_object *o, const char *k, __u32 v, int width) -{ - char str[STR_LEN]; - - sprintf(str, "0x%0*x", width, v); - obj_add_str(o, k, str); -} - -void obj_add_uint_02x(struct json_object *o, const char *k, __u32 v) -{ - obj_add_uint_0nx(o, k, v, 2); -} - static void obj_add_uint_nx(struct json_object *o, const char *k, __u32 v) { char str[STR_LEN]; @@ -103,14 +89,6 @@ static void obj_add_uint_nx(struct json_object *o, const char *k, __u32 v) obj_add_str(o, k, str); } -void obj_add_nprix64(struct json_object *o, const char *k, uint64_t v) -{ - char str[STR_LEN]; - - sprintf(str, "%#"PRIx64"", v); - obj_add_str(o, k, str); -} - static void obj_add_prix64(struct json_object *o, const char *k, uint64_t v) { char str[STR_LEN]; @@ -4692,36 +4670,3 @@ struct print_ops *nvme_get_json_print_ops(nvme_print_flags_t flags) json_print_ops.flags = flags; return &json_print_ops; } - -void obj_add_byte_array(struct json_object *o, const char *k, unsigned char *buf, int len) -{ - int i; - - _cleanup_free_ char *value = NULL; - - if (!buf || !len) { - obj_add_str(o, k, "No information provided"); - return; - } - - value = calloc(1, (len + 1) * 2 + 1); - - if (!value) { - obj_add_str(o, k, "Could not allocate string"); - return; - } - - sprintf(value, "0x"); - for (i = 1; i <= len; i++) - sprintf(&value[i * 2], "%02x", buf[len - i]); - - obj_add_str(o, k, value); -} - -void obj_add_0nprix64(struct json_object *o, const char *k, uint64_t v, int width) -{ - char str[STR_LEN]; - - sprintf(str, "0x%0*"PRIx64"", width, v); - obj_add_str(o, k, str); -} diff --git a/nvme-print.h b/nvme-print.h index 304d712a5a..00f19947c8 100644 --- a/nvme-print.h +++ b/nvme-print.h @@ -18,10 +18,6 @@ typedef struct nvme_effects_log_node { #define POWER_OF_TWO(exponent) (1 << (exponent)) -#define STR_LEN 100 - -#define obj_add_str json_object_add_value_string - void d(unsigned char *buf, int len, int width, int group); void d_raw(unsigned char *buf, unsigned len); @@ -329,12 +325,6 @@ bool nvme_registers_cmbloc_support(__u32 cmbsz); bool nvme_registers_pmrctl_ready(__u32 pmrctl); const char *nvme_degrees_string(long t); void print_array(char *name, __u8 *data, int size); -void obj_add_uint_02x(struct json_object *o, const char *k, __u32 v); void json_print(struct json_object *r); -void obj_add_uint_0x(struct json_object *o, const char *k, __u32 v); -void obj_add_byte_array(struct json_object *o, const char *k, unsigned char *buf, int len); -void obj_add_nprix64(struct json_object *o, const char *k, uint64_t v); struct json_object *obj_create_array_obj(struct json_object *o, const char *k); -void obj_add_uint_0nx(struct json_object *o, const char *k, __u32 v, int width); -void obj_add_0nprix64(struct json_object *o, const char *k, uint64_t v, int width); #endif /* NVME_PRINT_H */ diff --git a/nvme.h b/nvme.h index cae4345214..363a82d99d 100644 --- a/nvme.h +++ b/nvme.h @@ -31,6 +31,7 @@ #include "util/mem.h" #include "util/argconfig.h" #include "util/cleanup.h" +#include "util/types.h" enum nvme_print_flags { NORMAL = 0, @@ -147,7 +148,6 @@ const char *nvme_select_to_string(int sel); void d(unsigned char *buf, int len, int width, int group); void d_raw(unsigned char *buf, unsigned len); -uint64_t int48_to_long(uint8_t *data); int get_reg_size(int offset); bool nvme_is_ctrl_reg(int offset); diff --git a/plugins/ocp/ocp-fw-activation-history.h b/plugins/ocp/ocp-fw-activation-history.h index 15733a3fd5..fa37e4bd60 100644 --- a/plugins/ocp/ocp-fw-activation-history.h +++ b/plugins/ocp/ocp-fw-activation-history.h @@ -4,6 +4,7 @@ * * Authors: karl.dedow@solidigm.com */ +#include #include "common.h" #include "linux/types.h" @@ -18,7 +19,7 @@ struct __packed fw_activation_history_entry { __u8 entry_length; __le16 reserved1; __le16 activation_count; - __le64 timestamp; + struct nvme_timestamp ts; __le64 reserved2; __le64 power_cycle_count; char previous_fw[8]; diff --git a/plugins/ocp/ocp-print-json.c b/plugins/ocp/ocp-print-json.c index 17789cbd44..146dd0305e 100644 --- a/plugins/ocp/ocp-print-json.c +++ b/plugins/ocp/ocp-print-json.c @@ -11,15 +11,16 @@ static void print_hwcomp_desc_json(struct hwcomp_desc_entry *e, struct json_object *r) { - obj_add_str(r, "Description", hwcomp_id_to_string(le32_to_cpu(e->desc->id))); - obj_add_nprix64(r, "Date/Lot Size", e->date_lot_size); - obj_add_nprix64(r, "Additional Information Size", e->add_info_size); - obj_add_uint_0nx(r, "Identifier", le32_to_cpu(e->desc->id), 8); - obj_add_0nprix64(r, "Manufacture", le64_to_cpu(e->desc->mfg), 16); - obj_add_0nprix64(r, "Revision", le64_to_cpu(e->desc->rev), 16); - obj_add_0nprix64(r, "Manufacture Code", le64_to_cpu(e->desc->mfg_code), 16); - obj_add_byte_array(r, "Date/Lot Code", e->date_lot_code, e->date_lot_size); - obj_add_byte_array(r, "Additional Information", e->add_info, e->add_info_size); + json_object_add_value_string(r, "Description", + hwcomp_id_to_string(le32_to_cpu(e->desc->id))); + json_object_add_nprix64(r, "Date/Lot Size", e->date_lot_size); + json_object_add_nprix64(r, "Additional Information Size", e->add_info_size); + json_object_add_uint_0nx(r, "Identifier", le32_to_cpu(e->desc->id), 8); + json_object_add_0nprix64(r, "Manufacture", le64_to_cpu(e->desc->mfg), 16); + json_object_add_0nprix64(r, "Revision", le64_to_cpu(e->desc->rev), 16); + json_object_add_0nprix64(r, "Manufacture Code", le64_to_cpu(e->desc->mfg_code), 16); + json_object_add_byte_array(r, "Date/Lot Code", e->date_lot_code, e->date_lot_size); + json_object_add_byte_array(r, "Additional Information", e->add_info, e->add_info_size); } static void print_hwcomp_desc_list_json(struct json_object *r, struct hwcomp_desc_entry *e, @@ -31,7 +32,8 @@ static void print_hwcomp_desc_list_json(struct json_object *r, struct hwcomp_des return; if (list) { - obj_add_str(r, k, hwcomp_id_to_string(le32_to_cpu(e->desc->id))); + json_object_add_value_string(r, k, + hwcomp_id_to_string(le32_to_cpu(e->desc->id))); return; } @@ -69,12 +71,12 @@ static void json_hwcomp_log(struct hwcomp_log *log, __u32 id, bool list) if (log->ver == 1) log_size *= sizeof(__le32); - obj_add_uint_02x(r, "Log Identifier", LID_HWCOMP); - obj_add_uint_0x(r, "Log Page Version", le16_to_cpu(log->ver)); - obj_add_byte_array(r, "Reserved2", log->rsvd2, ARRAY_SIZE(log->rsvd2)); - obj_add_byte_array(r, "Log page GUID", log->guid, ARRAY_SIZE(log->guid)); - obj_add_nprix64(r, "Hardware Component Log Size", (unsigned long long)log_size); - obj_add_byte_array(r, "Reserved48", log->rsvd48, ARRAY_SIZE(log->rsvd48)); + json_object_add_uint_02x(r, "Log Identifier", LID_HWCOMP); + json_object_add_uint_0x(r, "Log Page Version", le16_to_cpu(log->ver)); + json_object_add_byte_array(r, "Reserved2", log->rsvd2, ARRAY_SIZE(log->rsvd2)); + json_object_add_byte_array(r, "Log page GUID", log->guid, ARRAY_SIZE(log->guid)); + json_object_add_nprix64(r, "Hardware Component Log Size", (unsigned long long)log_size); + json_object_add_byte_array(r, "Reserved48", log->rsvd48, ARRAY_SIZE(log->rsvd48)); print_hwcomp_descs_json(log->desc, log_size - offsetof(struct hwcomp_log, desc), id, list, obj_create_array_obj(r, "Component Descriptions")); @@ -99,7 +101,7 @@ static void json_fw_activation_history(const struct fw_activation_history *fw_hi json_object_add_value_uint(entry_obj, "activation count", le16_to_cpu(entry->activation_count)); json_object_add_value_uint64(entry_obj, "timestamp", - (0x0000FFFFFFFFFFFF & le64_to_cpu(entry->timestamp))); + int48_to_long(entry->ts.timestamp)); json_object_add_value_uint(entry_obj, "power cycle count", le64_to_cpu(entry->power_cycle_count)); @@ -150,21 +152,21 @@ static void json_smart_extended_log_v1(void *data) pmur = json_create_object(); json_object_add_value_uint64(pmuw, "hi", - (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUW + 8] & 0xFFFFFFFFFFFFFFFF)); + (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUW + 8])); json_object_add_value_uint64(pmuw, "lo", - (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUW] & 0xFFFFFFFFFFFFFFFF)); + (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUW])); json_object_add_value_object(root, "Physical media units written", pmuw); json_object_add_value_uint64(pmur, "hi", - (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUR + 8] & 0xFFFFFFFFFFFFFFFF)); + (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUR + 8])); json_object_add_value_uint64(pmur, "lo", - (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUR] & 0xFFFFFFFFFFFFFFFF)); + (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUR])); json_object_add_value_object(root, "Physical media units read", pmur); json_object_add_value_uint64(root, "Bad user nand blocks - Raw", - (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_BUNBR] & 0x0000FFFFFFFFFFFF)); + int48_to_long(&log_data[SCAO_BUNBR])); json_object_add_value_uint(root, "Bad user nand blocks - Normalized", (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_BUNBN])); json_object_add_value_uint64(root, "Bad system nand blocks - Raw", - (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_BSNBR] & 0x0000FFFFFFFFFFFF)); + int48_to_long(&log_data[SCAO_BSNBR])); json_object_add_value_uint(root, "Bad system nand blocks - Normalized", (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_BSNBN])); json_object_add_value_uint64(root, "XOR recovery count", @@ -179,8 +181,7 @@ static void json_smart_extended_log_v1(void *data) (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_EECE])); json_object_add_value_uint(root, "System data percent used", (__u8)log_data[SCAO_SDPU]); - json_object_add_value_uint64(root, "Refresh counts", - (uint64_t)(le64_to_cpu(*(uint64_t *)&log_data[SCAO_RFSC]) & 0x00FFFFFFFFFFFFFF)); + json_object_add_value_uint64(root, "Refresh counts", int56_to_long(&log_data[SCAO_RFSC])); json_object_add_value_uint(root, "Max User data erase counts", (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_MXUDEC])); json_object_add_value_uint(root, "Min User data erase counts", diff --git a/plugins/ocp/ocp-print-stdout.c b/plugins/ocp/ocp-print-stdout.c index f86c1b8428..5880104af6 100644 --- a/plugins/ocp/ocp-print-stdout.c +++ b/plugins/ocp/ocp-print-stdout.c @@ -75,8 +75,7 @@ static void stdout_fw_activation_history(const struct fw_activation_history *fw_ printf(" %-22s%d\n", "entry length:", entry->entry_length); printf(" %-22s%d\n", "activation count:", le16_to_cpu(entry->activation_count)); - printf(" %-22s%"PRIu64"\n", "timestamp:", - (0x0000FFFFFFFFFFFF & le64_to_cpu(entry->timestamp))); + printf(" %-22s%"PRIu64"\n", "timestamp:", int48_to_long(entry->ts.timestamp)); printf(" %-22s%"PRIu64"\n", "power cycle count:", le64_to_cpu(entry->power_cycle_count)); printf(" %-22s%.*s\n", "previous firmware:", (int)sizeof(entry->previous_fw), @@ -106,17 +105,17 @@ static void stdout_smart_extended_log(void *data, unsigned int version) printf("SMART Cloud Attributes :-\n"); printf(" Physical media units written - %"PRIu64" %"PRIu64"\n", - (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUW + 8] & 0xFFFFFFFFFFFFFFFF), - (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUW] & 0xFFFFFFFFFFFFFFFF)); + (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUW + 8]), + (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUW])); printf(" Physical media units read - %"PRIu64" %"PRIu64"\n", - (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUR + 8] & 0xFFFFFFFFFFFFFFFF), - (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUR] & 0xFFFFFFFFFFFFFFFF)); + (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUR + 8]), + (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUR])); printf(" Bad user nand blocks - Raw %"PRIu64"\n", - (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_BUNBR] & 0x0000FFFFFFFFFFFF)); + int48_to_long(&log_data[SCAO_BUNBR])); printf(" Bad user nand blocks - Normalized %d\n", (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_BUNBN])); printf(" Bad system nand blocks - Raw %"PRIu64"\n", - (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_BSNBR] & 0x0000FFFFFFFFFFFF)); + int48_to_long(&log_data[SCAO_BSNBR])); printf(" Bad system nand blocks - Normalized %d\n", (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_BSNBN])); printf(" XOR recovery count %"PRIu64"\n", @@ -132,7 +131,7 @@ static void stdout_smart_extended_log(void *data, unsigned int version) printf(" System data percent used %d\n", (__u8)log_data[SCAO_SDPU]); printf(" Refresh counts %"PRIu64"\n", - (uint64_t)(le64_to_cpu(*(uint64_t *)&log_data[SCAO_RFSC]) & 0x00FFFFFFFFFFFFFF)); + int56_to_long(&log_data[SCAO_RFSC])); printf(" Max User data erase counts %"PRIu32"\n", (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_MXUDEC])); printf(" Min User data erase counts %"PRIu32"\n", diff --git a/util/json.c b/util/json.c index 2de5848288..6c6413c348 100644 --- a/util/json.c +++ b/util/json.c @@ -4,6 +4,7 @@ #include "json.h" #include "types.h" +#include "cleanup.h" struct json_object *util_json_object_new_double(long double d) { @@ -72,3 +73,65 @@ uint64_t util_json_object_get_uint64(struct json_object *obj) return val; } + +void json_object_add_uint_02x(struct json_object *o, const char *k, __u32 v) +{ + json_object_add_uint_0nx(o, k, v, 2); +} + +void json_object_add_uint_0x(struct json_object *o, const char *k, __u32 v) +{ + char str[STR_LEN]; + + sprintf(str, "0x%x", v); + json_object_add_value_string(o, k, str); +} + +void json_object_add_byte_array(struct json_object *o, const char *k, unsigned char *buf, int len) +{ + int i; + + _cleanup_free_ char *value = NULL; + + if (!buf || !len) { + json_object_add_value_string(o, k, "No information provided"); + return; + } + + value = calloc(1, (len + 1) * 2 + 1); + + if (!value) { + json_object_add_value_string(o, k, "Could not allocate string"); + return; + } + + sprintf(value, "0x"); + for (i = 1; i <= len; i++) + sprintf(&value[i * 2], "%02x", buf[len - i]); + + json_object_add_value_string(o, k, value); +} + +void json_object_add_nprix64(struct json_object *o, const char *k, uint64_t v) +{ + char str[STR_LEN]; + + sprintf(str, "%#"PRIx64"", v); + json_object_add_value_string(o, k, str); +} + +void json_object_add_uint_0nx(struct json_object *o, const char *k, __u32 v, int width) +{ + char str[STR_LEN]; + + sprintf(str, "0x%0*x", width, v); + json_object_add_value_string(o, k, str); +} + +void json_object_add_0nprix64(struct json_object *o, const char *k, uint64_t v, int width) +{ + char str[STR_LEN]; + + sprintf(str, "0x%0*"PRIx64"", width, v); + json_object_add_value_string(o, k, str); +} diff --git a/util/json.h b/util/json.h index b98d8a9b61..da4d7a4586 100644 --- a/util/json.h +++ b/util/json.h @@ -72,4 +72,13 @@ struct json_object; #define json_object_add_value_array(o, k, v) json_object_object_add(o, k, v) #define json_object_add_value_object(o, k, v) json_object_object_add(o, k, v) +#define STR_LEN 100 + +void json_object_add_uint_02x(struct json_object *o, const char *k, __u32 v); +void json_object_add_uint_0x(struct json_object *o, const char *k, __u32 v); +void json_object_add_byte_array(struct json_object *o, const char *k, unsigned char *buf, int len); +void json_object_add_nprix64(struct json_object *o, const char *k, uint64_t v); +void json_object_add_uint_0nx(struct json_object *o, const char *k, __u32 v, int width); +void json_object_add_0nprix64(struct json_object *o, const char *k, uint64_t v, int width); + #endif /* __JSON__H */ diff --git a/util/types.c b/util/types.c index 20c121b1a6..a34479a551 100644 --- a/util/types.c +++ b/util/types.c @@ -5,6 +5,7 @@ #include #include #include +#include #include @@ -36,18 +37,30 @@ long double int128_to_double(__u8 *data) return result; } -uint64_t int48_to_long(__u8 *data) +static uint64_t int_to_long(int bits, const __u8 *data) { int i; uint64_t result = 0; + int bytes = (bits + CHAR_BIT - 1) / CHAR_BIT; - for (i = 0; i < 6; i++) { - result *= 256; - result += data[5 - i]; + for (i = 0; i < bytes; i++) { + result <<= CHAR_BIT; + result += data[bytes - 1 - i]; } + return result; } +uint64_t int48_to_long(const __u8 *data) +{ + return int_to_long(48, data); +} + +uint64_t int56_to_long(const __u8 *data) +{ + return int_to_long(56, data); +} + long double uint128_t_to_double(nvme_uint128_t data) { long double result = 0; diff --git a/util/types.h b/util/types.h index b2e8fc8df5..70a7760707 100644 --- a/util/types.h +++ b/util/types.h @@ -36,7 +36,8 @@ typedef union nvme_uint128 nvme_uint128_t; nvme_uint128_t le128_to_cpu(__u8 *data); long double int128_to_double(__u8 *data); -uint64_t int48_to_long(__u8 *data); +uint64_t int48_to_long(const __u8 *data); +uint64_t int56_to_long(const __u8 *data); char *uint128_t_to_string(nvme_uint128_t val); char *uint128_t_to_l10n_string(nvme_uint128_t val);