From d48bf01636d322443f69845da2f40bea70317c92 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Mon, 7 Mar 2022 10:11:12 +0100 Subject: [PATCH] memory-id: Work-around incorrect "Number of slots" In some BIOSes, the "Number of slots or sockets available for Memory Devices in this array" is incorrectly set to the number of memory array that's populated. Work-around this problem by outputting the number of sockets after having parsed them so that consumers of this data can carry on expecting an accurate number in this property. This fixes the number of memory slots advertised for the HP Z600. See https://gitlab.gnome.org/GNOME/gnome-control-center/-/issues/1686 --- src/udev/dmi_memory_id/dmi_memory_id.c | 16 +++++++++------- test/dmidecode-dumps/HP-Z600.bin.txt | 3 +-- .../dmidecode-dumps/Lenovo-ThinkPad-X280.bin.txt | 2 +- .../Lenovo-Thinkcentre-m720s.bin.txt | 2 +- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/udev/dmi_memory_id/dmi_memory_id.c b/src/udev/dmi_memory_id/dmi_memory_id.c index 67861cd364..bae05b8ecd 100644 --- a/src/udev/dmi_memory_id/dmi_memory_id.c +++ b/src/udev/dmi_memory_id/dmi_memory_id.c @@ -417,9 +417,9 @@ static void dmi_memory_device_size_detail( dmi_print_memory_size("MEMORY_DEVICE", attr_suffix, slot_num, code, MEMORY_SIZE_UNIT_BYTES); } -static void dmi_decode(const struct dmi_header *h) { +static void dmi_decode(const struct dmi_header *h, + unsigned *next_slot_num) { const uint8_t *data = h->data; - static unsigned next_slot_num = 0; unsigned slot_num; /* @@ -441,15 +441,14 @@ static void dmi_decode(const struct dmi_header *h) { dmi_print_memory_size("MEMORY_ARRAY", "MAX_CAPACITY", -1, DWORD(data + 0x07), MEMORY_SIZE_UNIT_KB); else if (h->length >= 0x17) dmi_print_memory_size("MEMORY_ARRAY", "MAX_CAPACITY", -1, QWORD(data + 0x0F), MEMORY_SIZE_UNIT_BYTES); - printf("MEMORY_ARRAY_NUM_DEVICES=%u\n", WORD(data + 0x0D)); break; case 17: /* 7.18 Memory Device */ - slot_num = next_slot_num; - next_slot_num++; + slot_num = *next_slot_num; + *next_slot_num = slot_num + 1; - log_debug("Memory Device"); + log_debug("Memory Device: %u", slot_num); if (h->length < 0x15) break; @@ -525,6 +524,7 @@ static void dmi_decode(const struct dmi_header *h) { static void dmi_table_decode(const uint8_t *buf, size_t len, uint16_t num) { const uint8_t *data = buf; + unsigned next_slot_num = 0; /* 4 is the length of an SMBIOS structure header */ for (uint16_t i = 0; (i < num || num == 0) && data + 4 <= buf + len; i++) { @@ -559,10 +559,12 @@ static void dmi_table_decode(const uint8_t *buf, size_t len, uint16_t num) { break; if (display) - dmi_decode(&h); + dmi_decode(&h, &next_slot_num); data = next; } + if (next_slot_num > 0) + printf("MEMORY_ARRAY_NUM_DEVICES=%u\n", next_slot_num); } static int dmi_table(int64_t base, uint32_t len, uint16_t num, const char *devmem, bool no_file_offset) { diff --git a/test/dmidecode-dumps/HP-Z600.bin.txt b/test/dmidecode-dumps/HP-Z600.bin.txt index d17fb8307f..58af9ac0e2 100644 --- a/test/dmidecode-dumps/HP-Z600.bin.txt +++ b/test/dmidecode-dumps/HP-Z600.bin.txt @@ -1,11 +1,9 @@ MEMORY_ARRAY_LOCATION=System Board Or Motherboard MEMORY_ARRAY_EC_TYPE=Multi-bit ECC MEMORY_ARRAY_MAX_CAPACITY=12884901888 -MEMORY_ARRAY_NUM_DEVICES=3 MEMORY_ARRAY_LOCATION=System Board Or Motherboard MEMORY_ARRAY_EC_TYPE=Multi-bit ECC MEMORY_ARRAY_MAX_CAPACITY=12884901888 -MEMORY_ARRAY_NUM_DEVICES=3 MEMORY_DEVICE_0_TOTAL_WIDTH=72 MEMORY_DEVICE_0_DATA_WIDTH=64 MEMORY_DEVICE_0_SIZE=8589934592 @@ -92,3 +90,4 @@ MEMORY_DEVICE_6_MANUFACTURER=Not Specified MEMORY_DEVICE_6_SERIAL_NUMBER=Not Specified MEMORY_DEVICE_6_ASSET_TAG=Not Specified MEMORY_DEVICE_6_PART_NUMBER=Not Specified +MEMORY_ARRAY_NUM_DEVICES=7 diff --git a/test/dmidecode-dumps/Lenovo-ThinkPad-X280.bin.txt b/test/dmidecode-dumps/Lenovo-ThinkPad-X280.bin.txt index 26a8faf5d8..d1c75e976c 100644 --- a/test/dmidecode-dumps/Lenovo-ThinkPad-X280.bin.txt +++ b/test/dmidecode-dumps/Lenovo-ThinkPad-X280.bin.txt @@ -1,6 +1,5 @@ MEMORY_ARRAY_LOCATION=System Board Or Motherboard MEMORY_ARRAY_MAX_CAPACITY=34359738368 -MEMORY_ARRAY_NUM_DEVICES=2 MEMORY_DEVICE_0_TOTAL_WIDTH=64 MEMORY_DEVICE_0_DATA_WIDTH=64 MEMORY_DEVICE_0_SIZE=4294967296 @@ -31,3 +30,4 @@ MEMORY_DEVICE_1_ASSET_TAG=None MEMORY_DEVICE_1_RANK=1 MEMORY_DEVICE_1_CONFIGURED_SPEED_MTS=2400 MEMORY_DEVICE_1_CONFIGURED_VOLTAGE=1 +MEMORY_ARRAY_NUM_DEVICES=2 diff --git a/test/dmidecode-dumps/Lenovo-Thinkcentre-m720s.bin.txt b/test/dmidecode-dumps/Lenovo-Thinkcentre-m720s.bin.txt index c90af66a7b..c9c3eda1c2 100644 --- a/test/dmidecode-dumps/Lenovo-Thinkcentre-m720s.bin.txt +++ b/test/dmidecode-dumps/Lenovo-Thinkcentre-m720s.bin.txt @@ -1,6 +1,5 @@ MEMORY_ARRAY_LOCATION=System Board Or Motherboard MEMORY_ARRAY_MAX_CAPACITY=68719476736 -MEMORY_ARRAY_NUM_DEVICES=4 MEMORY_DEVICE_0_TOTAL_WIDTH=64 MEMORY_DEVICE_0_DATA_WIDTH=64 MEMORY_DEVICE_0_SIZE=8589934592 @@ -65,3 +64,4 @@ MEMORY_DEVICE_3_CONFIGURED_SPEED_MTS=2400 MEMORY_DEVICE_3_MINIMUM_VOLTAGE=1 MEMORY_DEVICE_3_MAXIMUM_VOLTAGE=1 MEMORY_DEVICE_3_CONFIGURED_VOLTAGE=1 +MEMORY_ARRAY_NUM_DEVICES=4