]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
memory-id: Work-around incorrect "Number of slots"
authorBastien Nocera <hadess@hadess.net>
Mon, 7 Mar 2022 09:11:12 +0000 (10:11 +0100)
committerLuca Boccassi <luca.boccassi@gmail.com>
Mon, 7 Mar 2022 15:33:26 +0000 (15:33 +0000)
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
test/dmidecode-dumps/HP-Z600.bin.txt
test/dmidecode-dumps/Lenovo-ThinkPad-X280.bin.txt
test/dmidecode-dumps/Lenovo-Thinkcentre-m720s.bin.txt

index 67861cd3642bc1af8c34386795bea2dbd1534e6f..bae05b8ecdd864f19fca20997c5fbb4f0ef08c4c 100644 (file)
@@ -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) {
index d17fb8307fd2b98e8131729642e7b07dcad690b4..58af9ac0e2b1b4c445aaacef816553323a1d4eef 100644 (file)
@@ -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
index 26a8faf5d80cc156602c5dcc0fac7b7363cb90f0..d1c75e976cc1bac746c217b0464e96975b127b23 100644 (file)
@@ -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
index c90af66a7ba36ce110bbcba2ffb30fdd23a1cbfc..c9c3eda1c259445c9c89327a9dfca75ccae4fb58 100644 (file)
@@ -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