Blame SOURCES/0001-merge-Petr-Oros-pull-request.patch

df7b7f
From 17aa0a1e48bf9dd596c7678b93bd5aaaad94aeb8 Mon Sep 17 00:00:00 2001
df7b7f
From: Lyonel Vincent <lyonel@ezix.org>
df7b7f
Date: Tue, 20 Jun 2017 20:49:30 +0200
df7b7f
Subject: [PATCH] merge Petr Oros' pull request
df7b7f
df7b7f
cf. https://github.com/lyonel/lshw/pull/29
df7b7f
df7b7f
 * Proper detect vendor_id/device_id for virtual functions
df7b7f
 * Sync SMBIOS with latest specification
df7b7f
---
df7b7f
 src/core/dmi.cc   | 323 +++++++++++++++++++++++++++++++++---------------------
df7b7f
 src/core/pci.cc   |  13 ++-
df7b7f
 src/core/sysfs.cc |  10 ++
df7b7f
 src/core/sysfs.h  |   2 +
df7b7f
 4 files changed, 221 insertions(+), 127 deletions(-)
df7b7f
df7b7f
diff --git a/src/core/dmi.cc b/src/core/dmi.cc
df7b7f
index 250f485..d1b0b07 100644
df7b7f
--- a/src/core/dmi.cc
df7b7f
+++ b/src/core/dmi.cc
df7b7f
@@ -408,6 +408,13 @@ static unsigned long dmi_cache_size(u16 n)
df7b7f
     return (n & 0x7FFF) * 1024;                   // value is in 1K blocks
df7b7f
 }
df7b7f
 
df7b7f
+static unsigned long long dmi_cache_size_long(u32 n)
df7b7f
+{
df7b7f
+  if (n & (1 << 31))
df7b7f
+    return (n & 0x7FFFFFFF) * 64 * 1024;              // value is in 64K blocks
df7b7f
+  else
df7b7f
+    return (n & 0x7FFFFFFF) * 1024;                   // value is in 1K blocks
df7b7f
+}
df7b7f
 
df7b7f
 static void dmi_cache_sramtype(u16 c,
df7b7f
 hwNode & n)
df7b7f
@@ -657,9 +664,13 @@ void dmi_chassis(u8 code, hwNode & n)
df7b7f
     "tablet", N_("Tablet"), NULL,
df7b7f
     "convertible", N_("Convertible"), NULL,
df7b7f
     "detachable", N_("Detachable"), NULL,               /* 0x20 */
df7b7f
+    "iot-gateway", N_("IoT Gateway"), NULL,
df7b7f
+    "embedded", N_("Embedded PC"), NULL,
df7b7f
+    "mini", N_("Mini PC"), NULL,
df7b7f
+    "stick", N_("Stick PC"), NULL,               /* 0x24 */
df7b7f
   };
df7b7f
 
df7b7f
-  if(code <= 0x20)
df7b7f
+  if(code <= 0x24)
df7b7f
   {
df7b7f
     if(n.getDescription()=="") n.setDescription(_(chassis_type[1+3*code]));
df7b7f
 
df7b7f
@@ -720,9 +731,9 @@ static const char *dmi_processor_family(uint16_t code)
df7b7f
     "Core Solo mobile",
df7b7f
     "Atom",
df7b7f
     "Core M",
df7b7f
-    "",
df7b7f
-    "",
df7b7f
-    "",
df7b7f
+    "Core M3",
df7b7f
+    "Core M5",
df7b7f
+    "Core M7",
df7b7f
     "Alpha",                                      /* 0x30 */
df7b7f
     "Alpha 21064",
df7b7f
     "Alpha 21066",
df7b7f
@@ -780,9 +791,9 @@ static const char *dmi_processor_family(uint16_t code)
df7b7f
     "Athlon X4",                                  /* 0x66 */
df7b7f
     "Opteron X1000",
df7b7f
     "Opteron X2000 APU",
df7b7f
-    "",
df7b7f
-    "",
df7b7f
-    "",
df7b7f
+    "Opteron A",
df7b7f
+    "Opteron X3000 APU",
df7b7f
+    "Zen",
df7b7f
     "",
df7b7f
     "",
df7b7f
     "",
df7b7f
@@ -938,6 +949,8 @@ static const char *dmi_processor_family(uint16_t code)
df7b7f
 
df7b7f
   switch (code)
df7b7f
   {
df7b7f
+    case 0x100: return "ARMv7";
df7b7f
+    case 0x101: return "ARMv8";
df7b7f
     case 0x104: return "SH-3";
df7b7f
     case 0x105: return "SH-4";
df7b7f
     case 0x118: return "ARM";
df7b7f
@@ -966,7 +979,8 @@ static void dmi_table(const u8 *buf,
df7b7f
 int len,
df7b7f
 hwNode & node,
df7b7f
 int dmiversionmaj,
df7b7f
-int dmiversionmin)
df7b7f
+int dmiversionmin,
df7b7f
+int dmiversionrev)
df7b7f
 {
df7b7f
   struct dmi_header *dm;
df7b7f
   hwNode *hardwarenode = NULL;
df7b7f
@@ -1008,24 +1022,34 @@ int dmiversionmin)
df7b7f
 // BIOS Information Block
df7b7f
         {
df7b7f
           string release(dmi_string(dm,
df7b7f
-            data[8]));
df7b7f
+            data[0x08]));
df7b7f
           hwNode newnode("firmware",
df7b7f
             hw::memory,
df7b7f
             dmi_string(dm,
df7b7f
-            data[4]));
df7b7f
+            data[0x04]));
df7b7f
           newnode.setVersion(dmi_string(dm, data[5]));
df7b7f
-          newnode.setCapacity(64 * data[9] * 1024);
df7b7f
-          newnode.setSize(16 * (0x10000 - (data[7] << 8 | data[6])));
df7b7f
-//newnode.setPhysId(16 * (data[7] << 8 | data[6]));
df7b7f
+          if (data[0x09] != 0xFF)
df7b7f
+            newnode.setCapacity(64 * (data[0x09] + 1) * 1024);
df7b7f
+          else
df7b7f
+          {
df7b7f
+            if (dm->length < 0x1A)
df7b7f
+              newnode.setCapacity(16 * 1024 * 1024);
df7b7f
+            else
df7b7f
+            {
df7b7f
+              unsigned int unit = (data[0x19] << 8 | data[0x18]) & 0x4000 ? 1024 : 1024 * 1024;
df7b7f
+              newnode.setCapacity(((data[0x19] << 8 | data[0x18]) & 0x3FFF) * unit);
df7b7f
+            }
df7b7f
+          }
df7b7f
+          newnode.setSize(16 * (0x10000 - (data[0x07] << 8 | data[0x06])));
df7b7f
           newnode.setPhysId(dm->handle);
df7b7f
           newnode.setDescription(_("BIOS"));
df7b7f
           newnode.addHint("icon", string("chip"));
df7b7f
           newnode.claim();
df7b7f
 
df7b7f
-          dmi_bios_features(data[13] << 24 | data[12] << 16 | data[11] << 8 |
df7b7f
-            data[10],
df7b7f
-            data[17] << 24 | data[16] << 16 | data[15] << 8 |
df7b7f
-            data[14], newnode);
df7b7f
+          dmi_bios_features(data[0x0D] << 24 | data[0x0C] << 16 | data[0x0B] << 8 |
df7b7f
+            data[0x0A],
df7b7f
+            data[0x11] << 24 | data[0x10] << 16 | data[0x0F] << 8 |
df7b7f
+            data[0x0E], newnode);
df7b7f
 
df7b7f
           if (dm->length > 0x12)
df7b7f
             dmi_bios_features_ext(&data[0x12], dm->length - 0x12, newnode);
df7b7f
@@ -1039,12 +1063,12 @@ int dmiversionmin)
df7b7f
       case 1:
df7b7f
 // System Information Block
df7b7f
         node.setHandle(handle);
df7b7f
-        node.setVendor(dmi_string(dm, data[4]));
df7b7f
-        node.setProduct(dmi_string(dm, data[5]));
df7b7f
-        node.setVersion(dmi_string(dm, data[6]));
df7b7f
-        node.setSerial(dmi_string(dm, data[7]));
df7b7f
+        node.setVendor(dmi_string(dm, data[0x04]));
df7b7f
+        node.setProduct(dmi_string(dm, data[0x05]));
df7b7f
+        node.setVersion(dmi_string(dm, data[0x06]));
df7b7f
+        node.setSerial(dmi_string(dm, data[0x07]));
df7b7f
         if (dm->length >= 0x19)
df7b7f
-          node.setConfig("uuid", dmi_uuid(data + 8));
df7b7f
+          node.setConfig("uuid", dmi_uuid(data + 0x08));
df7b7f
         if (dm->length >= 0x1B)
df7b7f
         {
df7b7f
           node.setConfig("sku", dmi_string(dm, data[0x19]));
df7b7f
@@ -1057,15 +1081,14 @@ int dmiversionmin)
df7b7f
       case 2:
df7b7f
 // Board Information Block
df7b7f
         {
df7b7f
-
df7b7f
-                                                  // we are the only system board on the computer so connect everything to us
df7b7f
+          // we are the only system board on the computer so connect everything to us
df7b7f
           if ((dm->length <= 0x0E) || (data[0x0E] == 0))
df7b7f
           {
df7b7f
-            hardwarenode->setVendor(dmi_string(dm, data[4]));
df7b7f
-            hardwarenode->setProduct(dmi_string(dm, data[5]));
df7b7f
-            hardwarenode->setVersion(dmi_string(dm, data[6]));
df7b7f
-            hardwarenode->setSerial(dmi_string(dm, data[7]));
df7b7f
-            if(dm->length >= 0x0a)
df7b7f
+            hardwarenode->setVendor(dmi_string(dm, data[0x04]));
df7b7f
+            hardwarenode->setProduct(dmi_string(dm, data[0x05]));
df7b7f
+            hardwarenode->setVersion(dmi_string(dm, data[0x06]));
df7b7f
+            hardwarenode->setSerial(dmi_string(dm, data[0x07]));
df7b7f
+            if(dm->length >= 0x0A)
df7b7f
               hardwarenode->setSlot(dmi_string(dm, data[0x0A]));
df7b7f
             hardwarenode->setHandle(handle);
df7b7f
             hardwarenode->setDescription(_("Motherboard"));
df7b7f
@@ -1083,10 +1106,10 @@ int dmiversionmin)
df7b7f
                   (data[0x0F + 2 * i + 1] << 8 |
df7b7f
                   data[0x0F + 2 * i]));
df7b7f
 
df7b7f
-            newnode.setVendor(dmi_string(dm, data[4]));
df7b7f
-            newnode.setProduct(dmi_string(dm, data[5]));
df7b7f
-            newnode.setVersion(dmi_string(dm, data[6]));
df7b7f
-            newnode.setSerial(dmi_string(dm, data[7]));
df7b7f
+            newnode.setVendor(dmi_string(dm, data[0x04]));
df7b7f
+            newnode.setProduct(dmi_string(dm, data[0x05]));
df7b7f
+            newnode.setVersion(dmi_string(dm, data[0x06]));
df7b7f
+            newnode.setSerial(dmi_string(dm, data[0x07]));
df7b7f
             newnode.setSlot(dmi_string(dm, data[0x0A]));
df7b7f
             newnode.setHandle(handle);
df7b7f
             newnode.setPhysId(dm->handle);
df7b7f
@@ -1102,14 +1125,14 @@ int dmiversionmin)
df7b7f
 // special case: if the system characteristics are still unknown,
df7b7f
 // use values from the chassis
df7b7f
         if (node.getVendor() == "")
df7b7f
-          node.setVendor(dmi_string(dm, data[4]));
df7b7f
+          node.setVendor(dmi_string(dm, data[0x04]));
df7b7f
         if (node.getProduct() == "")
df7b7f
-          node.setProduct(dmi_string(dm, data[5]));
df7b7f
+          node.setProduct(dmi_string(dm, data[0x05]));
df7b7f
         if (node.getVersion() == "")
df7b7f
-          node.setVersion(dmi_string(dm, data[6]));
df7b7f
+          node.setVersion(dmi_string(dm, data[0x06]));
df7b7f
         if (node.getSerial() == "")
df7b7f
-          node.setSerial(dmi_string(dm, data[7]));
df7b7f
-        dmi_chassis(data[5] & 0x7F, node);
df7b7f
+          node.setSerial(dmi_string(dm, data[0x07]));
df7b7f
+        dmi_chassis(data[0x05] & 0x7F, node);
df7b7f
         break;
df7b7f
 
df7b7f
       case 4:
df7b7f
@@ -1120,16 +1143,16 @@ int dmiversionmin)
df7b7f
 
df7b7f
           newnode.claim();
df7b7f
           newnode.setBusInfo(cpubusinfo(currentcpu++));
df7b7f
-          newnode.setSlot(dmi_string(dm, data[4]));
df7b7f
+          newnode.setSlot(dmi_string(dm, data[0x04]));
df7b7f
           newnode.setDescription(_("CPU"));
df7b7f
           newnode.addHint("icon", string("cpu"));
df7b7f
           if (dm->length >= 0x2A)
df7b7f
             newnode.setProduct(dmi_processor_family(
df7b7f
                 (((uint16_t) data[0x29]) << 8) + data[0x28]));
df7b7f
           else
df7b7f
-            newnode.setProduct(dmi_processor_family(data[6]));
df7b7f
+            newnode.setProduct(dmi_processor_family(data[0x06]));
df7b7f
           newnode.setVersion(dmi_string(dm, data[0x10]));
df7b7f
-          newnode.setVendor(dmi_string(dm, data[7]));
df7b7f
+          newnode.setVendor(dmi_string(dm, data[0x07]));
df7b7f
           newnode.setPhysId(dm->handle);
df7b7f
           if (dm->length > 0x1A)
df7b7f
           {
df7b7f
@@ -1177,15 +1200,30 @@ int dmiversionmin)
df7b7f
           }
df7b7f
 
df7b7f
           if (dm->length >= 0x28)
df7b7f
-          { 
df7b7f
+          {
df7b7f
             if (data[0x23] != 0)
df7b7f
-		newnode.setConfig("cores", data[0x23]);
df7b7f
+            {
df7b7f
+              if (data[0x23] == 0xFF)
df7b7f
+                newnode.setConfig("cores", data[0x2B] << 8 | data[0x2A]);
df7b7f
+              else
df7b7f
+                newnode.setConfig("cores", data[0x23]);
df7b7f
+            }
df7b7f
             if (data[0x24] != 0)
df7b7f
-		newnode.setConfig("enabledcores", data[0x24]);
df7b7f
+            {
df7b7f
+              if (data[0x24] == 0xFF)
df7b7f
+                newnode.setConfig("enabledcores", data[0x2D] << 8 | data[0x2C]);
df7b7f
+              else
df7b7f
+                newnode.setConfig("enabledcores", data[0x24]);
df7b7f
+            }
df7b7f
             if (data[0x25] != 0)
df7b7f
-		newnode.setConfig("threads", data[0x25]);
df7b7f
+            {
df7b7f
+              if (data[0x25] == 0xFF)
df7b7f
+                newnode.setConfig("threads", data[0x2F] << 8 | data[0x2E]);
df7b7f
+              else
df7b7f
+                newnode.setConfig("threads", data[0x25]);
df7b7f
+            }
df7b7f
             if (data[0x26] & 0x4)
df7b7f
-		newnode.addCapability("lm", _("64-bit capable"));
df7b7f
+              newnode.addCapability("lm", _("64-bit capable"));
df7b7f
           }
df7b7f
 
df7b7f
           newnode.setHandle(handle);
df7b7f
@@ -1207,7 +1245,7 @@ int dmiversionmin)
df7b7f
           newnode.setHandle(handle);
df7b7f
           newnode.setPhysId(dm->handle);
df7b7f
 
df7b7f
-          size = data[0x0E] * (1 << data[8]) * 1024 * 1024;
df7b7f
+          size = data[0x0E] * (1 << data[0x08]) * 1024 * 1024;
df7b7f
           newnode.setCapacity(size);
df7b7f
 
df7b7f
 // loop through the controller's slots and link them to us
df7b7f
@@ -1237,44 +1275,44 @@ int dmiversionmin)
df7b7f
           unsigned long long size = 0;
df7b7f
 
df7b7f
           newnode.setDescription(_("empty memory bank"));
df7b7f
-          newnode.setSlot(dmi_string(dm, data[4]).c_str());
df7b7f
+          newnode.setSlot(dmi_string(dm, data[0x04]).c_str());
df7b7f
           if (data[6])
df7b7f
-            clock = 1000000000 / data[6];         // convert value from ns to Hz
df7b7f
+            clock = 1000000000 / data[0x06];         // convert value from ns to Hz
df7b7f
           newnode.setClock(clock);
df7b7f
-          newnode.setDescription(dmi_decode_ram(data[8] << 8 | data[7]));
df7b7f
+          newnode.setDescription(dmi_decode_ram(data[0x08] << 8 | data[0x07]));
df7b7f
           newnode.addHint("icon", string("memory"));
df7b7f
 // installed size
df7b7f
-          switch (data[9] & 0x7F)
df7b7f
+          switch (data[0x09] & 0x7F)
df7b7f
           {
df7b7f
             case 0x7D:
df7b7f
             case 0x7E:
df7b7f
             case 0x7F:
df7b7f
               break;
df7b7f
             default:
df7b7f
-              size = (1 << (data[9] & 0x7F)) << 20;
df7b7f
+              size = (1 << (data[0x09] & 0x7F)) << 20;
df7b7f
           }
df7b7f
-          if (data[9] & 0x80)
df7b7f
+          if (data[0x09] & 0x80)
df7b7f
             size *= 2;
df7b7f
 // enabled size
df7b7f
-          switch (data[10] & 0x7F)
df7b7f
+          switch (data[0x0A] & 0x7F)
df7b7f
           {
df7b7f
             case 0x7D:
df7b7f
             case 0x7E:
df7b7f
             case 0x7F:
df7b7f
               break;
df7b7f
             default:
df7b7f
-              capacity = (1 << (data[10] & 0x7F)) << 20;
df7b7f
+              capacity = (1 << (data[0x0A] & 0x7F)) << 20;
df7b7f
           }
df7b7f
-          if (data[10] & 0x80)
df7b7f
+          if (data[0x0A] & 0x80)
df7b7f
             capacity *= 2;
df7b7f
 
df7b7f
           newnode.setCapacity(capacity);
df7b7f
           newnode.setSize(size);
df7b7f
           if(newnode.getSize()==0)
df7b7f
             newnode.setDescription(newnode.getDescription() + " " + _("[empty]"));
df7b7f
-          if ((data[11] & 4) == 0)
df7b7f
+          if ((data[0x0B] & 4) == 0)
df7b7f
           {
df7b7f
-            if (data[11] & (1 << 0))
df7b7f
+            if (data[0x0B] & (1 << 0))
df7b7f
 // bank has uncorrectable errors (BIOS disabled)
df7b7f
               newnode.disable();
df7b7f
           }
df7b7f
@@ -1291,8 +1329,8 @@ int dmiversionmin)
df7b7f
             hw::memory);
df7b7f
 	  int level;
df7b7f
 
df7b7f
-          newnode.setSlot(dmi_string(dm, data[4]));
df7b7f
-          u = data[6] << 8 | data[5];
df7b7f
+          newnode.setSlot(dmi_string(dm, data[0x04]));
df7b7f
+          u = data[0x06] << 8 | data[0x05];
df7b7f
           level = 1 + (u & 7);
df7b7f
 
df7b7f
           if (dm->length > 0x11)
df7b7f
@@ -1305,11 +1343,19 @@ int dmiversionmin)
df7b7f
             newnode.disable();
df7b7f
 
df7b7f
           newnode.setConfig("level", level);
df7b7f
-          newnode.setSize(dmi_cache_size(data[9] | data[10] << 8));
df7b7f
-          newnode.setCapacity(dmi_cache_size(data[7] | (data[8] << 8)));
df7b7f
+          if ((data[0x08] << 8 | data[0x07]) == 0xFFFF)
df7b7f
+            newnode.setCapacity(dmi_cache_size_long(data[0x16] << 24 | data[0x15] << 16 | data[0x14] << 8 | data[0x13]));
df7b7f
+          else
df7b7f
+            newnode.setCapacity(dmi_cache_size(data[0x08] << 8 | data[0x07]));
df7b7f
+
df7b7f
+          if ((data[0x0A] << 8 | data[0x09]) == 0xFFFF)
df7b7f
+            newnode.setSize(dmi_cache_size_long(data[0x1A] << 24 | data[0x19] << 16 | data[0x18] << 8 | data[0x17]));
df7b7f
+          else
df7b7f
+            newnode.setSize(dmi_cache_size(data[0x0A] << 8 | data[0x09]));
df7b7f
+
df7b7f
           if ((dm->length > 0x0F) && (data[0x0F] != 0))
df7b7f
           {
df7b7f
-                                                  // convert from ns to Hz
df7b7f
+            // convert from ns to Hz
df7b7f
             newnode.setClock(1000000000 / data[0x0F]);
df7b7f
           }
df7b7f
 
df7b7f
@@ -1338,16 +1384,16 @@ int dmiversionmin)
df7b7f
           hwNode newnode("cardslot",
df7b7f
             hw::bus);
df7b7f
           newnode.setHandle(handle);
df7b7f
-          newnode.setSlot(dmi_string(dm, data[4]));
df7b7f
+          newnode.setSlot(dmi_string(dm, data[0x04]));
df7b7f
           printf("\t\tType: %s%s%s\n",
df7b7f
-            dmi_bus_width(data[6]),
df7b7f
-            dmi_card_size(data[8]), dmi_bus_name(data[5]));
df7b7f
-          if (data[7] == 3)
df7b7f
+            dmi_bus_width(data[0x06]),
df7b7f
+            dmi_card_size(data[0x08]), dmi_bus_name(data[0x05]));
df7b7f
+          if (data[0x07] == 3)
df7b7f
             printf("\t\tStatus: Available.\n");
df7b7f
-          if (data[7] == 4)
df7b7f
+          if (data[0x07] == 4)
df7b7f
             printf("\t\tStatus: In use.\n");
df7b7f
-          if (data[11] & 0xFE)
df7b7f
-            dmi_card_props(data[11]);
df7b7f
+          if (data[0x0B] & 0xFE)
df7b7f
+            dmi_card_props(data[0x0B]);
df7b7f
 //hardwarenode->addChild(newnode);
df7b7f
         }
df7b7f
 #endif
df7b7f
@@ -1374,13 +1420,13 @@ int dmiversionmin)
df7b7f
       case 13:
df7b7f
 #if 0
df7b7f
         printf("\tBIOS Language Information\n");
df7b7f
-        printf("\t\tInstallable Languages: %u\n", data[4]);
df7b7f
-        for (u = 1; u <= data[4]; u++)
df7b7f
+        printf("\t\tInstallable Languages: %u\n", data[0x04]);
df7b7f
+        for (u = 1; u <= data[0x04]; u++)
df7b7f
         {
df7b7f
           printf("\t\t\t%s\n", dmi_string(dm, u).c_str());
df7b7f
         }
df7b7f
         printf("\t\tCurrently Installed Language: %s\n",
df7b7f
-          dmi_string(dm, data[21]).c_str());
df7b7f
+          dmi_string(dm, data[0x15]).c_str());
df7b7f
 #endif
df7b7f
         break;
df7b7f
       case 14:
df7b7f
@@ -1395,7 +1441,7 @@ int dmiversionmin)
df7b7f
           string id = "memory";
df7b7f
           string description = "";
df7b7f
           bool claim = false, memory_icon = false;
df7b7f
-          switch (data[5])
df7b7f
+          switch (data[0x05])
df7b7f
           {
df7b7f
             case 0x03:
df7b7f
               description = _("System Memory");
df7b7f
@@ -1433,12 +1433,12 @@ int dmiversionrev)
df7b7f
           newnode.setHandle(handle);
df7b7f
           newnode.setPhysId(dm->handle);
df7b7f
           newnode.setDescription(description);
df7b7f
-          newnode.setSlot(dmi_memory_array_location(data[4]));
df7b7f
+          newnode.setSlot(dmi_memory_array_location(data[0x04]));
df7b7f
           if (memory_icon)
df7b7f
             newnode.addHint("icon", string("memory"));
df7b7f
           if (claim)
df7b7f
             newnode.claim();
df7b7f
-          switch (data[6])
df7b7f
+          switch (data[0x06])
df7b7f
           {
df7b7f
             case 0x04:
df7b7f
               newnode.addCapability("parity", _("Parity error correction"));
df7b7f
@@ -1457,7 +1503,7 @@ int dmiversionmin)
df7b7f
               newnode.setConfig("errordetection", "crc");
df7b7f
               break;
df7b7f
           }
df7b7f
-          u2 = data[10] << 24 | data[9] << 16 | data[8] << 8 | data[7];
df7b7f
+          u2 = data[0x0A] << 24 | data[0x09] << 16 | data[0x08] << 8 | data[0x07];
df7b7f
           if (u2 != 0x80000000)                   // magic value for "unknown"
df7b7f
             newnode.setCapacity(u2 * 1024);
df7b7f
           else if (dm->length >= 0x17)
df7b7f
@@ -1489,15 +1535,15 @@ int dmiversionmin)
df7b7f
           string arrayhandle;
df7b7f
           newnode.setDescription(_("empty memory bank"));
df7b7f
           newnode.addHint("icon", string("memory"));
df7b7f
-          arrayhandle = dmi_handle(data[5] << 8 | data[4]);
df7b7f
+          arrayhandle = dmi_handle(data[0x05] << 8 | data[0x04]);
df7b7f
           strcpy(bits, "");
df7b7f
 // total width
df7b7f
-          u = data[9] << 8 | data[8];
df7b7f
-          if (u != 0xffff)
df7b7f
+          u = data[0x09] << 8 | data[0x08];
df7b7f
+          if (u != 0xFFFF)
df7b7f
             width = u;
df7b7f
 //data width
df7b7f
-          u = data[11] << 8 | data[10];
df7b7f
-          if ((u != 0xffff) && (u != 0))
df7b7f
+          u = data[0x0B] << 8 | data[0x0A];
df7b7f
+          if ((u != 0xFFFF) && (u != 0))
df7b7f
           {
df7b7f
             if ((u == width) || (width == 0))
df7b7f
             {
df7b7f
@@ -1520,26 +1566,26 @@ int dmiversionmin)
df7b7f
           }
df7b7f
 
df7b7f
 // size
df7b7f
-          u = data[13] << 8 | data[12];
df7b7f
-          if(u == 0x7fff) {
df7b7f
-             unsigned long long extendsize = (data[0x1f] << 24) | (data[0x1e] << 16) | (data[0x1d] << 8) | data[0x1c];
df7b7f
-             extendsize &= 0x7fffffffUL;
df7b7f
+          u = data[0x0D] << 8 | data[0x0C];
df7b7f
+          if(u == 0x7FFF) {
df7b7f
+             unsigned long long extendsize = (data[0x1F] << 24) | (data[0x1E] << 16) | (data[0x1D] << 8) | data[0x1C];
df7b7f
+             extendsize &= 0x7FFFFFFFUL;
df7b7f
              size = extendsize * 1024ULL * 1024ULL;
df7b7f
           }
df7b7f
 	  else
df7b7f
-          if (u != 0xffff)
df7b7f
-            size = (1024ULL * (u & 0x7fff) * ((u & 0x8000) ? 1 : 1024ULL));
df7b7f
-          description += string(dmi_memory_device_form_factor(data[14]));
df7b7f
-          slot = dmi_string(dm, data[16]);
df7b7f
-//printf("\t\tBank Locator: %s\n", dmi_string(dm, data[17]));
df7b7f
-          description += string(dmi_memory_device_type(data[18]));
df7b7f
-          u = data[20] << 8 | data[19];
df7b7f
-          if (u & 0x1ffe)
df7b7f
+          if (u != 0xFFFF)
df7b7f
+            size = (1024ULL * (u & 0x7FFF) * ((u & 0x8000) ? 1 : 1024ULL));
df7b7f
+          description += string(dmi_memory_device_form_factor(data[0x0E]));
df7b7f
+          slot = dmi_string(dm, data[0x10]);
df7b7f
+//printf("\t\tBank Locator: %s\n", dmi_string(dm, data[0x11]));
df7b7f
+          description += string(dmi_memory_device_type(data[0x12]));
df7b7f
+          u = data[0x14] << 8 | data[0x13];
df7b7f
+          if (u & 0x1FFE)
df7b7f
             description += dmi_memory_device_detail(u);
df7b7f
-          if (dm->length > 21)
df7b7f
+          if (dm->length > 0x15)
df7b7f
           {
df7b7f
             char buffer[80];
df7b7f
-            u = data[22] << 8 | data[21];
df7b7f
+            u = data[0x16] << 8 | data[0x15];
df7b7f
 // speed
df7b7f
             clock = u * 1000000;                  // u is a frequency in MHz
df7b7f
             if (u == 0)
df7b7f
@@ -1553,12 +1599,12 @@ int dmiversionmin)
df7b7f
           newnode.setHandle(handle);
df7b7f
 //newnode.setPhysId(dm->handle);
df7b7f
           newnode.setSlot(slot);
df7b7f
-          if (dm->length > 23)
df7b7f
-            newnode.setVendor(dmi_string(dm, data[23]));
df7b7f
-          if (dm->length > 24)
df7b7f
-            newnode.setSerial(dmi_string(dm, data[24]));
df7b7f
-          if (dm->length > 26)
df7b7f
-            newnode.setProduct(dmi_string(dm, data[26]));
df7b7f
+          if (dm->length > 0x17)
df7b7f
+            newnode.setVendor(dmi_string(dm, data[0x17]));
df7b7f
+          if (dm->length > 0x18)
df7b7f
+            newnode.setSerial(dmi_string(dm, data[0x18]));
df7b7f
+          if (dm->length > 0x1A)
df7b7f
+            newnode.setProduct(dmi_string(dm, data[0x1A]));
df7b7f
           newnode.setDescription(description);
df7b7f
           newnode.setSize(size);
df7b7f
           if(newnode.getSize()==0)
df7b7f
@@ -1586,10 +1632,20 @@ int dmiversionmin)
df7b7f
         {
df7b7f
           hwNode newnode("range",
df7b7f
             hw::address);
df7b7f
-          unsigned long start, end;
df7b7f
+          uint64_t start = 0, end = 0;
df7b7f
           string arrayhandle = dmi_handle(data[0x0D] << 8 | data[0x0C]);
df7b7f
-          start = ((data[4] | data[5] << 8) | (data[6] | data[7] << 8) << 16);
df7b7f
-          end = ((data[8] | data[9] << 8) | (data[10] | data[11] << 8) << 16);
df7b7f
+          start = data[0x07] << 24 | data[0x06] << 16 | data[0x05] << 8 | data[0x04];
df7b7f
+          if (start == 0xFFFFFFFF)
df7b7f
+            start = uint64_t(data[0x16]) << 56 | uint64_t(data[0x15]) << 48 |
df7b7f
+                    uint64_t(data[0x14]) << 40 | uint64_t(data[0x13]) << 32 |
df7b7f
+                    uint64_t(data[0x12]) << 24 | uint64_t(data[0x11]) << 16 |
df7b7f
+                    uint64_t(data[0x10]) << 8 | uint64_t(data[0x0F]);
df7b7f
+          end = data[0x0B] << 24 | data[0x0A] << 16 | data[0x09] << 8 | data[0x08];
df7b7f
+          if (end == 0xFFFFFFFF)
df7b7f
+            end = uint64_t(data[0x1E]) << 56 | uint64_t(data[0x1D]) << 48 |
df7b7f
+                    uint64_t(data[0x1C]) << 40 | uint64_t(data[0x1B]) << 32 |
df7b7f
+                    uint64_t(data[0x1A]) << 24 | uint64_t(data[0x19]) << 16 |
df7b7f
+                    uint64_t(data[0x18]) << 8 | uint64_t(data[0x17]);
df7b7f
           if (end - start < 512)                  // memory range is smaller thant 512KB
df7b7f
           {
df7b7f
 // consider that values were expressed in megagytes
df7b7f
@@ -1614,10 +1670,20 @@ int dmiversionmin)
df7b7f
         {
df7b7f
           hwNode newnode("range",
df7b7f
             hw::address);
df7b7f
-          unsigned long start, end;
df7b7f
+          unsigned long long start = 0, end = 0;
df7b7f
           string devicehandle = dmi_handle(data[0x0D] << 8 | data[0x0C]);
df7b7f
-          start = ((data[4] | data[5] << 8) | (data[6] | data[7] << 8) << 16);
df7b7f
-          end = ((data[8] | data[9] << 8) | (data[10] | data[11] << 8) << 16);
df7b7f
+          start = data[0x07] << 24 | data[0x06] << 16 | data[0x05] << 8 | data[0x04];
df7b7f
+          if (start == 0xFFFFFFFF)
df7b7f
+            start = uint64_t(data[0x16]) << 56 | uint64_t(data[0x15]) << 48 |
df7b7f
+                    uint64_t(data[0x14]) << 40 | uint64_t(data[0x13]) << 32 |
df7b7f
+                    uint64_t(data[0x12]) << 24 | uint64_t(data[0x11]) << 16 |
df7b7f
+                    uint64_t(data[0x10]) << 8 | uint64_t(data[0x0F]);
df7b7f
+          end = data[0x0B] << 24 | data[0x0A] << 16 | data[0x09] << 8 | data[0x08];
df7b7f
+          if (end == 0xFFFFFFFF)
df7b7f
+            end = uint64_t(data[0x1E]) << 56 | uint64_t(data[0x1D]) << 48 |
df7b7f
+                    uint64_t(data[0x1C]) << 40 | uint64_t(data[0x1B]) << 32 |
df7b7f
+                    uint64_t(data[0x1A]) << 24 | uint64_t(data[0x19]) << 16 |
df7b7f
+                    uint64_t(data[0x18]) << 8 | uint64_t(data[0x17]);
df7b7f
           if (end - start < 512)                  // memory range is smaller than 512KB
df7b7f
           {
df7b7f
 // consider that values were expressed in megagytes
df7b7f
@@ -1661,11 +1727,11 @@ int dmiversionmin)
df7b7f
             batt.setVersion(dmi_string(dm, data[0x06]));
df7b7f
           if(data[0x07] || dm->length<0x1A)
df7b7f
             batt.setSerial(dmi_string(dm, data[0x07]));
df7b7f
-          batt.setConfig("voltage", dmi_battery_voltage(data[0x0c] + 256*data[0x0d]));
df7b7f
+          batt.setConfig("voltage", dmi_battery_voltage(data[0x0C] + 256*data[0x0D]));
df7b7f
           if(dm->length<0x1A)
df7b7f
-            batt.setCapacity(dmi_battery_capacity(data[0x0a] + 256*data[0x0b], 1));
df7b7f
+            batt.setCapacity(dmi_battery_capacity(data[0x0A] + 256*data[0x0B], 1));
df7b7f
           else
df7b7f
-            batt.setCapacity(dmi_battery_capacity(data[0x0a] + 256*data[0x0b], data[0x15]));
df7b7f
+            batt.setCapacity(dmi_battery_capacity(data[0x0A] + 256*data[0x0B], data[0x15]));
df7b7f
           if(data[0x09]!=0x02 || dm->length<0x1A)
df7b7f
             batt.setDescription(hw::strip(string(dmi_battery_chemistry(data[0x09])) + " Battery"));
df7b7f
 
df7b7f
@@ -1724,7 +1790,7 @@ int dmiversionmin)
df7b7f
 // System Boot Information
df7b7f
         if (dm->length < 0x0B)
df7b7f
           break;
df7b7f
-        node.setConfig("boot", dmi_bootinfo(data[0x0a]));
df7b7f
+        node.setConfig("boot", dmi_bootinfo(data[0x0A]));
df7b7f
         break;
df7b7f
       case 33:
df7b7f
 // 64-bit Memory Error Information
df7b7f
@@ -1755,9 +1821,9 @@ int dmiversionmin)
df7b7f
           power.setDescription(dmi_string(dm, data[0x06]));
df7b7f
           power.setVendor(dmi_string(dm, data[0x07]));
df7b7f
           power.setSerial(dmi_string(dm, data[0x08]));
df7b7f
-          power.setProduct(dmi_string(dm, data[0x0a]));
df7b7f
-          power.setVersion(dmi_string(dm, data[0x0b]));
df7b7f
-          power.setCapacity(data[0x0c] + 256*data[0x0d]);
df7b7f
+          power.setProduct(dmi_string(dm, data[0x0A]));
df7b7f
+          power.setVersion(dmi_string(dm, data[0x0B]));
df7b7f
+          power.setCapacity(data[0x0C] + 256*data[0x0D]);
df7b7f
           node.addChild(power);
df7b7f
         }
df7b7f
         break;
df7b7f
@@ -1780,17 +1846,19 @@ int dmiversionmin)
df7b7f
 
df7b7f
 
df7b7f
 static bool smbios_entry_point(const u8 *buf, size_t len,
df7b7f
-    hwNode & n, u16 & dmimaj, u16 & dmimin,
df7b7f
+    hwNode & n, u16 & dmimaj, u16 & dmimin, u16 & dmirev,
df7b7f
     uint32_t & table_len, uint64_t & table_base)
df7b7f
 {
df7b7f
   u8 smmajver = 0;
df7b7f
   u8 smminver = 0;
df7b7f
+  u8 smdocrev = 0;
df7b7f
 
df7b7f
   if (len >= 24 && memcmp(buf, "_SM3_", 5) == 0 && checksum(buf, buf[6]))
df7b7f
   {
df7b7f
     // SMBIOS 3.0 entry point structure (64-bit)
df7b7f
     dmimaj = smmajver = buf[7];
df7b7f
     dmimin = smminver = buf[8];
df7b7f
+    dmirev = smdocrev = buf[9];
df7b7f
     table_len = (((uint32_t) buf[15]) << 24) +
df7b7f
                 (((uint32_t) buf[14]) << 16) +
df7b7f
                 (((uint32_t) buf[13]) << 8) +
df7b7f
@@ -1823,9 +1891,16 @@ static bool smbios_entry_point(const u8 *buf, size_t len,
df7b7f
   if (smmajver > 0)
df7b7f
   {
df7b7f
     char buffer[20];
df7b7f
-    snprintf(buffer, sizeof(buffer), "%d.%d", smmajver, smminver);
df7b7f
+    if (smmajver == 3)
df7b7f
+      snprintf(buffer, sizeof(buffer), "%d.%d.%d", smmajver, smminver, smdocrev);
df7b7f
+    else
df7b7f
+      snprintf(buffer, sizeof(buffer), "%d.%d", smmajver, smminver);
df7b7f
     n.addCapability("smbios-"+string(buffer), "SMBIOS version "+string(buffer));
df7b7f
-    snprintf(buffer, sizeof(buffer), "%d.%d", dmimaj, dmimin);
df7b7f
+
df7b7f
+    if (dmimaj == 3)
df7b7f
+      snprintf(buffer, sizeof(buffer), "%d.%d.%d", dmimaj, dmimin, dmirev);
df7b7f
+    else
df7b7f
+      snprintf(buffer, sizeof(buffer), "%d.%d", dmimaj, dmimin);
df7b7f
     n.addCapability("dmi-"+string(buffer), "DMI version "+string(buffer));
df7b7f
 
df7b7f
     return true;
df7b7f
@@ -1842,7 +1917,7 @@ static bool scan_dmi_sysfs(hwNode & n)
df7b7f
 
df7b7f
   uint32_t table_len = 0;
df7b7f
   uint64_t table_base = 0;
df7b7f
-  u16 dmimaj = 0, dmimin = 0;
df7b7f
+  u16 dmimaj = 0, dmimin = 0, dmirev = 0;
df7b7f
 
df7b7f
   ifstream ep_stream(SYSFSDMI "/smbios_entry_point",
df7b7f
       ifstream::in | ifstream::binary | ifstream::ate);
df7b7f
@@ -1853,7 +1938,7 @@ static bool scan_dmi_sysfs(hwNode & n)
df7b7f
   if (!ep_stream)
df7b7f
     return false;
df7b7f
   if (!smbios_entry_point(ep_buf.data(), ep_len, n,
df7b7f
-        dmimaj, dmimin, table_len, table_base))
df7b7f
+        dmimaj, dmimin, dmirev, table_len, table_base))
df7b7f
     return false;
df7b7f
 
df7b7f
   ifstream dmi_stream(SYSFSDMI "/DMI",
df7b7f
@@ -1864,7 +1939,7 @@ static bool scan_dmi_sysfs(hwNode & n)
df7b7f
   dmi_stream.read((char *)dmi_buf.data(), dmi_len);
df7b7f
   if (!dmi_stream)
df7b7f
     return false;
df7b7f
-  dmi_table(dmi_buf.data(), dmi_len, n, dmimaj, dmimin);
df7b7f
+  dmi_table(dmi_buf.data(), dmi_len, n, dmimaj, dmimin, dmirev);
df7b7f
 
df7b7f
   return true;
df7b7f
 }
df7b7f
@@ -1902,7 +1977,7 @@ static bool scan_dmi_devmem(hwNode & n)
df7b7f
   u32 mmoffset = 0;
df7b7f
   void *mmp = NULL;
df7b7f
   bool efi = true;
df7b7f
-  u16 dmimaj = 0, dmimin = 0;
df7b7f
+  u16 dmimaj = 0, dmimin = 0, dmirev = 0;
df7b7f
 
df7b7f
   if (fd == -1)
df7b7f
     return false;
df7b7f
@@ -1932,7 +2007,7 @@ static bool scan_dmi_devmem(hwNode & n)
df7b7f
     }
df7b7f
     uint32_t len;
df7b7f
     uint64_t base;
df7b7f
-    if (smbios_entry_point(buf, sizeof(buf), n, dmimaj, dmimin, len, base))
df7b7f
+    if (smbios_entry_point(buf, sizeof(buf), n, dmimaj, dmimin, dmirev, len, base))
df7b7f
     {
df7b7f
       u8 *dmi_buf = (u8 *)malloc(len);
df7b7f
       mmoffset = base % getpagesize();
df7b7f
@@ -1944,7 +2019,7 @@ static bool scan_dmi_devmem(hwNode & n)
df7b7f
       }
df7b7f
       memcpy(dmi_buf, (u8 *) mmp + mmoffset, len);
df7b7f
       munmap(mmp, mmoffset + len);
df7b7f
-      dmi_table(dmi_buf, len, n, dmimaj, dmimin);
df7b7f
+      dmi_table(dmi_buf, len, n, dmimaj, dmimin, dmirev);
df7b7f
       free(dmi_buf);
df7b7f
       break;
df7b7f
     }
df7b7f
diff --git a/src/core/pci.cc b/src/core/pci.cc
df7b7f
index d1625cf..fa6a1e5 100644
df7b7f
--- a/src/core/pci.cc
df7b7f
+++ b/src/core/pci.cc
df7b7f
@@ -774,8 +774,12 @@ static hwNode *scan_pci_dev(struct pci_dev &d, hwNode & n)
df7b7f
   if(!pcidb_loaded)
df7b7f
     pcidb_loaded = load_pcidb();
df7b7f
 
df7b7f
-      d.vendor_id = get_conf_word(d, PCI_VENDOR_ID);
df7b7f
-      d.device_id = get_conf_word(d, PCI_DEVICE_ID);
df7b7f
+      u_int16_t tmp_vendor_id = get_conf_word(d, PCI_VENDOR_ID);
df7b7f
+      u_int16_t tmp_device_id = get_conf_word(d, PCI_DEVICE_ID);
df7b7f
+      if ((tmp_vendor_id & tmp_device_id) != 0xffff) {
df7b7f
+        d.vendor_id = tmp_vendor_id;
df7b7f
+        d.device_id = tmp_device_id;
df7b7f
+      }
df7b7f
       u_int16_t dclass = get_conf_word(d, PCI_CLASS_DEVICE);
df7b7f
       u_int16_t cmd = get_conf_word(d, PCI_COMMAND);
df7b7f
       u_int16_t status = get_conf_word(d, PCI_STATUS);
df7b7f
@@ -1122,6 +1126,7 @@ bool scan_pci(hwNode & n)
df7b7f
     if(matches(devices[i]->d_name, "^[[:xdigit:]]+:[[:xdigit:]]+:[[:xdigit:]]+\\.[[:xdigit:]]+$"))
df7b7f
     {
df7b7f
       string devicepath = string(devices[i]->d_name)+"/config";
df7b7f
+      sysfs::entry device_entry = sysfs::entry::byBus("pci", devices[i]->d_name);
df7b7f
       struct pci_dev d;
df7b7f
       int fd = open(devicepath.c_str(), O_RDONLY);
df7b7f
       if (fd >= 0)
df7b7f
@@ -1136,6 +1141,8 @@ bool scan_pci(hwNode & n)
df7b7f
       }
df7b7f
 
df7b7f
       sscanf(devices[i]->d_name, "%hx:%hx:%hhx.%hhx", &d.domain, &d.bus, &d.dev, &d.func);
df7b7f
+      sscanf(device_entry.vendor().c_str(), "%hx", &d.vendor_id);
df7b7f
+      sscanf(device_entry.device().c_str(), "%hx", &d.device_id);
df7b7f
       hwNode *device = scan_pci_dev(d, n);
df7b7f
 
df7b7f
       if(device)
df7b7f
@@ -1166,7 +1173,7 @@ bool scan_pci(hwNode & n)
df7b7f
           device->claim();
df7b7f
         }
df7b7f
 
df7b7f
-	device->setModalias(sysfs::entry::byBus("pci", devices[i]->d_name).modalias());
df7b7f
+        device->setModalias(device_entry.modalias());
df7b7f
 
df7b7f
         if(exists(resourcename))
df7b7f
         {
df7b7f
diff --git a/src/core/sysfs.cc b/src/core/sysfs.cc
df7b7f
index 97dbab5..486f8ee 100644
df7b7f
--- a/src/core/sysfs.cc
df7b7f
+++ b/src/core/sysfs.cc
df7b7f
@@ -358,6 +358,16 @@ string entry::modalias() const
df7b7f
   return get_string(This->devpath+"/modalias");
df7b7f
 }
df7b7f
 
df7b7f
+string entry::device() const
df7b7f
+{
df7b7f
+  return get_string(This->devpath+"/device");
df7b7f
+}
df7b7f
+
df7b7f
+string entry::vendor() const
df7b7f
+{
df7b7f
+  return get_string(This->devpath+"/vendor");
df7b7f
+}
df7b7f
+
df7b7f
 vector < entry > sysfs::entries_by_bus(const string & busname)
df7b7f
 {
df7b7f
   vector < entry > result;
df7b7f
diff --git a/src/core/sysfs.h b/src/core/sysfs.h
df7b7f
index d37e2d4..dffa4b2 100644
df7b7f
--- a/src/core/sysfs.h
df7b7f
+++ b/src/core/sysfs.h
df7b7f
@@ -26,6 +26,8 @@ namespace sysfs
df7b7f
       string businfo() const;
df7b7f
       string driver() const;
df7b7f
       string modalias() const;
df7b7f
+      string device() const;
df7b7f
+      string vendor() const;
df7b7f
       entry parent() const;
df7b7f
       string name_in_class(const string &) const;
df7b7f
       string string_attr(const string & name, const string & def = "") const;
df7b7f
-- 
df7b7f
2.14.0
df7b7f