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

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