diff --git a/SOURCES/0001-dmidecode-Print-type-33-name-unconditionally.patch b/SOURCES/0001-dmidecode-Print-type-33-name-unconditionally.patch new file mode 100644 index 0000000..1467d9b --- /dev/null +++ b/SOURCES/0001-dmidecode-Print-type-33-name-unconditionally.patch @@ -0,0 +1,30 @@ +From 65438a7ec0f4cddccf810136da6f280bd148af71 Mon Sep 17 00:00:00 2001 +From: Jean Delvare +Date: Mon, 23 Mar 2020 16:47:20 +0100 +Subject: [PATCH 01/23] dmidecode: Print type 33 name unconditionally + +Even if a type 33 structure is too short, we can still display its +type name as we do for all other structure types. + +Signed-off-by: Jean Delvare +--- + dmidecode.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/dmidecode.c b/dmidecode.c +index 8ebd8626d6ea..71c166f0595d 100644 +--- a/dmidecode.c ++++ b/dmidecode.c +@@ -4807,8 +4807,8 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + break; + + case 33: /* 7.34 64-bit Memory Error Information */ +- if (h->length < 0x1F) break; + printf("64-bit Memory Error Information\n"); ++ if (h->length < 0x1F) break; + printf("\tType: %s\n", + dmi_memory_error_type(data[0x04])); + printf("\tGranularity: %s\n", +-- +2.17.1 + diff --git a/SOURCES/0002-dmidecode-Don-t-choke-on-invalid-processor-voltage.patch b/SOURCES/0002-dmidecode-Don-t-choke-on-invalid-processor-voltage.patch new file mode 100644 index 0000000..d886ab2 --- /dev/null +++ b/SOURCES/0002-dmidecode-Don-t-choke-on-invalid-processor-voltage.patch @@ -0,0 +1,37 @@ +From 5bb7eb173b72256f70c6b3f3916d7a444be93340 Mon Sep 17 00:00:00 2001 +From: Jean Delvare +Date: Mon, 23 Mar 2020 16:47:23 +0100 +Subject: [PATCH 02/23] dmidecode: Don't choke on invalid processor voltage + +If the processor voltage encoding has some of the reserved bits set +and none of the proper bits set, print it as "Unknown" instead of an +empty field. + +Signed-off-by: Jean Delvare +--- + dmidecode.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/dmidecode.c b/dmidecode.c +index 71c166f0595d..ef9bbd54b7f8 100644 +--- a/dmidecode.c ++++ b/dmidecode.c +@@ -1190,13 +1190,13 @@ static void dmi_processor_voltage(u8 code) + + if (code & 0x80) + printf(" %.1f V", (float)(code & 0x7f) / 10); ++ else if ((code & 0x07) == 0x00) ++ printf(" Unknown"); + else + { + for (i = 0; i <= 2; i++) + if (code & (1 << i)) + printf(" %s", voltage[i]); +- if (code == 0x00) +- printf(" Unknown"); + } + } + +-- +2.17.1 + diff --git a/SOURCES/0003-dmidecode-Simplify-the-formatting-of-memory-error-st.patch b/SOURCES/0003-dmidecode-Simplify-the-formatting-of-memory-error-st.patch new file mode 100644 index 0000000..5c3c0c3 --- /dev/null +++ b/SOURCES/0003-dmidecode-Simplify-the-formatting-of-memory-error-st.patch @@ -0,0 +1,58 @@ +From 1347ccca96db6e157af39fcc565466fa98b9220b Mon Sep 17 00:00:00 2001 +From: Jean Delvare +Date: Mon, 23 Mar 2020 16:47:27 +0100 +Subject: [PATCH 03/23] dmidecode: Simplify the formatting of memory error + status + +Make the logic more simple so that we always report the status on a +single line. + +Signed-off-by: Jean Delvare +--- + dmidecode.c | 19 ++++++++++--------- + 1 file changed, 10 insertions(+), 9 deletions(-) + +diff --git a/dmidecode.c b/dmidecode.c +index ef9bbd54b7f8..5a0631e926c7 100644 +--- a/dmidecode.c ++++ b/dmidecode.c +@@ -1515,18 +1515,19 @@ static void dmi_memory_module_size(u8 code) + printf(" (Single-bank Connection)"); + } + +-static void dmi_memory_module_error(u8 code, const char *prefix) ++static void dmi_memory_module_error(u8 code) + { ++ static const char *status[] = { ++ "OK", /* 0x00 */ ++ "Uncorrectable Errors", ++ "Correctable Errors", ++ "Correctable and Uncorrectable Errors" /* 0x03 */ ++ }; ++ + if (code & (1 << 2)) + printf(" See Event Log\n"); + else +- { if ((code & 0x03) == 0) +- printf(" OK\n"); +- if (code & (1 << 0)) +- printf("%sUncorrectable Errors\n", prefix); +- if (code & (1 << 1)) +- printf("%sCorrectable Errors\n", prefix); +- } ++ printf(" %s\n", status[code & 0x03]); + } + + /* +@@ -4142,7 +4143,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + dmi_memory_module_size(data[0x0A]); + printf("\n"); + printf("\tError Status:"); +- dmi_memory_module_error(data[0x0B], "\t\t"); ++ dmi_memory_module_error(data[0x0B]); + break; + + case 7: /* 7.8 Cache Information */ +-- +2.17.1 + diff --git a/SOURCES/0004-dmidecode-Fix-the-alignment-of-type-25-name.patch b/SOURCES/0004-dmidecode-Fix-the-alignment-of-type-25-name.patch new file mode 100644 index 0000000..78d1caf --- /dev/null +++ b/SOURCES/0004-dmidecode-Fix-the-alignment-of-type-25-name.patch @@ -0,0 +1,28 @@ +From 557c3c373a9992d45d4358a6a2ccf53b03276f39 Mon Sep 17 00:00:00 2001 +From: Jean Delvare +Date: Mon, 23 Mar 2020 16:47:30 +0100 +Subject: [PATCH 04/23] dmidecode: Fix the alignment of type 25 name + +No tabulation needed before DMI structure names. + +Signed-off-by: Jean Delvare +--- + dmidecode.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/dmidecode.c b/dmidecode.c +index 5a0631e926c7..b459ed0ff84e 100644 +--- a/dmidecode.c ++++ b/dmidecode.c +@@ -4651,7 +4651,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + break; + + case 25: /* 7.26 System Power Controls */ +- printf("\tSystem Power Controls\n"); ++ printf("System Power Controls\n"); + if (h->length < 0x09) break; + printf("\tNext Scheduled Power-on:"); + dmi_power_controls_power_on(data + 0x04); +-- +2.17.1 + diff --git a/SOURCES/0005-dmidecode-Code-indentation-fixes.patch b/SOURCES/0005-dmidecode-Code-indentation-fixes.patch new file mode 100644 index 0000000..c3a481f --- /dev/null +++ b/SOURCES/0005-dmidecode-Code-indentation-fixes.patch @@ -0,0 +1,35 @@ +From 37a856266e4fb2f85bd8f2f269db8bcfb1962eb0 Mon Sep 17 00:00:00 2001 +From: Jean Delvare +Date: Mon, 23 Mar 2020 16:47:33 +0100 +Subject: [PATCH 05/23] dmidecode: Code indentation fixes + +Signed-off-by: Jean Delvare +--- + dmidecode.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/dmidecode.c b/dmidecode.c +index b459ed0ff84e..0d95cf9d8f7b 100644 +--- a/dmidecode.c ++++ b/dmidecode.c +@@ -3588,7 +3588,7 @@ static void dmi_parse_protocol_record(const char *prefix, u8 *rec) + printf("%s\t\tHost IP Assignment Type: %s\n", prefix, + dmi_protocol_assignment_type(assign_val)); + +- /* DSP0270: 8.6: Redfish Over IP Host Address format */ ++ /* DSP0270: 8.6: Redfish Over IP Host Address format */ + addrtype = rdata[17]; + addrstr = dmi_address_type(addrtype); + printf("%s\t\tHost IP Address Format: %s\n", prefix, +@@ -4856,7 +4856,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + WORD(data + 0x07)); + if (WORD(data + 0x09) != 0xFFFF) + printf("\tThreshold Handle: 0x%04X\n", +- WORD(data + 0x09)); ++ WORD(data + 0x09)); + } + break; + +-- +2.17.1 + diff --git a/SOURCES/0006-dmidecode-Reduce-the-indentation-of-type-42-structur.patch b/SOURCES/0006-dmidecode-Reduce-the-indentation-of-type-42-structur.patch new file mode 100644 index 0000000..67bb30e --- /dev/null +++ b/SOURCES/0006-dmidecode-Reduce-the-indentation-of-type-42-structur.patch @@ -0,0 +1,161 @@ +From 61f3f163b98b271c6613b9744128b99f33e6e19e Mon Sep 17 00:00:00 2001 +From: Jean Delvare +Date: Mon, 23 Mar 2020 16:47:37 +0100 +Subject: [PATCH 06/23] dmidecode: Reduce the indentation of type 42 structures + +There is no reason to indent the device information that much in type +42 structures. Remove the extra level of indentation for consistency +and readability. + +Signed-off-by: Jean Delvare +--- + dmidecode.c | 40 ++++++++++++++++++++-------------------- + 1 file changed, 20 insertions(+), 20 deletions(-) + +diff --git a/dmidecode.c b/dmidecode.c +index 0d95cf9d8f7b..fc140e7e36a9 100644 +--- a/dmidecode.c ++++ b/dmidecode.c +@@ -3545,7 +3545,7 @@ static void dmi_parse_protocol_record(const char *prefix, u8 *rec) + /* DSP0270: 8.5: Protocol Record Data */ + rdata = &rec[0x2]; + +- printf("%s\tProtocol ID: %02x (%s)\n", prefix, rid, ++ printf("%sProtocol ID: %02x (%s)\n", prefix, rid, + dmi_protocol_record_type(rid)); + + /* +@@ -3575,7 +3575,7 @@ static void dmi_parse_protocol_record(const char *prefix, u8 *rec) + * endianess of the field is always little after version 2.6.0 + * we can just pick a sufficiently recent version here. + */ +- printf("%s\t\tService UUID: ", prefix); ++ printf("%s\tService UUID: ", prefix); + dmi_system_uuid(&rdata[0], 0x311); + printf("\n"); + +@@ -3585,13 +3585,13 @@ static void dmi_parse_protocol_record(const char *prefix, u8 *rec) + * uses decimal, so as to make it more comparable + */ + assign_val = rdata[16]; +- printf("%s\t\tHost IP Assignment Type: %s\n", prefix, ++ printf("%s\tHost IP Assignment Type: %s\n", prefix, + dmi_protocol_assignment_type(assign_val)); + + /* DSP0270: 8.6: Redfish Over IP Host Address format */ + addrtype = rdata[17]; + addrstr = dmi_address_type(addrtype); +- printf("%s\t\tHost IP Address Format: %s\n", prefix, ++ printf("%s\tHost IP Address Format: %s\n", prefix, + addrstr); + + /* DSP0270: 8.6 IP Assignment types */ +@@ -3599,24 +3599,24 @@ static void dmi_parse_protocol_record(const char *prefix, u8 *rec) + if (assign_val == 0x1 || assign_val == 0x3) + { + /* DSP0270: 8.6: the Host IPv[4|6] Address */ +- printf("%s\t\t%s Address: %s\n", prefix, addrstr, ++ printf("%s\t%s Address: %s\n", prefix, addrstr, + dmi_address_decode(&rdata[18], buf, addrtype)); + + /* DSP0270: 8.6: Prints the Host IPv[4|6] Mask */ +- printf("%s\t\t%s Mask: %s\n", prefix, addrstr, ++ printf("%s\t%s Mask: %s\n", prefix, addrstr, + dmi_address_decode(&rdata[34], buf, addrtype)); + } + + /* DSP0270: 8.6: Get the Redfish Service IP Discovery Type */ + assign_val = rdata[50]; + /* Redfish Service IP Discovery type mirrors Host IP Assignment type */ +- printf("%s\t\tRedfish Service IP Discovery Type: %s\n", prefix, ++ printf("%s\tRedfish Service IP Discovery Type: %s\n", prefix, + dmi_protocol_assignment_type(assign_val)); + + /* DSP0270: 8.6: Get the Redfish Service IP Address Format */ + addrtype = rdata[51]; + addrstr = dmi_address_type(addrtype); +- printf("%s\t\tRedfish Service IP Address Format: %s\n", prefix, ++ printf("%s\tRedfish Service IP Address Format: %s\n", prefix, + addrstr); + + if (assign_val == 0x1 || assign_val == 0x3) +@@ -3625,20 +3625,20 @@ static void dmi_parse_protocol_record(const char *prefix, u8 *rec) + u32 vlan; + + /* DSP0270: 8.6: Prints the Redfish IPv[4|6] Service Address */ +- printf("%s\t\t%s Redfish Service Address: %s\n", prefix, ++ printf("%s\t%s Redfish Service Address: %s\n", prefix, + addrstr, dmi_address_decode(&rdata[52], buf, + addrtype)); + + /* DSP0270: 8.6: Prints the Redfish IPv[4|6] Service Mask */ +- printf("%s\t\t%s Redfish Service Mask: %s\n", prefix, ++ printf("%s\t%s Redfish Service Mask: %s\n", prefix, + addrstr, dmi_address_decode(&rdata[68], buf, + addrtype)); + + /* DSP0270: 8.6: Redfish vlan and port info */ + port = WORD(&rdata[84]); + vlan = DWORD(&rdata[86]); +- printf("%s\t\tRedfish Service Port: %hu\n", prefix, port); +- printf("%s\t\tRedfish Service Vlan: %u\n", prefix, vlan); ++ printf("%s\tRedfish Service Port: %hu\n", prefix, port); ++ printf("%s\tRedfish Service Vlan: %u\n", prefix, vlan); + } + + /* DSP0270: 8.6: Redfish host length and name */ +@@ -3655,7 +3655,7 @@ static void dmi_parse_protocol_record(const char *prefix, u8 *rec) + hname = out_of_spec; + hlen = strlen(out_of_spec); + } +- printf("%s\t\tRedfish Service Hostname: %.*s\n", prefix, hlen, hname); ++ printf("%s\tRedfish Service Hostname: %.*s\n", prefix, hlen, hname); + } + + /* +@@ -3728,10 +3728,10 @@ static void dmi_parse_controller_structure(const struct dmi_header *h, + /* USB Device Type - need at least 6 bytes */ + u8 *usbdata = &data[0x7]; + /* USB Device Descriptor: idVendor */ +- printf("%s\tidVendor: 0x%04x\n", prefix, ++ printf("%sidVendor: 0x%04x\n", prefix, + WORD(&usbdata[0x0])); + /* USB Device Descriptor: idProduct */ +- printf("%s\tidProduct: 0x%04x\n", prefix, ++ printf("%sidProduct: 0x%04x\n", prefix, + WORD(&usbdata[0x2])); + /* + * USB Serial number is here, but its useless, don't +@@ -3743,16 +3743,16 @@ static void dmi_parse_controller_structure(const struct dmi_header *h, + /* PCI Device Type - Need at least 8 bytes */ + u8 *pcidata = &data[0x7]; + /* PCI Device Descriptor: VendorID */ +- printf("%s\tVendorID: 0x%04x\n", prefix, ++ printf("%sVendorID: 0x%04x\n", prefix, + WORD(&pcidata[0x0])); + /* PCI Device Descriptor: DeviceID */ +- printf("%s\tDeviceID: 0x%04x\n", prefix, ++ printf("%sDeviceID: 0x%04x\n", prefix, + WORD(&pcidata[0x2])); + /* PCI Device Descriptor: PCI SubvendorID */ +- printf("%s\tSubVendorID: 0x%04x\n", prefix, ++ printf("%sSubVendorID: 0x%04x\n", prefix, + WORD(&pcidata[0x4])); + /* PCI Device Descriptor: PCI SubdeviceID */ +- printf("%s\tSubDeviceID: 0x%04x\n", prefix, ++ printf("%sSubDeviceID: 0x%04x\n", prefix, + WORD(&pcidata[0x6])); + } + else if (type == 0x4 && len >= 5) +@@ -3760,7 +3760,7 @@ static void dmi_parse_controller_structure(const struct dmi_header *h, + /* OEM Device Type - Need at least 4 bytes */ + u8 *oemdata = &data[0x7]; + /* OEM Device Descriptor: IANA */ +- printf("%s\tVendor ID: 0x%02x:0x%02x:0x%02x:0x%02x\n", ++ printf("%sVendor ID: 0x%02x:0x%02x:0x%02x:0x%02x\n", + prefix, oemdata[0x0], oemdata[0x1], + oemdata[0x2], oemdata[0x3]); + } +-- +2.17.1 + diff --git a/SOURCES/0007-dmidecode-Move-type-42-warning-messages-to-stderr.patch b/SOURCES/0007-dmidecode-Move-type-42-warning-messages-to-stderr.patch new file mode 100644 index 0000000..bcae831 --- /dev/null +++ b/SOURCES/0007-dmidecode-Move-type-42-warning-messages-to-stderr.patch @@ -0,0 +1,47 @@ +From 30121a064378b2c0174659cd52449c70aa2c271f Mon Sep 17 00:00:00 2001 +From: Jean Delvare +Date: Mon, 23 Mar 2020 16:47:40 +0100 +Subject: [PATCH 07/23] dmidecode: Move type 42 warning messages to stderr + +Write warning messages about invalid type 42 structures to stderr as +we do for all other warning messages. + +Also include the handle and record numbers in these warning messages +to make the problem easier to analyze. + +Signed-off-by: Jean Delvare +--- + dmidecode.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/dmidecode.c b/dmidecode.c +index fc140e7e36a9..50fd0bffa26d 100644 +--- a/dmidecode.c ++++ b/dmidecode.c +@@ -3780,8 +3780,9 @@ static void dmi_parse_controller_structure(const struct dmi_header *h, + total_read++; + if (total_read > h->length) + { +- printf("%s\tWARN: Total read length %d exceeds total structure length %d\n", +- prefix, total_read, h->length); ++ fprintf(stderr, ++ "Total read length %d exceeds total structure length %d (handle 0x%04hx)\n", ++ total_read, h->length, h->handle); + return; + } + +@@ -3801,8 +3802,9 @@ static void dmi_parse_controller_structure(const struct dmi_header *h, + total_read += rec[1] + 2; + if (total_read > h->length) + { +- printf("%s\tWARN: Total read length %d exceeds total structure length %d\n", +- prefix, total_read, h->length); ++ fprintf(stderr, ++ "Total read length %d exceeds total structure length %d (handle 0x%04hx, record %d)\n", ++ total_read, h->length, h->handle, i + 1); + return; + } + +-- +2.17.1 + diff --git a/SOURCES/0008-dmidecode-Refactor-ASCII-filtering-of-DMI-strings.patch b/SOURCES/0008-dmidecode-Refactor-ASCII-filtering-of-DMI-strings.patch new file mode 100644 index 0000000..db25961 --- /dev/null +++ b/SOURCES/0008-dmidecode-Refactor-ASCII-filtering-of-DMI-strings.patch @@ -0,0 +1,122 @@ +From 26a66d708c6caef09912245c93371ec96c1e0cbd Mon Sep 17 00:00:00 2001 +From: Jean Delvare +Date: Mon, 23 Mar 2020 16:47:44 +0100 +Subject: [PATCH 08/23] dmidecode: Refactor ASCII filtering of DMI strings + +Split dmi_string into 3 functions to make it more modular. ASCII +filtering is an explicit option now to give the caller more control. + +Use the new functions in dmi_dump to avoid reimplementing the ASCII +filtering and printing characters one by one. + +Signed-off-by: Jean Delvare +--- + dmidecode.c | 60 ++++++++++++++++++++++++++++------------------------- + 1 file changed, 32 insertions(+), 28 deletions(-) + +diff --git a/dmidecode.c b/dmidecode.c +index 50fd0bffa26d..8ec1d6b9597a 100644 +--- a/dmidecode.c ++++ b/dmidecode.c +@@ -109,13 +109,19 @@ int is_printable(const u8 *data, int len) + return 1; + } + +-const char *dmi_string(const struct dmi_header *dm, u8 s) ++/* Replace non-ASCII characters with dots */ ++static void ascii_filter(char *bp, size_t len) + { +- char *bp = (char *)dm->data; +- size_t i, len; ++ size_t i; + +- if (s == 0) +- return "Not Specified"; ++ for (i = 0; i < len; i++) ++ if (bp[i] < 32 || bp[i] == 127) ++ bp[i] = '.'; ++} ++ ++static char *_dmi_string(const struct dmi_header *dm, u8 s, int filter) ++{ ++ char *bp = (char *)dm->data; + + bp += dm->length; + while (s > 1 && *bp) +@@ -126,16 +132,24 @@ const char *dmi_string(const struct dmi_header *dm, u8 s) + } + + if (!*bp) +- return bad_index; ++ return NULL; + +- if (!(opt.flags & FLAG_DUMP)) +- { +- /* ASCII filtering */ +- len = strlen(bp); +- for (i = 0; i < len; i++) +- if (bp[i] < 32 || bp[i] == 127) +- bp[i] = '.'; +- } ++ if (filter) ++ ascii_filter(bp, strlen(bp)); ++ ++ return bp; ++} ++ ++const char *dmi_string(const struct dmi_header *dm, u8 s) ++{ ++ char *bp; ++ ++ if (s == 0) ++ return "Not Specified"; ++ ++ bp = _dmi_string(dm, s, 1); ++ if (bp == NULL) ++ return bad_index; + + return bp; + } +@@ -208,7 +222,7 @@ static int dmi_bcd_range(u8 value, u8 low, u8 high) + static void dmi_dump(const struct dmi_header *h, const char *prefix) + { + int row, i; +- const char *s; ++ char *s; + + printf("%sHeader and Data:\n", prefix); + for (row = 0; row < ((h->length - 1) >> 4) + 1; row++) +@@ -224,7 +238,7 @@ static void dmi_dump(const struct dmi_header *h, const char *prefix) + { + printf("%sStrings:\n", prefix); + i = 1; +- while ((s = dmi_string(h, i++)) != bad_index) ++ while ((s = _dmi_string(h, i++, !(opt.flags & FLAG_DUMP)))) + { + if (opt.flags & FLAG_DUMP) + { +@@ -238,19 +252,9 @@ static void dmi_dump(const struct dmi_header *h, const char *prefix) + printf("\n"); + } + /* String isn't filtered yet so do it now */ +- printf("%s\t\"", prefix); +- while (*s) +- { +- if (*s < 32 || *s == 127) +- fputc('.', stdout); +- else +- fputc(*s, stdout); +- s++; +- } +- printf("\"\n"); ++ ascii_filter(s, l - 1); + } +- else +- printf("%s\t%s\n", prefix, s); ++ printf("%s\t%s\n", prefix, s); + } + } + } +-- +2.17.1 + diff --git a/SOURCES/0009-dmidecode-Add-helper-function-pr_comment.patch b/SOURCES/0009-dmidecode-Add-helper-function-pr_comment.patch new file mode 100644 index 0000000..1eb9e8b --- /dev/null +++ b/SOURCES/0009-dmidecode-Add-helper-function-pr_comment.patch @@ -0,0 +1,214 @@ +From 2241f1dd232fe8e1d57fdb2482ad417ebe23279e Mon Sep 17 00:00:00 2001 +From: Jean Delvare +Date: Wed, 1 Apr 2020 09:51:46 +0200 +Subject: [PATCH 09/23] dmidecode: Add helper function pr_comment + +Print all comments through a helper function pr_comment. + +Signed-off-by: Jean Delvare +--- + Makefile | 7 +++++-- + dmidecode.c | 33 +++++++++++++++++---------------- + dmioutput.c | 35 +++++++++++++++++++++++++++++++++++ + dmioutput.h | 22 ++++++++++++++++++++++ + 4 files changed, 79 insertions(+), 18 deletions(-) + create mode 100644 dmioutput.c + create mode 100644 dmioutput.h + +diff --git a/Makefile b/Makefile +index 77c931091b0f..5d58266ef2de 100644 +--- a/Makefile ++++ b/Makefile +@@ -61,8 +61,8 @@ all : $(PROGRAMS) + # Programs + # + +-dmidecode : dmidecode.o dmiopt.o dmioem.o util.o +- $(CC) $(LDFLAGS) dmidecode.o dmiopt.o dmioem.o util.o -o $@ ++dmidecode : dmidecode.o dmiopt.o dmioem.o dmioutput.o util.o ++ $(CC) $(LDFLAGS) dmidecode.o dmiopt.o dmioem.o dmioutput.o util.o -o $@ + + biosdecode : biosdecode.o util.o + $(CC) $(LDFLAGS) biosdecode.o util.o -o $@ +@@ -87,6 +87,9 @@ dmiopt.o : dmiopt.c config.h types.h util.h dmidecode.h dmiopt.h + dmioem.o : dmioem.c types.h dmidecode.h dmioem.h + $(CC) $(CFLAGS) -c $< -o $@ + ++dmioutput.o : dmioutput.c types.h dmioutput.h ++ $(CC) $(CFLAGS) -c $< -o $@ ++ + biosdecode.o : biosdecode.c version.h types.h util.h config.h + $(CC) $(CFLAGS) -c $< -o $@ + +diff --git a/dmidecode.c b/dmidecode.c +index 8ec1d6b9597a..2939b2d307fc 100644 +--- a/dmidecode.c ++++ b/dmidecode.c +@@ -80,6 +80,7 @@ + #include "dmidecode.h" + #include "dmiopt.h" + #include "dmioem.h" ++#include "dmioutput.h" + + #define out_of_spec "" + static const char *bad_index = ""; +@@ -5162,7 +5163,7 @@ static void dmi_table_string(const struct dmi_header *h, const u8 *data, u16 ver + static void dmi_table_dump(const u8 *buf, u32 len) + { + if (!(opt.flags & FLAG_QUIET)) +- printf("# Writing %d bytes to %s.\n", len, opt.dumpfile); ++ pr_comment("Writing %d bytes to %s.", len, opt.dumpfile); + write_dump(32, len, buf, opt.dumpfile, 0); + } + +@@ -5283,11 +5284,11 @@ static void dmi_table(off_t base, u32 len, u16 num, u32 ver, const char *devmem, + + if (ver > SUPPORTED_SMBIOS_VER && !(opt.flags & FLAG_QUIET)) + { +- printf("# SMBIOS implementations newer than version %u.%u.%u are not\n" +- "# fully supported by this version of dmidecode.\n", +- SUPPORTED_SMBIOS_VER >> 16, +- (SUPPORTED_SMBIOS_VER >> 8) & 0xFF, +- SUPPORTED_SMBIOS_VER & 0xFF); ++ pr_comment("SMBIOS implementations newer than version %u.%u.%u are not", ++ SUPPORTED_SMBIOS_VER >> 16, ++ (SUPPORTED_SMBIOS_VER >> 8) & 0xFF, ++ SUPPORTED_SMBIOS_VER & 0xFF); ++ pr_comment("fully supported by this version of dmidecode."); + } + + if (!(opt.flags & FLAG_QUIET)) +@@ -5417,8 +5418,8 @@ static int smbios3_decode(u8 *buf, const char *devmem, u32 flags) + overwrite_smbios3_address(crafted); + + if (!(opt.flags & FLAG_QUIET)) +- printf("# Writing %d bytes to %s.\n", crafted[0x06], +- opt.dumpfile); ++ pr_comment("Writing %d bytes to %s.", crafted[0x06], ++ opt.dumpfile); + write_dump(0, crafted[0x06], crafted, opt.dumpfile, 1); + } + +@@ -5478,8 +5479,8 @@ static int smbios_decode(u8 *buf, const char *devmem, u32 flags) + overwrite_dmi_address(crafted + 0x10); + + if (!(opt.flags & FLAG_QUIET)) +- printf("# Writing %d bytes to %s.\n", crafted[0x05], +- opt.dumpfile); ++ pr_comment("Writing %d bytes to %s.", crafted[0x05], ++ opt.dumpfile); + write_dump(0, crafted[0x05], crafted, opt.dumpfile, 1); + } + +@@ -5507,8 +5508,8 @@ static int legacy_decode(u8 *buf, const char *devmem, u32 flags) + overwrite_dmi_address(crafted); + + if (!(opt.flags & FLAG_QUIET)) +- printf("# Writing %d bytes to %s.\n", 0x0F, +- opt.dumpfile); ++ pr_comment("Writing %d bytes to %s.", 0x0F, ++ opt.dumpfile); + write_dump(0, 0x0F, crafted, opt.dumpfile, 1); + } + +@@ -5586,8 +5587,8 @@ static int address_from_efi(off_t *address) + #endif + + if (ret == 0 && !(opt.flags & FLAG_QUIET)) +- printf("# %s entry point at 0x%08llx\n", +- eptype, (unsigned long long)*address); ++ pr_comment("%s entry point at 0x%08llx", ++ eptype, (unsigned long long)*address); + + return ret; + } +@@ -5638,7 +5639,7 @@ int main(int argc, char * const argv[]) + } + + if (!(opt.flags & FLAG_QUIET)) +- printf("# dmidecode %s\n", VERSION); ++ pr_comment("dmidecode %s", VERSION); + + /* Read from dump if so instructed */ + if (opt.flags & FLAG_FROM_DUMP) +@@ -5783,7 +5784,7 @@ int main(int argc, char * const argv[]) + + done: + if (!found && !(opt.flags & FLAG_QUIET)) +- printf("# No SMBIOS nor DMI entry point found, sorry.\n"); ++ pr_comment("No SMBIOS nor DMI entry point found, sorry."); + + free(buf); + exit_free: +diff --git a/dmioutput.c b/dmioutput.c +new file mode 100644 +index 000000000000..e762a035f39d +--- /dev/null ++++ b/dmioutput.c +@@ -0,0 +1,35 @@ ++/* ++ * Generic output functions ++ * This file is part of the dmidecode project. ++ * ++ * Copyright (C) 2020 Jean Delvare ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++#include ++#include ++#include "dmioutput.h" ++ ++void pr_comment(const char *format, ...) ++{ ++ va_list args; ++ ++ printf("# "); ++ va_start(args, format); ++ vprintf(format, args); ++ va_end(args); ++ printf("\n"); ++} +diff --git a/dmioutput.h b/dmioutput.h +new file mode 100644 +index 000000000000..b6cf5ee8b60e +--- /dev/null ++++ b/dmioutput.h +@@ -0,0 +1,22 @@ ++/* ++ * Generic output functions ++ * This file is part of the dmidecode project. ++ * ++ * Copyright (C) 2020 Jean Delvare ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++void pr_comment(const char *format, ...); +-- +2.17.1 + diff --git a/SOURCES/0010-dmidecode-Add-helper-function-pr_info.patch b/SOURCES/0010-dmidecode-Add-helper-function-pr_info.patch new file mode 100644 index 0000000..547e0cc --- /dev/null +++ b/SOURCES/0010-dmidecode-Add-helper-function-pr_info.patch @@ -0,0 +1,142 @@ +From dd593d2f0c7272658070208d0a6957d77fc7e6f2 Mon Sep 17 00:00:00 2001 +From: Jean Delvare +Date: Wed, 1 Apr 2020 09:51:51 +0200 +Subject: [PATCH 10/23] dmidecode: Add helper function pr_info + +Print all info messages through a helper function pr_info. + +Signed-off-by: Jean Delvare +--- + dmidecode.c | 30 +++++++++++++++--------------- + dmioutput.c | 10 ++++++++++ + dmioutput.h | 1 + + 3 files changed, 26 insertions(+), 15 deletions(-) + +diff --git a/dmidecode.c b/dmidecode.c +index 2939b2d307fc..e3f6e300efc2 100644 +--- a/dmidecode.c ++++ b/dmidecode.c +@@ -5296,11 +5296,11 @@ static void dmi_table(off_t base, u32 len, u16 num, u32 ver, const char *devmem, + if (opt.type == NULL) + { + if (num) +- printf("%u structures occupying %u bytes.\n", +- num, len); ++ pr_info("%u structures occupying %u bytes.", ++ num, len); + if (!(opt.flags & FLAG_FROM_DUMP)) +- printf("Table at 0x%08llX.\n", +- (unsigned long long)base); ++ pr_info("Table at 0x%08llX.", ++ (unsigned long long)base); + } + printf("\n"); + } +@@ -5397,8 +5397,8 @@ static int smbios3_decode(u8 *buf, const char *devmem, u32 flags) + + ver = (buf[0x07] << 16) + (buf[0x08] << 8) + buf[0x09]; + if (!(opt.flags & FLAG_QUIET)) +- printf("SMBIOS %u.%u.%u present.\n", +- buf[0x07], buf[0x08], buf[0x09]); ++ pr_info("SMBIOS %u.%u.%u present.", ++ buf[0x07], buf[0x08], buf[0x09]); + + offset = QWORD(buf + 0x10); + if (!(flags & FLAG_NO_FILE_OFFSET) && offset.h && sizeof(off_t) < 8) +@@ -5465,7 +5465,7 @@ static int smbios_decode(u8 *buf, const char *devmem, u32 flags) + break; + } + if (!(opt.flags & FLAG_QUIET)) +- printf("SMBIOS %u.%u present.\n", ++ pr_info("SMBIOS %u.%u present.", + ver >> 8, ver & 0xFF); + + dmi_table(DWORD(buf + 0x18), WORD(buf + 0x16), WORD(buf + 0x1C), +@@ -5493,7 +5493,7 @@ static int legacy_decode(u8 *buf, const char *devmem, u32 flags) + return 0; + + if (!(opt.flags & FLAG_QUIET)) +- printf("Legacy DMI %u.%u present.\n", ++ pr_info("Legacy DMI %u.%u present.", + buf[0x0E] >> 4, buf[0x0E] & 0x0F); + + dmi_table(DWORD(buf + 0x08), WORD(buf + 0x06), WORD(buf + 0x0C), +@@ -5645,8 +5645,8 @@ int main(int argc, char * const argv[]) + if (opt.flags & FLAG_FROM_DUMP) + { + if (!(opt.flags & FLAG_QUIET)) +- printf("Reading SMBIOS/DMI data from file %s.\n", +- opt.dumpfile); ++ pr_info("Reading SMBIOS/DMI data from file %s.", ++ opt.dumpfile); + if ((buf = mem_chunk(0, 0x20, opt.dumpfile)) == NULL) + { + ret = 1; +@@ -5681,7 +5681,7 @@ int main(int argc, char * const argv[]) + && (buf = read_file(0, &size, SYS_ENTRY_FILE)) != NULL) + { + if (!(opt.flags & FLAG_QUIET)) +- printf("Getting SMBIOS data from sysfs.\n"); ++ pr_info("Getting SMBIOS data from sysfs."); + if (size >= 24 && memcmp(buf, "_SM3_", 5) == 0) + { + if (smbios3_decode(buf, SYS_TABLE_FILE, FLAG_NO_FILE_OFFSET)) +@@ -5701,7 +5701,7 @@ int main(int argc, char * const argv[]) + if (found) + goto done; + if (!(opt.flags & FLAG_QUIET)) +- printf("Failed to get SMBIOS data from sysfs.\n"); ++ pr_info("Failed to get SMBIOS data from sysfs."); + } + + /* Next try EFI (ia64, Intel-based Mac, arm64) */ +@@ -5716,8 +5716,8 @@ int main(int argc, char * const argv[]) + } + + if (!(opt.flags & FLAG_QUIET)) +- printf("Found SMBIOS entry point in EFI, reading table from %s.\n", +- opt.devmem); ++ pr_info("Found SMBIOS entry point in EFI, reading table from %s.", ++ opt.devmem); + if ((buf = mem_chunk(fp, 0x20, opt.devmem)) == NULL) + { + ret = 1; +@@ -5739,7 +5739,7 @@ int main(int argc, char * const argv[]) + memory_scan: + #if defined __i386__ || defined __x86_64__ + if (!(opt.flags & FLAG_QUIET)) +- printf("Scanning %s for entry point.\n", opt.devmem); ++ pr_info("Scanning %s for entry point.", opt.devmem); + /* Fallback to memory scan (x86, x86_64) */ + if ((buf = mem_chunk(0xF0000, 0x10000, opt.devmem)) == NULL) + { +diff --git a/dmioutput.c b/dmioutput.c +index e762a035f39d..e702f114bb4a 100644 +--- a/dmioutput.c ++++ b/dmioutput.c +@@ -33,3 +33,13 @@ void pr_comment(const char *format, ...) + va_end(args); + printf("\n"); + } ++ ++void pr_info(const char *format, ...) ++{ ++ va_list args; ++ ++ va_start(args, format); ++ vprintf(format, args); ++ va_end(args); ++ printf("\n"); ++} +diff --git a/dmioutput.h b/dmioutput.h +index b6cf5ee8b60e..0dd8f0811934 100644 +--- a/dmioutput.h ++++ b/dmioutput.h +@@ -20,3 +20,4 @@ + */ + + void pr_comment(const char *format, ...); ++void pr_info(const char *format, ...); +-- +2.17.1 + diff --git a/SOURCES/0011-dmidecode-Protect-dmidecode.h-against-double-inclusi.patch b/SOURCES/0011-dmidecode-Protect-dmidecode.h-against-double-inclusi.patch new file mode 100644 index 0000000..ac660e2 --- /dev/null +++ b/SOURCES/0011-dmidecode-Protect-dmidecode.h-against-double-inclusi.patch @@ -0,0 +1,36 @@ +From 0c6f1819b5421166f55369bb33f538bf64805ff6 Mon Sep 17 00:00:00 2001 +From: Jean Delvare +Date: Wed, 1 Apr 2020 09:51:54 +0200 +Subject: [PATCH 11/23] dmidecode: Protect dmidecode.h against double inclusion + +We'll soon need to include dmidecode.h from another header file, so +protect it against double inclusion. + +Signed-off-by: Jean Delvare +--- + dmidecode.h | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/dmidecode.h b/dmidecode.h +index 20e7e96efc0f..9ecc1791702d 100644 +--- a/dmidecode.h ++++ b/dmidecode.h +@@ -18,6 +18,9 @@ + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + ++#ifndef DMIDECODE_H ++#define DMIDECODE_H ++ + #include "types.h" + + struct dmi_header +@@ -30,3 +33,5 @@ struct dmi_header + + int is_printable(const u8 *data, int len); + const char *dmi_string(const struct dmi_header *dm, u8 s); ++ ++#endif +-- +2.17.1 + diff --git a/SOURCES/0012-dmidecode-Add-helper-function-pr_handle.patch b/SOURCES/0012-dmidecode-Add-helper-function-pr_handle.patch new file mode 100644 index 0000000..d140c0b --- /dev/null +++ b/SOURCES/0012-dmidecode-Add-helper-function-pr_handle.patch @@ -0,0 +1,58 @@ +From d37eed24b07da16719ce969f119b4c636e0e2d96 Mon Sep 17 00:00:00 2001 +From: Jean Delvare +Date: Wed, 1 Apr 2020 09:51:57 +0200 +Subject: [PATCH 12/23] dmidecode: Add helper function pr_handle + +Print the handle information through a helper function pr_handle. + +Signed-off-by: Jean Delvare +--- + dmidecode.c | 3 +-- + dmioutput.c | 6 ++++++ + dmioutput.h | 3 +++ + 3 files changed, 10 insertions(+), 2 deletions(-) + +diff --git a/dmidecode.c b/dmidecode.c +index e3f6e300efc2..8ba8d078614e 100644 +--- a/dmidecode.c ++++ b/dmidecode.c +@@ -5212,8 +5212,7 @@ static void dmi_table_decode(u8 *buf, u32 len, u16 num, u16 ver, u32 flags) + + if (display + && (!(opt.flags & FLAG_QUIET) || (opt.flags & FLAG_DUMP))) +- printf("Handle 0x%04X, DMI type %d, %d bytes\n", +- h.handle, h.type, h.length); ++ pr_handle(&h); + + /* Look for the next handle */ + next = data + h.length; +diff --git a/dmioutput.c b/dmioutput.c +index e702f114bb4a..ad3b0398c446 100644 +--- a/dmioutput.c ++++ b/dmioutput.c +@@ -43,3 +43,9 @@ void pr_info(const char *format, ...) + va_end(args); + printf("\n"); + } ++ ++void pr_handle(const struct dmi_header *h) ++{ ++ printf("Handle 0x%04X, DMI type %d, %d bytes\n", ++ h->handle, h->type, h->length); ++} +diff --git a/dmioutput.h b/dmioutput.h +index 0dd8f0811934..6ef60f0ee3cd 100644 +--- a/dmioutput.h ++++ b/dmioutput.h +@@ -19,5 +19,8 @@ + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + ++#include "dmidecode.h" ++ + void pr_comment(const char *format, ...); + void pr_info(const char *format, ...); ++void pr_handle(const struct dmi_header *h); +-- +2.17.1 + diff --git a/SOURCES/0013-dmidecode-Add-helper-function-pr_handle_name.patch b/SOURCES/0013-dmidecode-Add-helper-function-pr_handle_name.patch new file mode 100644 index 0000000..f9f3aed --- /dev/null +++ b/SOURCES/0013-dmidecode-Add-helper-function-pr_handle_name.patch @@ -0,0 +1,569 @@ +From ebbe1dbe9a4413232949d97a506db6a7c00865fa Mon Sep 17 00:00:00 2001 +From: Jean Delvare +Date: Wed, 1 Apr 2020 09:52:00 +0200 +Subject: [PATCH 13/23] dmidecode: Add helper function pr_handle_name + +Print the name of each handle type through a helper function +pr_handle_name. + +Signed-off-by: Jean Delvare +--- + dmidecode.c | 99 ++++++++++++++++++++++++++--------------------------- + dmioem.c | 25 +++++++------- + dmioutput.c | 10 ++++++ + dmioutput.h | 1 + + 4 files changed, 73 insertions(+), 62 deletions(-) + +diff --git a/dmidecode.c b/dmidecode.c +index 8ba8d078614e..c226bad06638 100644 +--- a/dmidecode.c ++++ b/dmidecode.c +@@ -2083,11 +2083,10 @@ static void dmi_on_board_devices(const struct dmi_header *h, const char *prefix) + for (i = 0; i < count; i++) + { + if (count == 1) +- printf("%sOn Board Device Information\n", +- prefix); ++ pr_handle_name("On Board Device Information"); + else +- printf("%sOn Board Device %d Information\n", +- prefix, i + 1); ++ pr_handle_name("On Board Device %d Information", ++ i + 1); + printf("%s\tType: %s\n", + prefix, dmi_on_board_devices_type(p[2 * i] & 0x7F)); + printf("%s\tStatus: %s\n", +@@ -3397,7 +3396,7 @@ static void dmi_additional_info(const struct dmi_header *h, const char *prefix) + + for (i = 0; i < count; i++) + { +- printf("%sAdditional Information %d\n", prefix, i + 1); ++ pr_handle_name("Additional Information %d", i + 1); + + /* Check for short entries */ + if (h->length < offset + 1) break; +@@ -3893,7 +3892,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + switch (h->type) + { + case 0: /* 7.1 BIOS Information */ +- printf("BIOS Information\n"); ++ pr_handle_name("BIOS Information"); + if (h->length < 0x12) break; + printf("\tVendor: %s\n", + dmi_string(h, data[0x04])); +@@ -3933,7 +3932,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + break; + + case 1: /* 7.2 System Information */ +- printf("System Information\n"); ++ pr_handle_name("System Information"); + if (h->length < 0x08) break; + printf("\tManufacturer: %s\n", + dmi_string(h, data[0x04])); +@@ -3957,7 +3956,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + break; + + case 2: /* 7.3 Base Board Information */ +- printf("Base Board Information\n"); ++ pr_handle_name("Base Board Information"); + if (h->length < 0x08) break; + printf("\tManufacturer: %s\n", + dmi_string(h, data[0x04])); +@@ -3988,7 +3987,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + break; + + case 3: /* 7.4 Chassis Information */ +- printf("Chassis Information\n"); ++ pr_handle_name("Chassis Information"); + if (h->length < 0x09) break; + printf("\tManufacturer: %s\n", + dmi_string(h, data[0x04])); +@@ -4030,7 +4029,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + break; + + case 4: /* 7.5 Processor Information */ +- printf("Processor Information\n"); ++ pr_handle_name("Processor Information"); + if (h->length < 0x1A) break; + printf("\tSocket Designation: %s\n", + dmi_string(h, data[0x04])); +@@ -4100,7 +4099,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + break; + + case 5: /* 7.6 Memory Controller Information */ +- printf("Memory Controller Information\n"); ++ pr_handle_name("Memory Controller Information"); + if (h->length < 0x0F) break; + printf("\tError Detecting Method: %s\n", + dmi_memory_controller_ed_method(data[0x04])); +@@ -4130,7 +4129,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + break; + + case 6: /* 7.7 Memory Module Information */ +- printf("Memory Module Information\n"); ++ pr_handle_name("Memory Module Information"); + if (h->length < 0x0C) break; + printf("\tSocket Designation: %s\n", + dmi_string(h, data[0x04])); +@@ -4154,7 +4153,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + break; + + case 7: /* 7.8 Cache Information */ +- printf("Cache Information\n"); ++ pr_handle_name("Cache Information"); + if (h->length < 0x0F) break; + printf("\tSocket Designation: %s\n", + dmi_string(h, data[0x04])); +@@ -4197,7 +4196,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + break; + + case 8: /* 7.9 Port Connector Information */ +- printf("Port Connector Information\n"); ++ pr_handle_name("Port Connector Information"); + if (h->length < 0x09) break; + printf("\tInternal Reference Designator: %s\n", + dmi_string(h, data[0x04])); +@@ -4212,7 +4211,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + break; + + case 9: /* 7.10 System Slots */ +- printf("System Slot Information\n"); ++ pr_handle_name("System Slot Information"); + if (h->length < 0x0C) break; + printf("\tDesignation: %s\n", + dmi_string(h, data[0x04])); +@@ -4243,19 +4242,19 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + break; + + case 11: /* 7.12 OEM Strings */ +- printf("OEM Strings\n"); ++ pr_handle_name("OEM Strings"); + if (h->length < 0x05) break; + dmi_oem_strings(h, "\t"); + break; + + case 12: /* 7.13 System Configuration Options */ +- printf("System Configuration Options\n"); ++ pr_handle_name("System Configuration Options"); + if (h->length < 0x05) break; + dmi_system_configuration_options(h, "\t"); + break; + + case 13: /* 7.14 BIOS Language Information */ +- printf("BIOS Language Information\n"); ++ pr_handle_name("BIOS Language Information"); + if (h->length < 0x16) break; + if (ver >= 0x0201) + { +@@ -4269,7 +4268,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + break; + + case 14: /* 7.15 Group Associations */ +- printf("Group Associations\n"); ++ pr_handle_name("Group Associations"); + if (h->length < 0x05) break; + printf("\tName: %s\n", + dmi_string(h, data[0x04])); +@@ -4279,7 +4278,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + break; + + case 15: /* 7.16 System Event Log */ +- printf("System Event Log\n"); ++ pr_handle_name("System Event Log"); + if (h->length < 0x14) break; + printf("\tArea Length: %u bytes\n", + WORD(data + 0x04)); +@@ -4311,7 +4310,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + break; + + case 16: /* 7.17 Physical Memory Array */ +- printf("Physical Memory Array\n"); ++ pr_handle_name("Physical Memory Array"); + if (h->length < 0x0F) break; + printf("\tLocation: %s\n", + dmi_memory_array_location(data[0x04])); +@@ -4347,7 +4346,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + break; + + case 17: /* 7.18 Memory Device */ +- printf("Memory Device\n"); ++ pr_handle_name("Memory Device"); + if (h->length < 0x15) break; + if (!(opt.flags & FLAG_QUIET)) + { +@@ -4457,7 +4456,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + break; + + case 18: /* 7.19 32-bit Memory Error Information */ +- printf("32-bit Memory Error Information\n"); ++ pr_handle_name("32-bit Memory Error Information"); + if (h->length < 0x17) break; + printf("\tType: %s\n", + dmi_memory_error_type(data[0x04])); +@@ -4480,7 +4479,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + break; + + case 19: /* 7.20 Memory Array Mapped Address */ +- printf("Memory Array Mapped Address\n"); ++ pr_handle_name("Memory Array Mapped Address"); + if (h->length < 0x0F) break; + if (h->length >= 0x1F && DWORD(data + 0x04) == 0xFFFFFFFF) + { +@@ -4516,7 +4515,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + break; + + case 20: /* 7.21 Memory Device Mapped Address */ +- printf("Memory Device Mapped Address\n"); ++ pr_handle_name("Memory Device Mapped Address"); + if (h->length < 0x13) break; + if (h->length >= 0x23 && DWORD(data + 0x04) == 0xFFFFFFFF) + { +@@ -4559,7 +4558,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + break; + + case 21: /* 7.22 Built-in Pointing Device */ +- printf("Built-in Pointing Device\n"); ++ pr_handle_name("Built-in Pointing Device"); + if (h->length < 0x07) break; + printf("\tType: %s\n", + dmi_pointing_device_type(data[0x04])); +@@ -4570,7 +4569,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + break; + + case 22: /* 7.23 Portable Battery */ +- printf("Portable Battery\n"); ++ pr_handle_name("Portable Battery"); + if (h->length < 0x10) break; + printf("\tLocation: %s\n", + dmi_string(h, data[0x04])); +@@ -4618,7 +4617,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + break; + + case 23: /* 7.24 System Reset */ +- printf("System Reset\n"); ++ pr_handle_name("System Reset"); + if (h->length < 0x0D) break; + printf("\tStatus: %s\n", + data[0x04] & (1 << 0) ? "Enabled" : "Disabled"); +@@ -4645,7 +4644,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + break; + + case 24: /* 7.25 Hardware Security */ +- printf("Hardware Security\n"); ++ pr_handle_name("Hardware Security"); + if (h->length < 0x05) break; + printf("\tPower-On Password Status: %s\n", + dmi_hardware_security_status(data[0x04] >> 6)); +@@ -4658,7 +4657,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + break; + + case 25: /* 7.26 System Power Controls */ +- printf("System Power Controls\n"); ++ pr_handle_name("System Power Controls"); + if (h->length < 0x09) break; + printf("\tNext Scheduled Power-on:"); + dmi_power_controls_power_on(data + 0x04); +@@ -4666,7 +4665,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + break; + + case 26: /* 7.27 Voltage Probe */ +- printf("Voltage Probe\n"); ++ pr_handle_name("Voltage Probe"); + if (h->length < 0x14) break; + printf("\tDescription: %s\n", + dmi_string(h, data[0x04])); +@@ -4698,7 +4697,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + break; + + case 27: /* 7.28 Cooling Device */ +- printf("Cooling Device\n"); ++ pr_handle_name("Cooling Device"); + if (h->length < 0x0C) break; + if (!(opt.flags & FLAG_QUIET) && WORD(data + 0x04) != 0xFFFF) + printf("\tTemperature Probe Handle: 0x%04X\n", +@@ -4721,7 +4720,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + break; + + case 28: /* 7.29 Temperature Probe */ +- printf("Temperature Probe\n"); ++ pr_handle_name("Temperature Probe"); + if (h->length < 0x14) break; + printf("\tDescription: %s\n", + dmi_string(h, data[0x04])); +@@ -4753,7 +4752,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + break; + + case 29: /* 7.30 Electrical Current Probe */ +- printf("Electrical Current Probe\n"); ++ pr_handle_name("Electrical Current Probe"); + if (h->length < 0x14) break; + printf("\tDescription: %s\n", + dmi_string(h, data[0x04])); +@@ -4785,7 +4784,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + break; + + case 30: /* 7.31 Out-of-band Remote Access */ +- printf("Out-of-band Remote Access\n"); ++ pr_handle_name("Out-of-band Remote Access"); + if (h->length < 0x06) break; + printf("\tManufacturer Name: %s\n", + dmi_string(h, data[0x04])); +@@ -4796,7 +4795,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + break; + + case 31: /* 7.32 Boot Integrity Services Entry Point */ +- printf("Boot Integrity Services Entry Point\n"); ++ pr_handle_name("Boot Integrity Services Entry Point"); + if (h->length < 0x1C) break; + printf("\tChecksum: %s\n", + checksum(data, h->length) ? "OK" : "Invalid"); +@@ -4808,14 +4807,14 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + break; + + case 32: /* 7.33 System Boot Information */ +- printf("System Boot Information\n"); ++ pr_handle_name("System Boot Information"); + if (h->length < 0x0B) break; + printf("\tStatus: %s\n", + dmi_system_boot_status(data[0x0A])); + break; + + case 33: /* 7.34 64-bit Memory Error Information */ +- printf("64-bit Memory Error Information\n"); ++ pr_handle_name("64-bit Memory Error Information"); + if (h->length < 0x1F) break; + printf("\tType: %s\n", + dmi_memory_error_type(data[0x04])); +@@ -4838,7 +4837,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + break; + + case 34: /* 7.35 Management Device */ +- printf("Management Device\n"); ++ pr_handle_name("Management Device"); + if (h->length < 0x0B) break; + printf("\tDescription: %s\n", + dmi_string(h, data[0x04])); +@@ -4851,7 +4850,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + break; + + case 35: /* 7.36 Management Device Component */ +- printf("Management Device Component\n"); ++ pr_handle_name("Management Device Component"); + if (h->length < 0x0B) break; + printf("\tDescription: %s\n", + dmi_string(h, data[0x04])); +@@ -4868,7 +4867,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + break; + + case 36: /* 7.37 Management Device Threshold Data */ +- printf("Management Device Threshold Data\n"); ++ pr_handle_name("Management Device Threshold Data"); + if (h->length < 0x10) break; + if (WORD(data + 0x04) != 0x8000) + printf("\tLower Non-critical Threshold: %d\n", +@@ -4891,7 +4890,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + break; + + case 37: /* 7.38 Memory Channel */ +- printf("Memory Channel\n"); ++ pr_handle_name("Memory Channel"); + if (h->length < 0x07) break; + printf("\tType: %s\n", + dmi_memory_channel_type(data[0x04])); +@@ -4908,7 +4907,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + * We use the word "Version" instead of "Revision", conforming to + * the IPMI specification. + */ +- printf("IPMI Device Information\n"); ++ pr_handle_name("IPMI Device Information"); + if (h->length < 0x10) break; + printf("\tInterface Type: %s\n", + dmi_ipmi_interface_type(data[0x04])); +@@ -4946,7 +4945,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + break; + + case 39: /* 7.40 System Power Supply */ +- printf("System Power Supply\n"); ++ pr_handle_name("System Power Supply"); + if (h->length < 0x10) break; + if (data[0x04] != 0x00) + printf("\tPower Unit Group: %u\n", +@@ -5006,7 +5005,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + break; + + case 41: /* 7.42 Onboard Device Extended Information */ +- printf("Onboard Device\n"); ++ pr_handle_name("Onboard Device"); + if (h->length < 0x0B) break; + printf("\tReference Designation: %s\n", dmi_string(h, data[0x04])); + printf("\tType: %s\n", +@@ -5018,7 +5017,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + break; + + case 42: /* 7.43 Management Controller Host Interface */ +- printf("Management Controller Host Interface\n"); ++ pr_handle_name("Management Controller Host Interface"); + if (ver < 0x0302) + { + if (h->length < 0x05) break; +@@ -5043,7 +5042,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + break; + + case 43: /* 7.44 TPM Device */ +- printf("TPM Device\n"); ++ pr_handle_name("TPM Device"); + if (h->length < 0x1B) break; + printf("\tVendor ID:"); + dmi_tpm_vendor_id(data + 0x04); +@@ -5080,11 +5079,11 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + break; + + case 126: /* 7.44 Inactive */ +- printf("Inactive\n"); ++ pr_handle_name("Inactive"); + break; + + case 127: /* 7.45 End Of Table */ +- printf("End Of Table\n"); ++ pr_handle_name("End Of Table"); + break; + + default: +@@ -5092,7 +5091,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + break; + if (opt.flags & FLAG_QUIET) + return; +- printf("%s Type\n", ++ pr_handle_name("%s Type", + h->type >= 128 ? "OEM-specific" : "Unknown"); + dmi_dump(h, "\t"); + } +diff --git a/dmioem.c b/dmioem.c +index 1a9bd8264fcb..c999c08c4475 100644 +--- a/dmioem.c ++++ b/dmioem.c +@@ -25,6 +25,7 @@ + #include "types.h" + #include "dmidecode.h" + #include "dmioem.h" ++#include "dmioutput.h" + + /* + * Globals for vendor-specific decodes +@@ -92,7 +93,7 @@ static int dmi_decode_acer(const struct dmi_header *h) + * brands, including Fujitsu-Siemens, Medion, Lenovo, + * and eMachines. + */ +- printf("Acer Hotkey Function\n"); ++ pr_handle_name("Acer Hotkey Function"); + if (h->length < 0x0F) break; + cap = WORD(data + 0x04); + printf("\tFunction bitmap for Communication Button: 0x%04hx\n", cap); +@@ -157,7 +158,7 @@ static int dmi_decode_hp(const struct dmi_header *h) + /* + * Vendor Specific: HPE ProLiant System/Rack Locator + */ +- printf("%s ProLiant System/Rack Locator\n", company); ++ pr_handle_name("%s ProLiant System/Rack Locator", company); + if (h->length < 0x0B) break; + printf("\tRack Name: %s\n", dmi_string(h, data[0x04])); + printf("\tEnclosure Name: %s\n", dmi_string(h, data[0x05])); +@@ -189,10 +190,9 @@ static int dmi_decode_hp(const struct dmi_header *h) + * + * Type 221: is deprecated in the latest docs + */ +- printf("%s %s\n", company, +- h->type == 221 ? +- "BIOS iSCSI NIC PCI and MAC Information" : +- "BIOS PXE NIC PCI and MAC Information"); ++ pr_handle_name("%s %s", company, h->type == 221 ? ++ "BIOS iSCSI NIC PCI and MAC Information" : ++ "BIOS PXE NIC PCI and MAC Information"); + nic = 1; + ptr = 4; + while (h->length >= ptr + 8) +@@ -224,7 +224,8 @@ static int dmi_decode_hp(const struct dmi_header *h) + * 0x08 | MAC | 32B | MAC addr padded w/ 0s + * 0x28 | Port No| BYTE | Each NIC maps to a Port + */ +- printf("%s BIOS PXE NIC PCI and MAC Information\n", company); ++ pr_handle_name("%s BIOS PXE NIC PCI and MAC Information", ++ company); + if (h->length < 0x0E) break; + /* If the record isn't long enough, we don't have an ID + * use 0xFF to use the internal counter. +@@ -240,7 +241,7 @@ static int dmi_decode_hp(const struct dmi_header *h) + * + * Source: hpwdt kernel driver + */ +- printf("%s 64-bit CRU Information\n", company); ++ pr_handle_name("%s 64-bit CRU Information", company); + if (h->length < 0x18) break; + printf("\tSignature: 0x%08x", DWORD(data + 0x04)); + if (is_printable(data + 0x04, 4)) +@@ -265,7 +266,7 @@ static int dmi_decode_hp(const struct dmi_header *h) + * + * Source: hpwdt kernel driver + */ +- printf("%s ProLiant Information\n", company); ++ pr_handle_name("%s ProLiant Information", company); + if (h->length < 0x08) break; + printf("\tPower Features: 0x%08x\n", DWORD(data + 0x04)); + if (h->length < 0x0C) break; +@@ -318,7 +319,7 @@ static int dmi_decode_ibm_lenovo(const struct dmi_header *h) + || strcmp(dmi_string(h, 1), "TVT-Enablement") != 0) + return 0; + +- printf("ThinkVantage Technologies\n"); ++ pr_handle_name("ThinkVantage Technologies"); + printf("\tVersion: %u\n", data[0x04]); + printf("\tDiagnostics: %s\n", + data[0x14] & 0x80 ? "Available" : "No"); +@@ -357,7 +358,7 @@ static int dmi_decode_ibm_lenovo(const struct dmi_header *h) + if (data[0x06] != 0x07 || data[0x07] != 0x03 || data[0x08] != 0x01) + return 0; + +- printf("ThinkPad Device Presence Detection\n"); ++ pr_handle_name("ThinkPad Device Presence Detection"); + printf("\tFingerprint Reader: %s\n", + data[0x09] & 0x01 ? "Present" : "No"); + break; +@@ -390,7 +391,7 @@ static int dmi_decode_ibm_lenovo(const struct dmi_header *h) + if (data[0x0A] != 0x0B || data[0x0B] != 0x07 || data[0x0C] != 0x01) + return 0; + +- printf("ThinkPad Embedded Controller Program\n"); ++ pr_handle_name("ThinkPad Embedded Controller Program"); + printf("\tVersion ID: %s\n", dmi_string(h, 1)); + printf("\tRelease Date: %s\n", dmi_string(h, 2)); + break; +diff --git a/dmioutput.c b/dmioutput.c +index ad3b0398c446..ca7edab5cc69 100644 +--- a/dmioutput.c ++++ b/dmioutput.c +@@ -49,3 +49,13 @@ void pr_handle(const struct dmi_header *h) + printf("Handle 0x%04X, DMI type %d, %d bytes\n", + h->handle, h->type, h->length); + } ++ ++void pr_handle_name(const char *format, ...) ++{ ++ va_list args; ++ ++ va_start(args, format); ++ vprintf(format, args); ++ va_end(args); ++ printf("\n"); ++} +diff --git a/dmioutput.h b/dmioutput.h +index 6ef60f0ee3cd..0acdce7658c9 100644 +--- a/dmioutput.h ++++ b/dmioutput.h +@@ -24,3 +24,4 @@ + void pr_comment(const char *format, ...); + void pr_info(const char *format, ...); + void pr_handle(const struct dmi_header *h); ++void pr_handle_name(const char *format, ...); +-- +2.17.1 + diff --git a/SOURCES/0014-dmidecode-Add-helper-function-pr_attr.patch b/SOURCES/0014-dmidecode-Add-helper-function-pr_attr.patch new file mode 100644 index 0000000..cf7a2fb --- /dev/null +++ b/SOURCES/0014-dmidecode-Add-helper-function-pr_attr.patch @@ -0,0 +1,2987 @@ +From 07968a8a578d34137eb6db0c26b860c567f60903 Mon Sep 17 00:00:00 2001 +From: Jean Delvare +Date: Wed, 1 Apr 2020 09:52:04 +0200 +Subject: [PATCH 14/23] dmidecode: Add helper function pr_attr + +Print all first-level attributes through a helper function pr_attr. + +Signed-off-by: Jean Delvare +--- + dmidecode.c | 1357 ++++++++++++++++++++++++--------------------------- + dmioem.c | 66 +-- + dmioutput.c | 12 + + dmioutput.h | 1 + + 4 files changed, 691 insertions(+), 745 deletions(-) + +diff --git a/dmidecode.c b/dmidecode.c +index c226bad06638..7ab058b61ef0 100644 +--- a/dmidecode.c ++++ b/dmidecode.c +@@ -261,7 +261,7 @@ static void dmi_dump(const struct dmi_header *h, const char *prefix) + } + + /* shift is 0 if the value is in bytes, 1 if it is in kilobytes */ +-static void dmi_print_memory_size(u64 code, int shift) ++static void dmi_print_memory_size(const char *attr, u64 code, int shift) + { + unsigned long capacity; + u16 split[7]; +@@ -301,7 +301,7 @@ static void dmi_print_memory_size(u64 code, int shift) + else + capacity = split[i]; + +- printf(" %lu %s", capacity, unit[i + shift]); ++ pr_attr(attr, "%lu %s", capacity, unit[i + shift]); + } + + /* +@@ -310,10 +310,19 @@ static void dmi_print_memory_size(u64 code, int shift) + + static void dmi_bios_runtime_size(u32 code) + { ++ const char *format; ++ + if (code & 0x000003FF) +- printf(" %u bytes", code); ++ { ++ format = "%u bytes"; ++ } + else +- printf(" %u kB", code >> 10); ++ { ++ format = "%u kB"; ++ code >>= 10; ++ } ++ ++ pr_attr("Runtime Size", format, code); + } + + static void dmi_bios_rom_size(u8 code1, u16 code2) +@@ -325,10 +334,10 @@ static void dmi_bios_rom_size(u8 code1, u16 code2) + if (code1 != 0xFF) + { + u64 s = { .l = (code1 + 1) << 6 }; +- dmi_print_memory_size(s, 1); ++ dmi_print_memory_size("ROM Size", s, 1); + } + else +- printf(" %u %s", code2 & 0x3FFF, unit[code2 >> 14]); ++ pr_attr("ROM Size", "%u %s", code2 & 0x3FFF, unit[code2 >> 14]); + } + + static void dmi_bios_characteristics(u64 code, const char *prefix) +@@ -426,7 +435,7 @@ static void dmi_bios_characteristics_x2(u8 code, const char *prefix) + * 7.2 System Information (Type 1) + */ + +-static void dmi_system_uuid(const u8 *p, u16 ver) ++static void dmi_system_uuid(const char *attr, const u8 *p, u16 ver) + { + int only0xFF = 1, only0x00 = 1; + int i; +@@ -439,12 +448,18 @@ static void dmi_system_uuid(const u8 *p, u16 ver) + + if (only0xFF) + { +- printf("Not Present"); ++ if (attr) ++ pr_attr(attr, "Not Present"); ++ else ++ printf("Not Present\n"); + return; + } + if (only0x00) + { +- printf("Not Settable"); ++ if (attr) ++ pr_attr(attr, "Not Settable"); ++ else ++ printf("Not Settable\n"); + return; + } + +@@ -457,13 +472,29 @@ static void dmi_system_uuid(const u8 *p, u16 ver) + * for older versions. + */ + if (ver >= 0x0206) +- printf("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", +- p[3], p[2], p[1], p[0], p[5], p[4], p[7], p[6], +- p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]); ++ { ++ if (attr) ++ pr_attr(attr, ++ "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", ++ p[3], p[2], p[1], p[0], p[5], p[4], p[7], p[6], ++ p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]); ++ else ++ printf("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n", ++ p[3], p[2], p[1], p[0], p[5], p[4], p[7], p[6], ++ p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]); ++ } + else +- printf("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", +- p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], +- p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]); ++ { ++ if (attr) ++ pr_attr(attr, ++ "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", ++ p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], ++ p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]); ++ else ++ printf("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n", ++ p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], ++ p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]); ++ } + } + + static const char *dmi_system_wake_up_type(u8 code) +@@ -649,17 +680,17 @@ static const char *dmi_chassis_security_status(u8 code) + static void dmi_chassis_height(u8 code) + { + if (code == 0x00) +- printf(" Unspecified"); ++ pr_attr("Height", "Unspecified"); + else +- printf(" %u U", code); ++ pr_attr("Height", "%u U", code); + } + + static void dmi_chassis_power_cords(u8 code) + { + if (code == 0x00) +- printf(" Unspecified"); ++ pr_attr("Number Of Power Cords", "Unspecified"); + else +- printf(" %u", code); ++ pr_attr("Number Of Power Cords", "%u", code); + } + + static void dmi_chassis_elements(u8 count, u8 len, const u8 *p, const char *prefix) +@@ -1052,8 +1083,8 @@ static void dmi_processor_id(const struct dmi_header *h, const char *prefix) + * This might help learn about new processors supporting the + * CPUID instruction or another form of identification. + */ +- printf("%sID: %02X %02X %02X %02X %02X %02X %02X %02X\n", +- prefix, p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); ++ pr_attr("ID", "%02X %02X %02X %02X %02X %02X %02X %02X", ++ p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); + + if (type == 0x05) /* 80386 */ + { +@@ -1061,8 +1092,9 @@ static void dmi_processor_id(const struct dmi_header *h, const char *prefix) + /* + * 80386 have a different signature. + */ +- printf("%sSignature: Type %u, Family %u, Major Stepping %u, Minor Stepping %u\n", +- prefix, dx >> 12, (dx >> 8) & 0xF, ++ pr_attr("Signature", ++ "Type %u, Family %u, Major Stepping %u, Minor Stepping %u", ++ dx >> 12, (dx >> 8) & 0xF, + (dx >> 4) & 0xF, dx & 0xF); + return; + } +@@ -1080,8 +1112,9 @@ static void dmi_processor_id(const struct dmi_header *h, const char *prefix) + sig = 1; + else + { +- printf("%sSignature: Type %u, Family %u, Model %u, Stepping %u\n", +- prefix, (dx >> 12) & 0x3, (dx >> 8) & 0xF, ++ pr_attr("Signature", ++ "Type %u, Family %u, Model %u, Stepping %u", ++ (dx >> 12) & 0x3, (dx >> 8) & 0xF, + (dx >> 4) & 0xF, dx & 0xF); + return; + } +@@ -1097,8 +1130,9 @@ static void dmi_processor_id(const struct dmi_header *h, const char *prefix) + */ + if (midr == 0) + return; +- printf("%sSignature: Implementor 0x%02x, Variant 0x%x, Architecture %u, Part 0x%03x, Revision %u\n", +- prefix, midr >> 24, (midr >> 20) & 0xF, ++ pr_attr("Signature", ++ "Implementor 0x%02x, Variant 0x%x, Architecture %u, Part 0x%03x, Revision %u", ++ midr >> 24, (midr >> 20) & 0xF, + (midr >> 16) & 0xF, (midr >> 4) & 0xFFF, midr & 0xF); + return; + } +@@ -1153,15 +1187,15 @@ static void dmi_processor_id(const struct dmi_header *h, const char *prefix) + switch (sig) + { + case 1: /* Intel */ +- printf("%sSignature: Type %u, Family %u, Model %u, Stepping %u\n", +- prefix, (eax >> 12) & 0x3, ++ pr_attr("Signature", ++ "Type %u, Family %u, Model %u, Stepping %u", ++ (eax >> 12) & 0x3, + ((eax >> 20) & 0xFF) + ((eax >> 8) & 0x0F), + ((eax >> 12) & 0xF0) + ((eax >> 4) & 0x0F), + eax & 0xF); + break; + case 2: /* AMD, publication #25481 revision 2.28 */ +- printf("%sSignature: Family %u, Model %u, Stepping %u\n", +- prefix, ++ pr_attr("Signature", "Family %u, Model %u, Stepping %u", + ((eax >> 8) & 0xF) + (((eax >> 8) & 0xF) == 0xF ? (eax >> 20) & 0xFF : 0), + ((eax >> 4) & 0xF) | (((eax >> 8) & 0xF) == 0xF ? (eax >> 12) & 0xF0 : 0), + eax & 0xF); +@@ -1183,7 +1217,7 @@ static void dmi_processor_id(const struct dmi_header *h, const char *prefix) + } + } + +-static void dmi_processor_voltage(u8 code) ++static void dmi_processor_voltage(const char *attr, u8 code) + { + /* 7.5.4 */ + static const char *voltage[] = { +@@ -1194,25 +1228,47 @@ static void dmi_processor_voltage(u8 code) + int i; + + if (code & 0x80) +- printf(" %.1f V", (float)(code & 0x7f) / 10); ++ pr_attr(attr, "%.1f V", (float)(code & 0x7f) / 10); + else if ((code & 0x07) == 0x00) +- printf(" Unknown"); ++ pr_attr(attr, "Unknown"); + else + { ++ char voltage_str[18]; ++ int off = 0; ++ + for (i = 0; i <= 2; i++) ++ { + if (code & (1 << i)) +- printf(" %s", voltage[i]); ++ { ++ /* Insert space if not the first value */ ++ off += sprintf(voltage_str + off, ++ off ? " %s" :"%s", ++ voltage[i]); ++ } ++ } ++ if (off) ++ pr_attr(attr, voltage_str); + } + } + +-static void dmi_processor_frequency(const u8 *p) ++static void dmi_processor_frequency(const char *attr, const u8 *p) + { + u16 code = WORD(p); + + if (code) +- printf("%u MHz", code); ++ { ++ if (attr) ++ pr_attr(attr, "%u MHz", code); ++ else ++ printf("%u MHz\n", code); ++ } + else +- printf("Unknown"); ++ { ++ if (attr) ++ pr_attr(attr, "Unknown"); ++ else ++ printf("Unknown\n"); ++ } + } + + /* code is assumed to be a 3-bit value */ +@@ -1303,17 +1359,18 @@ static const char *dmi_processor_upgrade(u8 code) + return out_of_spec; + } + +-static void dmi_processor_cache(u16 code, const char *level, u16 ver) ++static void dmi_processor_cache(const char *attr, u16 code, const char *level, ++ u16 ver) + { + if (code == 0xFFFF) + { + if (ver >= 0x0203) +- printf(" Not Provided"); ++ pr_attr(attr, "Not Provided"); + else +- printf(" No %s Cache", level); ++ pr_attr(attr, "No %s Cache", level); + } + else +- printf(" 0x%04X", code); ++ pr_attr(attr, "0x%04X", code); + } + + static void dmi_processor_characteristics(u16 code, const char *prefix) +@@ -1478,46 +1535,48 @@ static void dmi_memory_module_types(u16 code, const char *sep) + static void dmi_memory_module_connections(u8 code) + { + if (code == 0xFF) +- printf(" None"); ++ pr_attr("Bank Connections", "None"); ++ else if ((code & 0xF0) == 0xF0) ++ pr_attr("Bank Connections", "%u", code & 0x0F); ++ else if ((code & 0x0F) == 0x0F) ++ pr_attr("Bank Connections", "%u", code >> 4); + else +- { +- if ((code & 0xF0) != 0xF0) +- printf(" %u", code >> 4); +- if ((code & 0x0F) != 0x0F) +- printf(" %u", code & 0x0F); +- } ++ pr_attr("Bank Connections", "%u %u", code >> 4, code & 0x0F); + } + +-static void dmi_memory_module_speed(u8 code) ++static void dmi_memory_module_speed(const char *attr, u8 code) + { + if (code == 0) +- printf(" Unknown"); ++ pr_attr(attr, "Unknown"); + else +- printf(" %u ns", code); ++ pr_attr(attr, "%u ns", code); + } + +-static void dmi_memory_module_size(u8 code) ++static void dmi_memory_module_size(const char *attr, u8 code) + { ++ const char *connection; ++ + /* 7.7.2 */ ++ if (code & 0x80) ++ connection = " (Double-bank Connection)"; ++ else ++ connection = " (Single-bank Connection)"; ++ + switch (code & 0x7F) + { + case 0x7D: +- printf(" Not Determinable"); ++ pr_attr(attr, "Not Determinable%s", connection); + break; + case 0x7E: +- printf(" Disabled"); ++ pr_attr(attr, "Disabled%s", connection); + break; + case 0x7F: +- printf(" Not Installed"); ++ pr_attr(attr, "Not Installed"); + return; + default: +- printf(" %u MB", 1 << (code & 0x7F)); ++ pr_attr(attr, "%u MB%s", 1 << (code & 0x7F), ++ connection); + } +- +- if (code & 0x80) +- printf(" (Double-bank Connection)"); +- else +- printf(" (Single-bank Connection)"); + } + + static void dmi_memory_module_error(u8 code) +@@ -1530,9 +1589,9 @@ static void dmi_memory_module_error(u8 code) + }; + + if (code & (1 << 2)) +- printf(" See Event Log\n"); ++ pr_attr("Error Status", "See Event Log"); + else +- printf(" %s\n", status[code & 0x03]); ++ pr_attr("Error Status", "%s", status[code & 0x03]); + } + + /* +@@ -1564,7 +1623,7 @@ static const char *dmi_cache_location(u8 code) + return location[code]; + } + +-static void dmi_cache_size_2(u32 code) ++static void dmi_cache_size_2(const char *attr, u32 code) + { + u64 size; + +@@ -1581,12 +1640,13 @@ static void dmi_cache_size_2(u32 code) + } + + /* Use a more convenient unit for large cache size */ +- dmi_print_memory_size(size, 1); ++ dmi_print_memory_size(attr, size, 1); + } + +-static void dmi_cache_size(u16 code) ++static void dmi_cache_size(const char *attr, u16 code) + { +- dmi_cache_size_2((((u32)code & 0x8000LU) << 16) | (code & 0x7FFFLU)); ++ dmi_cache_size_2(attr, ++ (((u32)code & 0x8000LU) << 16) | (code & 0x7FFFLU)); + } + + static void dmi_cache_types(u16 code, const char *sep) +@@ -1938,16 +1998,16 @@ static const char *dmi_slot_length(u8 code) + return out_of_spec; + } + +-static void dmi_slot_id(u8 code1, u8 code2, u8 type, const char *prefix) ++static void dmi_slot_id(u8 code1, u8 code2, u8 type) + { + /* 7.10.5 */ + switch (type) + { + case 0x04: /* MCA */ +- printf("%sID: %u\n", prefix, code1); ++ pr_attr("ID", "%u", code1); + break; + case 0x05: /* EISA */ +- printf("%sID: %u\n", prefix, code1); ++ pr_attr("ID", "%u", code1); + break; + case 0x06: /* PCI */ + case 0x0E: /* PCI */ +@@ -1985,10 +2045,10 @@ static void dmi_slot_id(u8 code1, u8 code2, u8 type, const char *prefix) + case 0xBB: /* PCI Express 4 */ + case 0xBC: /* PCI Express 4 */ + case 0xBD: /* PCI Express 4 */ +- printf("%sID: %u\n", prefix, code1); ++ pr_attr("ID", "%u", code1); + break; + case 0x07: /* PCMCIA */ +- printf("%sID: Adapter %u, Socket %u\n", prefix, code1, code2); ++ pr_attr("ID", "Adapter %u, Socket %u", code1, code2); + break; + } + } +@@ -2031,22 +2091,26 @@ static void dmi_slot_characteristics(u8 code1, u8 code2, const char *prefix) + } + } + +-static void dmi_slot_segment_bus_func(u16 code1, u8 code2, u8 code3, const char *prefix) ++static void dmi_slot_segment_bus_func(u16 code1, u8 code2, u8 code3) + { + /* 7.10.8 */ + if (!(code1 == 0xFFFF && code2 == 0xFF && code3 == 0xFF)) +- printf("%sBus Address: %04x:%02x:%02x.%x\n", +- prefix, code1, code2, code3 >> 3, code3 & 0x7); ++ pr_attr("Bus Address", "%04x:%02x:%02x.%x", ++ code1, code2, code3 >> 3, code3 & 0x7); + } + +-static void dmi_slot_peers(u8 n, const u8 *data, const char *prefix) ++static void dmi_slot_peers(u8 n, const u8 *data) + { ++ char attr[16]; + int i; + + for (i = 1; i <= n; i++, data += 5) +- printf("%sPeer Device %d: %04x:%02x:%02x.%x (Width %u)\n", +- prefix, i, WORD(data), data[2], data[3] >> 3, +- data[3] & 0x07, data[4]); ++ { ++ sprintf(attr, "Peer Device %hu", i); ++ pr_attr(attr, "%04x:%02x:%02x.%x (Width %u)", ++ WORD(data), data[2], data[3] >> 3, data[3] & 0x07, ++ data[4]); ++ } + } + + /* +@@ -2074,7 +2138,7 @@ static const char *dmi_on_board_devices_type(u8 code) + return out_of_spec; + } + +-static void dmi_on_board_devices(const struct dmi_header *h, const char *prefix) ++static void dmi_on_board_devices(const struct dmi_header *h) + { + u8 *p = h->data + 4; + u8 count = (h->length - 0x04) / 2; +@@ -2087,12 +2151,11 @@ static void dmi_on_board_devices(const struct dmi_header *h, const char *prefix) + else + pr_handle_name("On Board Device %d Information", + i + 1); +- printf("%s\tType: %s\n", +- prefix, dmi_on_board_devices_type(p[2 * i] & 0x7F)); +- printf("%s\tStatus: %s\n", +- prefix, p[2 * i] & 0x80 ? "Enabled" : "Disabled"); +- printf("%s\tDescription: %s\n", +- prefix, dmi_string(h, p[2 * i + 1])); ++ pr_attr("Type", "%s", ++ dmi_on_board_devices_type(p[2 * i] & 0x7F)); ++ pr_attr("Status", "%s", ++ p[2 * i] & 0x80 ? "Enabled" : "Disabled"); ++ pr_attr("Description", "%s", dmi_string(h, p[2 * i + 1])); + } + } + +@@ -2100,30 +2163,36 @@ static void dmi_on_board_devices(const struct dmi_header *h, const char *prefix) + * 7.12 OEM Strings (Type 11) + */ + +-static void dmi_oem_strings(const struct dmi_header *h, const char *prefix) ++static void dmi_oem_strings(const struct dmi_header *h) + { ++ char attr[11]; + u8 *p = h->data + 4; + u8 count = p[0x00]; + int i; + + for (i = 1; i <= count; i++) +- printf("%sString %d: %s\n", +- prefix, i, dmi_string(h, i)); ++ { ++ sprintf(attr, "String %hu", i); ++ pr_attr(attr, "%s",dmi_string(h, i)); ++ } + } + + /* + * 7.13 System Configuration Options (Type 12) + */ + +-static void dmi_system_configuration_options(const struct dmi_header *h, const char *prefix) ++static void dmi_system_configuration_options(const struct dmi_header *h) + { ++ char attr[11]; + u8 *p = h->data + 4; + u8 count = p[0x00]; + int i; + + for (i = 1; i <= count; i++) +- printf("%sOption %d: %s\n", +- prefix, i, dmi_string(h, i)); ++ { ++ sprintf(attr, "Option %hu", i); ++ pr_attr(attr, "%s",dmi_string(h, i)); ++ } + } + + /* +@@ -2197,7 +2266,7 @@ static void dmi_event_log_status(u8 code) + "Full" /* 1 */ + }; + +- printf(" %s, %s", ++ pr_attr("Status", "%s, %s", + valid[(code >> 0) & 1], full[(code >> 1) & 1]); + } + +@@ -2209,16 +2278,17 @@ static void dmi_event_log_address(u8 method, const u8 *p) + case 0x00: + case 0x01: + case 0x02: +- printf(" Index 0x%04X, Data 0x%04X", WORD(p), WORD(p + 2)); ++ pr_attr("Access Address", "Index 0x%04X, Data 0x%04X", ++ WORD(p), WORD(p + 2)); + break; + case 0x03: +- printf(" 0x%08X", DWORD(p)); ++ pr_attr("Access Address", "0x%08X", DWORD(p)); + break; + case 0x04: +- printf(" 0x%04X", WORD(p)); ++ pr_attr("Access Address", "0x%04X", WORD(p)); + break; + default: +- printf(" Unknown"); ++ pr_attr("Access Address", "Unknown"); + } + } + +@@ -2295,19 +2365,22 @@ static const char *dmi_event_log_descriptor_format(u8 code) + return out_of_spec; + } + +-static void dmi_event_log_descriptors(u8 count, u8 len, const u8 *p, const char *prefix) ++static void dmi_event_log_descriptors(u8 count, u8 len, const u8 *p) + { + /* 7.16.1 */ ++ char attr[16]; + int i; + + for (i = 0; i < count; i++) + { + if (len >= 0x02) + { +- printf("%sDescriptor %u: %s\n", +- prefix, i + 1, dmi_event_log_descriptor_type(p[i * len])); +- printf("%sData Format %u: %s\n", +- prefix, i + 1, dmi_event_log_descriptor_format(p[i * len + 1])); ++ sprintf(attr, "Descriptor %hu", i + 1); ++ pr_attr(attr, "%s", ++ dmi_event_log_descriptor_type(p[i * len])); ++ sprintf(attr, "Data Format %hu", i + 1); ++ pr_attr(attr, "%s", ++ dmi_event_log_descriptor_format(p[i * len + 1])); + } + } + } +@@ -2385,40 +2458,40 @@ static const char *dmi_memory_array_ec_type(u8 code) + static void dmi_memory_array_error_handle(u16 code) + { + if (code == 0xFFFE) +- printf(" Not Provided"); ++ pr_attr("Error Information Handle", "Not Provided"); + else if (code == 0xFFFF) +- printf(" No Error"); ++ pr_attr("Error Information Handle", "No Error"); + else +- printf(" 0x%04X", code); ++ pr_attr("Error Information Handle", "0x%04X", code); + } + + /* + * 7.18 Memory Device (Type 17) + */ + +-static void dmi_memory_device_width(u16 code) ++static void dmi_memory_device_width(const char *attr, u16 code) + { + /* + * If no memory module is present, width may be 0 + */ + if (code == 0xFFFF || code == 0) +- printf(" Unknown"); ++ pr_attr(attr, "Unknown"); + else +- printf(" %u bits", code); ++ pr_attr(attr, "%u bits", code); + } + + static void dmi_memory_device_size(u16 code) + { + if (code == 0) +- printf(" No Module Installed"); ++ pr_attr("Size", "No Module Installed"); + else if (code == 0xFFFF) +- printf(" Unknown"); ++ pr_attr("Size", "Unknown"); + else + { + u64 s = { .l = code & 0x7FFF }; + if (!(code & 0x8000)) + s.l <<= 10; +- dmi_print_memory_size(s, 1); ++ dmi_print_memory_size("Size", s, 1); + } + } + +@@ -2431,19 +2504,20 @@ static void dmi_memory_device_extended_size(u32 code) + * as an integer without rounding + */ + if (code & 0x3FFUL) +- printf(" %lu MB", (unsigned long)code); ++ pr_attr("Size", "%lu MB", (unsigned long)code); + else if (code & 0xFFC00UL) +- printf(" %lu GB", (unsigned long)code >> 10); ++ pr_attr("Size", "%lu GB", (unsigned long)code >> 10); + else +- printf(" %lu TB", (unsigned long)code >> 20); ++ pr_attr("Size", "%lu TB", (unsigned long)code >> 20); + } + +-static void dmi_memory_voltage_value(u16 code) ++static void dmi_memory_voltage_value(const char *attr, u16 code) + { + if (code == 0) +- printf(" Unknown"); ++ pr_attr(attr, "Unknown"); + else +- printf(code % 100 ? " %g V" : " %.1f V", (float)code / 1000); ++ pr_attr(attr, code % 100 ? "%g V" : "%.1f V", ++ (float)code / 1000); + } + + static const char *dmi_memory_device_form_factor(u8 code) +@@ -2476,11 +2550,11 @@ static const char *dmi_memory_device_form_factor(u8 code) + static void dmi_memory_device_set(u8 code) + { + if (code == 0) +- printf(" None"); ++ pr_attr("Set", "None"); + else if (code == 0xFF) +- printf(" Unknown"); ++ pr_attr("Set", "Unknown"); + else +- printf(" %u", code); ++ pr_attr("Set", "%u", code); + } + + static const char *dmi_memory_device_type(u8 code) +@@ -2547,25 +2621,29 @@ static void dmi_memory_device_type_detail(u16 code) + "Unbuffered (Unregistered)", + "LRDIMM" /* 15 */ + }; ++ char list[172]; /* Update length if you touch the array above */ + + if ((code & 0xFFFE) == 0) +- printf(" None"); ++ pr_attr("Type Detail", "None"); + else + { +- int i; ++ int i, off = 0; + ++ list[0] = '\0'; + for (i = 1; i <= 15; i++) + if (code & (1 << i)) +- printf(" %s", detail[i - 1]); ++ off += sprintf(list + off, off ? " %s" : "%s", ++ detail[i - 1]); ++ pr_attr("Type Detail", list); + } + } + +-static void dmi_memory_device_speed(u16 code) ++static void dmi_memory_device_speed(const char *attr, u16 code) + { + if (code == 0) +- printf(" Unknown"); ++ pr_attr(attr, "Unknown"); + else +- printf(" %u MT/s", code); ++ pr_attr(attr, "%u MT/s", code); + } + + static void dmi_memory_technology(u8 code) +@@ -2581,9 +2659,9 @@ static void dmi_memory_technology(u8 code) + "Intel Optane DC persistent memory" /* 0x07 */ + }; + if (code >= 0x01 && code <= 0x07) +- printf(" %s", technology[code - 0x01]); ++ pr_attr("Memory Technology", "%s", technology[code - 0x01]); + else +- printf(" %s", out_of_spec); ++ pr_attr("Memory Technology", "%s", out_of_spec); + } + + static void dmi_memory_operating_mode_capability(u16 code) +@@ -2596,49 +2674,54 @@ static void dmi_memory_operating_mode_capability(u16 code) + "Byte-accessible persistent memory", + "Block-accessible persistent memory" /* 5 */ + }; ++ char list[99]; /* Update length if you touch the array above */ + + if ((code & 0xFFFE) == 0) +- printf(" None"); ++ pr_attr("Memory Operating Mode Capability", "None"); + else { +- int i; ++ int i, off = 0; + ++ list[0] = '\0'; + for (i = 1; i <= 5; i++) + if (code & (1 << i)) +- printf(" %s", mode[i - 1]); ++ off += sprintf(list + off, off ? " %s" : "%s", ++ mode[i - 1]); ++ pr_attr("Memory Operating Mode Capability", list); + } + } + +-static void dmi_memory_manufacturer_id(u16 code) ++static void dmi_memory_manufacturer_id(const char *attr, u16 code) + { + /* 7.18.8 */ + /* 7.18.10 */ + /* LSB is 7-bit Odd Parity number of continuation codes */ + if (code == 0) +- printf(" Unknown"); ++ pr_attr(attr, "Unknown"); + else +- printf(" Bank %d, Hex 0x%02X", (code & 0x7F) + 1, code >> 8); ++ pr_attr(attr, "Bank %d, Hex 0x%02X", ++ (code & 0x7F) + 1, code >> 8); + } + +-static void dmi_memory_product_id(u16 code) ++static void dmi_memory_product_id(const char *attr, u16 code) + { + /* 7.18.9 */ + /* 7.18.11 */ + if (code == 0) +- printf(" Unknown"); ++ pr_attr(attr, "Unknown"); + else +- printf(" 0x%04X", code); ++ pr_attr(attr, "0x%04X", code); + } + +-static void dmi_memory_size(u64 code) ++static void dmi_memory_size(const char *attr, u64 code) + { + /* 7.18.12 */ + /* 7.18.13 */ + if (code.h == 0xFFFFFFFF && code.l == 0xFFFFFFFF) +- printf(" Unknown"); ++ pr_attr(attr, "Unknown"); + else if (code.h == 0x0 && code.l == 0x0) +- printf(" None"); ++ pr_attr(attr, "None"); + else +- dmi_print_memory_size(code, 0); ++ dmi_print_memory_size(attr, code, 0); + } + + /* +@@ -2704,17 +2787,17 @@ static const char *dmi_memory_error_operation(u8 code) + static void dmi_memory_error_syndrome(u32 code) + { + if (code == 0x00000000) +- printf(" Unknown"); ++ pr_attr("Vendor Syndrome", "Unknown"); + else +- printf(" 0x%08X", code); ++ pr_attr("Vendor Syndrome", "0x%08X", code); + } + +-static void dmi_32bit_memory_error_address(u32 code) ++static void dmi_32bit_memory_error_address(const char *attr, u32 code) + { + if (code == 0x80000000) +- printf(" Unknown"); ++ pr_attr(attr, "Unknown"); + else +- printf(" 0x%08X", code); ++ pr_attr(attr, "0x%08X", code); + } + + /* +@@ -2724,23 +2807,23 @@ static void dmi_32bit_memory_error_address(u32 code) + static void dmi_mapped_address_size(u32 code) + { + if (code == 0) +- printf(" Invalid"); ++ pr_attr("Range Size", "Invalid"); + else + { + u64 size; + + size.h = 0; + size.l = code; +- dmi_print_memory_size(size, 1); ++ dmi_print_memory_size("Range Size", size, 1); + } + } + + static void dmi_mapped_address_extended_size(u64 start, u64 end) + { + if (start.h == end.h && start.l == end.l) +- printf(" Invalid"); ++ pr_attr("Range Size", "Invalid"); + else +- dmi_print_memory_size(u64_range(start, end), 0); ++ dmi_print_memory_size("Range Size", u64_range(start, end), 0); + } + + /* +@@ -2750,36 +2833,32 @@ static void dmi_mapped_address_extended_size(u64 start, u64 end) + static void dmi_mapped_address_row_position(u8 code) + { + if (code == 0) +- printf(" %s", out_of_spec); ++ pr_attr("Partition Row Position", "%s", out_of_spec); + else if (code == 0xFF) +- printf(" Unknown"); ++ pr_attr("Partition Row Position", "Unknown"); + else +- printf(" %u", code); ++ pr_attr("Partition Row Position", "%u", code); + } + +-static void dmi_mapped_address_interleave_position(u8 code, const char *prefix) ++static void dmi_mapped_address_interleave_position(u8 code) + { + if (code != 0) + { +- printf("%sInterleave Position:", prefix); + if (code == 0xFF) +- printf(" Unknown"); ++ pr_attr("Interleave Position", "Unknown"); + else +- printf(" %u", code); +- printf("\n"); ++ pr_attr("Interleave Position", "%u", code); + } + } + +-static void dmi_mapped_address_interleaved_data_depth(u8 code, const char *prefix) ++static void dmi_mapped_address_interleaved_data_depth(u8 code) + { + if (code != 0) + { +- printf("%sInterleaved Data Depth:", prefix); + if (code == 0xFF) +- printf(" Unknown"); ++ pr_attr("Interleaved Data Depth", "Unknown"); + else +- printf(" %u", code); +- printf("\n"); ++ pr_attr("Interleaved Data Depth", "%u", code); + } + } + +@@ -2859,25 +2938,25 @@ static const char *dmi_battery_chemistry(u8 code) + static void dmi_battery_capacity(u16 code, u8 multiplier) + { + if (code == 0) +- printf(" Unknown"); ++ pr_attr("Design Capacity", "Unknown"); + else +- printf(" %u mWh", code * multiplier); ++ pr_attr("Design Capacity", "%u mWh", code * multiplier); + } + + static void dmi_battery_voltage(u16 code) + { + if (code == 0) +- printf(" Unknown"); ++ pr_attr("Design Voltage", "Unknown"); + else +- printf(" %u mV", code); ++ pr_attr("Design Voltage", "%u mV", code); + } + + static void dmi_battery_maximum_error(u8 code) + { + if (code == 0xFF) +- printf(" Unknown"); ++ pr_attr("Maximum Error", "Unknown"); + else +- printf(" %u%%", code); ++ pr_attr("Maximum Error", "%u%%", code); + } + + /* +@@ -2897,20 +2976,20 @@ static const char *dmi_system_reset_boot_option(u8 code) + return option[code]; + } + +-static void dmi_system_reset_count(u16 code) ++static void dmi_system_reset_count(const char *attr, u16 code) + { + if (code == 0xFFFF) +- printf(" Unknown"); ++ pr_attr(attr, "Unknown"); + else +- printf(" %u", code); ++ pr_attr(attr, "%u", code); + } + +-static void dmi_system_reset_timer(u16 code) ++static void dmi_system_reset_timer(const char *attr, u16 code) + { + if (code == 0xFFFF) +- printf(" Unknown"); ++ pr_attr(attr, "Unknown"); + else +- printf(" %u min", code); ++ pr_attr(attr, "%u min", code); + } + + /* +@@ -2935,27 +3014,32 @@ static const char *dmi_hardware_security_status(u8 code) + + static void dmi_power_controls_power_on(const u8 *p) + { ++ char time[15]; ++ int off = 0; ++ + /* 7.26.1 */ + if (dmi_bcd_range(p[0], 0x01, 0x12)) +- printf(" %02X", p[0]); ++ off += sprintf(time + off, "%02X", p[0]); + else +- printf(" *"); ++ off += sprintf(time + off, "*"); + if (dmi_bcd_range(p[1], 0x01, 0x31)) +- printf("-%02X", p[1]); ++ off += sprintf(time + off, "-%02X", p[1]); + else +- printf("-*"); ++ off += sprintf(time + off, "-*"); + if (dmi_bcd_range(p[2], 0x00, 0x23)) +- printf(" %02X", p[2]); ++ off += sprintf(time + off, " %02X", p[2]); + else +- printf(" *"); ++ off += sprintf(time + off, " *"); + if (dmi_bcd_range(p[3], 0x00, 0x59)) +- printf(":%02X", p[3]); ++ off += sprintf(time + off, ":%02X", p[3]); + else +- printf(":*"); ++ off += sprintf(time + off, ":*"); + if (dmi_bcd_range(p[4], 0x00, 0x59)) +- printf(":%02X", p[4]); ++ off += sprintf(time + off, ":%02X", p[4]); + else +- printf(":*"); ++ off += sprintf(time + off, ":*"); ++ ++ pr_attr("Next Scheduled Power-on", time); + } + + /* +@@ -3001,28 +3085,28 @@ static const char *dmi_probe_status(u8 code) + return out_of_spec; + } + +-static void dmi_voltage_probe_value(u16 code) ++static void dmi_voltage_probe_value(const char *attr, u16 code) + { + if (code == 0x8000) +- printf(" Unknown"); ++ pr_attr(attr, "Unknown"); + else +- printf(" %.3f V", (float)(i16)code / 1000); ++ pr_attr(attr, "%.3f V", (float)(i16)code / 1000); + } + + static void dmi_voltage_probe_resolution(u16 code) + { + if (code == 0x8000) +- printf(" Unknown"); ++ pr_attr("Resolution", "Unknown"); + else +- printf(" %.1f mV", (float)code / 10); ++ pr_attr("Resolution", "%.1f mV", (float)code / 10); + } + + static void dmi_probe_accuracy(u16 code) + { + if (code == 0x8000) +- printf(" Unknown"); ++ pr_attr("Accuracy", "Unknown"); + else +- printf(" %.2f%%", (float)code / 100); ++ pr_attr("Accuracy", "%.2f%%", (float)code / 100); + } + + /* +@@ -3058,9 +3142,9 @@ static const char *dmi_cooling_device_type(u8 code) + static void dmi_cooling_device_speed(u16 code) + { + if (code == 0x8000) +- printf(" Unknown Or Non-rotating"); ++ pr_attr("Nominal Speed", "Unknown Or Non-rotating"); + else +- printf(" %u rpm", code); ++ pr_attr("Nominal Speed", "%u rpm", code); + } + + /* +@@ -3093,40 +3177,40 @@ static const char *dmi_temperature_probe_location(u8 code) + return out_of_spec; + } + +-static void dmi_temperature_probe_value(u16 code) ++static void dmi_temperature_probe_value(const char *attr, u16 code) + { + if (code == 0x8000) +- printf(" Unknown"); ++ pr_attr(attr, "Unknown"); + else +- printf(" %.1f deg C", (float)(i16)code / 10); ++ pr_attr(attr, "%.1f deg C", (float)(i16)code / 10); + } + + static void dmi_temperature_probe_resolution(u16 code) + { + if (code == 0x8000) +- printf(" Unknown"); ++ pr_attr("Resolution", "Unknown"); + else +- printf(" %.3f deg C", (float)code / 1000); ++ pr_attr("Resolution", "%.3f deg C", (float)code / 1000); + } + + /* + * 7.30 Electrical Current Probe (Type 29) + */ + +-static void dmi_current_probe_value(u16 code) ++static void dmi_current_probe_value(const char *attr, u16 code) + { + if (code == 0x8000) +- printf(" Unknown"); ++ pr_attr(attr, "Unknown"); + else +- printf(" %.3f A", (float)(i16)code / 1000); ++ pr_attr(attr, "%.3f A", (float)(i16)code / 1000); + } + + static void dmi_current_probe_resolution(u16 code) + { + if (code == 0x8000) +- printf(" Unknown"); ++ pr_attr("Resolution", "Unknown"); + else +- printf(" %.1f mA", (float)code / 10); ++ pr_attr("Resolution", "%.1f mA", (float)code / 10); + } + + /* +@@ -3160,12 +3244,12 @@ static const char *dmi_system_boot_status(u8 code) + * 7.34 64-bit Memory Error Information (Type 33) + */ + +-static void dmi_64bit_memory_error_address(u64 code) ++static void dmi_64bit_memory_error_address(const char *attr, u64 code) + { + if (code.h == 0x80000000 && code.l == 0x00000000) +- printf(" Unknown"); ++ pr_attr(attr, "Unknown"); + else +- printf(" 0x%08X%08X", code.h, code.l); ++ pr_attr(attr, "0x%08X%08X", code.h, code.l); + } + + /* +@@ -3253,17 +3337,20 @@ static const char *dmi_memory_channel_type(u8 code) + return out_of_spec; + } + +-static void dmi_memory_channel_devices(u8 count, const u8 *p, const char *prefix) ++static void dmi_memory_channel_devices(u8 count, const u8 *p) + { ++ char attr[18]; + int i; + + for (i = 1; i <= count; i++) + { +- printf("%sDevice %u Load: %u\n", +- prefix, i, p[3 * i]); ++ sprintf(attr, "Device %hu Load", i); ++ pr_attr(attr, "%u", p[3 * i]); + if (!(opt.flags & FLAG_QUIET)) +- printf("%sDevice %u Handle: 0x%04X\n", +- prefix, i, WORD(p + 3 * i + 1)); ++ { ++ sprintf(attr, "Device %hu Handle", i); ++ pr_attr(attr, "0x%04X", WORD(p + 3 * i + 1)); ++ } + } + } + +@@ -3291,12 +3378,13 @@ static void dmi_ipmi_base_address(u8 type, const u8 *p, u8 lsb) + { + if (type == 0x04) /* SSIF */ + { +- printf("0x%02X (SMBus)", (*p) >> 1); ++ pr_attr("Base Address", "0x%02X (SMBus)", (*p) >> 1); + } + else + { + u64 address = QWORD(p); +- printf("0x%08X%08X (%s)", address.h, (address.l & ~1) | lsb, ++ pr_attr("Base Address", "0x%08X%08X (%s)", ++ address.h, (address.l & ~1) | lsb, + address.l & 1 ? "I/O" : "Memory-mapped"); + } + } +@@ -3322,9 +3410,9 @@ static const char *dmi_ipmi_register_spacing(u8 code) + static void dmi_power_supply_power(u16 code) + { + if (code == 0x8000) +- printf(" Unknown"); ++ pr_attr("Max Power Capacity", "Unknown"); + else +- printf(" %u W", (unsigned int)code); ++ pr_attr("Max Power Capacity", "%u W", (unsigned int)code); + } + + static const char *dmi_power_supply_type(u8 code) +@@ -3387,7 +3475,7 @@ static const char *dmi_power_supply_range_switching(u8 code) + * whether it's worth the effort. + */ + +-static void dmi_additional_info(const struct dmi_header *h, const char *prefix) ++static void dmi_additional_info(const struct dmi_header *h) + { + u8 *p = h->data + 4; + u8 count = *p++; +@@ -3403,30 +3491,28 @@ static void dmi_additional_info(const struct dmi_header *h, const char *prefix) + length = p[0x00]; + if (length < 0x05 || h->length < offset + length) break; + +- printf("%s\tReferenced Handle: 0x%04x\n", +- prefix, WORD(p + 0x01)); +- printf("%s\tReferenced Offset: 0x%02x\n", +- prefix, p[0x03]); +- printf("%s\tString: %s\n", +- prefix, dmi_string(h, p[0x04])); ++ pr_attr("Referenced Handle", "0x%04x", ++ WORD(p + 0x01)); ++ pr_attr("Referenced Offset", "0x%02x", ++ p[0x03]); ++ pr_attr("String", "%s", ++ dmi_string(h, p[0x04])); + +- printf("%s\tValue: ", prefix); + switch (length - 0x05) + { + case 1: +- printf("0x%02x", p[0x05]); ++ pr_attr("Value", "0x%02x", p[0x05]); + break; + case 2: +- printf("0x%04x", WORD(p + 0x05)); ++ pr_attr("Value", "0x%04x", WORD(p + 0x05)); + break; + case 4: +- printf("0x%08x", DWORD(p + 0x05)); ++ pr_attr("Value", "0x%08x", DWORD(p + 0x05)); + break; + default: +- printf("Unexpected size"); ++ pr_attr("Value", "Unexpected size"); + break; + } +- printf("\n"); + + p += length; + offset += length; +@@ -3580,8 +3666,7 @@ static void dmi_parse_protocol_record(const char *prefix, u8 *rec) + * we can just pick a sufficiently recent version here. + */ + printf("%s\tService UUID: ", prefix); +- dmi_system_uuid(&rdata[0], 0x311); +- printf("\n"); ++ dmi_system_uuid(NULL, &rdata[0], 0x311); /* FIXME */ + + /* + * DSP0270: 8.6: Redfish Over IP Host IP Assignment Type +@@ -3710,7 +3795,7 @@ static void dmi_parse_controller_structure(const struct dmi_header *h, + return; + + type = data[0x4]; +- printf("%sHost Interface Type: %s\n", prefix, ++ pr_attr("Host Interface Type", "%s", + dmi_management_controller_host_type(type)); + + /* +@@ -3725,17 +3810,17 @@ static void dmi_parse_controller_structure(const struct dmi_header *h, + /* DSP0270: 8.3 Table 2: Device Type */ + type = data[0x6]; + +- printf("%sDevice Type: %s\n", prefix, ++ pr_attr("Device Type", "%s", + dmi_parse_device_type(type)); + if (type == 0x2 && len >= 5) + { + /* USB Device Type - need at least 6 bytes */ + u8 *usbdata = &data[0x7]; + /* USB Device Descriptor: idVendor */ +- printf("%sidVendor: 0x%04x\n", prefix, ++ pr_attr("idVendor", "0x%04x", + WORD(&usbdata[0x0])); + /* USB Device Descriptor: idProduct */ +- printf("%sidProduct: 0x%04x\n", prefix, ++ pr_attr("idProduct", "0x%04x", + WORD(&usbdata[0x2])); + /* + * USB Serial number is here, but its useless, don't +@@ -3747,16 +3832,16 @@ static void dmi_parse_controller_structure(const struct dmi_header *h, + /* PCI Device Type - Need at least 8 bytes */ + u8 *pcidata = &data[0x7]; + /* PCI Device Descriptor: VendorID */ +- printf("%sVendorID: 0x%04x\n", prefix, ++ pr_attr("VendorID", "0x%04x", + WORD(&pcidata[0x0])); + /* PCI Device Descriptor: DeviceID */ +- printf("%sDeviceID: 0x%04x\n", prefix, ++ pr_attr("DeviceID", "0x%04x", + WORD(&pcidata[0x2])); + /* PCI Device Descriptor: PCI SubvendorID */ +- printf("%sSubVendorID: 0x%04x\n", prefix, ++ pr_attr("SubVendorID", "0x%04x", + WORD(&pcidata[0x4])); + /* PCI Device Descriptor: PCI SubdeviceID */ +- printf("%sSubDeviceID: 0x%04x\n", prefix, ++ pr_attr("SubDeviceID", "0x%04x", + WORD(&pcidata[0x6])); + } + else if (type == 0x4 && len >= 5) +@@ -3764,8 +3849,8 @@ static void dmi_parse_controller_structure(const struct dmi_header *h, + /* OEM Device Type - Need at least 4 bytes */ + u8 *oemdata = &data[0x7]; + /* OEM Device Descriptor: IANA */ +- printf("%sVendor ID: 0x%02x:0x%02x:0x%02x:0x%02x\n", +- prefix, oemdata[0x0], oemdata[0x1], ++ pr_attr("Vendor ID", "0x%02x:0x%02x:0x%02x:0x%02x", ++ oemdata[0x0], oemdata[0x1], + oemdata[0x2], oemdata[0x3]); + } + /* Don't mess with unknown types for now */ +@@ -3848,7 +3933,7 @@ static void dmi_tpm_vendor_id(const u8 *p) + /* Terminate the string */ + vendor_id[i] = '\0'; + +- printf(" %s", vendor_id); ++ pr_attr("Vendor ID", "%s", vendor_id); + } + + static void dmi_tpm_characteristics(u64 code, const char *prefix) +@@ -3894,11 +3979,11 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + case 0: /* 7.1 BIOS Information */ + pr_handle_name("BIOS Information"); + if (h->length < 0x12) break; +- printf("\tVendor: %s\n", ++ pr_attr("Vendor", "%s", + dmi_string(h, data[0x04])); +- printf("\tVersion: %s\n", ++ pr_attr("Version", "%s", + dmi_string(h, data[0x05])); +- printf("\tRelease Date: %s\n", ++ pr_attr("Release Date", "%s", + dmi_string(h, data[0x08])); + /* + * On IA-64, the BIOS base address will read 0 because +@@ -3907,15 +3992,11 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + */ + if (WORD(data + 0x06) != 0) + { +- printf("\tAddress: 0x%04X0\n", ++ pr_attr("Address", "0x%04X0", + WORD(data + 0x06)); +- printf("\tRuntime Size:"); + dmi_bios_runtime_size((0x10000 - WORD(data + 0x06)) << 4); +- printf("\n"); + } +- printf("\tROM Size:"); + dmi_bios_rom_size(data[0x09], h->length < 0x1A ? 16 : WORD(data + 0x18)); +- printf("\n"); + printf("\tCharacteristics:\n"); + dmi_bios_characteristics(QWORD(data + 0x0A), "\t\t"); + if (h->length < 0x13) break; +@@ -3924,61 +4005,59 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + dmi_bios_characteristics_x2(data[0x13], "\t\t"); + if (h->length < 0x18) break; + if (data[0x14] != 0xFF && data[0x15] != 0xFF) +- printf("\tBIOS Revision: %u.%u\n", ++ pr_attr("BIOS Revision", "%u.%u", + data[0x14], data[0x15]); + if (data[0x16] != 0xFF && data[0x17] != 0xFF) +- printf("\tFirmware Revision: %u.%u\n", ++ pr_attr("Firmware Revision", "%u.%u", + data[0x16], data[0x17]); + break; + + case 1: /* 7.2 System Information */ + pr_handle_name("System Information"); + if (h->length < 0x08) break; +- printf("\tManufacturer: %s\n", ++ pr_attr("Manufacturer", "%s", + dmi_string(h, data[0x04])); +- printf("\tProduct Name: %s\n", ++ pr_attr("Product Name", "%s", + dmi_string(h, data[0x05])); +- printf("\tVersion: %s\n", ++ pr_attr("Version", "%s", + dmi_string(h, data[0x06])); +- printf("\tSerial Number: %s\n", ++ pr_attr("Serial Number", "%s", + dmi_string(h, data[0x07])); + if (h->length < 0x19) break; +- printf("\tUUID: "); +- dmi_system_uuid(data + 0x08, ver); +- printf("\n"); +- printf("\tWake-up Type: %s\n", ++ dmi_system_uuid("UUID", data + 0x08, ver); ++ pr_attr("Wake-up Type", "%s", + dmi_system_wake_up_type(data[0x18])); + if (h->length < 0x1B) break; +- printf("\tSKU Number: %s\n", ++ pr_attr("SKU Number", "%s", + dmi_string(h, data[0x19])); +- printf("\tFamily: %s\n", ++ pr_attr("Family", "%s", + dmi_string(h, data[0x1A])); + break; + + case 2: /* 7.3 Base Board Information */ + pr_handle_name("Base Board Information"); + if (h->length < 0x08) break; +- printf("\tManufacturer: %s\n", ++ pr_attr("Manufacturer", "%s", + dmi_string(h, data[0x04])); +- printf("\tProduct Name: %s\n", ++ pr_attr("Product Name", "%s", + dmi_string(h, data[0x05])); +- printf("\tVersion: %s\n", ++ pr_attr("Version", "%s", + dmi_string(h, data[0x06])); +- printf("\tSerial Number: %s\n", ++ pr_attr("Serial Number", "%s", + dmi_string(h, data[0x07])); + if (h->length < 0x09) break; +- printf("\tAsset Tag: %s\n", ++ pr_attr("Asset Tag", "%s", + dmi_string(h, data[0x08])); + if (h->length < 0x0A) break; + printf("\tFeatures:"); + dmi_base_board_features(data[0x09], "\t\t"); + if (h->length < 0x0E) break; +- printf("\tLocation In Chassis: %s\n", ++ pr_attr("Location In Chassis", "%s", + dmi_string(h, data[0x0A])); + if (!(opt.flags & FLAG_QUIET)) +- printf("\tChassis Handle: 0x%04X\n", ++ pr_attr("Chassis Handle", "0x%04X", + WORD(data + 0x0B)); +- printf("\tType: %s\n", ++ pr_attr("Type", "%s", + dmi_base_board_type(data[0x0D])); + if (h->length < 0x0F) break; + if (h->length < 0x0F + data[0x0E] * sizeof(u16)) break; +@@ -3989,109 +4068,94 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + case 3: /* 7.4 Chassis Information */ + pr_handle_name("Chassis Information"); + if (h->length < 0x09) break; +- printf("\tManufacturer: %s\n", ++ pr_attr("Manufacturer", "%s", + dmi_string(h, data[0x04])); +- printf("\tType: %s\n", ++ pr_attr("Type", "%s", + dmi_chassis_type(data[0x05])); +- printf("\tLock: %s\n", ++ pr_attr("Lock", "%s", + dmi_chassis_lock(data[0x05] >> 7)); +- printf("\tVersion: %s\n", ++ pr_attr("Version", "%s", + dmi_string(h, data[0x06])); +- printf("\tSerial Number: %s\n", ++ pr_attr("Serial Number", "%s", + dmi_string(h, data[0x07])); +- printf("\tAsset Tag: %s\n", ++ pr_attr("Asset Tag", "%s", + dmi_string(h, data[0x08])); + if (h->length < 0x0D) break; +- printf("\tBoot-up State: %s\n", ++ pr_attr("Boot-up State", "%s", + dmi_chassis_state(data[0x09])); +- printf("\tPower Supply State: %s\n", ++ pr_attr("Power Supply State", "%s", + dmi_chassis_state(data[0x0A])); +- printf("\tThermal State: %s\n", ++ pr_attr("Thermal State", "%s", + dmi_chassis_state(data[0x0B])); +- printf("\tSecurity Status: %s\n", ++ pr_attr("Security Status", "%s", + dmi_chassis_security_status(data[0x0C])); + if (h->length < 0x11) break; +- printf("\tOEM Information: 0x%08X\n", ++ pr_attr("OEM Information", "0x%08X", + DWORD(data + 0x0D)); + if (h->length < 0x13) break; +- printf("\tHeight:"); + dmi_chassis_height(data[0x11]); +- printf("\n"); +- printf("\tNumber Of Power Cords:"); + dmi_chassis_power_cords(data[0x12]); +- printf("\n"); + if (h->length < 0x15) break; + if (h->length < 0x15 + data[0x13] * data[0x14]) break; + dmi_chassis_elements(data[0x13], data[0x14], data + 0x15, "\t"); + if (h->length < 0x16 + data[0x13] * data[0x14]) break; +- printf("\tSKU Number: %s\n", ++ pr_attr("SKU Number", "%s", + dmi_string(h, data[0x15 + data[0x13] * data[0x14]])); + break; + + case 4: /* 7.5 Processor Information */ + pr_handle_name("Processor Information"); + if (h->length < 0x1A) break; +- printf("\tSocket Designation: %s\n", ++ pr_attr("Socket Designation", "%s", + dmi_string(h, data[0x04])); +- printf("\tType: %s\n", ++ pr_attr("Type", "%s", + dmi_processor_type(data[0x05])); +- printf("\tFamily: %s\n", ++ pr_attr("Family", "%s", + dmi_processor_family(h, ver)); +- printf("\tManufacturer: %s\n", ++ pr_attr("Manufacturer", "%s", + dmi_string(h, data[0x07])); + dmi_processor_id(h, "\t"); +- printf("\tVersion: %s\n", ++ pr_attr("Version", "%s", + dmi_string(h, data[0x10])); +- printf("\tVoltage:"); +- dmi_processor_voltage(data[0x11]); +- printf("\n"); +- printf("\tExternal Clock: "); +- dmi_processor_frequency(data + 0x12); +- printf("\n"); +- printf("\tMax Speed: "); +- dmi_processor_frequency(data + 0x14); +- printf("\n"); +- printf("\tCurrent Speed: "); +- dmi_processor_frequency(data + 0x16); +- printf("\n"); ++ dmi_processor_voltage("Voltage", data[0x11]); ++ dmi_processor_frequency("External Clock", data + 0x12); ++ dmi_processor_frequency("Max Speed", data + 0x14); ++ dmi_processor_frequency("Current Speed", data + 0x16); + if (data[0x18] & (1 << 6)) +- printf("\tStatus: Populated, %s\n", ++ pr_attr("Status", "Populated, %s", + dmi_processor_status(data[0x18] & 0x07)); + else +- printf("\tStatus: Unpopulated\n"); +- printf("\tUpgrade: %s\n", ++ pr_attr("Status", "Unpopulated"); ++ pr_attr("Upgrade", "%s", + dmi_processor_upgrade(data[0x19])); + if (h->length < 0x20) break; + if (!(opt.flags & FLAG_QUIET)) + { +- printf("\tL1 Cache Handle:"); +- dmi_processor_cache(WORD(data + 0x1A), "L1", ver); +- printf("\n"); +- printf("\tL2 Cache Handle:"); +- dmi_processor_cache(WORD(data + 0x1C), "L2", ver); +- printf("\n"); +- printf("\tL3 Cache Handle:"); +- dmi_processor_cache(WORD(data + 0x1E), "L3", ver); +- printf("\n"); ++ dmi_processor_cache("L1 Cache Handle", ++ WORD(data + 0x1A), "L1", ver); ++ dmi_processor_cache("L2 Cache Handle", ++ WORD(data + 0x1C), "L2", ver); ++ dmi_processor_cache("L3 Cache Handle", ++ WORD(data + 0x1E), "L3", ver); + } + if (h->length < 0x23) break; +- printf("\tSerial Number: %s\n", ++ pr_attr("Serial Number", "%s", + dmi_string(h, data[0x20])); +- printf("\tAsset Tag: %s\n", ++ pr_attr("Asset Tag", "%s", + dmi_string(h, data[0x21])); +- printf("\tPart Number: %s\n", ++ pr_attr("Part Number", "%s", + dmi_string(h, data[0x22])); + if (h->length < 0x28) break; + if (data[0x23] != 0) +- printf("\tCore Count: %u\n", ++ pr_attr("Core Count", "%u", + h->length >= 0x2C && data[0x23] == 0xFF ? + WORD(data + 0x2A) : data[0x23]); + if (data[0x24] != 0) +- printf("\tCore Enabled: %u\n", ++ pr_attr("Core Enabled", "%u", + h->length >= 0x2E && data[0x24] == 0xFF ? + WORD(data + 0x2C) : data[0x24]); + if (data[0x25] != 0) +- printf("\tThread Count: %u\n", ++ pr_attr("Thread Count", "%u", + h->length >= 0x30 && data[0x25] == 0xFF ? + WORD(data + 0x2E) : data[0x25]); + printf("\tCharacteristics:"); +@@ -4101,26 +4165,24 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + case 5: /* 7.6 Memory Controller Information */ + pr_handle_name("Memory Controller Information"); + if (h->length < 0x0F) break; +- printf("\tError Detecting Method: %s\n", ++ pr_attr("Error Detecting Method", "%s", + dmi_memory_controller_ed_method(data[0x04])); + printf("\tError Correcting Capabilities:"); + dmi_memory_controller_ec_capabilities(data[0x05], "\t\t"); +- printf("\tSupported Interleave: %s\n", ++ pr_attr("Supported Interleave", "%s", + dmi_memory_controller_interleave(data[0x06])); +- printf("\tCurrent Interleave: %s\n", ++ pr_attr("Current Interleave", "%s", + dmi_memory_controller_interleave(data[0x07])); +- printf("\tMaximum Memory Module Size: %u MB\n", ++ pr_attr("Maximum Memory Module Size", "%u MB", + 1 << data[0x08]); +- printf("\tMaximum Total Memory Size: %u MB\n", ++ pr_attr("Maximum Total Memory Size", "%u MB", + data[0x0E] * (1 << data[0x08])); + printf("\tSupported Speeds:"); + dmi_memory_controller_speeds(WORD(data + 0x09), "\t\t"); + printf("\tSupported Memory Types:"); + dmi_memory_module_types(WORD(data + 0x0B), "\n\t\t"); + printf("\n"); +- printf("\tMemory Module Voltage:"); +- dmi_processor_voltage(data[0x0D]); +- printf("\n"); ++ dmi_processor_voltage("Memory Module Voltage", data[0x0D]); + if (h->length < 0x0F + data[0x0E] * sizeof(u16)) break; + dmi_memory_controller_slots(data[0x0E], data + 0x0F, "\t"); + if (h->length < 0x10 + data[0x0E] * sizeof(u16)) break; +@@ -4131,52 +4193,39 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + case 6: /* 7.7 Memory Module Information */ + pr_handle_name("Memory Module Information"); + if (h->length < 0x0C) break; +- printf("\tSocket Designation: %s\n", ++ pr_attr("Socket Designation", "%s", + dmi_string(h, data[0x04])); +- printf("\tBank Connections:"); + dmi_memory_module_connections(data[0x05]); +- printf("\n"); +- printf("\tCurrent Speed:"); +- dmi_memory_module_speed(data[0x06]); +- printf("\n"); ++ dmi_memory_module_speed("Current Speed", data[0x06]); + printf("\tType:"); + dmi_memory_module_types(WORD(data + 0x07), " "); + printf("\n"); +- printf("\tInstalled Size:"); +- dmi_memory_module_size(data[0x09]); +- printf("\n"); +- printf("\tEnabled Size:"); +- dmi_memory_module_size(data[0x0A]); +- printf("\n"); +- printf("\tError Status:"); ++ dmi_memory_module_size("Installed Size", data[0x09]); ++ dmi_memory_module_size("Enabled Size", data[0x0A]); + dmi_memory_module_error(data[0x0B]); + break; + + case 7: /* 7.8 Cache Information */ + pr_handle_name("Cache Information"); + if (h->length < 0x0F) break; +- printf("\tSocket Designation: %s\n", ++ pr_attr("Socket Designation", "%s", + dmi_string(h, data[0x04])); +- printf("\tConfiguration: %s, %s, Level %u\n", ++ pr_attr("Configuration", "%s, %s, Level %u", + WORD(data + 0x05) & 0x0080 ? "Enabled" : "Disabled", + WORD(data + 0x05) & 0x0008 ? "Socketed" : "Not Socketed", + (WORD(data + 0x05) & 0x0007) + 1); +- printf("\tOperational Mode: %s\n", ++ pr_attr("Operational Mode", "%s", + dmi_cache_mode((WORD(data + 0x05) >> 8) & 0x0003)); +- printf("\tLocation: %s\n", ++ pr_attr("Location", "%s", + dmi_cache_location((WORD(data + 0x05) >> 5) & 0x0003)); +- printf("\tInstalled Size:"); + if (h->length >= 0x1B) +- dmi_cache_size_2(DWORD(data + 0x17)); ++ dmi_cache_size_2("Installed Size", DWORD(data + 0x17)); + else +- dmi_cache_size(WORD(data + 0x09)); +- printf("\n"); +- printf("\tMaximum Size:"); ++ dmi_cache_size("Installed Size", WORD(data + 0x09)); + if (h->length >= 0x17) +- dmi_cache_size_2(DWORD(data + 0x13)); ++ dmi_cache_size_2("Maximum Size", DWORD(data + 0x13)); + else +- dmi_cache_size(WORD(data + 0x07)); +- printf("\n"); ++ dmi_cache_size("Maximum Size", WORD(data + 0x07)); + printf("\tSupported SRAM Types:"); + dmi_cache_types(WORD(data + 0x0B), "\n\t\t"); + printf("\n"); +@@ -4184,73 +4233,71 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + dmi_cache_types(WORD(data + 0x0D), " "); + printf("\n"); + if (h->length < 0x13) break; +- printf("\tSpeed:"); +- dmi_memory_module_speed(data[0x0F]); +- printf("\n"); +- printf("\tError Correction Type: %s\n", ++ dmi_memory_module_speed("Speed", data[0x0F]); ++ pr_attr("Error Correction Type", "%s", + dmi_cache_ec_type(data[0x10])); +- printf("\tSystem Type: %s\n", ++ pr_attr("System Type", "%s", + dmi_cache_type(data[0x11])); +- printf("\tAssociativity: %s\n", ++ pr_attr("Associativity", "%s", + dmi_cache_associativity(data[0x12])); + break; + + case 8: /* 7.9 Port Connector Information */ + pr_handle_name("Port Connector Information"); + if (h->length < 0x09) break; +- printf("\tInternal Reference Designator: %s\n", ++ pr_attr("Internal Reference Designator", "%s", + dmi_string(h, data[0x04])); +- printf("\tInternal Connector Type: %s\n", ++ pr_attr("Internal Connector Type", "%s", + dmi_port_connector_type(data[0x05])); +- printf("\tExternal Reference Designator: %s\n", ++ pr_attr("External Reference Designator", "%s", + dmi_string(h, data[0x06])); +- printf("\tExternal Connector Type: %s\n", ++ pr_attr("External Connector Type", "%s", + dmi_port_connector_type(data[0x07])); +- printf("\tPort Type: %s\n", ++ pr_attr("Port Type", "%s", + dmi_port_type(data[0x08])); + break; + + case 9: /* 7.10 System Slots */ + pr_handle_name("System Slot Information"); + if (h->length < 0x0C) break; +- printf("\tDesignation: %s\n", ++ pr_attr("Designation", "%s", + dmi_string(h, data[0x04])); +- printf("\tType: %s%s\n", ++ pr_attr("Type", "%s%s", + dmi_slot_bus_width(data[0x06]), + dmi_slot_type(data[0x05])); +- printf("\tCurrent Usage: %s\n", ++ pr_attr("Current Usage", "%s", + dmi_slot_current_usage(data[0x07])); +- printf("\tLength: %s\n", ++ pr_attr("Length", "%s", + dmi_slot_length(data[0x08])); +- dmi_slot_id(data[0x09], data[0x0A], data[0x05], "\t"); ++ dmi_slot_id(data[0x09], data[0x0A], data[0x05]); + printf("\tCharacteristics:"); + if (h->length < 0x0D) + dmi_slot_characteristics(data[0x0B], 0x00, "\t\t"); + else + dmi_slot_characteristics(data[0x0B], data[0x0C], "\t\t"); + if (h->length < 0x11) break; +- dmi_slot_segment_bus_func(WORD(data + 0x0D), data[0x0F], data[0x10], "\t"); ++ dmi_slot_segment_bus_func(WORD(data + 0x0D), data[0x0F], data[0x10]); + if (h->length < 0x13) break; +- printf("\tData Bus Width: %u\n", data[0x11]); +- printf("\tPeer Devices: %u\n", data[0x12]); ++ pr_attr("Data Bus Width", "%u", data[0x11]); ++ pr_attr("Peer Devices", "%u", data[0x12]); + if (h->length - 0x13 >= data[0x12] * 5) +- dmi_slot_peers(data[0x12], data + 0x13, "\t"); ++ dmi_slot_peers(data[0x12], data + 0x13); + break; + + case 10: /* 7.11 On Board Devices Information */ +- dmi_on_board_devices(h, ""); ++ dmi_on_board_devices(h); + break; + + case 11: /* 7.12 OEM Strings */ + pr_handle_name("OEM Strings"); + if (h->length < 0x05) break; +- dmi_oem_strings(h, "\t"); ++ dmi_oem_strings(h); + break; + + case 12: /* 7.13 System Configuration Options */ + pr_handle_name("System Configuration Options"); + if (h->length < 0x05) break; +- dmi_system_configuration_options(h, "\t"); ++ dmi_system_configuration_options(h); + break; + + case 13: /* 7.14 BIOS Language Information */ +@@ -4258,19 +4305,19 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + if (h->length < 0x16) break; + if (ver >= 0x0201) + { +- printf("\tLanguage Description Format: %s\n", ++ pr_attr("Language Description Format", "%s", + dmi_bios_language_format(data[0x05])); + } + printf("\tInstallable Languages: %u\n", data[0x04]); + dmi_bios_languages(h, "\t\t"); +- printf("\tCurrently Installed Language: %s\n", ++ pr_attr("Currently Installed Language", "%s", + dmi_string(h, data[0x15])); + break; + + case 14: /* 7.15 Group Associations */ + pr_handle_name("Group Associations"); + if (h->length < 0x05) break; +- printf("\tName: %s\n", ++ pr_attr("Name", "%s", + dmi_string(h, data[0x04])); + printf("\tItems: %u\n", + (h->length - 0x05) / 3); +@@ -4280,51 +4327,47 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + case 15: /* 7.16 System Event Log */ + pr_handle_name("System Event Log"); + if (h->length < 0x14) break; +- printf("\tArea Length: %u bytes\n", ++ pr_attr("Area Length", "%u bytes", + WORD(data + 0x04)); +- printf("\tHeader Start Offset: 0x%04X\n", ++ pr_attr("Header Start Offset", "0x%04X", + WORD(data + 0x06)); + if (WORD(data + 0x08) - WORD(data + 0x06)) +- printf("\tHeader Length: %u byte%s\n", ++ pr_attr("Header Length", "%u byte%s", + WORD(data + 0x08) - WORD(data + 0x06), + WORD(data + 0x08) - WORD(data + 0x06) > 1 ? "s" : ""); +- printf("\tData Start Offset: 0x%04X\n", ++ pr_attr("Data Start Offset", "0x%04X", + WORD(data + 0x08)); +- printf("\tAccess Method: %s\n", ++ pr_attr("Access Method", "%s", + dmi_event_log_method(data[0x0A])); +- printf("\tAccess Address:"); + dmi_event_log_address(data[0x0A], data + 0x10); +- printf("\n"); +- printf("\tStatus:"); + dmi_event_log_status(data[0x0B]); +- printf("\n"); +- printf("\tChange Token: 0x%08X\n", ++ pr_attr("Change Token", "0x%08X", + DWORD(data + 0x0C)); + if (h->length < 0x17) break; +- printf("\tHeader Format: %s\n", ++ pr_attr("Header Format", "%s", + dmi_event_log_header_type(data[0x14])); +- printf("\tSupported Log Type Descriptors: %u\n", ++ pr_attr("Supported Log Type Descriptors", "%u", + data[0x15]); + if (h->length < 0x17 + data[0x15] * data[0x16]) break; +- dmi_event_log_descriptors(data[0x15], data[0x16], data + 0x17, "\t"); ++ dmi_event_log_descriptors(data[0x15], data[0x16], data + 0x17); + break; + + case 16: /* 7.17 Physical Memory Array */ + pr_handle_name("Physical Memory Array"); + if (h->length < 0x0F) break; +- printf("\tLocation: %s\n", ++ pr_attr("Location", "%s", + dmi_memory_array_location(data[0x04])); +- printf("\tUse: %s\n", ++ pr_attr("Use", "%s", + dmi_memory_array_use(data[0x05])); +- printf("\tError Correction Type: %s\n", ++ pr_attr("Error Correction Type", "%s", + dmi_memory_array_ec_type(data[0x06])); +- printf("\tMaximum Capacity:"); + if (DWORD(data + 0x07) == 0x80000000) + { + if (h->length < 0x17) +- printf(" Unknown"); ++ pr_attr("Maximum Capacity", "Unknown"); + else +- dmi_print_memory_size(QWORD(data + 0x0F), 0); ++ dmi_print_memory_size("Maximum Capacity", ++ QWORD(data + 0x0F), 0); + } + else + { +@@ -4332,16 +4375,12 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + + capacity.h = 0; + capacity.l = DWORD(data + 0x07); +- dmi_print_memory_size(capacity, 1); ++ dmi_print_memory_size("Maximum Capacity", ++ capacity, 1); + } +- printf("\n"); + if (!(opt.flags & FLAG_QUIET)) +- { +- printf("\tError Information Handle:"); + dmi_memory_array_error_handle(WORD(data + 0x0B)); +- printf("\n"); +- } +- printf("\tNumber Of Devices: %u\n", ++ pr_attr("Number Of Devices", "%u", + WORD(data + 0x0D)); + break; + +@@ -4350,132 +4389,91 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + if (h->length < 0x15) break; + if (!(opt.flags & FLAG_QUIET)) + { +- printf("\tArray Handle: 0x%04X\n", ++ pr_attr("Array Handle", "0x%04X", + WORD(data + 0x04)); +- printf("\tError Information Handle:"); + dmi_memory_array_error_handle(WORD(data + 0x06)); +- printf("\n"); + } +- printf("\tTotal Width:"); +- dmi_memory_device_width(WORD(data + 0x08)); +- printf("\n"); +- printf("\tData Width:"); +- dmi_memory_device_width(WORD(data + 0x0A)); +- printf("\n"); +- printf("\tSize:"); ++ dmi_memory_device_width("Total Width", WORD(data + 0x08)); ++ dmi_memory_device_width("Data Width", WORD(data + 0x0A)); + if (h->length >= 0x20 && WORD(data + 0x0C) == 0x7FFF) + dmi_memory_device_extended_size(DWORD(data + 0x1C)); + else + dmi_memory_device_size(WORD(data + 0x0C)); +- printf("\n"); +- printf("\tForm Factor: %s\n", ++ pr_attr("Form Factor", "%s", + dmi_memory_device_form_factor(data[0x0E])); +- printf("\tSet:"); + dmi_memory_device_set(data[0x0F]); +- printf("\n"); +- printf("\tLocator: %s\n", ++ pr_attr("Locator", "%s", + dmi_string(h, data[0x10])); +- printf("\tBank Locator: %s\n", ++ pr_attr("Bank Locator", "%s", + dmi_string(h, data[0x11])); +- printf("\tType: %s\n", ++ pr_attr("Type", "%s", + dmi_memory_device_type(data[0x12])); +- printf("\tType Detail:"); + dmi_memory_device_type_detail(WORD(data + 0x13)); +- printf("\n"); + if (h->length < 0x17) break; +- printf("\tSpeed:"); +- dmi_memory_device_speed(WORD(data + 0x15)); +- printf("\n"); ++ dmi_memory_device_speed("Speed", WORD(data + 0x15)); + if (h->length < 0x1B) break; +- printf("\tManufacturer: %s\n", ++ pr_attr("Manufacturer", "%s", + dmi_string(h, data[0x17])); +- printf("\tSerial Number: %s\n", ++ pr_attr("Serial Number", "%s", + dmi_string(h, data[0x18])); +- printf("\tAsset Tag: %s\n", ++ pr_attr("Asset Tag", "%s", + dmi_string(h, data[0x19])); +- printf("\tPart Number: %s\n", ++ pr_attr("Part Number", "%s", + dmi_string(h, data[0x1A])); + if (h->length < 0x1C) break; +- printf("\tRank: "); + if ((data[0x1B] & 0x0F) == 0) +- printf("Unknown"); ++ pr_attr("Rank", "Unknown"); + else +- printf("%u", data[0x1B] & 0x0F); +- printf("\n"); ++ pr_attr("Rank", "%u", data[0x1B] & 0x0F); + if (h->length < 0x22) break; +- printf("\tConfigured Memory Speed:"); +- dmi_memory_device_speed(WORD(data + 0x20)); +- printf("\n"); ++ dmi_memory_device_speed("Configured Memory Speed", ++ WORD(data + 0x20)); + if (h->length < 0x28) break; +- printf("\tMinimum Voltage:"); +- dmi_memory_voltage_value(WORD(data + 0x22)); +- printf("\n"); +- printf("\tMaximum Voltage:"); +- dmi_memory_voltage_value(WORD(data + 0x24)); +- printf("\n"); +- printf("\tConfigured Voltage:"); +- dmi_memory_voltage_value(WORD(data + 0x26)); +- printf("\n"); ++ dmi_memory_voltage_value("Minimum Voltage", ++ WORD(data + 0x22)); ++ dmi_memory_voltage_value("Maximum Voltage", ++ WORD(data + 0x24)); ++ dmi_memory_voltage_value("Configured Voltage", ++ WORD(data + 0x26)); + if (h->length < 0x34) break; +- printf("\tMemory Technology:"); + dmi_memory_technology(data[0x28]); +- printf("\n"); +- printf("\tMemory Operating Mode Capability:"); + dmi_memory_operating_mode_capability(WORD(data + 0x29)); +- printf("\n"); +- printf("\tFirmware Version: %s\n", ++ pr_attr("Firmware Version", "%s", + dmi_string(h, data[0x2B])); +- printf("\tModule Manufacturer ID:"); +- dmi_memory_manufacturer_id(WORD(data + 0x2C)); +- printf("\n"); +- printf("\tModule Product ID:"); +- dmi_memory_product_id(WORD(data + 0x2E)); +- printf("\n"); +- printf("\tMemory Subsystem Controller Manufacturer ID:"); +- dmi_memory_manufacturer_id(WORD(data + 0x30)); +- printf("\n"); +- printf("\tMemory Subsystem Controller Product ID:"); +- dmi_memory_product_id(WORD(data + 0x32)); +- printf("\n"); ++ dmi_memory_manufacturer_id("Module Manufacturer ID", ++ WORD(data + 0x2C)); ++ dmi_memory_product_id("Module Product ID", ++ WORD(data + 0x2E)); ++ dmi_memory_manufacturer_id("Memory Subsystem Controller Manufacturer ID", ++ WORD(data + 0x30)); ++ dmi_memory_product_id("Memory Subsystem Controller Product ID", ++ WORD(data + 0x32)); + if (h->length < 0x3C) break; +- printf("\tNon-Volatile Size:"); +- dmi_memory_size(QWORD(data + 0x34)); +- printf("\n"); ++ dmi_memory_size("Non-Volatile Size", QWORD(data + 0x34)); + if (h->length < 0x44) break; +- printf("\tVolatile Size:"); +- dmi_memory_size(QWORD(data + 0x3C)); +- printf("\n"); ++ dmi_memory_size("Volatile Size", QWORD(data + 0x3C)); + if (h->length < 0x4C) break; +- printf("\tCache Size:"); +- dmi_memory_size(QWORD(data + 0x44)); +- printf("\n"); ++ dmi_memory_size("Cache Size", QWORD(data + 0x44)); + if (h->length < 0x54) break; +- printf("\tLogical Size:"); +- dmi_memory_size(QWORD(data + 0x4C)); +- printf("\n"); ++ dmi_memory_size("Logical Size", QWORD(data + 0x4C)); + break; + + case 18: /* 7.19 32-bit Memory Error Information */ + pr_handle_name("32-bit Memory Error Information"); + if (h->length < 0x17) break; +- printf("\tType: %s\n", ++ pr_attr("Type", "%s", + dmi_memory_error_type(data[0x04])); +- printf("\tGranularity: %s\n", ++ pr_attr("Granularity", "%s", + dmi_memory_error_granularity(data[0x05])); +- printf("\tOperation: %s\n", ++ pr_attr("Operation", "%s", + dmi_memory_error_operation(data[0x06])); +- printf("\tVendor Syndrome:"); + dmi_memory_error_syndrome(DWORD(data + 0x07)); +- printf("\n"); +- printf("\tMemory Array Address:"); +- dmi_32bit_memory_error_address(DWORD(data + 0x0B)); +- printf("\n"); +- printf("\tDevice Address:"); +- dmi_32bit_memory_error_address(DWORD(data + 0x0F)); +- printf("\n"); +- printf("\tResolution:"); +- dmi_32bit_memory_error_address(DWORD(data + 0x13)); +- printf("\n"); ++ dmi_32bit_memory_error_address("Memory Array Address", ++ DWORD(data + 0x0B)); ++ dmi_32bit_memory_error_address("Device Address", ++ DWORD(data + 0x0F)); ++ dmi_32bit_memory_error_address("Resolution", ++ DWORD(data + 0x13)); + break; + + case 19: /* 7.20 Memory Array Mapped Address */ +@@ -4488,29 +4486,26 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + start = QWORD(data + 0x0F); + end = QWORD(data + 0x17); + +- printf("\tStarting Address: 0x%08X%08Xk\n", ++ pr_attr("Starting Address", "0x%08X%08Xk", + start.h, start.l); +- printf("\tEnding Address: 0x%08X%08Xk\n", ++ pr_attr("Ending Address", "0x%08X%08Xk", + end.h, end.l); +- printf("\tRange Size:"); + dmi_mapped_address_extended_size(start, end); + } + else + { +- printf("\tStarting Address: 0x%08X%03X\n", ++ pr_attr("Starting Address", "0x%08X%03X", + DWORD(data + 0x04) >> 2, + (DWORD(data + 0x04) & 0x3) << 10); +- printf("\tEnding Address: 0x%08X%03X\n", ++ pr_attr("Ending Address", "0x%08X%03X", + DWORD(data + 0x08) >> 2, + ((DWORD(data + 0x08) & 0x3) << 10) + 0x3FF); +- printf("\tRange Size:"); + dmi_mapped_address_size(DWORD(data + 0x08) - DWORD(data + 0x04) + 1); + } +- printf("\n"); + if (!(opt.flags & FLAG_QUIET)) +- printf("\tPhysical Array Handle: 0x%04X\n", ++ pr_attr("Physical Array Handle", "0x%04X", + WORD(data + 0x0C)); +- printf("\tPartition Width: %u\n", ++ pr_attr("Partition Width", "%u", + data[0x0E]); + break; + +@@ -4524,344 +4519,288 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + start = QWORD(data + 0x13); + end = QWORD(data + 0x1B); + +- printf("\tStarting Address: 0x%08X%08Xk\n", ++ pr_attr("Starting Address", "0x%08X%08Xk", + start.h, start.l); +- printf("\tEnding Address: 0x%08X%08Xk\n", ++ pr_attr("Ending Address", "0x%08X%08Xk", + end.h, end.l); +- printf("\tRange Size:"); + dmi_mapped_address_extended_size(start, end); + } + else + { +- printf("\tStarting Address: 0x%08X%03X\n", ++ pr_attr("Starting Address", "0x%08X%03X", + DWORD(data + 0x04) >> 2, + (DWORD(data + 0x04) & 0x3) << 10); +- printf("\tEnding Address: 0x%08X%03X\n", ++ pr_attr("Ending Address", "0x%08X%03X", + DWORD(data + 0x08) >> 2, + ((DWORD(data + 0x08) & 0x3) << 10) + 0x3FF); +- printf("\tRange Size:"); + dmi_mapped_address_size(DWORD(data + 0x08) - DWORD(data + 0x04) + 1); + } +- printf("\n"); + if (!(opt.flags & FLAG_QUIET)) + { +- printf("\tPhysical Device Handle: 0x%04X\n", ++ pr_attr("Physical Device Handle", "0x%04X", + WORD(data + 0x0C)); +- printf("\tMemory Array Mapped Address Handle: 0x%04X\n", ++ pr_attr("Memory Array Mapped Address Handle", "0x%04X", + WORD(data + 0x0E)); + } +- printf("\tPartition Row Position:"); + dmi_mapped_address_row_position(data[0x10]); +- printf("\n"); +- dmi_mapped_address_interleave_position(data[0x11], "\t"); +- dmi_mapped_address_interleaved_data_depth(data[0x12], "\t"); ++ dmi_mapped_address_interleave_position(data[0x11]); ++ dmi_mapped_address_interleaved_data_depth(data[0x12]); + break; + + case 21: /* 7.22 Built-in Pointing Device */ + pr_handle_name("Built-in Pointing Device"); + if (h->length < 0x07) break; +- printf("\tType: %s\n", ++ pr_attr("Type", "%s", + dmi_pointing_device_type(data[0x04])); +- printf("\tInterface: %s\n", ++ pr_attr("Interface", "%s", + dmi_pointing_device_interface(data[0x05])); +- printf("\tButtons: %u\n", ++ pr_attr("Buttons", "%u", + data[0x06]); + break; + + case 22: /* 7.23 Portable Battery */ + pr_handle_name("Portable Battery"); + if (h->length < 0x10) break; +- printf("\tLocation: %s\n", ++ pr_attr("Location", "%s", + dmi_string(h, data[0x04])); +- printf("\tManufacturer: %s\n", ++ pr_attr("Manufacturer", "%s", + dmi_string(h, data[0x05])); + if (data[0x06] || h->length < 0x1A) +- printf("\tManufacture Date: %s\n", ++ pr_attr("Manufacture Date", "%s", + dmi_string(h, data[0x06])); + if (data[0x07] || h->length < 0x1A) +- printf("\tSerial Number: %s\n", ++ pr_attr("Serial Number", "%s", + dmi_string(h, data[0x07])); +- printf("\tName: %s\n", ++ pr_attr("Name", "%s", + dmi_string(h, data[0x08])); + if (data[0x09] != 0x02 || h->length < 0x1A) +- printf("\tChemistry: %s\n", ++ pr_attr("Chemistry", "%s", + dmi_battery_chemistry(data[0x09])); +- printf("\tDesign Capacity:"); + if (h->length < 0x16) + dmi_battery_capacity(WORD(data + 0x0A), 1); + else + dmi_battery_capacity(WORD(data + 0x0A), data[0x15]); +- printf("\n"); +- printf("\tDesign Voltage:"); + dmi_battery_voltage(WORD(data + 0x0C)); +- printf("\n"); +- printf("\tSBDS Version: %s\n", ++ pr_attr("SBDS Version", "%s", + dmi_string(h, data[0x0E])); +- printf("\tMaximum Error:"); + dmi_battery_maximum_error(data[0x0F]); +- printf("\n"); + if (h->length < 0x1A) break; + if (data[0x07] == 0) +- printf("\tSBDS Serial Number: %04X\n", ++ pr_attr("SBDS Serial Number", "%04X", + WORD(data + 0x10)); + if (data[0x06] == 0) +- printf("\tSBDS Manufacture Date: %u-%02u-%02u\n", ++ pr_attr("SBDS Manufacture Date", "%u-%02u-%02u", + 1980 + (WORD(data + 0x12) >> 9), + (WORD(data + 0x12) >> 5) & 0x0F, + WORD(data + 0x12) & 0x1F); + if (data[0x09] == 0x02) +- printf("\tSBDS Chemistry: %s\n", ++ pr_attr("SBDS Chemistry", "%s", + dmi_string(h, data[0x14])); +- printf("\tOEM-specific Information: 0x%08X\n", ++ pr_attr("OEM-specific Information", "0x%08X", + DWORD(data + 0x16)); + break; + + case 23: /* 7.24 System Reset */ + pr_handle_name("System Reset"); + if (h->length < 0x0D) break; +- printf("\tStatus: %s\n", ++ pr_attr("Status", "%s", + data[0x04] & (1 << 0) ? "Enabled" : "Disabled"); +- printf("\tWatchdog Timer: %s\n", ++ pr_attr("Watchdog Timer", "%s", + data[0x04] & (1 << 5) ? "Present" : "Not Present"); + if (!(data[0x04] & (1 << 5))) + break; +- printf("\tBoot Option: %s\n", ++ pr_attr("Boot Option", "%s", + dmi_system_reset_boot_option((data[0x04] >> 1) & 0x3)); +- printf("\tBoot Option On Limit: %s\n", ++ pr_attr("Boot Option On Limit", "%s", + dmi_system_reset_boot_option((data[0x04] >> 3) & 0x3)); +- printf("\tReset Count:"); +- dmi_system_reset_count(WORD(data + 0x05)); +- printf("\n"); +- printf("\tReset Limit:"); +- dmi_system_reset_count(WORD(data + 0x07)); +- printf("\n"); +- printf("\tTimer Interval:"); +- dmi_system_reset_timer(WORD(data + 0x09)); +- printf("\n"); +- printf("\tTimeout:"); +- dmi_system_reset_timer(WORD(data + 0x0B)); +- printf("\n"); ++ dmi_system_reset_count("Reset Count", WORD(data + 0x05)); ++ dmi_system_reset_count("Reset Limit", WORD(data + 0x07)); ++ dmi_system_reset_timer("Timer Interval", WORD(data + 0x09)); ++ dmi_system_reset_timer("Timeout", WORD(data + 0x0B)); + break; + + case 24: /* 7.25 Hardware Security */ + pr_handle_name("Hardware Security"); + if (h->length < 0x05) break; +- printf("\tPower-On Password Status: %s\n", ++ pr_attr("Power-On Password Status", "%s", + dmi_hardware_security_status(data[0x04] >> 6)); +- printf("\tKeyboard Password Status: %s\n", ++ pr_attr("Keyboard Password Status", "%s", + dmi_hardware_security_status((data[0x04] >> 4) & 0x3)); +- printf("\tAdministrator Password Status: %s\n", ++ pr_attr("Administrator Password Status", "%s", + dmi_hardware_security_status((data[0x04] >> 2) & 0x3)); +- printf("\tFront Panel Reset Status: %s\n", ++ pr_attr("Front Panel Reset Status", "%s", + dmi_hardware_security_status(data[0x04] & 0x3)); + break; + + case 25: /* 7.26 System Power Controls */ + pr_handle_name("System Power Controls"); + if (h->length < 0x09) break; +- printf("\tNext Scheduled Power-on:"); + dmi_power_controls_power_on(data + 0x04); +- printf("\n"); + break; + + case 26: /* 7.27 Voltage Probe */ + pr_handle_name("Voltage Probe"); + if (h->length < 0x14) break; +- printf("\tDescription: %s\n", ++ pr_attr("Description", "%s", + dmi_string(h, data[0x04])); +- printf("\tLocation: %s\n", ++ pr_attr("Location", "%s", + dmi_voltage_probe_location(data[0x05] & 0x1f)); +- printf("\tStatus: %s\n", ++ pr_attr("Status", "%s", + dmi_probe_status(data[0x05] >> 5)); +- printf("\tMaximum Value:"); +- dmi_voltage_probe_value(WORD(data + 0x06)); +- printf("\n"); +- printf("\tMinimum Value:"); +- dmi_voltage_probe_value(WORD(data + 0x08)); +- printf("\n"); +- printf("\tResolution:"); ++ dmi_voltage_probe_value("Maximum Value", WORD(data + 0x06)); ++ dmi_voltage_probe_value("Minimum Value", WORD(data + 0x08)); + dmi_voltage_probe_resolution(WORD(data + 0x0A)); +- printf("\n"); +- printf("\tTolerance:"); +- dmi_voltage_probe_value(WORD(data + 0x0C)); +- printf("\n"); +- printf("\tAccuracy:"); ++ dmi_voltage_probe_value("Tolerance", WORD(data + 0x0C)); + dmi_probe_accuracy(WORD(data + 0x0E)); +- printf("\n"); +- printf("\tOEM-specific Information: 0x%08X\n", ++ pr_attr("OEM-specific Information", "0x%08X", + DWORD(data + 0x10)); + if (h->length < 0x16) break; +- printf("\tNominal Value:"); +- dmi_voltage_probe_value(WORD(data + 0x14)); +- printf("\n"); ++ dmi_voltage_probe_value("Nominal Value", WORD(data + 0x14)); + break; + + case 27: /* 7.28 Cooling Device */ + pr_handle_name("Cooling Device"); + if (h->length < 0x0C) break; + if (!(opt.flags & FLAG_QUIET) && WORD(data + 0x04) != 0xFFFF) +- printf("\tTemperature Probe Handle: 0x%04X\n", ++ pr_attr("Temperature Probe Handle", "0x%04X", + WORD(data + 0x04)); +- printf("\tType: %s\n", ++ pr_attr("Type", "%s", + dmi_cooling_device_type(data[0x06] & 0x1f)); +- printf("\tStatus: %s\n", ++ pr_attr("Status", "%s", + dmi_probe_status(data[0x06] >> 5)); + if (data[0x07] != 0x00) +- printf("\tCooling Unit Group: %u\n", ++ pr_attr("Cooling Unit Group", "%u", + data[0x07]); +- printf("\tOEM-specific Information: 0x%08X\n", ++ pr_attr("OEM-specific Information", "0x%08X", + DWORD(data + 0x08)); + if (h->length < 0x0E) break; +- printf("\tNominal Speed:"); + dmi_cooling_device_speed(WORD(data + 0x0C)); +- printf("\n"); + if (h->length < 0x0F) break; +- printf("\tDescription: %s\n", dmi_string(h, data[0x0E])); ++ pr_attr("Description", "%s", dmi_string(h, data[0x0E])); + break; + + case 28: /* 7.29 Temperature Probe */ + pr_handle_name("Temperature Probe"); + if (h->length < 0x14) break; +- printf("\tDescription: %s\n", ++ pr_attr("Description", "%s", + dmi_string(h, data[0x04])); +- printf("\tLocation: %s\n", ++ pr_attr("Location", "%s", + dmi_temperature_probe_location(data[0x05] & 0x1F)); +- printf("\tStatus: %s\n", ++ pr_attr("Status", "%s", + dmi_probe_status(data[0x05] >> 5)); +- printf("\tMaximum Value:"); +- dmi_temperature_probe_value(WORD(data + 0x06)); +- printf("\n"); +- printf("\tMinimum Value:"); +- dmi_temperature_probe_value(WORD(data + 0x08)); +- printf("\n"); +- printf("\tResolution:"); ++ dmi_temperature_probe_value("Maximum Value", ++ WORD(data + 0x06)); ++ dmi_temperature_probe_value("Minimum Value", ++ WORD(data + 0x08)); + dmi_temperature_probe_resolution(WORD(data + 0x0A)); +- printf("\n"); +- printf("\tTolerance:"); +- dmi_temperature_probe_value(WORD(data + 0x0C)); +- printf("\n"); +- printf("\tAccuracy:"); ++ dmi_temperature_probe_value("Tolerance", ++ WORD(data + 0x0C)); + dmi_probe_accuracy(WORD(data + 0x0E)); +- printf("\n"); +- printf("\tOEM-specific Information: 0x%08X\n", ++ pr_attr("OEM-specific Information", "0x%08X", + DWORD(data + 0x10)); + if (h->length < 0x16) break; +- printf("\tNominal Value:"); +- dmi_temperature_probe_value(WORD(data + 0x14)); +- printf("\n"); ++ dmi_temperature_probe_value("Nominal Value", ++ WORD(data + 0x14)); + break; + + case 29: /* 7.30 Electrical Current Probe */ + pr_handle_name("Electrical Current Probe"); + if (h->length < 0x14) break; +- printf("\tDescription: %s\n", ++ pr_attr("Description", "%s", + dmi_string(h, data[0x04])); +- printf("\tLocation: %s\n", ++ pr_attr("Location", "%s", + dmi_voltage_probe_location(data[5] & 0x1F)); +- printf("\tStatus: %s\n", ++ pr_attr("Status", "%s", + dmi_probe_status(data[0x05] >> 5)); +- printf("\tMaximum Value:"); +- dmi_current_probe_value(WORD(data + 0x06)); +- printf("\n"); +- printf("\tMinimum Value:"); +- dmi_current_probe_value(WORD(data + 0x08)); +- printf("\n"); +- printf("\tResolution:"); ++ dmi_current_probe_value("Maximum Value", ++ WORD(data + 0x06)); ++ dmi_current_probe_value("Minimum Value", ++ WORD(data + 0x08)); + dmi_current_probe_resolution(WORD(data + 0x0A)); +- printf("\n"); +- printf("\tTolerance:"); +- dmi_current_probe_value(WORD(data + 0x0C)); +- printf("\n"); +- printf("\tAccuracy:"); ++ dmi_current_probe_value("Tolerance", ++ WORD(data + 0x0C)); + dmi_probe_accuracy(WORD(data + 0x0E)); +- printf("\n"); +- printf("\tOEM-specific Information: 0x%08X\n", ++ pr_attr("OEM-specific Information", "0x%08X", + DWORD(data + 0x10)); + if (h->length < 0x16) break; +- printf("\tNominal Value:"); +- dmi_current_probe_value(WORD(data + 0x14)); +- printf("\n"); ++ dmi_current_probe_value("Nominal Value", ++ WORD(data + 0x14)); + break; + + case 30: /* 7.31 Out-of-band Remote Access */ + pr_handle_name("Out-of-band Remote Access"); + if (h->length < 0x06) break; +- printf("\tManufacturer Name: %s\n", ++ pr_attr("Manufacturer Name", "%s", + dmi_string(h, data[0x04])); +- printf("\tInbound Connection: %s\n", ++ pr_attr("Inbound Connection", "%s", + data[0x05] & (1 << 0) ? "Enabled" : "Disabled"); +- printf("\tOutbound Connection: %s\n", ++ pr_attr("Outbound Connection", "%s", + data[0x05] & (1 << 1) ? "Enabled" : "Disabled"); + break; + + case 31: /* 7.32 Boot Integrity Services Entry Point */ + pr_handle_name("Boot Integrity Services Entry Point"); + if (h->length < 0x1C) break; +- printf("\tChecksum: %s\n", ++ pr_attr("Checksum", "%s", + checksum(data, h->length) ? "OK" : "Invalid"); +- printf("\t16-bit Entry Point Address: %04X:%04X\n", ++ pr_attr("16-bit Entry Point Address", "%04X:%04X", + DWORD(data + 0x08) >> 16, + DWORD(data + 0x08) & 0xFFFF); +- printf("\t32-bit Entry Point Address: 0x%08X\n", ++ pr_attr("32-bit Entry Point Address", "0x%08X", + DWORD(data + 0x0C)); + break; + + case 32: /* 7.33 System Boot Information */ + pr_handle_name("System Boot Information"); + if (h->length < 0x0B) break; +- printf("\tStatus: %s\n", ++ pr_attr("Status", "%s", + dmi_system_boot_status(data[0x0A])); + break; + + case 33: /* 7.34 64-bit Memory Error Information */ + pr_handle_name("64-bit Memory Error Information"); + if (h->length < 0x1F) break; +- printf("\tType: %s\n", ++ pr_attr("Type", "%s", + dmi_memory_error_type(data[0x04])); +- printf("\tGranularity: %s\n", ++ pr_attr("Granularity", "%s", + dmi_memory_error_granularity(data[0x05])); +- printf("\tOperation: %s\n", ++ pr_attr("Operation", "%s", + dmi_memory_error_operation(data[0x06])); +- printf("\tVendor Syndrome:"); + dmi_memory_error_syndrome(DWORD(data + 0x07)); +- printf("\n"); +- printf("\tMemory Array Address:"); +- dmi_64bit_memory_error_address(QWORD(data + 0x0B)); +- printf("\n"); +- printf("\tDevice Address:"); +- dmi_64bit_memory_error_address(QWORD(data + 0x13)); +- printf("\n"); +- printf("\tResolution:"); +- dmi_32bit_memory_error_address(DWORD(data + 0x1B)); +- printf("\n"); ++ dmi_64bit_memory_error_address("Memory Array Address", ++ QWORD(data + 0x0B)); ++ dmi_64bit_memory_error_address("Device Address", ++ QWORD(data + 0x13)); ++ dmi_32bit_memory_error_address("Resolution", ++ DWORD(data + 0x1B)); + break; + + case 34: /* 7.35 Management Device */ + pr_handle_name("Management Device"); + if (h->length < 0x0B) break; +- printf("\tDescription: %s\n", ++ pr_attr("Description", "%s", + dmi_string(h, data[0x04])); +- printf("\tType: %s\n", ++ pr_attr("Type", "%s", + dmi_management_device_type(data[0x05])); +- printf("\tAddress: 0x%08X\n", ++ pr_attr("Address", "0x%08X", + DWORD(data + 0x06)); +- printf("\tAddress Type: %s\n", ++ pr_attr("Address Type", "%s", + dmi_management_device_address_type(data[0x0A])); + break; + + case 35: /* 7.36 Management Device Component */ + pr_handle_name("Management Device Component"); + if (h->length < 0x0B) break; +- printf("\tDescription: %s\n", ++ pr_attr("Description", "%s", + dmi_string(h, data[0x04])); + if (!(opt.flags & FLAG_QUIET)) + { +- printf("\tManagement Device Handle: 0x%04X\n", ++ pr_attr("Management Device Handle", "0x%04X", + WORD(data + 0x05)); +- printf("\tComponent Handle: 0x%04X\n", ++ pr_attr("Component Handle", "0x%04X", + WORD(data + 0x07)); + if (WORD(data + 0x09) != 0xFFFF) +- printf("\tThreshold Handle: 0x%04X\n", ++ pr_attr("Threshold Handle", "0x%04X", + WORD(data + 0x09)); + } + break; +@@ -4870,36 +4809,36 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + pr_handle_name("Management Device Threshold Data"); + if (h->length < 0x10) break; + if (WORD(data + 0x04) != 0x8000) +- printf("\tLower Non-critical Threshold: %d\n", ++ pr_attr("Lower Non-critical Threshold", "%d", + (i16)WORD(data + 0x04)); + if (WORD(data + 0x06) != 0x8000) +- printf("\tUpper Non-critical Threshold: %d\n", ++ pr_attr("Upper Non-critical Threshold", "%d", + (i16)WORD(data + 0x06)); + if (WORD(data + 0x08) != 0x8000) +- printf("\tLower Critical Threshold: %d\n", ++ pr_attr("Lower Critical Threshold", "%d", + (i16)WORD(data + 0x08)); + if (WORD(data + 0x0A) != 0x8000) +- printf("\tUpper Critical Threshold: %d\n", ++ pr_attr("Upper Critical Threshold", "%d", + (i16)WORD(data + 0x0A)); + if (WORD(data + 0x0C) != 0x8000) +- printf("\tLower Non-recoverable Threshold: %d\n", ++ pr_attr("Lower Non-recoverable Threshold", "%d", + (i16)WORD(data + 0x0C)); + if (WORD(data + 0x0E) != 0x8000) +- printf("\tUpper Non-recoverable Threshold: %d\n", ++ pr_attr("Upper Non-recoverable Threshold", "%d", + (i16)WORD(data + 0x0E)); + break; + + case 37: /* 7.38 Memory Channel */ + pr_handle_name("Memory Channel"); + if (h->length < 0x07) break; +- printf("\tType: %s\n", ++ pr_attr("Type", "%s", + dmi_memory_channel_type(data[0x04])); +- printf("\tMaximal Load: %u\n", ++ pr_attr("Maximal Load", "%u", + data[0x05]); +- printf("\tDevices: %u\n", ++ pr_attr("Devices", "%u", + data[0x06]); + if (h->length < 0x07 + 3 * data[0x06]) break; +- dmi_memory_channel_devices(data[0x06], data + 0x07, "\t"); ++ dmi_memory_channel_devices(data[0x06], data + 0x07); + break; + + case 38: /* 7.39 IPMI Device Information */ +@@ -4909,37 +4848,35 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + */ + pr_handle_name("IPMI Device Information"); + if (h->length < 0x10) break; +- printf("\tInterface Type: %s\n", ++ pr_attr("Interface Type", "%s", + dmi_ipmi_interface_type(data[0x04])); +- printf("\tSpecification Version: %u.%u\n", ++ pr_attr("Specification Version", "%u.%u", + data[0x05] >> 4, data[0x05] & 0x0F); +- printf("\tI2C Slave Address: 0x%02x\n", ++ pr_attr("I2C Slave Address", "0x%02x", + data[0x06] >> 1); + if (data[0x07] != 0xFF) +- printf("\tNV Storage Device Address: %u\n", ++ pr_attr("NV Storage Device Address", "%u", + data[0x07]); + else +- printf("\tNV Storage Device: Not Present\n"); +- printf("\tBase Address: "); ++ pr_attr("NV Storage Device", "Not Present"); + dmi_ipmi_base_address(data[0x04], data + 0x08, + h->length < 0x11 ? 0 : (data[0x10] >> 4) & 1); +- printf("\n"); + if (h->length < 0x12) break; + if (data[0x04] != 0x04) + { +- printf("\tRegister Spacing: %s\n", ++ pr_attr("Register Spacing", "%s", + dmi_ipmi_register_spacing(data[0x10] >> 6)); + if (data[0x10] & (1 << 3)) + { +- printf("\tInterrupt Polarity: %s\n", ++ pr_attr("Interrupt Polarity", "%s", + data[0x10] & (1 << 1) ? "Active High" : "Active Low"); +- printf("\tInterrupt Trigger Mode: %s\n", ++ pr_attr("Interrupt Trigger Mode", "%s", + data[0x10] & (1 << 0) ? "Level" : "Edge"); + } + } + if (data[0x11] != 0x00) + { +- printf("\tInterrupt Number: %u\n", ++ pr_attr("Interrupt Number", "%u", + data[0x11]); + } + break; +@@ -4948,51 +4885,47 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + pr_handle_name("System Power Supply"); + if (h->length < 0x10) break; + if (data[0x04] != 0x00) +- printf("\tPower Unit Group: %u\n", ++ pr_attr("Power Unit Group", "%u", + data[0x04]); +- printf("\tLocation: %s\n", ++ pr_attr("Location", "%s", + dmi_string(h, data[0x05])); +- printf("\tName: %s\n", ++ pr_attr("Name", "%s", + dmi_string(h, data[0x06])); +- printf("\tManufacturer: %s\n", ++ pr_attr("Manufacturer", "%s", + dmi_string(h, data[0x07])); +- printf("\tSerial Number: %s\n", ++ pr_attr("Serial Number", "%s", + dmi_string(h, data[0x08])); +- printf("\tAsset Tag: %s\n", ++ pr_attr("Asset Tag", "%s", + dmi_string(h, data[0x09])); +- printf("\tModel Part Number: %s\n", ++ pr_attr("Model Part Number", "%s", + dmi_string(h, data[0x0A])); +- printf("\tRevision: %s\n", ++ pr_attr("Revision", "%s", + dmi_string(h, data[0x0B])); +- printf("\tMax Power Capacity:"); + dmi_power_supply_power(WORD(data + 0x0C)); +- printf("\n"); +- printf("\tStatus:"); + if (WORD(data + 0x0E) & (1 << 1)) +- printf(" Present, %s", ++ pr_attr("Status", "Present, %s", + dmi_power_supply_status((WORD(data + 0x0E) >> 7) & 0x07)); + else +- printf(" Not Present"); +- printf("\n"); +- printf("\tType: %s\n", ++ pr_attr("Status", "Not Present"); ++ pr_attr("Type", "%s", + dmi_power_supply_type((WORD(data + 0x0E) >> 10) & 0x0F)); +- printf("\tInput Voltage Range Switching: %s\n", ++ pr_attr("Input Voltage Range Switching", "%s", + dmi_power_supply_range_switching((WORD(data + 0x0E) >> 3) & 0x0F)); +- printf("\tPlugged: %s\n", ++ pr_attr("Plugged", "%s", + WORD(data + 0x0E) & (1 << 2) ? "No" : "Yes"); +- printf("\tHot Replaceable: %s\n", ++ pr_attr("Hot Replaceable", "%s", + WORD(data + 0x0E) & (1 << 0) ? "Yes" : "No"); + if (h->length < 0x16) break; + if (!(opt.flags & FLAG_QUIET)) + { + if (WORD(data + 0x10) != 0xFFFF) +- printf("\tInput Voltage Probe Handle: 0x%04X\n", ++ pr_attr("Input Voltage Probe Handle", "0x%04X", + WORD(data + 0x10)); + if (WORD(data + 0x12) != 0xFFFF) +- printf("\tCooling Device Handle: 0x%04X\n", ++ pr_attr("Cooling Device Handle", "0x%04X", + WORD(data + 0x12)); + if (WORD(data + 0x14) != 0xFFFF) +- printf("\tInput Current Probe Handle: 0x%04X\n", ++ pr_attr("Input Current Probe Handle", "0x%04X", + WORD(data + 0x14)); + } + break; +@@ -5001,19 +4934,19 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + if (h->length < 0x0B) break; + if (opt.flags & FLAG_QUIET) + return; +- dmi_additional_info(h, ""); ++ dmi_additional_info(h); + break; + + case 41: /* 7.42 Onboard Device Extended Information */ + pr_handle_name("Onboard Device"); + if (h->length < 0x0B) break; +- printf("\tReference Designation: %s\n", dmi_string(h, data[0x04])); +- printf("\tType: %s\n", ++ pr_attr("Reference Designation", "%s", dmi_string(h, data[0x04])); ++ pr_attr("Type", "%s", + dmi_on_board_devices_type(data[0x05] & 0x7F)); +- printf("\tStatus: %s\n", ++ pr_attr("Status", "%s", + data[0x05] & 0x80 ? "Enabled" : "Disabled"); +- printf("\tType Instance: %u\n", data[0x06]); +- dmi_slot_segment_bus_func(WORD(data + 0x07), data[0x09], data[0x0A], "\t"); ++ pr_attr("Type Instance", "%u", data[0x06]); ++ dmi_slot_segment_bus_func(WORD(data + 0x07), data[0x09], data[0x0A]); + break; + + case 42: /* 7.43 Management Controller Host Interface */ +@@ -5021,7 +4954,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + if (ver < 0x0302) + { + if (h->length < 0x05) break; +- printf("\tInterface Type: %s\n", ++ pr_attr("Interface Type", "%s", + dmi_management_controller_host_type(data[0x04])); + /* + * There you have a type-dependent, variable-length +@@ -5032,7 +4965,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + if (h->length < 0x09) break; + if (data[0x04] == 0xF0) /* OEM */ + { +- printf("\tVendor ID: 0x%02X%02X%02X%02X\n", ++ pr_attr("Vendor ID", "0x%02X%02X%02X%02X", + data[0x05], data[0x06], data[0x07], + data[0x08]); + } +@@ -5044,10 +4977,8 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + case 43: /* 7.44 TPM Device */ + pr_handle_name("TPM Device"); + if (h->length < 0x1B) break; +- printf("\tVendor ID:"); + dmi_tpm_vendor_id(data + 0x04); +- printf("\n"); +- printf("\tSpecification Version: %d.%d\n", data[0x08], data[0x09]); ++ pr_attr("Specification Version", "%d.%d", data[0x08], data[0x09]); + switch (data[0x08]) + { + case 0x01: +@@ -5056,11 +4987,11 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + * redundant with the above, and uncoded + * in a silly way. + */ +- printf("\tFirmware Revision: %u.%u\n", ++ pr_attr("Firmware Revision", "%u.%u", + data[0x0C], data[0x0D]); + break; + case 0x02: +- printf("\tFirmware Revision: %u.%u\n", ++ pr_attr("Firmware Revision", "%u.%u", + DWORD(data + 0x0A) >> 16, + DWORD(data + 0x0A) & 0xFFFF); + /* +@@ -5070,11 +5001,11 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + */ + break; + } +- printf("\tDescription: %s\n", dmi_string(h, data[0x12])); ++ pr_attr("Description", "%s", dmi_string(h, data[0x12])); + printf("\tCharacteristics:\n"); + dmi_tpm_characteristics(QWORD(data + 0x13), "\t\t"); + if (h->length < 0x1F) break; +- printf("\tOEM-specific Information: 0x%08X\n", ++ pr_attr("OEM-specific Information", "0x%08X", + DWORD(data + 0x1B)); + break; + +@@ -5141,8 +5072,7 @@ static void dmi_table_string(const struct dmi_header *h, const u8 *data, u16 ver + printf("%u.%u\n", data[key - 1], data[key]); + break; + case 0x108: +- dmi_system_uuid(data + offset, ver); +- printf("\n"); ++ dmi_system_uuid(NULL, data + offset, ver); + break; + case 0x305: + printf("%s\n", dmi_chassis_type(data[offset])); +@@ -5151,8 +5081,7 @@ static void dmi_table_string(const struct dmi_header *h, const u8 *data, u16 ver + printf("%s\n", dmi_processor_family(h, ver)); + break; + case 0x416: +- dmi_processor_frequency(data + offset); +- printf("\n"); ++ dmi_processor_frequency(NULL, data + offset); + break; + default: + printf("%s\n", dmi_string(h, data[offset])); +diff --git a/dmioem.c b/dmioem.c +index c999c08c4475..873ec1068c16 100644 +--- a/dmioem.c ++++ b/dmioem.c +@@ -96,16 +96,16 @@ static int dmi_decode_acer(const struct dmi_header *h) + pr_handle_name("Acer Hotkey Function"); + if (h->length < 0x0F) break; + cap = WORD(data + 0x04); +- printf("\tFunction bitmap for Communication Button: 0x%04hx\n", cap); ++ pr_attr("Function bitmap for Communication Button", "0x%04hx", cap); + printf("\t\tWiFi: %s\n", cap & 0x0001 ? "Yes" : "No"); + printf("\t\t3G: %s\n", cap & 0x0040 ? "Yes" : "No"); + printf("\t\tWiMAX: %s\n", cap & 0x0080 ? "Yes" : "No"); + printf("\t\tBluetooth: %s\n", cap & 0x0800 ? "Yes" : "No"); +- printf("\tFunction bitmap for Application Button: 0x%04hx\n", WORD(data + 0x06)); +- printf("\tFunction bitmap for Media Button: 0x%04hx\n", WORD(data + 0x08)); +- printf("\tFunction bitmap for Display Button: 0x%04hx\n", WORD(data + 0x0A)); +- printf("\tFunction bitmap for Others Button: 0x%04hx\n", WORD(data + 0x0C)); +- printf("\tCommunication Function Key Number: %d\n", data[0x0E]); ++ pr_attr("Function bitmap for Application Button", "0x%04hx", WORD(data + 0x06)); ++ pr_attr("Function bitmap for Media Button", "0x%04hx", WORD(data + 0x08)); ++ pr_attr("Function bitmap for Display Button", "0x%04hx", WORD(data + 0x0A)); ++ pr_attr("Function bitmap for Others Button", "0x%04hx", WORD(data + 0x0C)); ++ pr_attr("Communication Function Key Number", "%d", data[0x0E]); + break; + + default: +@@ -128,19 +128,21 @@ static void dmi_print_hp_net_iface_rec(u8 id, u8 bus, u8 dev, const u8 *mac) + * 640K ought to be enough for anybody(said no one, ever). + * */ + static u8 nic_ctr; ++ char attr[8]; + + if (id == 0xFF) + id = ++nic_ctr; + ++ sprintf(attr, "NIC %hu", id); + if (dev == 0x00 && bus == 0x00) +- printf("\tNIC %d: Disabled\n", id); ++ pr_attr(attr, "Disabled"); + else if (dev == 0xFF && bus == 0xFF) +- printf("\tNIC %d: Not Installed\n", id); ++ pr_attr(attr, "Not Installed"); + else + { +- printf("\tNIC %d: PCI device %02x:%02x.%x, " +- "MAC address %02X:%02X:%02X:%02X:%02X:%02X\n", +- id, bus, dev >> 3, dev & 7, ++ pr_attr(attr, "PCI device %02x:%02x.%x, " ++ "MAC address %02X:%02X:%02X:%02X:%02X:%02X", ++ bus, dev >> 3, dev & 7, + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + } + } +@@ -160,13 +162,13 @@ static int dmi_decode_hp(const struct dmi_header *h) + */ + pr_handle_name("%s ProLiant System/Rack Locator", company); + if (h->length < 0x0B) break; +- printf("\tRack Name: %s\n", dmi_string(h, data[0x04])); +- printf("\tEnclosure Name: %s\n", dmi_string(h, data[0x05])); +- printf("\tEnclosure Model: %s\n", dmi_string(h, data[0x06])); +- printf("\tEnclosure Serial: %s\n", dmi_string(h, data[0x0A])); +- printf("\tEnclosure Bays: %d\n", data[0x08]); +- printf("\tServer Bay: %s\n", dmi_string(h, data[0x07])); +- printf("\tBays Filled: %d\n", data[0x09]); ++ pr_attr("Rack Name", "%s", dmi_string(h, data[0x04])); ++ pr_attr("Enclosure Name", "%s", dmi_string(h, data[0x05])); ++ pr_attr("Enclosure Model", "%s", dmi_string(h, data[0x06])); ++ pr_attr("Enclosure Serial", "%s", dmi_string(h, data[0x0A])); ++ pr_attr("Enclosure Bays", "%d", data[0x08]); ++ pr_attr("Server Bay", "%s", dmi_string(h, data[0x07])); ++ pr_attr("Bays Filled", "%d", data[0x09]); + break; + + case 209: +@@ -243,20 +245,22 @@ static int dmi_decode_hp(const struct dmi_header *h) + */ + pr_handle_name("%s 64-bit CRU Information", company); + if (h->length < 0x18) break; +- printf("\tSignature: 0x%08x", DWORD(data + 0x04)); + if (is_printable(data + 0x04, 4)) +- printf(" (%c%c%c%c)", data[0x04], data[0x05], ++ pr_attr("Signature", "0x%08x (%c%c%c%c)", ++ DWORD(data + 0x04), ++ data[0x04], data[0x05], + data[0x06], data[0x07]); +- printf("\n"); ++ else ++ pr_attr("Signature", "0x%08x", DWORD(data + 0x04)); + if (DWORD(data + 0x04) == 0x55524324) + { + u64 paddr = QWORD(data + 0x08); + paddr.l += DWORD(data + 0x14); + if (paddr.l < DWORD(data + 0x14)) + paddr.h++; +- printf("\tPhysical Address: 0x%08x%08x\n", ++ pr_attr("Physical Address", "0x%08x%08x", + paddr.h, paddr.l); +- printf("\tLength: 0x%08x\n", DWORD(data + 0x10)); ++ pr_attr("Length", "0x%08x", DWORD(data + 0x10)); + } + break; + +@@ -268,12 +272,12 @@ static int dmi_decode_hp(const struct dmi_header *h) + */ + pr_handle_name("%s ProLiant Information", company); + if (h->length < 0x08) break; +- printf("\tPower Features: 0x%08x\n", DWORD(data + 0x04)); ++ pr_attr("Power Features", "0x%08x", DWORD(data + 0x04)); + if (h->length < 0x0C) break; +- printf("\tOmega Features: 0x%08x\n", DWORD(data + 0x08)); ++ pr_attr("Omega Features", "0x%08x", DWORD(data + 0x08)); + if (h->length < 0x14) break; + feat = DWORD(data + 0x10); +- printf("\tMisc. Features: 0x%08x\n", feat); ++ pr_attr("Misc. Features", "0x%08x", feat); + printf("\t\tiCRU: %s\n", feat & 0x0001 ? "Yes" : "No"); + printf("\t\tUEFI: %s\n", feat & 0x1400 ? "Yes" : "No"); + break; +@@ -320,8 +324,8 @@ static int dmi_decode_ibm_lenovo(const struct dmi_header *h) + return 0; + + pr_handle_name("ThinkVantage Technologies"); +- printf("\tVersion: %u\n", data[0x04]); +- printf("\tDiagnostics: %s\n", ++ pr_attr("Version", "%u", data[0x04]); ++ pr_attr("Diagnostics", "%s", + data[0x14] & 0x80 ? "Available" : "No"); + break; + +@@ -359,7 +363,7 @@ static int dmi_decode_ibm_lenovo(const struct dmi_header *h) + return 0; + + pr_handle_name("ThinkPad Device Presence Detection"); +- printf("\tFingerprint Reader: %s\n", ++ pr_attr("Fingerprint Reader", "%s", + data[0x09] & 0x01 ? "Present" : "No"); + break; + +@@ -392,8 +396,8 @@ static int dmi_decode_ibm_lenovo(const struct dmi_header *h) + return 0; + + pr_handle_name("ThinkPad Embedded Controller Program"); +- printf("\tVersion ID: %s\n", dmi_string(h, 1)); +- printf("\tRelease Date: %s\n", dmi_string(h, 2)); ++ pr_attr("Version ID", "%s", dmi_string(h, 1)); ++ pr_attr("Release Date", "%s", dmi_string(h, 2)); + break; + + default: +diff --git a/dmioutput.c b/dmioutput.c +index ca7edab5cc69..2330b65755c9 100644 +--- a/dmioutput.c ++++ b/dmioutput.c +@@ -59,3 +59,15 @@ void pr_handle_name(const char *format, ...) + va_end(args); + printf("\n"); + } ++ ++void pr_attr(const char *name, const char *format, ...) ++{ ++ va_list args; ++ ++ printf("\t%s: ", name); ++ ++ va_start(args, format); ++ vprintf(format, args); ++ va_end(args); ++ printf("\n"); ++} +diff --git a/dmioutput.h b/dmioutput.h +index 0acdce7658c9..981dcb45f26a 100644 +--- a/dmioutput.h ++++ b/dmioutput.h +@@ -25,3 +25,4 @@ void pr_comment(const char *format, ...); + void pr_info(const char *format, ...); + void pr_handle(const struct dmi_header *h); + void pr_handle_name(const char *format, ...); ++void pr_attr(const char *name, const char *format, ...); +-- +2.17.1 + diff --git a/SOURCES/0015-dmidecode-Add-helper-functions-pr_list_start-item-en.patch b/SOURCES/0015-dmidecode-Add-helper-functions-pr_list_start-item-en.patch new file mode 100644 index 0000000..319877a --- /dev/null +++ b/SOURCES/0015-dmidecode-Add-helper-functions-pr_list_start-item-en.patch @@ -0,0 +1,727 @@ +From 5893721859b73354a935135b4aee297bd41a5b1a Mon Sep 17 00:00:00 2001 +From: Jean Delvare +Date: Wed, 1 Apr 2020 09:57:56 +0200 +Subject: [PATCH 15/23] dmidecode: Add helper functions pr_list_start/item/end + +Print lists through helper functions. pr_list_start() starts the +list, with an optional value. pr_list_item() prints a single item. +pr_list_end() is a no-op for plain text output, but is in place in +anticipation of supporting other output formats such as HTML. + +Signed-off-by: Jean Delvare +--- + dmidecode.c | 260 +++++++++++++++++++++++++++++----------------------- + dmioutput.c | 35 +++++++ + dmioutput.h | 3 + + 3 files changed, 184 insertions(+), 114 deletions(-) + +diff --git a/dmidecode.c b/dmidecode.c +index 7ab058b61ef0..5a5299ed13ba 100644 +--- a/dmidecode.c ++++ b/dmidecode.c +@@ -340,7 +340,7 @@ static void dmi_bios_rom_size(u8 code1, u16 code2) + pr_attr("ROM Size", "%u %s", code2 & 0x3FFF, unit[code2 >> 14]); + } + +-static void dmi_bios_characteristics(u64 code, const char *prefix) ++static void dmi_bios_characteristics(u64 code) + { + /* 7.1.1 */ + static const char *characteristics[] = { +@@ -381,18 +381,16 @@ static void dmi_bios_characteristics(u64 code, const char *prefix) + */ + if (code.l & (1 << 3)) + { +- printf("%s%s\n", +- prefix, characteristics[0]); ++ pr_list_item("%s", characteristics[0]); + return; + } + + for (i = 4; i <= 31; i++) + if (code.l & (1 << i)) +- printf("%s%s\n", +- prefix, characteristics[i - 3]); ++ pr_list_item("%s", characteristics[i - 3]); + } + +-static void dmi_bios_characteristics_x1(u8 code, const char *prefix) ++static void dmi_bios_characteristics_x1(u8 code) + { + /* 7.1.2.1 */ + static const char *characteristics[] = { +@@ -409,11 +407,10 @@ static void dmi_bios_characteristics_x1(u8 code, const char *prefix) + + for (i = 0; i <= 7; i++) + if (code & (1 << i)) +- printf("%s%s\n", +- prefix, characteristics[i]); ++ pr_list_item("%s", characteristics[i]); + } + +-static void dmi_bios_characteristics_x2(u8 code, const char *prefix) ++static void dmi_bios_characteristics_x2(u8 code) + { + /* 37.1.2.2 */ + static const char *characteristics[] = { +@@ -427,8 +424,7 @@ static void dmi_bios_characteristics_x2(u8 code, const char *prefix) + + for (i = 0; i <= 4; i++) + if (code & (1 << i)) +- printf("%s%s\n", +- prefix, characteristics[i]); ++ pr_list_item("%s", characteristics[i]); + } + + /* +@@ -521,7 +517,7 @@ static const char *dmi_system_wake_up_type(u8 code) + * 7.3 Base Board Information (Type 2) + */ + +-static void dmi_base_board_features(u8 code, const char *prefix) ++static void dmi_base_board_features(u8 code) + { + /* 7.3.1 */ + static const char *features[] = { +@@ -533,17 +529,17 @@ static void dmi_base_board_features(u8 code, const char *prefix) + }; + + if ((code & 0x1F) == 0) +- printf(" None\n"); ++ pr_list_start("Features", "%s", "None"); + else + { + int i; + +- printf("\n"); ++ pr_list_start("Features", NULL); + for (i = 0; i <= 4; i++) + if (code & (1 << i)) +- printf("%s%s\n", +- prefix, features[i]); ++ pr_list_item("%s", features[i]); + } ++ pr_list_end(); + } + + static const char *dmi_base_board_type(u8 code) +@@ -570,15 +566,14 @@ static const char *dmi_base_board_type(u8 code) + return out_of_spec; + } + +-static void dmi_base_board_handles(u8 count, const u8 *p, const char *prefix) ++static void dmi_base_board_handles(u8 count, const u8 *p) + { + int i; + +- printf("%sContained Object Handles: %u\n", +- prefix, count); ++ pr_list_start("Contained Object Handles", "%u", count); + for (i = 0; i < count; i++) +- printf("%s\t0x%04X\n", +- prefix, WORD(p + sizeof(u16) * i)); ++ pr_list_item("0x%04X", WORD(p + sizeof(u16) * i)); ++ pr_list_end(); + } + + /* +@@ -693,27 +688,29 @@ static void dmi_chassis_power_cords(u8 code) + pr_attr("Number Of Power Cords", "%u", code); + } + +-static void dmi_chassis_elements(u8 count, u8 len, const u8 *p, const char *prefix) ++static void dmi_chassis_elements(u8 count, u8 len, const u8 *p) + { + int i; + +- printf("%sContained Elements: %u\n", +- prefix, count); ++ pr_list_start("Contained Elements", "%u", count); + for (i = 0; i < count; i++) + { + if (len >= 0x03) + { +- printf("%s\t%s (", +- prefix, p[i * len] & 0x80 ? ++ const char *type; ++ ++ type = (p[i * len] & 0x80) ? + dmi_smbios_structure_type(p[i * len] & 0x7F) : +- dmi_base_board_type(p[i * len] & 0x7F)); ++ dmi_base_board_type(p[i * len] & 0x7F); ++ + if (p[1 + i * len] == p[2 + i * len]) +- printf("%u", p[1 + i * len]); ++ pr_list_item("%s (%u)", type, p[1 + i * len]); + else +- printf("%u-%u", p[1 + i * len], p[2 + i * len]); +- printf(")\n"); ++ pr_list_item("%s (%u-%u)", type, p[1 + i * len], ++ p[2 + i * len]); + } + } ++ pr_list_end(); + } + + /* +@@ -1033,7 +1030,7 @@ static const char *dmi_processor_family(const struct dmi_header *h, u16 ver) + } + } + +-static void dmi_processor_id(const struct dmi_header *h, const char *prefix) ++static void dmi_processor_id(const struct dmi_header *h) + { + /* Intel AP-485 revision 36, table 2-4 */ + static const char *flags[32] = { +@@ -1203,18 +1200,18 @@ static void dmi_processor_id(const struct dmi_header *h, const char *prefix) + } + + edx = DWORD(p + 4); +- printf("%sFlags:", prefix); + if ((edx & 0xBFEFFBFF) == 0) +- printf(" None\n"); ++ pr_list_start("Flags", "None"); + else + { + int i; + +- printf("\n"); ++ pr_list_start("Flags", NULL); + for (i = 0; i <= 31; i++) + if (flags[i] != NULL && edx & (1 << i)) +- printf("%s\t%s\n", prefix, flags[i]); ++ pr_list_item("%s", flags[i]); + } ++ pr_list_end(); + } + + static void dmi_processor_voltage(const char *attr, u8 code) +@@ -1373,7 +1370,7 @@ static void dmi_processor_cache(const char *attr, u16 code, const char *level, + pr_attr(attr, "0x%04X", code); + } + +-static void dmi_processor_characteristics(u16 code, const char *prefix) ++static void dmi_processor_characteristics(const char *attr, u16 code) + { + /* 7.5.9 */ + static const char *characteristics[] = { +@@ -1386,15 +1383,16 @@ static void dmi_processor_characteristics(u16 code, const char *prefix) + }; + + if ((code & 0x00FC) == 0) +- printf(" None\n"); ++ pr_attr(attr, "None"); + else + { + int i; + +- printf("\n"); ++ pr_list_start(attr, NULL); + for (i = 2; i <= 7; i++) + if (code & (1 << i)) +- printf("%s%s\n", prefix, characteristics[i - 2]); ++ pr_list_item("%s", characteristics[i - 2]); ++ pr_list_end(); + } + } + +@@ -1421,7 +1419,7 @@ static const char *dmi_memory_controller_ed_method(u8 code) + return out_of_spec; + } + +-static void dmi_memory_controller_ec_capabilities(u8 code, const char *prefix) ++static void dmi_memory_controller_ec_capabilities(const char *attr, u8 code) + { + /* 7.6.2 */ + static const char *capabilities[] = { +@@ -1434,15 +1432,16 @@ static void dmi_memory_controller_ec_capabilities(u8 code, const char *prefix) + }; + + if ((code & 0x3F) == 0) +- printf(" None\n"); ++ pr_attr(attr, "None"); + else + { + int i; + +- printf("\n"); ++ pr_list_start(attr, NULL); + for (i = 0; i <= 5; i++) + if (code & (1 << i)) +- printf("%s%s\n", prefix, capabilities[i]); ++ pr_list_item("%s", capabilities[i]); ++ pr_list_end(); + } + } + +@@ -1464,7 +1463,7 @@ static const char *dmi_memory_controller_interleave(u8 code) + return out_of_spec; + } + +-static void dmi_memory_controller_speeds(u16 code, const char *prefix) ++static void dmi_memory_controller_speeds(const char *attr, u16 code) + { + /* 7.6.4 */ + const char *speeds[] = { +@@ -1476,34 +1475,34 @@ static void dmi_memory_controller_speeds(u16 code, const char *prefix) + }; + + if ((code & 0x001F) == 0) +- printf(" None\n"); ++ pr_attr(attr, "None"); + else + { + int i; + +- printf("\n"); ++ pr_list_start(attr, NULL); + for (i = 0; i <= 4; i++) + if (code & (1 << i)) +- printf("%s%s\n", prefix, speeds[i]); ++ pr_list_item("%s", speeds[i]); ++ pr_list_end(); + } + } + +-static void dmi_memory_controller_slots(u8 count, const u8 *p, const char *prefix) ++static void dmi_memory_controller_slots(u8 count, const u8 *p) + { + int i; + +- printf("%sAssociated Memory Slots: %u\n", +- prefix, count); ++ pr_list_start("Associated Memory Slots", "%u", count); + for (i = 0; i < count; i++) +- printf("%s\t0x%04X\n", +- prefix, WORD(p + sizeof(u16) * i)); ++ pr_list_item("0x%04X", WORD(p + sizeof(u16) * i)); ++ pr_list_end(); + } + + /* + * 7.7 Memory Module Information (Type 6) + */ + +-static void dmi_memory_module_types(u16 code, const char *sep) ++static void dmi_memory_module_types(const char *attr, u16 code, int flat) + { + /* 7.7.1 */ + static const char *types[] = { +@@ -1521,14 +1520,34 @@ static void dmi_memory_module_types(u16 code, const char *sep) + }; + + if ((code & 0x07FF) == 0) +- printf(" None"); ++ pr_attr(attr, "None"); ++ else if (flat) ++ { ++ char type_str[68]; ++ int i, off = 0; ++ ++ for (i = 0; i <= 10; i++) ++ { ++ if (code & (1 << i)) ++ { ++ /* Insert space if not the first value */ ++ off += sprintf(type_str + off, ++ off ? " %s" :"%s", ++ types[i]); ++ } ++ } ++ if (off) ++ pr_attr(attr, type_str); ++ } + else + { + int i; + ++ pr_list_start(attr, NULL); + for (i = 0; i <= 10; i++) + if (code & (1 << i)) +- printf("%s%s", sep, types[i]); ++ pr_list_item("%s", types[i]); ++ pr_list_end(); + } + } + +@@ -1649,7 +1668,7 @@ static void dmi_cache_size(const char *attr, u16 code) + (((u32)code & 0x8000LU) << 16) | (code & 0x7FFFLU)); + } + +-static void dmi_cache_types(u16 code, const char *sep) ++static void dmi_cache_types(const char *attr, u16 code, int flat) + { + /* 7.8.2 */ + static const char *types[] = { +@@ -1663,14 +1682,34 @@ static void dmi_cache_types(u16 code, const char *sep) + }; + + if ((code & 0x007F) == 0) +- printf(" None"); ++ pr_attr(attr, "None"); ++ else if (flat) ++ { ++ char type_str[70]; ++ int i, off = 0; ++ ++ for (i = 0; i <= 6; i++) ++ { ++ if (code & (1 << i)) ++ { ++ /* Insert space if not the first value */ ++ off += sprintf(type_str + off, ++ off ? " %s" :"%s", ++ types[i]); ++ } ++ } ++ if (off) ++ pr_attr(attr, type_str); ++ } + else + { + int i; + ++ pr_list_start(attr, NULL); + for (i = 0; i <= 6; i++) + if (code & (1 << i)) +- printf("%s%s", sep, types[i]); ++ pr_list_item("%s", types[i]); ++ pr_list_end(); + } + } + +@@ -2053,7 +2092,7 @@ static void dmi_slot_id(u8 code1, u8 code2, u8 type) + } + } + +-static void dmi_slot_characteristics(u8 code1, u8 code2, const char *prefix) ++static void dmi_slot_characteristics(const char *attr, u8 code1, u8 code2) + { + /* 7.10.6 */ + static const char *characteristics1[] = { +@@ -2074,20 +2113,21 @@ static void dmi_slot_characteristics(u8 code1, u8 code2, const char *prefix) + }; + + if (code1 & (1 << 0)) +- printf(" Unknown\n"); ++ pr_attr(attr, "Unknown"); + else if ((code1 & 0xFE) == 0 && (code2 & 0x07) == 0) +- printf(" None\n"); ++ pr_attr(attr, "None"); + else + { + int i; + +- printf("\n"); ++ pr_list_start(attr, NULL); + for (i = 1; i <= 7; i++) + if (code1 & (1 << i)) +- printf("%s%s\n", prefix, characteristics1[i - 1]); ++ pr_list_item("%s", characteristics1[i - 1]); + for (i = 0; i <= 3; i++) + if (code2 & (1 << i)) +- printf("%s%s\n", prefix, characteristics2[i]); ++ pr_list_item("%s", characteristics2[i]); ++ pr_list_end(); + } + } + +@@ -2199,15 +2239,14 @@ static void dmi_system_configuration_options(const struct dmi_header *h) + * 7.14 BIOS Language Information (Type 13) + */ + +-static void dmi_bios_languages(const struct dmi_header *h, const char *prefix) ++static void dmi_bios_languages(const struct dmi_header *h) + { + u8 *p = h->data + 4; + u8 count = p[0x00]; + int i; + + for (i = 1; i <= count; i++) +- printf("%s%s\n", +- prefix, dmi_string(h, i)); ++ pr_list_item("%s", dmi_string(h, i)); + } + + static const char *dmi_bios_language_format(u8 code) +@@ -2222,14 +2261,14 @@ static const char *dmi_bios_language_format(u8 code) + * 7.15 Group Associations (Type 14) + */ + +-static void dmi_group_associations_items(u8 count, const u8 *p, const char *prefix) ++static void dmi_group_associations_items(u8 count, const u8 *p) + { + int i; + + for (i = 0; i < count; i++) + { +- printf("%s0x%04X (%s)\n", +- prefix, WORD(p + 3 * i + 1), ++ pr_list_item("0x%04X (%s)", ++ WORD(p + 3 * i + 1), + dmi_smbios_structure_type(p[3 * i])); + } + } +@@ -3936,7 +3975,7 @@ static void dmi_tpm_vendor_id(const u8 *p) + pr_attr("Vendor ID", "%s", vendor_id); + } + +-static void dmi_tpm_characteristics(u64 code, const char *prefix) ++static void dmi_tpm_characteristics(u64 code) + { + /* 7.1.1 */ + static const char *characteristics[] = { +@@ -3952,15 +3991,13 @@ static void dmi_tpm_characteristics(u64 code, const char *prefix) + */ + if (code.l & (1 << 2)) + { +- printf("%s%s\n", +- prefix, characteristics[0]); ++ pr_list_item("%s", characteristics[0]); + return; + } + + for (i = 3; i <= 5; i++) + if (code.l & (1 << i)) +- printf("%s%s\n", +- prefix, characteristics[i - 2]); ++ pr_list_item("%s", characteristics[i - 2]); + } + + /* +@@ -3997,12 +4034,13 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + dmi_bios_runtime_size((0x10000 - WORD(data + 0x06)) << 4); + } + dmi_bios_rom_size(data[0x09], h->length < 0x1A ? 16 : WORD(data + 0x18)); +- printf("\tCharacteristics:\n"); +- dmi_bios_characteristics(QWORD(data + 0x0A), "\t\t"); ++ pr_list_start("Characteristics", NULL); ++ dmi_bios_characteristics(QWORD(data + 0x0A)); ++ pr_list_end(); + if (h->length < 0x13) break; +- dmi_bios_characteristics_x1(data[0x12], "\t\t"); ++ dmi_bios_characteristics_x1(data[0x12]); + if (h->length < 0x14) break; +- dmi_bios_characteristics_x2(data[0x13], "\t\t"); ++ dmi_bios_characteristics_x2(data[0x13]); + if (h->length < 0x18) break; + if (data[0x14] != 0xFF && data[0x15] != 0xFF) + pr_attr("BIOS Revision", "%u.%u", +@@ -4049,8 +4087,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + pr_attr("Asset Tag", "%s", + dmi_string(h, data[0x08])); + if (h->length < 0x0A) break; +- printf("\tFeatures:"); +- dmi_base_board_features(data[0x09], "\t\t"); ++ dmi_base_board_features(data[0x09]); + if (h->length < 0x0E) break; + pr_attr("Location In Chassis", "%s", + dmi_string(h, data[0x0A])); +@@ -4062,7 +4099,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + if (h->length < 0x0F) break; + if (h->length < 0x0F + data[0x0E] * sizeof(u16)) break; + if (!(opt.flags & FLAG_QUIET)) +- dmi_base_board_handles(data[0x0E], data + 0x0F, "\t"); ++ dmi_base_board_handles(data[0x0E], data + 0x0F); + break; + + case 3: /* 7.4 Chassis Information */ +@@ -4097,7 +4134,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + dmi_chassis_power_cords(data[0x12]); + if (h->length < 0x15) break; + if (h->length < 0x15 + data[0x13] * data[0x14]) break; +- dmi_chassis_elements(data[0x13], data[0x14], data + 0x15, "\t"); ++ dmi_chassis_elements(data[0x13], data[0x14], data + 0x15); + if (h->length < 0x16 + data[0x13] * data[0x14]) break; + pr_attr("SKU Number", "%s", + dmi_string(h, data[0x15 + data[0x13] * data[0x14]])); +@@ -4114,7 +4151,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + dmi_processor_family(h, ver)); + pr_attr("Manufacturer", "%s", + dmi_string(h, data[0x07])); +- dmi_processor_id(h, "\t"); ++ dmi_processor_id(h); + pr_attr("Version", "%s", + dmi_string(h, data[0x10])); + dmi_processor_voltage("Voltage", data[0x11]); +@@ -4158,8 +4195,8 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + pr_attr("Thread Count", "%u", + h->length >= 0x30 && data[0x25] == 0xFF ? + WORD(data + 0x2E) : data[0x25]); +- printf("\tCharacteristics:"); +- dmi_processor_characteristics(WORD(data + 0x26), "\t\t"); ++ dmi_processor_characteristics("Characteristics", ++ WORD(data + 0x26)); + break; + + case 5: /* 7.6 Memory Controller Information */ +@@ -4167,8 +4204,8 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + if (h->length < 0x0F) break; + pr_attr("Error Detecting Method", "%s", + dmi_memory_controller_ed_method(data[0x04])); +- printf("\tError Correcting Capabilities:"); +- dmi_memory_controller_ec_capabilities(data[0x05], "\t\t"); ++ dmi_memory_controller_ec_capabilities("Error Correcting Capabilities", ++ data[0x05]); + pr_attr("Supported Interleave", "%s", + dmi_memory_controller_interleave(data[0x06])); + pr_attr("Current Interleave", "%s", +@@ -4177,17 +4214,16 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + 1 << data[0x08]); + pr_attr("Maximum Total Memory Size", "%u MB", + data[0x0E] * (1 << data[0x08])); +- printf("\tSupported Speeds:"); +- dmi_memory_controller_speeds(WORD(data + 0x09), "\t\t"); +- printf("\tSupported Memory Types:"); +- dmi_memory_module_types(WORD(data + 0x0B), "\n\t\t"); +- printf("\n"); ++ dmi_memory_controller_speeds("Supported Speeds", ++ WORD(data + 0x09)); ++ dmi_memory_module_types("Supported Memory Types", ++ WORD(data + 0x0B), 0); + dmi_processor_voltage("Memory Module Voltage", data[0x0D]); + if (h->length < 0x0F + data[0x0E] * sizeof(u16)) break; +- dmi_memory_controller_slots(data[0x0E], data + 0x0F, "\t"); ++ dmi_memory_controller_slots(data[0x0E], data + 0x0F); + if (h->length < 0x10 + data[0x0E] * sizeof(u16)) break; +- printf("\tEnabled Error Correcting Capabilities:"); +- dmi_memory_controller_ec_capabilities(data[0x0F + data[0x0E] * sizeof(u16)], "\t\t"); ++ dmi_memory_controller_ec_capabilities("Enabled Error Correcting Capabilities", ++ data[0x0F + data[0x0E] * sizeof(u16)]); + break; + + case 6: /* 7.7 Memory Module Information */ +@@ -4197,9 +4233,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + dmi_string(h, data[0x04])); + dmi_memory_module_connections(data[0x05]); + dmi_memory_module_speed("Current Speed", data[0x06]); +- printf("\tType:"); +- dmi_memory_module_types(WORD(data + 0x07), " "); +- printf("\n"); ++ dmi_memory_module_types("Type", WORD(data + 0x07), 1); + dmi_memory_module_size("Installed Size", data[0x09]); + dmi_memory_module_size("Enabled Size", data[0x0A]); + dmi_memory_module_error(data[0x0B]); +@@ -4226,12 +4260,8 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + dmi_cache_size_2("Maximum Size", DWORD(data + 0x13)); + else + dmi_cache_size("Maximum Size", WORD(data + 0x07)); +- printf("\tSupported SRAM Types:"); +- dmi_cache_types(WORD(data + 0x0B), "\n\t\t"); +- printf("\n"); +- printf("\tInstalled SRAM Type:"); +- dmi_cache_types(WORD(data + 0x0D), " "); +- printf("\n"); ++ dmi_cache_types("Supported SRAM Types", WORD(data + 0x0B), 0); ++ dmi_cache_types("Installed SRAM Type", WORD(data + 0x0D), 1); + if (h->length < 0x13) break; + dmi_memory_module_speed("Speed", data[0x0F]); + pr_attr("Error Correction Type", "%s", +@@ -4270,11 +4300,10 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + pr_attr("Length", "%s", + dmi_slot_length(data[0x08])); + dmi_slot_id(data[0x09], data[0x0A], data[0x05]); +- printf("\tCharacteristics:"); + if (h->length < 0x0D) +- dmi_slot_characteristics(data[0x0B], 0x00, "\t\t"); ++ dmi_slot_characteristics("Characteristics", data[0x0B], 0x00); + else +- dmi_slot_characteristics(data[0x0B], data[0x0C], "\t\t"); ++ dmi_slot_characteristics("Characteristics", data[0x0B], data[0x0C]); + if (h->length < 0x11) break; + dmi_slot_segment_bus_func(WORD(data + 0x0D), data[0x0F], data[0x10]); + if (h->length < 0x13) break; +@@ -4308,8 +4337,9 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + pr_attr("Language Description Format", "%s", + dmi_bios_language_format(data[0x05])); + } +- printf("\tInstallable Languages: %u\n", data[0x04]); +- dmi_bios_languages(h, "\t\t"); ++ pr_list_start("Installable Languages", "%u", data[0x04]); ++ dmi_bios_languages(h); ++ pr_list_end(); + pr_attr("Currently Installed Language", "%s", + dmi_string(h, data[0x15])); + break; +@@ -4319,9 +4349,10 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + if (h->length < 0x05) break; + pr_attr("Name", "%s", + dmi_string(h, data[0x04])); +- printf("\tItems: %u\n", ++ pr_list_start("Items", "%u", + (h->length - 0x05) / 3); +- dmi_group_associations_items((h->length - 0x05) / 3, data + 0x05, "\t\t"); ++ dmi_group_associations_items((h->length - 0x05) / 3, data + 0x05); ++ pr_list_end(); + break; + + case 15: /* 7.16 System Event Log */ +@@ -5002,8 +5033,9 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + break; + } + pr_attr("Description", "%s", dmi_string(h, data[0x12])); +- printf("\tCharacteristics:\n"); +- dmi_tpm_characteristics(QWORD(data + 0x13), "\t\t"); ++ pr_list_start("Characteristics", NULL); ++ dmi_tpm_characteristics(QWORD(data + 0x13)); ++ pr_list_end(); + if (h->length < 0x1F) break; + pr_attr("OEM-specific Information", "0x%08X", + DWORD(data + 0x1B)); +diff --git a/dmioutput.c b/dmioutput.c +index 2330b65755c9..4c8a32a3569a 100644 +--- a/dmioutput.c ++++ b/dmioutput.c +@@ -71,3 +71,38 @@ void pr_attr(const char *name, const char *format, ...) + va_end(args); + printf("\n"); + } ++ ++void pr_list_start(const char *name, const char *format, ...) ++{ ++ va_list args; ++ ++ printf("\t%s:", name); ++ ++ /* format is optional, skip value if not provided */ ++ if (format) ++ { ++ printf(" "); ++ va_start(args, format); ++ vprintf(format, args); ++ va_end(args); ++ } ++ printf("\n"); ++ ++} ++ ++void pr_list_item(const char *format, ...) ++{ ++ va_list args; ++ ++ printf("\t\t"); ++ ++ va_start(args, format); ++ vprintf(format, args); ++ va_end(args); ++ printf("\n"); ++} ++ ++void pr_list_end(void) ++{ ++ /* a no-op for text output */ ++} +diff --git a/dmioutput.h b/dmioutput.h +index 981dcb45f26a..33f09c4452bb 100644 +--- a/dmioutput.h ++++ b/dmioutput.h +@@ -26,3 +26,6 @@ void pr_info(const char *format, ...); + void pr_handle(const struct dmi_header *h); + void pr_handle_name(const char *format, ...); + void pr_attr(const char *name, const char *format, ...); ++void pr_list_start(const char *name, const char *format, ...); ++void pr_list_item(const char *format, ...); ++void pr_list_end(void); +-- +2.17.1 + diff --git a/SOURCES/0016-dmidecode-Add-helper-function-pr_subattr.patch b/SOURCES/0016-dmidecode-Add-helper-function-pr_subattr.patch new file mode 100644 index 0000000..6e92b55 --- /dev/null +++ b/SOURCES/0016-dmidecode-Add-helper-function-pr_subattr.patch @@ -0,0 +1,307 @@ +From 20d50c70b98d2a7013b604d575656a098d294f7f Mon Sep 17 00:00:00 2001 +From: Jean Delvare +Date: Wed, 1 Apr 2020 10:00:27 +0200 +Subject: [PATCH 16/23] dmidecode: Add helper function pr_subattr + +Print all second-level attributes through a helper function pr_subattr. + +Signed-off-by: Jean Delvare +--- + dmidecode.c | 68 ++++++++++++++++++++++++++++------------------------- + dmioem.c | 12 +++++----- + dmioutput.c | 12 ++++++++++ + dmioutput.h | 1 + + 4 files changed, 55 insertions(+), 38 deletions(-) + +diff --git a/dmidecode.c b/dmidecode.c +index 5a5299ed13ba..3d1da955bab8 100644 +--- a/dmidecode.c ++++ b/dmidecode.c +@@ -431,7 +431,8 @@ static void dmi_bios_characteristics_x2(u8 code) + * 7.2 System Information (Type 1) + */ + +-static void dmi_system_uuid(const char *attr, const u8 *p, u16 ver) ++static void dmi_system_uuid(void (*print_cb)(const char *name, const char *format, ...), ++ const char *attr, const u8 *p, u16 ver) + { + int only0xFF = 1, only0x00 = 1; + int i; +@@ -444,16 +445,16 @@ static void dmi_system_uuid(const char *attr, const u8 *p, u16 ver) + + if (only0xFF) + { +- if (attr) +- pr_attr(attr, "Not Present"); ++ if (print_cb) ++ print_cb(attr, "Not Present"); + else + printf("Not Present\n"); + return; + } + if (only0x00) + { +- if (attr) +- pr_attr(attr, "Not Settable"); ++ if (print_cb) ++ print_cb(attr, "Not Settable"); + else + printf("Not Settable\n"); + return; +@@ -469,8 +470,8 @@ static void dmi_system_uuid(const char *attr, const u8 *p, u16 ver) + */ + if (ver >= 0x0206) + { +- if (attr) +- pr_attr(attr, ++ if (print_cb) ++ print_cb(attr, + "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", + p[3], p[2], p[1], p[0], p[5], p[4], p[7], p[6], + p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]); +@@ -481,8 +482,8 @@ static void dmi_system_uuid(const char *attr, const u8 *p, u16 ver) + } + else + { +- if (attr) +- pr_attr(attr, ++ if (print_cb) ++ print_cb(attr, + "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", + p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], + p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]); +@@ -3655,7 +3656,7 @@ static const char *dmi_address_decode(u8 *data, char *storage, u8 addrtype) + /* + * DSP0270: 8.5: Parse the protocol record format + */ +-static void dmi_parse_protocol_record(const char *prefix, u8 *rec) ++static void dmi_parse_protocol_record(u8 *rec) + { + u8 rid; + u8 rlen; +@@ -3666,6 +3667,7 @@ static void dmi_parse_protocol_record(const char *prefix, u8 *rec) + u8 hlen; + const char *addrstr; + const char *hname; ++ char attr[38]; + + /* DSP0270: 8.5: Protocol Identifier */ + rid = rec[0x0]; +@@ -3674,7 +3676,7 @@ static void dmi_parse_protocol_record(const char *prefix, u8 *rec) + /* DSP0270: 8.5: Protocol Record Data */ + rdata = &rec[0x2]; + +- printf("%sProtocol ID: %02x (%s)\n", prefix, rid, ++ pr_attr("Protocol ID", "%02x (%s)", rid, + dmi_protocol_record_type(rid)); + + /* +@@ -3704,8 +3706,7 @@ static void dmi_parse_protocol_record(const char *prefix, u8 *rec) + * endianess of the field is always little after version 2.6.0 + * we can just pick a sufficiently recent version here. + */ +- printf("%s\tService UUID: ", prefix); +- dmi_system_uuid(NULL, &rdata[0], 0x311); /* FIXME */ ++ dmi_system_uuid(pr_subattr, "Service UUID", &rdata[0], 0x311); + + /* + * DSP0270: 8.6: Redfish Over IP Host IP Assignment Type +@@ -3713,13 +3714,13 @@ static void dmi_parse_protocol_record(const char *prefix, u8 *rec) + * uses decimal, so as to make it more comparable + */ + assign_val = rdata[16]; +- printf("%s\tHost IP Assignment Type: %s\n", prefix, ++ pr_subattr("Host IP Assignment Type", "%s", + dmi_protocol_assignment_type(assign_val)); + + /* DSP0270: 8.6: Redfish Over IP Host Address format */ + addrtype = rdata[17]; + addrstr = dmi_address_type(addrtype); +- printf("%s\tHost IP Address Format: %s\n", prefix, ++ pr_subattr("Host IP Address Format", "%s", + addrstr); + + /* DSP0270: 8.6 IP Assignment types */ +@@ -3727,24 +3728,26 @@ static void dmi_parse_protocol_record(const char *prefix, u8 *rec) + if (assign_val == 0x1 || assign_val == 0x3) + { + /* DSP0270: 8.6: the Host IPv[4|6] Address */ +- printf("%s\t%s Address: %s\n", prefix, addrstr, ++ sprintf(attr, "%s Address", addrstr); ++ pr_subattr(attr, "%s", + dmi_address_decode(&rdata[18], buf, addrtype)); + + /* DSP0270: 8.6: Prints the Host IPv[4|6] Mask */ +- printf("%s\t%s Mask: %s\n", prefix, addrstr, ++ sprintf(attr, "%s Mask", addrstr); ++ pr_subattr(attr, "%s", + dmi_address_decode(&rdata[34], buf, addrtype)); + } + + /* DSP0270: 8.6: Get the Redfish Service IP Discovery Type */ + assign_val = rdata[50]; + /* Redfish Service IP Discovery type mirrors Host IP Assignment type */ +- printf("%s\tRedfish Service IP Discovery Type: %s\n", prefix, ++ pr_subattr("Redfish Service IP Discovery Type", "%s", + dmi_protocol_assignment_type(assign_val)); + + /* DSP0270: 8.6: Get the Redfish Service IP Address Format */ + addrtype = rdata[51]; + addrstr = dmi_address_type(addrtype); +- printf("%s\tRedfish Service IP Address Format: %s\n", prefix, ++ pr_subattr("Redfish Service IP Address Format", "%s", + addrstr); + + if (assign_val == 0x1 || assign_val == 0x3) +@@ -3753,20 +3756,22 @@ static void dmi_parse_protocol_record(const char *prefix, u8 *rec) + u32 vlan; + + /* DSP0270: 8.6: Prints the Redfish IPv[4|6] Service Address */ +- printf("%s\t%s Redfish Service Address: %s\n", prefix, +- addrstr, dmi_address_decode(&rdata[52], buf, ++ sprintf(attr, "%s Redfish Service Address", addrstr); ++ pr_subattr(attr, "%s", ++ dmi_address_decode(&rdata[52], buf, + addrtype)); + + /* DSP0270: 8.6: Prints the Redfish IPv[4|6] Service Mask */ +- printf("%s\t%s Redfish Service Mask: %s\n", prefix, +- addrstr, dmi_address_decode(&rdata[68], buf, ++ sprintf(attr, "%s Redfish Service Mask", addrstr); ++ pr_subattr(attr, "%s", ++ dmi_address_decode(&rdata[68], buf, + addrtype)); + + /* DSP0270: 8.6: Redfish vlan and port info */ + port = WORD(&rdata[84]); + vlan = DWORD(&rdata[86]); +- printf("%s\tRedfish Service Port: %hu\n", prefix, port); +- printf("%s\tRedfish Service Vlan: %u\n", prefix, vlan); ++ pr_subattr("Redfish Service Port", "%hu", port); ++ pr_subattr("Redfish Service Vlan", "%u", vlan); + } + + /* DSP0270: 8.6: Redfish host length and name */ +@@ -3783,7 +3788,7 @@ static void dmi_parse_protocol_record(const char *prefix, u8 *rec) + hname = out_of_spec; + hlen = strlen(out_of_spec); + } +- printf("%s\tRedfish Service Hostname: %.*s\n", prefix, hlen, hname); ++ pr_subattr("Redfish Service Hostname", "%.*s", hlen, hname); + } + + /* +@@ -3803,8 +3808,7 @@ static const char *dmi_parse_device_type(u8 type) + return out_of_spec; + } + +-static void dmi_parse_controller_structure(const struct dmi_header *h, +- const char *prefix) ++static void dmi_parse_controller_structure(const struct dmi_header *h) + { + int i; + u8 *data = h->data; +@@ -3936,7 +3940,7 @@ static void dmi_parse_controller_structure(const struct dmi_header *h, + return; + } + +- dmi_parse_protocol_record(prefix, rec); ++ dmi_parse_protocol_record(rec); + + /* + * DSP0270: 8.6 +@@ -4062,7 +4066,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + pr_attr("Serial Number", "%s", + dmi_string(h, data[0x07])); + if (h->length < 0x19) break; +- dmi_system_uuid("UUID", data + 0x08, ver); ++ dmi_system_uuid(pr_attr, "UUID", data + 0x08, ver); + pr_attr("Wake-up Type", "%s", + dmi_system_wake_up_type(data[0x18])); + if (h->length < 0x1B) break; +@@ -5002,7 +5006,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + } + } + else +- dmi_parse_controller_structure(h, "\t"); ++ dmi_parse_controller_structure(h); + break; + + case 43: /* 7.44 TPM Device */ +@@ -5104,7 +5108,7 @@ static void dmi_table_string(const struct dmi_header *h, const u8 *data, u16 ver + printf("%u.%u\n", data[key - 1], data[key]); + break; + case 0x108: +- dmi_system_uuid(NULL, data + offset, ver); ++ dmi_system_uuid(NULL, NULL, data + offset, ver); + break; + case 0x305: + printf("%s\n", dmi_chassis_type(data[offset])); +diff --git a/dmioem.c b/dmioem.c +index 873ec1068c16..9d6ec7520287 100644 +--- a/dmioem.c ++++ b/dmioem.c +@@ -97,10 +97,10 @@ static int dmi_decode_acer(const struct dmi_header *h) + if (h->length < 0x0F) break; + cap = WORD(data + 0x04); + pr_attr("Function bitmap for Communication Button", "0x%04hx", cap); +- printf("\t\tWiFi: %s\n", cap & 0x0001 ? "Yes" : "No"); +- printf("\t\t3G: %s\n", cap & 0x0040 ? "Yes" : "No"); +- printf("\t\tWiMAX: %s\n", cap & 0x0080 ? "Yes" : "No"); +- printf("\t\tBluetooth: %s\n", cap & 0x0800 ? "Yes" : "No"); ++ pr_subattr("WiFi", "%s", cap & 0x0001 ? "Yes" : "No"); ++ pr_subattr("3G", "%s", cap & 0x0040 ? "Yes" : "No"); ++ pr_subattr("WiMAX", "%s", cap & 0x0080 ? "Yes" : "No"); ++ pr_subattr("Bluetooth", "%s", cap & 0x0800 ? "Yes" : "No"); + pr_attr("Function bitmap for Application Button", "0x%04hx", WORD(data + 0x06)); + pr_attr("Function bitmap for Media Button", "0x%04hx", WORD(data + 0x08)); + pr_attr("Function bitmap for Display Button", "0x%04hx", WORD(data + 0x0A)); +@@ -278,8 +278,8 @@ static int dmi_decode_hp(const struct dmi_header *h) + if (h->length < 0x14) break; + feat = DWORD(data + 0x10); + pr_attr("Misc. Features", "0x%08x", feat); +- printf("\t\tiCRU: %s\n", feat & 0x0001 ? "Yes" : "No"); +- printf("\t\tUEFI: %s\n", feat & 0x1400 ? "Yes" : "No"); ++ pr_subattr("iCRU", "%s", feat & 0x0001 ? "Yes" : "No"); ++ pr_subattr("UEFI", "%s", feat & 0x1400 ? "Yes" : "No"); + break; + + default: +diff --git a/dmioutput.c b/dmioutput.c +index 4c8a32a3569a..da04450494f7 100644 +--- a/dmioutput.c ++++ b/dmioutput.c +@@ -72,6 +72,18 @@ void pr_attr(const char *name, const char *format, ...) + printf("\n"); + } + ++void pr_subattr(const char *name, const char *format, ...) ++{ ++ va_list args; ++ ++ printf("\t\t%s: ", name); ++ ++ va_start(args, format); ++ vprintf(format, args); ++ va_end(args); ++ printf("\n"); ++} ++ + void pr_list_start(const char *name, const char *format, ...) + { + va_list args; +diff --git a/dmioutput.h b/dmioutput.h +index 33f09c4452bb..58ca5a854a79 100644 +--- a/dmioutput.h ++++ b/dmioutput.h +@@ -26,6 +26,7 @@ void pr_info(const char *format, ...); + void pr_handle(const struct dmi_header *h); + void pr_handle_name(const char *format, ...); + void pr_attr(const char *name, const char *format, ...); ++void pr_subattr(const char *name, const char *format, ...); + void pr_list_start(const char *name, const char *format, ...); + void pr_list_item(const char *format, ...); + void pr_list_end(void); +-- +2.17.1 + diff --git a/SOURCES/0017-dmidecode-Use-the-print-helpers-in-dump-mode-too.patch b/SOURCES/0017-dmidecode-Use-the-print-helpers-in-dump-mode-too.patch new file mode 100644 index 0000000..7627758 --- /dev/null +++ b/SOURCES/0017-dmidecode-Use-the-print-helpers-in-dump-mode-too.patch @@ -0,0 +1,95 @@ +From da06888d08b9f1108fe89560c06d39675c10cd95 Mon Sep 17 00:00:00 2001 +From: Jean Delvare +Date: Wed, 1 Apr 2020 10:00:30 +0200 +Subject: [PATCH 17/23] dmidecode: Use the print helpers in dump mode too + +Signed-off-by: Jean Delvare +--- + dmidecode.c | 30 ++++++++++++++++++------------ + 1 file changed, 18 insertions(+), 12 deletions(-) + +diff --git a/dmidecode.c b/dmidecode.c +index 3d1da955bab8..5e9b9899ec1f 100644 +--- a/dmidecode.c ++++ b/dmidecode.c +@@ -220,43 +220,49 @@ static int dmi_bcd_range(u8 value, u8 low, u8 high) + return 1; + } + +-static void dmi_dump(const struct dmi_header *h, const char *prefix) ++static void dmi_dump(const struct dmi_header *h) + { ++ static char raw_data[48]; + int row, i; ++ unsigned int off; + char *s; + +- printf("%sHeader and Data:\n", prefix); ++ pr_list_start("Header and Data", NULL); + for (row = 0; row < ((h->length - 1) >> 4) + 1; row++) + { +- printf("%s\t", prefix); ++ off = 0; + for (i = 0; i < 16 && i < h->length - (row << 4); i++) +- printf("%s%02X", i ? " " : "", ++ off += sprintf(raw_data + off, i ? " %02X" : "%02X", + (h->data)[(row << 4) + i]); +- printf("\n"); ++ pr_list_item(raw_data); + } ++ pr_list_end(); + + if ((h->data)[h->length] || (h->data)[h->length + 1]) + { +- printf("%sStrings:\n", prefix); ++ pr_list_start("Strings", NULL); + i = 1; + while ((s = _dmi_string(h, i++, !(opt.flags & FLAG_DUMP)))) + { + if (opt.flags & FLAG_DUMP) + { + int j, l = strlen(s) + 1; ++ ++ off = 0; + for (row = 0; row < ((l - 1) >> 4) + 1; row++) + { +- printf("%s\t", prefix); + for (j = 0; j < 16 && j < l - (row << 4); j++) +- printf("%s%02X", j ? " " : "", ++ off += sprintf(raw_data + off, ++ j ? " %02X" : "%02X", + (unsigned char)s[(row << 4) + j]); +- printf("\n"); ++ pr_list_item(raw_data); + } + /* String isn't filtered yet so do it now */ + ascii_filter(s, l - 1); + } +- printf("%s\t%s\n", prefix, s); ++ pr_list_item("%s", s); + } ++ pr_list_end(); + } + } + +@@ -5060,7 +5066,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + return; + pr_handle_name("%s Type", + h->type >= 128 ? "OEM-specific" : "Unknown"); +- dmi_dump(h, "\t"); ++ dmi_dump(h); + } + printf("\n"); + } +@@ -5206,7 +5212,7 @@ static void dmi_table_decode(u8 *buf, u32 len, u16 num, u16 ver, u32 flags) + { + if (opt.flags & FLAG_DUMP) + { +- dmi_dump(&h, "\t"); ++ dmi_dump(&h); + printf("\n"); + } + else +-- +2.17.1 + diff --git a/SOURCES/0018-dmidecode-Add-helper-function-for-separators.patch b/SOURCES/0018-dmidecode-Add-helper-function-for-separators.patch new file mode 100644 index 0000000..4d64681 --- /dev/null +++ b/SOURCES/0018-dmidecode-Add-helper-function-for-separators.patch @@ -0,0 +1,80 @@ +From 9c7db76f373a1d25e52177b81e97bb9e0f9c32b5 Mon Sep 17 00:00:00 2001 +From: Jean Delvare +Date: Wed, 1 Apr 2020 10:00:33 +0200 +Subject: [PATCH 18/23] dmidecode: Add helper function for separators + +A simple helper function to print a blank line between records. + +Signed-off-by: Jean Delvare +--- + dmidecode.c | 9 +++++---- + dmioutput.c | 5 +++++ + dmioutput.h | 1 + + 3 files changed, 11 insertions(+), 4 deletions(-) + +diff --git a/dmidecode.c b/dmidecode.c +index 5e9b9899ec1f..3551637e7b16 100644 +--- a/dmidecode.c ++++ b/dmidecode.c +@@ -5068,7 +5068,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + h->type >= 128 ? "OEM-specific" : "Unknown"); + dmi_dump(h); + } +- printf("\n"); ++ pr_sep(); + } + + static void to_dmi_header(struct dmi_header *h, u8 *data) +@@ -5195,7 +5195,8 @@ static void dmi_table_decode(u8 *buf, u32 len, u16 num, u16 ver, u32 flags) + if ((unsigned long)(next - buf) > len) + { + if (display && !(opt.flags & FLAG_QUIET)) +- printf("\t\n\n"); ++ printf("\t\n"); ++ pr_sep(); + data = next; + break; + } +@@ -5213,7 +5214,7 @@ static void dmi_table_decode(u8 *buf, u32 len, u16 num, u16 ver, u32 flags) + if (opt.flags & FLAG_DUMP) + { + dmi_dump(&h); +- printf("\n"); ++ pr_sep(); + } + else + dmi_decode(&h, ver); +@@ -5271,7 +5272,7 @@ static void dmi_table(off_t base, u32 len, u16 num, u32 ver, const char *devmem, + pr_info("Table at 0x%08llX.", + (unsigned long long)base); + } +- printf("\n"); ++ pr_sep(); + } + + if ((flags & FLAG_NO_FILE_OFFSET) || (opt.flags & FLAG_FROM_DUMP)) +diff --git a/dmioutput.c b/dmioutput.c +index da04450494f7..ef1c41b2f94e 100644 +--- a/dmioutput.c ++++ b/dmioutput.c +@@ -118,3 +118,8 @@ void pr_list_end(void) + { + /* a no-op for text output */ + } ++ ++void pr_sep(void) ++{ ++ printf("\n"); ++} +diff --git a/dmioutput.h b/dmioutput.h +index 58ca5a854a79..6b5f0e0e92c5 100644 +--- a/dmioutput.h ++++ b/dmioutput.h +@@ -30,3 +30,4 @@ void pr_subattr(const char *name, const char *format, ...); + void pr_list_start(const char *name, const char *format, ...); + void pr_list_item(const char *format, ...); + void pr_list_end(void); ++void pr_sep(void); +-- +2.17.1 + diff --git a/SOURCES/0019-dmidecode-Add-helper-function-for-structure-errors.patch b/SOURCES/0019-dmidecode-Add-helper-function-for-structure-errors.patch new file mode 100644 index 0000000..98a87c9 --- /dev/null +++ b/SOURCES/0019-dmidecode-Add-helper-function-for-structure-errors.patch @@ -0,0 +1,60 @@ +From 25e63d7757f77a15704175c00193753be4176797 Mon Sep 17 00:00:00 2001 +From: Jean Delvare +Date: Wed, 1 Apr 2020 10:00:36 +0200 +Subject: [PATCH 19/23] dmidecode: Add helper function for structure errors + +Add a helper function to print structure errors, specifically for +structures which do not fit in the table. + +Signed-off-by: Jean Delvare +--- + dmidecode.c | 2 +- + dmioutput.c | 12 ++++++++++++ + dmioutput.h | 1 + + 3 files changed, 14 insertions(+), 1 deletion(-) + +diff --git a/dmidecode.c b/dmidecode.c +index 3551637e7b16..59f4fe09e642 100644 +--- a/dmidecode.c ++++ b/dmidecode.c +@@ -5195,7 +5195,7 @@ static void dmi_table_decode(u8 *buf, u32 len, u16 num, u16 ver, u32 flags) + if ((unsigned long)(next - buf) > len) + { + if (display && !(opt.flags & FLAG_QUIET)) +- printf("\t\n"); ++ pr_struct_err(""); + pr_sep(); + data = next; + break; +diff --git a/dmioutput.c b/dmioutput.c +index ef1c41b2f94e..42f8d3218c43 100644 +--- a/dmioutput.c ++++ b/dmioutput.c +@@ -123,3 +123,15 @@ void pr_sep(void) + { + printf("\n"); + } ++ ++void pr_struct_err(const char *format, ...) ++{ ++ va_list args; ++ ++ printf("\t"); ++ ++ va_start(args, format); ++ vprintf(format, args); ++ va_end(args); ++ printf("\n"); ++} +diff --git a/dmioutput.h b/dmioutput.h +index 6b5f0e0e92c5..a492ec0eb4e7 100644 +--- a/dmioutput.h ++++ b/dmioutput.h +@@ -31,3 +31,4 @@ void pr_list_start(const char *name, const char *format, ...); + void pr_list_item(const char *format, ...); + void pr_list_end(void); + void pr_sep(void); ++void pr_struct_err(const char *format, ...); +-- +2.17.1 + diff --git a/SOURCES/0020-dmidecode-White-space-fixes.patch b/SOURCES/0020-dmidecode-White-space-fixes.patch new file mode 100644 index 0000000..4dbd844 --- /dev/null +++ b/SOURCES/0020-dmidecode-White-space-fixes.patch @@ -0,0 +1,34 @@ +From e0d05fdeb0cd9b6be47fb7e9c11ae6b5794f3df3 Mon Sep 17 00:00:00 2001 +From: Jean Delvare +Date: Wed, 1 Apr 2020 10:02:04 +0200 +Subject: [PATCH 20/23] dmidecode: White space fixes + +--- + dmidecode.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/dmidecode.c b/dmidecode.c +index 59f4fe09e642..d0dc98467bdc 100644 +--- a/dmidecode.c ++++ b/dmidecode.c +@@ -3312,7 +3312,7 @@ static void dmi_fixup_type_34(struct dmi_header *h, int display) + { + u8 *p = h->data; + +- /* Make sure the hidden data is ASCII only */ ++ /* Make sure the hidden data is ASCII only */ + if (h->length == 0x10 + && is_printable(p + 0x0B, 0x10 - 0x0B)) + { +@@ -3603,7 +3603,7 @@ static const char *dmi_protocol_record_type(u8 type) + "Reserved", + "IPMI", + "MCTP", +- "Redfish over IP", /* 0x4 */ ++ "Redfish over IP", /* 0x4 */ + }; + + if (type <= 0x4) +-- +2.17.1 + diff --git a/SOURCES/0021-dmidecode-Update-copyright-year.patch b/SOURCES/0021-dmidecode-Update-copyright-year.patch new file mode 100644 index 0000000..4546f3a --- /dev/null +++ b/SOURCES/0021-dmidecode-Update-copyright-year.patch @@ -0,0 +1,67 @@ +From fd4a87bffcf55db6c9c9d460b1b0b5e6fe9a0f03 Mon Sep 17 00:00:00 2001 +From: Jean Delvare +Date: Wed, 1 Apr 2020 10:04:27 +0200 +Subject: [PATCH 21/23] dmidecode: Update copyright year + +--- + Makefile | 2 +- + dmidecode.c | 2 +- + dmidecode.h | 2 +- + dmioem.c | 2 +- + 4 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/Makefile b/Makefile +index 5d58266ef2de..97a1782fde3f 100644 +--- a/Makefile ++++ b/Makefile +@@ -4,7 +4,7 @@ + # VPD Decode + # + # Copyright (C) 2000-2002 Alan Cox +-# Copyright (C) 2002-2015 Jean Delvare ++# Copyright (C) 2002-2020 Jean Delvare + # + # This program is free software; you can redistribute it and/or modify + # it under the terms of the GNU General Public License as published by +diff --git a/dmidecode.c b/dmidecode.c +index d0dc98467bdc..981fe9697458 100644 +--- a/dmidecode.c ++++ b/dmidecode.c +@@ -2,7 +2,7 @@ + * DMI Decode + * + * Copyright (C) 2000-2002 Alan Cox +- * Copyright (C) 2002-2019 Jean Delvare ++ * Copyright (C) 2002-2020 Jean Delvare + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +diff --git a/dmidecode.h b/dmidecode.h +index 9ecc1791702d..1dc59a7e5536 100644 +--- a/dmidecode.h ++++ b/dmidecode.h +@@ -1,7 +1,7 @@ + /* + * This file is part of the dmidecode project. + * +- * Copyright (C) 2005-2008 Jean Delvare ++ * Copyright (C) 2005-2020 Jean Delvare + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +diff --git a/dmioem.c b/dmioem.c +index 9d6ec7520287..60b667416563 100644 +--- a/dmioem.c ++++ b/dmioem.c +@@ -2,7 +2,7 @@ + * Decoding of OEM-specific entries + * This file is part of the dmidecode project. + * +- * Copyright (C) 2007-2008 Jean Delvare ++ * Copyright (C) 2007-2020 Jean Delvare + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +-- +2.17.1 + diff --git a/SOURCES/0022-dmidecode-Add-missing-build-dependencies-on-dmioutpu.patch b/SOURCES/0022-dmidecode-Add-missing-build-dependencies-on-dmioutpu.patch new file mode 100644 index 0000000..edd3449 --- /dev/null +++ b/SOURCES/0022-dmidecode-Add-missing-build-dependencies-on-dmioutpu.patch @@ -0,0 +1,37 @@ +From 51bfbe2d5e8728e47f38eb44464f58ad674c4289 Mon Sep 17 00:00:00 2001 +From: Jean Delvare +Date: Tue, 7 Apr 2020 11:55:41 +0200 +Subject: [PATCH 22/23] dmidecode: Add missing build dependencies on + dmioutput.h + +dmidecode.c and dmioem.c both include dmioutput.h so they must be +rebuilt if that header file changes. + +Signed-off-by: Jean Delvare +--- + Makefile | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/Makefile b/Makefile +index 97a1782fde3f..194a523bdb46 100644 +--- a/Makefile ++++ b/Makefile +@@ -78,13 +78,13 @@ vpddecode : vpddecode.o vpdopt.o util.o + # + + dmidecode.o : dmidecode.c version.h types.h util.h config.h dmidecode.h \ +- dmiopt.h dmioem.h ++ dmiopt.h dmioem.h dmioutput.h + $(CC) $(CFLAGS) -c $< -o $@ + + dmiopt.o : dmiopt.c config.h types.h util.h dmidecode.h dmiopt.h + $(CC) $(CFLAGS) -c $< -o $@ + +-dmioem.o : dmioem.c types.h dmidecode.h dmioem.h ++dmioem.o : dmioem.c types.h dmidecode.h dmioem.h dmioutput.h + $(CC) $(CFLAGS) -c $< -o $@ + + dmioutput.o : dmioutput.c types.h dmioutput.h +-- +2.17.1 + diff --git a/SOURCES/0023-Allow-overriding-build-settings-from-the-environment.patch b/SOURCES/0023-Allow-overriding-build-settings-from-the-environment.patch new file mode 100644 index 0000000..183223b --- /dev/null +++ b/SOURCES/0023-Allow-overriding-build-settings-from-the-environment.patch @@ -0,0 +1,55 @@ +From 5b3c8e9950262fc941bb5b3b3a1275720d47d62d Mon Sep 17 00:00:00 2001 +From: Jean Delvare +Date: Fri, 17 Apr 2020 17:14:15 +0200 +Subject: [PATCH 23/23] Allow overriding build settings from the environment + +Let packagers pass their own CC, CFLAGS and LDFLAGS settings. The +settings which are specific to dmidecode are appended later so that +they are applied no matter what. + +This should fix bug #55805: +https://savannah.nongnu.org/bugs/?55805 + +Signed-off-by: Jean Delvare +--- + Makefile | 17 +++++++++-------- + 1 file changed, 9 insertions(+), 8 deletions(-) + +diff --git a/Makefile b/Makefile +index 194a523bdb46..7aa729d8ca01 100644 +--- a/Makefile ++++ b/Makefile +@@ -12,8 +12,13 @@ + # (at your option) any later version. + # + +-CC = gcc +-CFLAGS = -W -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual \ ++CC ?= gcc ++# Base CFLAGS can be overridden by environment ++CFLAGS ?= -O2 ++# When debugging, disable -O2 and enable -g ++#CFLAGS ?= -g ++ ++CFLAGS += -W -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual \ + -Wcast-align -Wwrite-strings -Wmissing-prototypes -Winline -Wundef + + # Let lseek and mmap support 64-bit wide offsets +@@ -22,12 +27,8 @@ CFLAGS += -D_FILE_OFFSET_BITS=64 + #CFLAGS += -DBIGENDIAN + #CFLAGS += -DALIGNMENT_WORKAROUND + +-# When debugging, disable -O2 and enable -g. +-CFLAGS += -O2 +-#CFLAGS += -g +- +-# Pass linker flags here +-LDFLAGS = ++# Pass linker flags here (can be set from environment too) ++LDFLAGS ?= + + DESTDIR = + prefix = /usr/local +-- +2.17.1 + diff --git a/SPECS/dmidecode.spec b/SPECS/dmidecode.spec index f87fca5..a677511 100644 --- a/SPECS/dmidecode.spec +++ b/SPECS/dmidecode.spec @@ -1,7 +1,7 @@ Summary: Tool to analyse BIOS DMI data Name: dmidecode Version: 3.2 -Release: 5%{?dist} +Release: 6%{?dist} Epoch: 1 License: GPLv2+ Source0: http://download.savannah.gnu.org/releases/%{name}/%{name}-%{version}.tar.xz @@ -25,6 +25,29 @@ Patch14: 0010-dmidecode-Fix-System-Slot-Information-for-PCIe-SSD.patch Patch15: 0011-Typo.patch Patch16: 0001-dmidecode-Add-enumerated-values-from-SMBIOS-3.3.0.patch Patch17: 0002-dmidecode-Decode-system-slot-base-bus-width-and-peer.patch +Patch18: 0001-dmidecode-Print-type-33-name-unconditionally.patch +Patch19: 0002-dmidecode-Don-t-choke-on-invalid-processor-voltage.patch +Patch20: 0003-dmidecode-Simplify-the-formatting-of-memory-error-st.patch +Patch21: 0004-dmidecode-Fix-the-alignment-of-type-25-name.patch +Patch22: 0005-dmidecode-Code-indentation-fixes.patch +Patch23: 0006-dmidecode-Reduce-the-indentation-of-type-42-structur.patch +Patch24: 0007-dmidecode-Move-type-42-warning-messages-to-stderr.patch +Patch25: 0008-dmidecode-Refactor-ASCII-filtering-of-DMI-strings.patch +Patch26: 0009-dmidecode-Add-helper-function-pr_comment.patch +Patch27: 0010-dmidecode-Add-helper-function-pr_info.patch +Patch28: 0011-dmidecode-Protect-dmidecode.h-against-double-inclusi.patch +Patch29: 0012-dmidecode-Add-helper-function-pr_handle.patch +Patch30: 0013-dmidecode-Add-helper-function-pr_handle_name.patch +Patch31: 0014-dmidecode-Add-helper-function-pr_attr.patch +Patch32: 0015-dmidecode-Add-helper-functions-pr_list_start-item-en.patch +Patch33: 0016-dmidecode-Add-helper-function-pr_subattr.patch +Patch34: 0017-dmidecode-Use-the-print-helpers-in-dump-mode-too.patch +Patch35: 0018-dmidecode-Add-helper-function-for-separators.patch +Patch36: 0019-dmidecode-Add-helper-function-for-structure-errors.patch +Patch37: 0020-dmidecode-White-space-fixes.patch +Patch38: 0021-dmidecode-Update-copyright-year.patch +Patch39: 0022-dmidecode-Add-missing-build-dependencies-on-dmioutpu.patch +Patch40: 0023-Allow-overriding-build-settings-from-the-environment.patch BuildRequires: gcc make ExclusiveArch: %{ix86} x86_64 ia64 aarch64 @@ -60,6 +83,29 @@ I/O ports (e.g. serial, parallel, USB). %patch15 -p1 %patch16 -p1 %patch17 -p1 +%patch18 -p1 +%patch19 -p1 +%patch20 -p1 +%patch21 -p1 +%patch22 -p1 +%patch23 -p1 +%patch24 -p1 +%patch25 -p1 +%patch26 -p1 +%patch27 -p1 +%patch28 -p1 +%patch29 -p1 +%patch30 -p1 +%patch31 -p1 +%patch32 -p1 +%patch33 -p1 +%patch34 -p1 +%patch35 -p1 +%patch36 -p1 +%patch37 -p1 +%patch38 -p1 +%patch39 -p1 +%patch40 -p1 %build make %{?_smp_mflags} CFLAGS="%{optflags}" LDFLAGS="%{__global_ldflags}" @@ -80,6 +126,11 @@ make %{?_smp_mflags} DESTDIR=%{buildroot} prefix=%{_prefix} install-bin install- %{_mandir}/man8/* %changelog +* Wed May 20 2020 Lianbo Jiang - 1:3.2-6 +- Updated to the latest upstream(5b3c8e995026 ("Allow overriding + build settings from the environment")) +- Resolves: rhbz#1796581 + * Sun Oct 27 2019 Lianbo Jiang - 1:3.2-5 - Fix the "OUT OF SPEC" for type 9 - Resolves: rhbz#1763678