diff --git a/SOURCES/0001-Escape-special-characters-in-html-output.patch b/SOURCES/0001-Escape-special-characters-in-html-output.patch
new file mode 100644
index 0000000..87478a4
--- /dev/null
+++ b/SOURCES/0001-Escape-special-characters-in-html-output.patch
@@ -0,0 +1,193 @@
+From d17b62d7fca7647a1e935285869b93856c924890 Mon Sep 17 00:00:00 2001
+From: Petr Oros <poros@redhat.com>
+Date: Tue, 15 Aug 2017 09:18:02 +0200
+Subject: [PATCH 1/1] Escape special characters in html output
+
+Signed-off-by Petr Oros <poros@redhat.com>
+---
+ src/core/print.cc | 77 +++++++++++++++++++++++++++++++++++++++----------------
+ 1 file changed, 55 insertions(+), 22 deletions(-)
+
+diff --git a/src/core/print.cc b/src/core/print.cc
+index 5df078e..958bf6a 100644
+--- a/src/core/print.cc
++++ b/src/core/print.cc
+@@ -156,10 +156,13 @@ int level)
+         cout << "<tr><td class=\"first\">";
+       cout << "handle: ";
+       if (html)
++      {
+         cout << "</td><td class=\"second\">";
+-      cout << node.getHandle();
+-      if (html)
++        cout << escape(node.getHandle());
+         cout << "</td></tr>";
++      }
++      else
++        cout << node.getHandle()
+       cout << endl;
+     }
+ #endif
+@@ -174,10 +177,13 @@ int level)
+         cout << "<tr><td class=\"first\">";
+       cout << _("description") << ": ";
+       if (html)
++      {
+         cout << "</td><td class=\"second\">";
+-      cout << node.getDescription();
+-      if (html)
++        cout << escape(node.getDescription());
+         cout << "</td></tr>";
++      }
++      else
++        cout << node.getDescription();
+       cout << endl;
+     }
+ 
+@@ -188,10 +194,13 @@ int level)
+         cout << "<tr><td class=\"first\">";
+       cout << _("product") << ": ";
+       if (html)
++      {
+         cout << "</td><td class=\"second\">";
+-      cout << node.getProduct();
+-      if (html)
++        cout << escape(node.getProduct());
+         cout << "</td></tr>";
++      }
++      else
++        cout << node.getProduct();
+       cout << endl;
+     }
+ 
+@@ -202,10 +211,13 @@ int level)
+         cout << "<tr><td class=\"first\">";
+       cout << _("vendor") << ": ";
+       if (html)
++      {
+         cout << "</td><td class=\"second\">";
+-      cout << node.getVendor();
+-      if (html)
++        cout << escape(node.getVendor());
+         cout << "</td></tr>";
++      }
++      else
++        cout << node.getVendor();
+       cout << endl;
+     }
+ 
+@@ -216,10 +228,13 @@ int level)
+         cout << "<tr><td class=\"first\">";
+       cout << _("physical id") << ": ";
+       if (html)
++      {
+         cout << "</td><td class=\"second\"><div class=\"id\">";
+-      cout << node.getPhysId();
+-      if (html)
++        cout << escape(node.getPhysId());
+         cout << "</div></td></tr>";
++      }
++      else
++        cout << node.getPhysId();
+       cout << endl;
+     }
+ 
+@@ -230,10 +245,13 @@ int level)
+         cout << "<tr><td class=\"first\">";
+       cout << _("bus info") << ": ";
+       if (html)
++      {
+         cout << "</td><td class=\"second\"><div class=\"id\">";
+-      cout << node.getBusInfo();
+-      if (html)
++        cout << escape(node.getBusInfo());
+         cout << "</div></td></tr>";
++      }
++      else
++        cout << node.getBusInfo();
+       cout << endl;
+     }
+ 
+@@ -248,10 +266,13 @@ int level)
+           cout << "<tr><td class=\"first\">";
+         cout << _("logical name") << ": ";
+         if (html)
++        {
+           cout << "</td><td class=\"second\"><div class=\"id\">";
+-        cout << logicalnames[i];
+-        if (html)
++          cout << escape(logicalnames[i]);
+           cout << "</div></td></tr>";
++        }
++        else
++          cout << logicalnames[i];
+         cout << endl;
+       }
+     }
+@@ -263,10 +284,13 @@ int level)
+         cout << "<tr><td class=\"first\">";
+       cout << _("version") << ": ";
+       if (html)
++      {
+         cout << "</td><td class=\"second\">";
+-      cout << node.getVersion();
+-      if (html)
++        cout << escape(node.getVersion());
+         cout << "</td></tr>";
++      }
++      else
++        cout << node.getVersion();
+       cout << endl;
+     }
+ 
+@@ -277,10 +301,13 @@ int level)
+         cout << "<tr><td class=\"first\">";
+       cout << _("date") << ": ";
+       if (html)
++      {
+         cout << "</td><td class=\"second\">";
+-      cout << node.getDate();
+-      if (html)
++        cout << escape(node.getDate());
+         cout << "</td></tr>";
++      }
++      else
++        cout << node.getDate();
+       cout << endl;
+     }
+ 
+@@ -291,10 +318,13 @@ int level)
+         cout << "<tr><td class=\"first\">";
+       cout << _("serial") << ": ";
+       if (html)
++      {
+         cout << "</td><td class=\"second\">";
+-      cout << (enabled("output:sanitize")?REMOVED:node.getSerial());
+-      if (html)
++        cout << escape(enabled("output:sanitize")?REMOVED:node.getSerial());
+         cout << "</td></tr>";
++      }
++      else
++        cout << (enabled("output:sanitize")?REMOVED:node.getSerial());
+       cout << endl;
+     }
+ 
+@@ -305,10 +335,13 @@ int level)
+         cout << "<tr><td class=\"first\">";
+       cout << _("slot") << ": ";
+       if (html)
++      {
+         cout << "</td><td class=\"second\">";
+-      cout << node.getSlot();
+-      if (html)
++        cout << escape(node.getSlot());
+         cout << "</td></tr>";
++      }
++      else
++        cout << node.getSlot();
+       cout << endl;
+     }
+ 
+-- 
+2.14.1
+
diff --git a/SOURCES/0001-Proper-detect-vendor_id-device_id-for-virtual-functi.patch b/SOURCES/0001-Proper-detect-vendor_id-device_id-for-virtual-functi.patch
deleted file mode 100644
index cd27c00..0000000
--- a/SOURCES/0001-Proper-detect-vendor_id-device_id-for-virtual-functi.patch
+++ /dev/null
@@ -1,118 +0,0 @@
-From 76ada4fa8f5aa64d2de254aa5081582a77384b09 Mon Sep 17 00:00:00 2001
-From: Petr Oros <poros@redhat.com>
-Date: Thu, 16 Mar 2017 17:50:53 +0100
-Subject: [PATCH] Proper detect vendor_id/device_id for virtual functions
-
-  PCI Single Root I/O Virtualization and Sharing  (AKA SRIOV)
-  Specification Revision 1.1 sections 3.4.1.1 and 3.4.1.2 control these values.
-  Both the Vendor ID and the Device ID are required to return values of "FFFFh when read.
-
-  Proper value can read from sysfs
-
-  Tests:
-  Before patch
-    # lshw -short -numeric -class network
-    H/W path            Device      Class          Description
-    ==========================================================
-    /0/9/0                          network        82599ES 10-Gigabit SFI/SFP+ Network Connection [8086:10FB]
-    /0/9/0.1            p3p2        network        82599ES 10-Gigabit SFI/SFP+ Network Connection [8086:10FB]
-    /0/9/10.1           p3p2_0      network        Illegal Vendor ID [FFFF:FFFF]
-    /0/9/10.3           p3p2_1      network        Illegal Vendor ID [FFFF:FFFF]
-
-  After patch
-    # lshw -short -numeric -class network
-    H/W path            Device      Class      Description
-    ======================================================
-    /0/9/0                          network    82599ES 10-Gigabit SFI/SFP+ Network Connection [8086:10FB]
-    /0/9/0.1            p3p2        network    82599ES 10-Gigabit SFI/SFP+ Network Connection [8086:10FB]
-    /0/9/10.1           p3p2_0      network    82599 Ethernet Controller Virtual Function [8086:10ED]
-    /0/9/10.3           p3p2_1      network    82599 Ethernet Controller Virtual Function [8086:10ED]
-
-Signed-off-by: Petr Oros <poros@redhat.com>
----
- src/core/pci.cc   | 13 ++++++++++---
- src/core/sysfs.cc | 10 ++++++++++
- src/core/sysfs.h  |  2 ++
- 3 files changed, 22 insertions(+), 3 deletions(-)
-
-diff --git a/src/core/pci.cc b/src/core/pci.cc
-index d1625cf..7803eac 100644
---- a/src/core/pci.cc
-+++ b/src/core/pci.cc
-@@ -774,8 +774,12 @@ static hwNode *scan_pci_dev(struct pci_dev &d, hwNode & n)
-   if(!pcidb_loaded)
-     pcidb_loaded = load_pcidb();
- 
--      d.vendor_id = get_conf_word(d, PCI_VENDOR_ID);
--      d.device_id = get_conf_word(d, PCI_DEVICE_ID);
-+      u_int16_t tmp_vendor_id = get_conf_word(d, PCI_VENDOR_ID);
-+      u_int16_t tmp_device_id = get_conf_word(d, PCI_DEVICE_ID);
-+      if ((tmp_vendor_id & tmp_device_id) != 0xffff) {
-+        d.vendor_id = tmp_vendor_id;
-+        d.device_id = tmp_device_id;
-+      }
-       u_int16_t dclass = get_conf_word(d, PCI_CLASS_DEVICE);
-       u_int16_t cmd = get_conf_word(d, PCI_COMMAND);
-       u_int16_t status = get_conf_word(d, PCI_STATUS);
-@@ -1122,6 +1126,7 @@ bool scan_pci(hwNode & n)
-     if(matches(devices[i]->d_name, "^[[:xdigit:]]+:[[:xdigit:]]+:[[:xdigit:]]+\\.[[:xdigit:]]+$"))
-     {
-       string devicepath = string(devices[i]->d_name)+"/config";
-+      sysfs::entry device_entry = sysfs::entry::byBus("pci", devices[i]->d_name);
-       struct pci_dev d;
-       int fd = open(devicepath.c_str(), O_RDONLY);
-       if (fd >= 0)
-@@ -1136,6 +1141,8 @@ bool scan_pci(hwNode & n)
-       }
- 
-       sscanf(devices[i]->d_name, "%hx:%hx:%hhx.%hhx", &d.domain, &d.bus, &d.dev, &d.func);
-+      sscanf(device_entry.vendor().c_str(), "%hx", &d.vendor_id);
-+      sscanf(device_entry.device().c_str(), "%hx", &d.device_id);
-       hwNode *device = scan_pci_dev(d, n);
- 
-       if(device)
-@@ -1166,7 +1173,7 @@ bool scan_pci(hwNode & n)
-           device->claim();
-         }
- 
--	device->setModalias(sysfs::entry::byBus("pci", devices[i]->d_name).modalias());
-+        device->setModalias(device_entry.modalias());
- 
-         if(exists(resourcename))
-         {
-diff --git a/src/core/sysfs.cc b/src/core/sysfs.cc
-index 97dbab5..486f8ee 100644
---- a/src/core/sysfs.cc
-+++ b/src/core/sysfs.cc
-@@ -358,6 +358,16 @@ string entry::modalias() const
-   return get_string(This->devpath+"/modalias");
- }
- 
-+string entry::device() const
-+{
-+  return get_string(This->devpath+"/device");
-+}
-+
-+string entry::vendor() const
-+{
-+  return get_string(This->devpath+"/vendor");
-+}
-+
- vector < entry > sysfs::entries_by_bus(const string & busname)
- {
-   vector < entry > result;
-diff --git a/src/core/sysfs.h b/src/core/sysfs.h
-index d37e2d4..dffa4b2 100644
---- a/src/core/sysfs.h
-+++ b/src/core/sysfs.h
-@@ -26,6 +26,8 @@ namespace sysfs
-       string businfo() const;
-       string driver() const;
-       string modalias() const;
-+      string device() const;
-+      string vendor() const;
-       entry parent() const;
-       string name_in_class(const string &) const;
-       string string_attr(const string & name, const string & def = "") const;
--- 
-2.10.2
diff --git a/SOURCES/0001-cpuinfo-Fix-compiler-warnings-in-cpuinfo-code.patch b/SOURCES/0001-cpuinfo-Fix-compiler-warnings-in-cpuinfo-code.patch
new file mode 100644
index 0000000..86a6a3e
--- /dev/null
+++ b/SOURCES/0001-cpuinfo-Fix-compiler-warnings-in-cpuinfo-code.patch
@@ -0,0 +1,44 @@
+From 1ed69e46e27b9085507e5498dbcc354dd5563338 Mon Sep 17 00:00:00 2001
+From: Petr Oros <poros@redhat.com>
+Date: Tue, 12 Sep 2017 16:29:48 +0200
+Subject: [PATCH] cpuinfo: Fix compiler warnings in cpuinfo code
+
+Signed-off-by: Petr Oros <poros@redhat.com>
+---
+ src/core/cpuinfo.cc | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/src/core/cpuinfo.cc b/src/core/cpuinfo.cc
+index c617ef2..0fb0ea3 100644
+--- a/src/core/cpuinfo.cc
++++ b/src/core/cpuinfo.cc
+@@ -136,7 +136,7 @@ string value)
+       cpu->claim(true);
+       cpu->setVendor(s390x_vendor);
+ 
+-      for(int i=0; i < s390x_features.size(); i++)
++      for(size_t i=0; i < s390x_features.size(); i++)
+         cpu->addCapability(s390x_features[i]);
+       /* many thanks to Martin Schwidefsky for communicating the descriptions
+          of the feature flags
+@@ -258,7 +258,7 @@ static void cpuinfo_aarch64(hwNode & node,
+               if (node.getDescription() == "")
+                 node.setDescription(aarch64_processor_name);
+               cpu->claim(true);
+-              for(int i=0; i < aarch64_features.size(); i++)
++              for(size_t i=0; i < aarch64_features.size(); i++)
+                 {
+                   cpu->addCapability(aarch64_features[i]);
+                   cpu->describeCapability("fp", "Floating point instructions");
+@@ -279,8 +279,6 @@ static void cpuinfo_ia64(hwNode & node,
+ string id,
+ string value)
+ {
+-  unsigned long long frequency = 0;
+-  int i;
+ 
+   if (id == "processor")
+     currentcpu++;
+-- 
+2.14.1
+
diff --git a/SOURCES/0001-devtree-Check-status-property-for-caches.patch b/SOURCES/0001-devtree-Check-status-property-for-caches.patch
new file mode 100644
index 0000000..33c1ad9
--- /dev/null
+++ b/SOURCES/0001-devtree-Check-status-property-for-caches.patch
@@ -0,0 +1,44 @@
+From ec4dcbf19646e52389c72d85daf20b4e74dc0f92 Mon Sep 17 00:00:00 2001
+From: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
+Date: Tue, 22 Aug 2017 20:53:41 +0530
+Subject: [PATCH 1/5] devtree: Check status property for caches
+
+Check status property for L1 cache before enabling cache node.
+Also check status before enabling L2/L3 icache.
+
+Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
+---
+ src/core/device-tree.cc | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/src/core/device-tree.cc b/src/core/device-tree.cc
+index 05b5b3c..e14a3b3 100644
+--- a/src/core/device-tree.cc
++++ b/src/core/device-tree.cc
+@@ -670,7 +670,10 @@ static void scan_devtree_cpu_power(hwNode & core)
+     product = hw::strip(get_string(basepath + "/name"));
+ 
+     if (hw::strip(get_string(basepath + "/status")) != "okay")
++    {
+       cache.disable();
++      icache.disable();
++    }
+ 
+     if (product == "l2-cache")
+       fill_cache_info("L2 Cache", basepath, cache, icache);
+@@ -773,6 +776,12 @@ static void scan_devtree_cpu_power(hwNode & core)
+ 
+       if (cache.getSize() > 0)
+         cpu.addChild(cache);
++
++      if (hw::strip(get_string(basepath + "/status")) != "okay")
++      {
++        cache.disable();
++        icache.disable();
++      }
+     }
+ 
+     if (exists(basepath + "/l2-cache"))
+-- 
+1.8.3.1
+
diff --git a/SOURCES/0001-lshw-Parse-OPAL-firmware-properties-from-the-device-.patch b/SOURCES/0001-lshw-Parse-OPAL-firmware-properties-from-the-device-.patch
deleted file mode 100644
index 258970a..0000000
--- a/SOURCES/0001-lshw-Parse-OPAL-firmware-properties-from-the-device-.patch
+++ /dev/null
@@ -1,102 +0,0 @@
-From 2c38e1c6a9dd4e35685be5ba7f64e51fd0e31c1a Mon Sep 17 00:00:00 2001
-From: Jeremy Kerr <jk@ozlabs.org>
-Date: Mon, 8 Jun 2015 12:35:00 +0800
-Subject: [PATCH] lshw: Parse OPAL firmware properties from the device tree
-
-OPAL-firmware-based Power machines expose a firmware device tree node in
-/ibm,opal, containing version information and available interfaces.
-
-This change adds a function to parse information about OPAL firmware and
-add it to lshw's machine information. With a current OpenPower machine,
-we get something like this:
-
-     *-firmware
-          product: OPAL firmware
-          physical id: 1
-          version: skiboot-5.0.2
-          capabilities: opal-v2 opal-v3 prd ipmi
-
-Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
----
- src/core/device-tree.cc | 59 +++++++++++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 59 insertions(+)
-
-diff --git a/src/core/device-tree.cc b/src/core/device-tree.cc
-index 8908fd1..73a98a9 100644
---- a/src/core/device-tree.cc
-+++ b/src/core/device-tree.cc
-@@ -219,6 +219,64 @@ static void scan_devtree_bootrom(hwNode
-   }
- }
- 
-+static void scan_devtree_opal_firmware(hwNode & core)
-+{
-+  vector < string >::iterator it;
-+  vector < string > compat;
-+  struct dirent **namelist;
-+  int i, n;
-+
-+  if (!exists(DEVICETREE "/ibm,opal"))
-+    return;
-+
-+  hwNode opal("firmware", hw::memory);
-+
-+  opal.setProduct("OPAL firmware");
-+  if (exists(DEVICETREE "/ibm,opal/firmware/version"))
-+    opal.setVersion(get_string(DEVICETREE "/ibm,opal/firmware/version"));
-+
-+  compat = get_strings(DEVICETREE "/ibm,opal/compatible");
-+
-+  for (it = compat.begin(); it != compat.end(); ++it) {
-+    if (matches(*it, "^ibm,opal-v2"))
-+      opal.addCapability("opal-v2");
-+    if (matches(*it, "^ibm,opal-v3"))
-+      opal.addCapability("opal-v3");
-+  }
-+
-+  /* collect compatible strings from firmware sub-nodes */
-+  compat.clear();
-+  pushd(DEVICETREE "/ibm,opal");
-+  n = scandir(".", &namelist, selectdir, alphasort);
-+  popd();
-+  for (i = 0; i < n; i++) {
-+    string path = string(DEVICETREE "/ibm,opal/")
-+                        + string(namelist[i]->d_name)
-+                        + string("/compatible");
-+
-+    vector < string > tmp = get_strings(path);
-+    compat.insert(compat.end(), tmp.begin(), tmp.end());
-+
-+    free(namelist[i]);
-+  }
-+
-+  if (n >= 0)
-+    free(namelist);
-+
-+  /* check our collected compatible strings for known capabilities */
-+  for (it = compat.begin(); it != compat.end(); ++it) {
-+
-+    if (*it == "ibm,opal-prd")
-+      opal.addCapability("prd");
-+
-+    if (*it == "ibm,opal-ipmi")
-+      opal.addCapability("ipmi");
-+  }
-+
-+  opal.claim();
-+  core.addChild(opal);
-+}
-+
- static void scan_devtree_firmware_powernv(hwNode & core)
- {
-   int n;
-@@ -1378,6 +1436,7 @@ bool scan_device_tree(hwNode & n)
-       scan_devtree_memory_ibm(*core);
-       scan_devtree_memory_powernv(*core);
-       scan_devtree_firmware_powernv(*core);
-+      scan_devtree_opal_firmware(*core);
-       n.addCapability("powernv", "Non-virtualized");
-       n.addCapability("opal", "OPAL firmware");
-     }
--- 
-1.9.1
diff --git a/SOURCES/0001-merge-Petr-Oros-pull-request.patch b/SOURCES/0001-merge-Petr-Oros-pull-request.patch
new file mode 100644
index 0000000..d367396
--- /dev/null
+++ b/SOURCES/0001-merge-Petr-Oros-pull-request.patch
@@ -0,0 +1,784 @@
+From 17aa0a1e48bf9dd596c7678b93bd5aaaad94aeb8 Mon Sep 17 00:00:00 2001
+From: Lyonel Vincent <lyonel@ezix.org>
+Date: Tue, 20 Jun 2017 20:49:30 +0200
+Subject: [PATCH] merge Petr Oros' pull request
+
+cf. https://github.com/lyonel/lshw/pull/29
+
+ * Proper detect vendor_id/device_id for virtual functions
+ * Sync SMBIOS with latest specification
+---
+ src/core/dmi.cc   | 323 +++++++++++++++++++++++++++++++++---------------------
+ src/core/pci.cc   |  13 ++-
+ src/core/sysfs.cc |  10 ++
+ src/core/sysfs.h  |   2 +
+ 4 files changed, 221 insertions(+), 127 deletions(-)
+
+diff --git a/src/core/dmi.cc b/src/core/dmi.cc
+index 250f485..d1b0b07 100644
+--- a/src/core/dmi.cc
++++ b/src/core/dmi.cc
+@@ -408,6 +408,13 @@ static unsigned long dmi_cache_size(u16 n)
+     return (n & 0x7FFF) * 1024;                   // value is in 1K blocks
+ }
+ 
++static unsigned long long dmi_cache_size_long(u32 n)
++{
++  if (n & (1 << 31))
++    return (n & 0x7FFFFFFF) * 64 * 1024;              // value is in 64K blocks
++  else
++    return (n & 0x7FFFFFFF) * 1024;                   // value is in 1K blocks
++}
+ 
+ static void dmi_cache_sramtype(u16 c,
+ hwNode & n)
+@@ -657,9 +664,13 @@ void dmi_chassis(u8 code, hwNode & n)
+     "tablet", N_("Tablet"), NULL,
+     "convertible", N_("Convertible"), NULL,
+     "detachable", N_("Detachable"), NULL,               /* 0x20 */
++    "iot-gateway", N_("IoT Gateway"), NULL,
++    "embedded", N_("Embedded PC"), NULL,
++    "mini", N_("Mini PC"), NULL,
++    "stick", N_("Stick PC"), NULL,               /* 0x24 */
+   };
+ 
+-  if(code <= 0x20)
++  if(code <= 0x24)
+   {
+     if(n.getDescription()=="") n.setDescription(_(chassis_type[1+3*code]));
+ 
+@@ -720,9 +731,9 @@ static const char *dmi_processor_family(uint16_t code)
+     "Core Solo mobile",
+     "Atom",
+     "Core M",
+-    "",
+-    "",
+-    "",
++    "Core M3",
++    "Core M5",
++    "Core M7",
+     "Alpha",                                      /* 0x30 */
+     "Alpha 21064",
+     "Alpha 21066",
+@@ -780,9 +791,9 @@ static const char *dmi_processor_family(uint16_t code)
+     "Athlon X4",                                  /* 0x66 */
+     "Opteron X1000",
+     "Opteron X2000 APU",
+-    "",
+-    "",
+-    "",
++    "Opteron A",
++    "Opteron X3000 APU",
++    "Zen",
+     "",
+     "",
+     "",
+@@ -938,6 +949,8 @@ static const char *dmi_processor_family(uint16_t code)
+ 
+   switch (code)
+   {
++    case 0x100: return "ARMv7";
++    case 0x101: return "ARMv8";
+     case 0x104: return "SH-3";
+     case 0x105: return "SH-4";
+     case 0x118: return "ARM";
+@@ -966,7 +979,8 @@ static void dmi_table(const u8 *buf,
+ int len,
+ hwNode & node,
+ int dmiversionmaj,
+-int dmiversionmin)
++int dmiversionmin,
++int dmiversionrev)
+ {
+   struct dmi_header *dm;
+   hwNode *hardwarenode = NULL;
+@@ -1008,24 +1022,34 @@ int dmiversionmin)
+ // BIOS Information Block
+         {
+           string release(dmi_string(dm,
+-            data[8]));
++            data[0x08]));
+           hwNode newnode("firmware",
+             hw::memory,
+             dmi_string(dm,
+-            data[4]));
++            data[0x04]));
+           newnode.setVersion(dmi_string(dm, data[5]));
+-          newnode.setCapacity(64 * data[9] * 1024);
+-          newnode.setSize(16 * (0x10000 - (data[7] << 8 | data[6])));
+-//newnode.setPhysId(16 * (data[7] << 8 | data[6]));
++          if (data[0x09] != 0xFF)
++            newnode.setCapacity(64 * (data[0x09] + 1) * 1024);
++          else
++          {
++            if (dm->length < 0x1A)
++              newnode.setCapacity(16 * 1024 * 1024);
++            else
++            {
++              unsigned int unit = (data[0x19] << 8 | data[0x18]) & 0x4000 ? 1024 : 1024 * 1024;
++              newnode.setCapacity(((data[0x19] << 8 | data[0x18]) & 0x3FFF) * unit);
++            }
++          }
++          newnode.setSize(16 * (0x10000 - (data[0x07] << 8 | data[0x06])));
+           newnode.setPhysId(dm->handle);
+           newnode.setDescription(_("BIOS"));
+           newnode.addHint("icon", string("chip"));
+           newnode.claim();
+ 
+-          dmi_bios_features(data[13] << 24 | data[12] << 16 | data[11] << 8 |
+-            data[10],
+-            data[17] << 24 | data[16] << 16 | data[15] << 8 |
+-            data[14], newnode);
++          dmi_bios_features(data[0x0D] << 24 | data[0x0C] << 16 | data[0x0B] << 8 |
++            data[0x0A],
++            data[0x11] << 24 | data[0x10] << 16 | data[0x0F] << 8 |
++            data[0x0E], newnode);
+ 
+           if (dm->length > 0x12)
+             dmi_bios_features_ext(&data[0x12], dm->length - 0x12, newnode);
+@@ -1039,12 +1063,12 @@ int dmiversionmin)
+       case 1:
+ // System Information Block
+         node.setHandle(handle);
+-        node.setVendor(dmi_string(dm, data[4]));
+-        node.setProduct(dmi_string(dm, data[5]));
+-        node.setVersion(dmi_string(dm, data[6]));
+-        node.setSerial(dmi_string(dm, data[7]));
++        node.setVendor(dmi_string(dm, data[0x04]));
++        node.setProduct(dmi_string(dm, data[0x05]));
++        node.setVersion(dmi_string(dm, data[0x06]));
++        node.setSerial(dmi_string(dm, data[0x07]));
+         if (dm->length >= 0x19)
+-          node.setConfig("uuid", dmi_uuid(data + 8));
++          node.setConfig("uuid", dmi_uuid(data + 0x08));
+         if (dm->length >= 0x1B)
+         {
+           node.setConfig("sku", dmi_string(dm, data[0x19]));
+@@ -1057,15 +1081,14 @@ int dmiversionmin)
+       case 2:
+ // Board Information Block
+         {
+-
+-                                                  // we are the only system board on the computer so connect everything to us
++          // we are the only system board on the computer so connect everything to us
+           if ((dm->length <= 0x0E) || (data[0x0E] == 0))
+           {
+-            hardwarenode->setVendor(dmi_string(dm, data[4]));
+-            hardwarenode->setProduct(dmi_string(dm, data[5]));
+-            hardwarenode->setVersion(dmi_string(dm, data[6]));
+-            hardwarenode->setSerial(dmi_string(dm, data[7]));
+-            if(dm->length >= 0x0a)
++            hardwarenode->setVendor(dmi_string(dm, data[0x04]));
++            hardwarenode->setProduct(dmi_string(dm, data[0x05]));
++            hardwarenode->setVersion(dmi_string(dm, data[0x06]));
++            hardwarenode->setSerial(dmi_string(dm, data[0x07]));
++            if(dm->length >= 0x0A)
+               hardwarenode->setSlot(dmi_string(dm, data[0x0A]));
+             hardwarenode->setHandle(handle);
+             hardwarenode->setDescription(_("Motherboard"));
+@@ -1083,10 +1106,10 @@ int dmiversionmin)
+                   (data[0x0F + 2 * i + 1] << 8 |
+                   data[0x0F + 2 * i]));
+ 
+-            newnode.setVendor(dmi_string(dm, data[4]));
+-            newnode.setProduct(dmi_string(dm, data[5]));
+-            newnode.setVersion(dmi_string(dm, data[6]));
+-            newnode.setSerial(dmi_string(dm, data[7]));
++            newnode.setVendor(dmi_string(dm, data[0x04]));
++            newnode.setProduct(dmi_string(dm, data[0x05]));
++            newnode.setVersion(dmi_string(dm, data[0x06]));
++            newnode.setSerial(dmi_string(dm, data[0x07]));
+             newnode.setSlot(dmi_string(dm, data[0x0A]));
+             newnode.setHandle(handle);
+             newnode.setPhysId(dm->handle);
+@@ -1102,14 +1125,14 @@ int dmiversionmin)
+ // special case: if the system characteristics are still unknown,
+ // use values from the chassis
+         if (node.getVendor() == "")
+-          node.setVendor(dmi_string(dm, data[4]));
++          node.setVendor(dmi_string(dm, data[0x04]));
+         if (node.getProduct() == "")
+-          node.setProduct(dmi_string(dm, data[5]));
++          node.setProduct(dmi_string(dm, data[0x05]));
+         if (node.getVersion() == "")
+-          node.setVersion(dmi_string(dm, data[6]));
++          node.setVersion(dmi_string(dm, data[0x06]));
+         if (node.getSerial() == "")
+-          node.setSerial(dmi_string(dm, data[7]));
+-        dmi_chassis(data[5] & 0x7F, node);
++          node.setSerial(dmi_string(dm, data[0x07]));
++        dmi_chassis(data[0x05] & 0x7F, node);
+         break;
+ 
+       case 4:
+@@ -1120,16 +1143,16 @@ int dmiversionmin)
+ 
+           newnode.claim();
+           newnode.setBusInfo(cpubusinfo(currentcpu++));
+-          newnode.setSlot(dmi_string(dm, data[4]));
++          newnode.setSlot(dmi_string(dm, data[0x04]));
+           newnode.setDescription(_("CPU"));
+           newnode.addHint("icon", string("cpu"));
+           if (dm->length >= 0x2A)
+             newnode.setProduct(dmi_processor_family(
+                 (((uint16_t) data[0x29]) << 8) + data[0x28]));
+           else
+-            newnode.setProduct(dmi_processor_family(data[6]));
++            newnode.setProduct(dmi_processor_family(data[0x06]));
+           newnode.setVersion(dmi_string(dm, data[0x10]));
+-          newnode.setVendor(dmi_string(dm, data[7]));
++          newnode.setVendor(dmi_string(dm, data[0x07]));
+           newnode.setPhysId(dm->handle);
+           if (dm->length > 0x1A)
+           {
+@@ -1177,15 +1200,30 @@ int dmiversionmin)
+           }
+ 
+           if (dm->length >= 0x28)
+-          { 
++          {
+             if (data[0x23] != 0)
+-		newnode.setConfig("cores", data[0x23]);
++            {
++              if (data[0x23] == 0xFF)
++                newnode.setConfig("cores", data[0x2B] << 8 | data[0x2A]);
++              else
++                newnode.setConfig("cores", data[0x23]);
++            }
+             if (data[0x24] != 0)
+-		newnode.setConfig("enabledcores", data[0x24]);
++            {
++              if (data[0x24] == 0xFF)
++                newnode.setConfig("enabledcores", data[0x2D] << 8 | data[0x2C]);
++              else
++                newnode.setConfig("enabledcores", data[0x24]);
++            }
+             if (data[0x25] != 0)
+-		newnode.setConfig("threads", data[0x25]);
++            {
++              if (data[0x25] == 0xFF)
++                newnode.setConfig("threads", data[0x2F] << 8 | data[0x2E]);
++              else
++                newnode.setConfig("threads", data[0x25]);
++            }
+             if (data[0x26] & 0x4)
+-		newnode.addCapability("lm", _("64-bit capable"));
++              newnode.addCapability("lm", _("64-bit capable"));
+           }
+ 
+           newnode.setHandle(handle);
+@@ -1207,7 +1245,7 @@ int dmiversionmin)
+           newnode.setHandle(handle);
+           newnode.setPhysId(dm->handle);
+ 
+-          size = data[0x0E] * (1 << data[8]) * 1024 * 1024;
++          size = data[0x0E] * (1 << data[0x08]) * 1024 * 1024;
+           newnode.setCapacity(size);
+ 
+ // loop through the controller's slots and link them to us
+@@ -1237,44 +1275,44 @@ int dmiversionmin)
+           unsigned long long size = 0;
+ 
+           newnode.setDescription(_("empty memory bank"));
+-          newnode.setSlot(dmi_string(dm, data[4]).c_str());
++          newnode.setSlot(dmi_string(dm, data[0x04]).c_str());
+           if (data[6])
+-            clock = 1000000000 / data[6];         // convert value from ns to Hz
++            clock = 1000000000 / data[0x06];         // convert value from ns to Hz
+           newnode.setClock(clock);
+-          newnode.setDescription(dmi_decode_ram(data[8] << 8 | data[7]));
++          newnode.setDescription(dmi_decode_ram(data[0x08] << 8 | data[0x07]));
+           newnode.addHint("icon", string("memory"));
+ // installed size
+-          switch (data[9] & 0x7F)
++          switch (data[0x09] & 0x7F)
+           {
+             case 0x7D:
+             case 0x7E:
+             case 0x7F:
+               break;
+             default:
+-              size = (1 << (data[9] & 0x7F)) << 20;
++              size = (1 << (data[0x09] & 0x7F)) << 20;
+           }
+-          if (data[9] & 0x80)
++          if (data[0x09] & 0x80)
+             size *= 2;
+ // enabled size
+-          switch (data[10] & 0x7F)
++          switch (data[0x0A] & 0x7F)
+           {
+             case 0x7D:
+             case 0x7E:
+             case 0x7F:
+               break;
+             default:
+-              capacity = (1 << (data[10] & 0x7F)) << 20;
++              capacity = (1 << (data[0x0A] & 0x7F)) << 20;
+           }
+-          if (data[10] & 0x80)
++          if (data[0x0A] & 0x80)
+             capacity *= 2;
+ 
+           newnode.setCapacity(capacity);
+           newnode.setSize(size);
+           if(newnode.getSize()==0)
+             newnode.setDescription(newnode.getDescription() + " " + _("[empty]"));
+-          if ((data[11] & 4) == 0)
++          if ((data[0x0B] & 4) == 0)
+           {
+-            if (data[11] & (1 << 0))
++            if (data[0x0B] & (1 << 0))
+ // bank has uncorrectable errors (BIOS disabled)
+               newnode.disable();
+           }
+@@ -1291,8 +1329,8 @@ int dmiversionmin)
+             hw::memory);
+ 	  int level;
+ 
+-          newnode.setSlot(dmi_string(dm, data[4]));
+-          u = data[6] << 8 | data[5];
++          newnode.setSlot(dmi_string(dm, data[0x04]));
++          u = data[0x06] << 8 | data[0x05];
+           level = 1 + (u & 7);
+ 
+           if (dm->length > 0x11)
+@@ -1305,11 +1343,19 @@ int dmiversionmin)
+             newnode.disable();
+ 
+           newnode.setConfig("level", level);
+-          newnode.setSize(dmi_cache_size(data[9] | data[10] << 8));
+-          newnode.setCapacity(dmi_cache_size(data[7] | (data[8] << 8)));
++          if ((data[0x08] << 8 | data[0x07]) == 0xFFFF)
++            newnode.setCapacity(dmi_cache_size_long(data[0x16] << 24 | data[0x15] << 16 | data[0x14] << 8 | data[0x13]));
++          else
++            newnode.setCapacity(dmi_cache_size(data[0x08] << 8 | data[0x07]));
++
++          if ((data[0x0A] << 8 | data[0x09]) == 0xFFFF)
++            newnode.setSize(dmi_cache_size_long(data[0x1A] << 24 | data[0x19] << 16 | data[0x18] << 8 | data[0x17]));
++          else
++            newnode.setSize(dmi_cache_size(data[0x0A] << 8 | data[0x09]));
++
+           if ((dm->length > 0x0F) && (data[0x0F] != 0))
+           {
+-                                                  // convert from ns to Hz
++            // convert from ns to Hz
+             newnode.setClock(1000000000 / data[0x0F]);
+           }
+ 
+@@ -1338,16 +1384,16 @@ int dmiversionmin)
+           hwNode newnode("cardslot",
+             hw::bus);
+           newnode.setHandle(handle);
+-          newnode.setSlot(dmi_string(dm, data[4]));
++          newnode.setSlot(dmi_string(dm, data[0x04]));
+           printf("\t\tType: %s%s%s\n",
+-            dmi_bus_width(data[6]),
+-            dmi_card_size(data[8]), dmi_bus_name(data[5]));
+-          if (data[7] == 3)
++            dmi_bus_width(data[0x06]),
++            dmi_card_size(data[0x08]), dmi_bus_name(data[0x05]));
++          if (data[0x07] == 3)
+             printf("\t\tStatus: Available.\n");
+-          if (data[7] == 4)
++          if (data[0x07] == 4)
+             printf("\t\tStatus: In use.\n");
+-          if (data[11] & 0xFE)
+-            dmi_card_props(data[11]);
++          if (data[0x0B] & 0xFE)
++            dmi_card_props(data[0x0B]);
+ //hardwarenode->addChild(newnode);
+         }
+ #endif
+@@ -1374,13 +1420,13 @@ int dmiversionmin)
+       case 13:
+ #if 0
+         printf("\tBIOS Language Information\n");
+-        printf("\t\tInstallable Languages: %u\n", data[4]);
+-        for (u = 1; u <= data[4]; u++)
++        printf("\t\tInstallable Languages: %u\n", data[0x04]);
++        for (u = 1; u <= data[0x04]; u++)
+         {
+           printf("\t\t\t%s\n", dmi_string(dm, u).c_str());
+         }
+         printf("\t\tCurrently Installed Language: %s\n",
+-          dmi_string(dm, data[21]).c_str());
++          dmi_string(dm, data[0x15]).c_str());
+ #endif
+         break;
+       case 14:
+@@ -1395,7 +1441,7 @@ int dmiversionmin)
+           string id = "memory";
+           string description = "";
+           bool claim = false, memory_icon = false;
+-          switch (data[5])
++          switch (data[0x05])
+           {
+             case 0x03:
+               description = _("System Memory");
+@@ -1433,12 +1433,12 @@ int dmiversionrev)
+           newnode.setHandle(handle);
+           newnode.setPhysId(dm->handle);
+           newnode.setDescription(description);
+-          newnode.setSlot(dmi_memory_array_location(data[4]));
++          newnode.setSlot(dmi_memory_array_location(data[0x04]));
+           if (memory_icon)
+             newnode.addHint("icon", string("memory"));
+           if (claim)
+             newnode.claim();
+-          switch (data[6])
++          switch (data[0x06])
+           {
+             case 0x04:
+               newnode.addCapability("parity", _("Parity error correction"));
+@@ -1457,7 +1503,7 @@ int dmiversionmin)
+               newnode.setConfig("errordetection", "crc");
+               break;
+           }
+-          u2 = data[10] << 24 | data[9] << 16 | data[8] << 8 | data[7];
++          u2 = data[0x0A] << 24 | data[0x09] << 16 | data[0x08] << 8 | data[0x07];
+           if (u2 != 0x80000000)                   // magic value for "unknown"
+             newnode.setCapacity(u2 * 1024);
+           else if (dm->length >= 0x17)
+@@ -1489,15 +1535,15 @@ int dmiversionmin)
+           string arrayhandle;
+           newnode.setDescription(_("empty memory bank"));
+           newnode.addHint("icon", string("memory"));
+-          arrayhandle = dmi_handle(data[5] << 8 | data[4]);
++          arrayhandle = dmi_handle(data[0x05] << 8 | data[0x04]);
+           strcpy(bits, "");
+ // total width
+-          u = data[9] << 8 | data[8];
+-          if (u != 0xffff)
++          u = data[0x09] << 8 | data[0x08];
++          if (u != 0xFFFF)
+             width = u;
+ //data width
+-          u = data[11] << 8 | data[10];
+-          if ((u != 0xffff) && (u != 0))
++          u = data[0x0B] << 8 | data[0x0A];
++          if ((u != 0xFFFF) && (u != 0))
+           {
+             if ((u == width) || (width == 0))
+             {
+@@ -1520,26 +1566,26 @@ int dmiversionmin)
+           }
+ 
+ // size
+-          u = data[13] << 8 | data[12];
+-          if(u == 0x7fff) {
+-             unsigned long long extendsize = (data[0x1f] << 24) | (data[0x1e] << 16) | (data[0x1d] << 8) | data[0x1c];
+-             extendsize &= 0x7fffffffUL;
++          u = data[0x0D] << 8 | data[0x0C];
++          if(u == 0x7FFF) {
++             unsigned long long extendsize = (data[0x1F] << 24) | (data[0x1E] << 16) | (data[0x1D] << 8) | data[0x1C];
++             extendsize &= 0x7FFFFFFFUL;
+              size = extendsize * 1024ULL * 1024ULL;
+           }
+ 	  else
+-          if (u != 0xffff)
+-            size = (1024ULL * (u & 0x7fff) * ((u & 0x8000) ? 1 : 1024ULL));
+-          description += string(dmi_memory_device_form_factor(data[14]));
+-          slot = dmi_string(dm, data[16]);
+-//printf("\t\tBank Locator: %s\n", dmi_string(dm, data[17]));
+-          description += string(dmi_memory_device_type(data[18]));
+-          u = data[20] << 8 | data[19];
+-          if (u & 0x1ffe)
++          if (u != 0xFFFF)
++            size = (1024ULL * (u & 0x7FFF) * ((u & 0x8000) ? 1 : 1024ULL));
++          description += string(dmi_memory_device_form_factor(data[0x0E]));
++          slot = dmi_string(dm, data[0x10]);
++//printf("\t\tBank Locator: %s\n", dmi_string(dm, data[0x11]));
++          description += string(dmi_memory_device_type(data[0x12]));
++          u = data[0x14] << 8 | data[0x13];
++          if (u & 0x1FFE)
+             description += dmi_memory_device_detail(u);
+-          if (dm->length > 21)
++          if (dm->length > 0x15)
+           {
+             char buffer[80];
+-            u = data[22] << 8 | data[21];
++            u = data[0x16] << 8 | data[0x15];
+ // speed
+             clock = u * 1000000;                  // u is a frequency in MHz
+             if (u == 0)
+@@ -1553,12 +1599,12 @@ int dmiversionmin)
+           newnode.setHandle(handle);
+ //newnode.setPhysId(dm->handle);
+           newnode.setSlot(slot);
+-          if (dm->length > 23)
+-            newnode.setVendor(dmi_string(dm, data[23]));
+-          if (dm->length > 24)
+-            newnode.setSerial(dmi_string(dm, data[24]));
+-          if (dm->length > 26)
+-            newnode.setProduct(dmi_string(dm, data[26]));
++          if (dm->length > 0x17)
++            newnode.setVendor(dmi_string(dm, data[0x17]));
++          if (dm->length > 0x18)
++            newnode.setSerial(dmi_string(dm, data[0x18]));
++          if (dm->length > 0x1A)
++            newnode.setProduct(dmi_string(dm, data[0x1A]));
+           newnode.setDescription(description);
+           newnode.setSize(size);
+           if(newnode.getSize()==0)
+@@ -1586,10 +1632,20 @@ int dmiversionmin)
+         {
+           hwNode newnode("range",
+             hw::address);
+-          unsigned long start, end;
++          uint64_t start = 0, end = 0;
+           string arrayhandle = dmi_handle(data[0x0D] << 8 | data[0x0C]);
+-          start = ((data[4] | data[5] << 8) | (data[6] | data[7] << 8) << 16);
+-          end = ((data[8] | data[9] << 8) | (data[10] | data[11] << 8) << 16);
++          start = data[0x07] << 24 | data[0x06] << 16 | data[0x05] << 8 | data[0x04];
++          if (start == 0xFFFFFFFF)
++            start = uint64_t(data[0x16]) << 56 | uint64_t(data[0x15]) << 48 |
++                    uint64_t(data[0x14]) << 40 | uint64_t(data[0x13]) << 32 |
++                    uint64_t(data[0x12]) << 24 | uint64_t(data[0x11]) << 16 |
++                    uint64_t(data[0x10]) << 8 | uint64_t(data[0x0F]);
++          end = data[0x0B] << 24 | data[0x0A] << 16 | data[0x09] << 8 | data[0x08];
++          if (end == 0xFFFFFFFF)
++            end = uint64_t(data[0x1E]) << 56 | uint64_t(data[0x1D]) << 48 |
++                    uint64_t(data[0x1C]) << 40 | uint64_t(data[0x1B]) << 32 |
++                    uint64_t(data[0x1A]) << 24 | uint64_t(data[0x19]) << 16 |
++                    uint64_t(data[0x18]) << 8 | uint64_t(data[0x17]);
+           if (end - start < 512)                  // memory range is smaller thant 512KB
+           {
+ // consider that values were expressed in megagytes
+@@ -1614,10 +1670,20 @@ int dmiversionmin)
+         {
+           hwNode newnode("range",
+             hw::address);
+-          unsigned long start, end;
++          unsigned long long start = 0, end = 0;
+           string devicehandle = dmi_handle(data[0x0D] << 8 | data[0x0C]);
+-          start = ((data[4] | data[5] << 8) | (data[6] | data[7] << 8) << 16);
+-          end = ((data[8] | data[9] << 8) | (data[10] | data[11] << 8) << 16);
++          start = data[0x07] << 24 | data[0x06] << 16 | data[0x05] << 8 | data[0x04];
++          if (start == 0xFFFFFFFF)
++            start = uint64_t(data[0x16]) << 56 | uint64_t(data[0x15]) << 48 |
++                    uint64_t(data[0x14]) << 40 | uint64_t(data[0x13]) << 32 |
++                    uint64_t(data[0x12]) << 24 | uint64_t(data[0x11]) << 16 |
++                    uint64_t(data[0x10]) << 8 | uint64_t(data[0x0F]);
++          end = data[0x0B] << 24 | data[0x0A] << 16 | data[0x09] << 8 | data[0x08];
++          if (end == 0xFFFFFFFF)
++            end = uint64_t(data[0x1E]) << 56 | uint64_t(data[0x1D]) << 48 |
++                    uint64_t(data[0x1C]) << 40 | uint64_t(data[0x1B]) << 32 |
++                    uint64_t(data[0x1A]) << 24 | uint64_t(data[0x19]) << 16 |
++                    uint64_t(data[0x18]) << 8 | uint64_t(data[0x17]);
+           if (end - start < 512)                  // memory range is smaller than 512KB
+           {
+ // consider that values were expressed in megagytes
+@@ -1661,11 +1727,11 @@ int dmiversionmin)
+             batt.setVersion(dmi_string(dm, data[0x06]));
+           if(data[0x07] || dm->length<0x1A)
+             batt.setSerial(dmi_string(dm, data[0x07]));
+-          batt.setConfig("voltage", dmi_battery_voltage(data[0x0c] + 256*data[0x0d]));
++          batt.setConfig("voltage", dmi_battery_voltage(data[0x0C] + 256*data[0x0D]));
+           if(dm->length<0x1A)
+-            batt.setCapacity(dmi_battery_capacity(data[0x0a] + 256*data[0x0b], 1));
++            batt.setCapacity(dmi_battery_capacity(data[0x0A] + 256*data[0x0B], 1));
+           else
+-            batt.setCapacity(dmi_battery_capacity(data[0x0a] + 256*data[0x0b], data[0x15]));
++            batt.setCapacity(dmi_battery_capacity(data[0x0A] + 256*data[0x0B], data[0x15]));
+           if(data[0x09]!=0x02 || dm->length<0x1A)
+             batt.setDescription(hw::strip(string(dmi_battery_chemistry(data[0x09])) + " Battery"));
+ 
+@@ -1724,7 +1790,7 @@ int dmiversionmin)
+ // System Boot Information
+         if (dm->length < 0x0B)
+           break;
+-        node.setConfig("boot", dmi_bootinfo(data[0x0a]));
++        node.setConfig("boot", dmi_bootinfo(data[0x0A]));
+         break;
+       case 33:
+ // 64-bit Memory Error Information
+@@ -1755,9 +1821,9 @@ int dmiversionmin)
+           power.setDescription(dmi_string(dm, data[0x06]));
+           power.setVendor(dmi_string(dm, data[0x07]));
+           power.setSerial(dmi_string(dm, data[0x08]));
+-          power.setProduct(dmi_string(dm, data[0x0a]));
+-          power.setVersion(dmi_string(dm, data[0x0b]));
+-          power.setCapacity(data[0x0c] + 256*data[0x0d]);
++          power.setProduct(dmi_string(dm, data[0x0A]));
++          power.setVersion(dmi_string(dm, data[0x0B]));
++          power.setCapacity(data[0x0C] + 256*data[0x0D]);
+           node.addChild(power);
+         }
+         break;
+@@ -1780,17 +1846,19 @@ int dmiversionmin)
+ 
+ 
+ static bool smbios_entry_point(const u8 *buf, size_t len,
+-    hwNode & n, u16 & dmimaj, u16 & dmimin,
++    hwNode & n, u16 & dmimaj, u16 & dmimin, u16 & dmirev,
+     uint32_t & table_len, uint64_t & table_base)
+ {
+   u8 smmajver = 0;
+   u8 smminver = 0;
++  u8 smdocrev = 0;
+ 
+   if (len >= 24 && memcmp(buf, "_SM3_", 5) == 0 && checksum(buf, buf[6]))
+   {
+     // SMBIOS 3.0 entry point structure (64-bit)
+     dmimaj = smmajver = buf[7];
+     dmimin = smminver = buf[8];
++    dmirev = smdocrev = buf[9];
+     table_len = (((uint32_t) buf[15]) << 24) +
+                 (((uint32_t) buf[14]) << 16) +
+                 (((uint32_t) buf[13]) << 8) +
+@@ -1823,9 +1891,16 @@ static bool smbios_entry_point(const u8 *buf, size_t len,
+   if (smmajver > 0)
+   {
+     char buffer[20];
+-    snprintf(buffer, sizeof(buffer), "%d.%d", smmajver, smminver);
++    if (smmajver == 3)
++      snprintf(buffer, sizeof(buffer), "%d.%d.%d", smmajver, smminver, smdocrev);
++    else
++      snprintf(buffer, sizeof(buffer), "%d.%d", smmajver, smminver);
+     n.addCapability("smbios-"+string(buffer), "SMBIOS version "+string(buffer));
+-    snprintf(buffer, sizeof(buffer), "%d.%d", dmimaj, dmimin);
++
++    if (dmimaj == 3)
++      snprintf(buffer, sizeof(buffer), "%d.%d.%d", dmimaj, dmimin, dmirev);
++    else
++      snprintf(buffer, sizeof(buffer), "%d.%d", dmimaj, dmimin);
+     n.addCapability("dmi-"+string(buffer), "DMI version "+string(buffer));
+ 
+     return true;
+@@ -1842,7 +1917,7 @@ static bool scan_dmi_sysfs(hwNode & n)
+ 
+   uint32_t table_len = 0;
+   uint64_t table_base = 0;
+-  u16 dmimaj = 0, dmimin = 0;
++  u16 dmimaj = 0, dmimin = 0, dmirev = 0;
+ 
+   ifstream ep_stream(SYSFSDMI "/smbios_entry_point",
+       ifstream::in | ifstream::binary | ifstream::ate);
+@@ -1853,7 +1938,7 @@ static bool scan_dmi_sysfs(hwNode & n)
+   if (!ep_stream)
+     return false;
+   if (!smbios_entry_point(ep_buf.data(), ep_len, n,
+-        dmimaj, dmimin, table_len, table_base))
++        dmimaj, dmimin, dmirev, table_len, table_base))
+     return false;
+ 
+   ifstream dmi_stream(SYSFSDMI "/DMI",
+@@ -1864,7 +1939,7 @@ static bool scan_dmi_sysfs(hwNode & n)
+   dmi_stream.read((char *)dmi_buf.data(), dmi_len);
+   if (!dmi_stream)
+     return false;
+-  dmi_table(dmi_buf.data(), dmi_len, n, dmimaj, dmimin);
++  dmi_table(dmi_buf.data(), dmi_len, n, dmimaj, dmimin, dmirev);
+ 
+   return true;
+ }
+@@ -1902,7 +1977,7 @@ static bool scan_dmi_devmem(hwNode & n)
+   u32 mmoffset = 0;
+   void *mmp = NULL;
+   bool efi = true;
+-  u16 dmimaj = 0, dmimin = 0;
++  u16 dmimaj = 0, dmimin = 0, dmirev = 0;
+ 
+   if (fd == -1)
+     return false;
+@@ -1932,7 +2007,7 @@ static bool scan_dmi_devmem(hwNode & n)
+     }
+     uint32_t len;
+     uint64_t base;
+-    if (smbios_entry_point(buf, sizeof(buf), n, dmimaj, dmimin, len, base))
++    if (smbios_entry_point(buf, sizeof(buf), n, dmimaj, dmimin, dmirev, len, base))
+     {
+       u8 *dmi_buf = (u8 *)malloc(len);
+       mmoffset = base % getpagesize();
+@@ -1944,7 +2019,7 @@ static bool scan_dmi_devmem(hwNode & n)
+       }
+       memcpy(dmi_buf, (u8 *) mmp + mmoffset, len);
+       munmap(mmp, mmoffset + len);
+-      dmi_table(dmi_buf, len, n, dmimaj, dmimin);
++      dmi_table(dmi_buf, len, n, dmimaj, dmimin, dmirev);
+       free(dmi_buf);
+       break;
+     }
+diff --git a/src/core/pci.cc b/src/core/pci.cc
+index d1625cf..fa6a1e5 100644
+--- a/src/core/pci.cc
++++ b/src/core/pci.cc
+@@ -774,8 +774,12 @@ static hwNode *scan_pci_dev(struct pci_dev &d, hwNode & n)
+   if(!pcidb_loaded)
+     pcidb_loaded = load_pcidb();
+ 
+-      d.vendor_id = get_conf_word(d, PCI_VENDOR_ID);
+-      d.device_id = get_conf_word(d, PCI_DEVICE_ID);
++      u_int16_t tmp_vendor_id = get_conf_word(d, PCI_VENDOR_ID);
++      u_int16_t tmp_device_id = get_conf_word(d, PCI_DEVICE_ID);
++      if ((tmp_vendor_id & tmp_device_id) != 0xffff) {
++        d.vendor_id = tmp_vendor_id;
++        d.device_id = tmp_device_id;
++      }
+       u_int16_t dclass = get_conf_word(d, PCI_CLASS_DEVICE);
+       u_int16_t cmd = get_conf_word(d, PCI_COMMAND);
+       u_int16_t status = get_conf_word(d, PCI_STATUS);
+@@ -1122,6 +1126,7 @@ bool scan_pci(hwNode & n)
+     if(matches(devices[i]->d_name, "^[[:xdigit:]]+:[[:xdigit:]]+:[[:xdigit:]]+\\.[[:xdigit:]]+$"))
+     {
+       string devicepath = string(devices[i]->d_name)+"/config";
++      sysfs::entry device_entry = sysfs::entry::byBus("pci", devices[i]->d_name);
+       struct pci_dev d;
+       int fd = open(devicepath.c_str(), O_RDONLY);
+       if (fd >= 0)
+@@ -1136,6 +1141,8 @@ bool scan_pci(hwNode & n)
+       }
+ 
+       sscanf(devices[i]->d_name, "%hx:%hx:%hhx.%hhx", &d.domain, &d.bus, &d.dev, &d.func);
++      sscanf(device_entry.vendor().c_str(), "%hx", &d.vendor_id);
++      sscanf(device_entry.device().c_str(), "%hx", &d.device_id);
+       hwNode *device = scan_pci_dev(d, n);
+ 
+       if(device)
+@@ -1166,7 +1173,7 @@ bool scan_pci(hwNode & n)
+           device->claim();
+         }
+ 
+-	device->setModalias(sysfs::entry::byBus("pci", devices[i]->d_name).modalias());
++        device->setModalias(device_entry.modalias());
+ 
+         if(exists(resourcename))
+         {
+diff --git a/src/core/sysfs.cc b/src/core/sysfs.cc
+index 97dbab5..486f8ee 100644
+--- a/src/core/sysfs.cc
++++ b/src/core/sysfs.cc
+@@ -358,6 +358,16 @@ string entry::modalias() const
+   return get_string(This->devpath+"/modalias");
+ }
+ 
++string entry::device() const
++{
++  return get_string(This->devpath+"/device");
++}
++
++string entry::vendor() const
++{
++  return get_string(This->devpath+"/vendor");
++}
++
+ vector < entry > sysfs::entries_by_bus(const string & busname)
+ {
+   vector < entry > result;
+diff --git a/src/core/sysfs.h b/src/core/sysfs.h
+index d37e2d4..dffa4b2 100644
+--- a/src/core/sysfs.h
++++ b/src/core/sysfs.h
+@@ -26,6 +26,8 @@ namespace sysfs
+       string businfo() const;
+       string driver() const;
+       string modalias() const;
++      string device() const;
++      string vendor() const;
+       entry parent() const;
+       string name_in_class(const string &) const;
+       string string_attr(const string & name, const string & def = "") const;
+-- 
+2.14.0
+
diff --git a/SOURCES/0002-devtree-Revert-vendor-property-for-Power-System.patch b/SOURCES/0002-devtree-Revert-vendor-property-for-Power-System.patch
new file mode 100644
index 0000000..ba46623
--- /dev/null
+++ b/SOURCES/0002-devtree-Revert-vendor-property-for-Power-System.patch
@@ -0,0 +1,34 @@
+From 26f621009875f3bf1312d64750734420cdd1de03 Mon Sep 17 00:00:00 2001
+From: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
+Date: Tue, 16 Jan 2018 15:29:36 +0530
+Subject: [PATCH 2/5] devtree: Revert "vendor" property for Power System
+
+Commit f95aa917 removed vendor property for Power System PowerNV platform.
+We have "/vendor" property in device tree which gives Vendor name.
+
+Hence revert changes. Note that this only reverts "vendor" property for
+particular platform and no side effect on other platform.
+
+Fixes: f95aa917 (merge patches from beaker-fork)
+CC: Lyonel Vincent <lyonel@ezix.org>
+Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
+---
+ src/core/device-tree.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/src/core/device-tree.cc b/src/core/device-tree.cc
+index e14a3b3..2981130 100644
+--- a/src/core/device-tree.cc
++++ b/src/core/device-tree.cc
+@@ -1432,6 +1432,8 @@ bool scan_device_tree(hwNode & n)
+   get_ibm_model(n);
+   if (matches(get_string(DEVICETREE "/compatible"), "^ibm,powernv"))
+   {
++    n.setVendor(get_string(DEVICETREE "/vendor", "IBM"));
++
+     if (exists(DEVICETREE "/model-name"))
+       n.setProduct(n.getProduct() + " (" +
+ 		   hw::strip(get_string(DEVICETREE "/model-name")) + ")");
+-- 
+1.8.3.1
+
diff --git a/SOURCES/0003-devtree-Parse-spd-data.patch b/SOURCES/0003-devtree-Parse-spd-data.patch
new file mode 100644
index 0000000..11115fa
--- /dev/null
+++ b/SOURCES/0003-devtree-Parse-spd-data.patch
@@ -0,0 +1,32 @@
+From 06229e401aa0cd2c525f9af616b9bb95c2dd7abf Mon Sep 17 00:00:00 2001
+From: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
+Date: Tue, 22 Aug 2017 22:08:43 +0530
+Subject: [PATCH 3/5] devtree: Parse spd data
+
+In some Power system (like P9 system), spd data is available under
+ms-dimm node in device tree. Hence call add_memory_bank_spd() from
+ms-dimm section as well.
+
+Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
+---
+ src/core/device-tree.cc | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/src/core/device-tree.cc b/src/core/device-tree.cc
+index 2981130..6bcc52d 100644
+--- a/src/core/device-tree.cc
++++ b/src/core/device-tree.cc
+@@ -1086,6 +1086,10 @@ static void add_memory_bank(string name, string path, hwNode & core)
+     if (size > 0)
+       bank.setSize(size);
+ 
++    // Parse Memory SPD data
++    if (exists("spd"))
++      add_memory_bank_spd(path + "/" + name + "/spd", bank);
++
+     memory->addChild(bank);
+   } else if(name.substr(0, 4) == "dimm") {
+     hwNode bank("bank", hw::memory);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/0004-cpuinfo-Do-not-enable-cpu-node-on-IBM-Power-System.patch b/SOURCES/0004-cpuinfo-Do-not-enable-cpu-node-on-IBM-Power-System.patch
new file mode 100644
index 0000000..8bf0743
--- /dev/null
+++ b/SOURCES/0004-cpuinfo-Do-not-enable-cpu-node-on-IBM-Power-System.patch
@@ -0,0 +1,32 @@
+From 5438d15e79fdbd3c0ad9e156a850d964d257201c Mon Sep 17 00:00:00 2001
+From: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
+Date: Tue, 22 Aug 2017 20:58:11 +0530
+Subject: [PATCH 4/5] cpuinfo: Do not enable cpu node on IBM Power System
+
+On IBM Power System device tree parsing code detects CPU state
+and sets enable flag properly. Hence do not call enable() from
+cpuinfo code.
+
+Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
+---
+ src/core/cpuinfo.cc | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/src/core/cpuinfo.cc b/src/core/cpuinfo.cc
+index 9628ab3..2cf8eae 100644
+--- a/src/core/cpuinfo.cc
++++ b/src/core/cpuinfo.cc
+@@ -36,7 +36,9 @@ int n = 0)
+   {
+     cpu->addHint("icon", string("cpu"));
+     cpu->claim(true);                             // claim the cpu and all its children
+-    cpu->enable();                                // enable it
++    if (!is_system_ppc_ibm(node))
++      cpu->enable();                                // enable it
++
+     return cpu;
+   }
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/0005-devtree-Add-vendor-field-for-cpu-node.patch b/SOURCES/0005-devtree-Add-vendor-field-for-cpu-node.patch
new file mode 100644
index 0000000..3ae9d24
--- /dev/null
+++ b/SOURCES/0005-devtree-Add-vendor-field-for-cpu-node.patch
@@ -0,0 +1,46 @@
+From aba767384ea79e3b9e4bcfced7c0e2cb0234963f Mon Sep 17 00:00:00 2001
+From: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
+Date: Tue, 16 Jan 2018 16:11:53 +0530
+Subject: [PATCH 5/5] devtree: Add vendor field for cpu node
+
+Device tree provides 'vendor' property for cpu nodes. Use that to
+populate cpu vendor field
+
+Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
+---
+ src/core/device-tree.cc | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/src/core/device-tree.cc b/src/core/device-tree.cc
+index 6bcc52d..0e7f399 100644
+--- a/src/core/device-tree.cc
++++ b/src/core/device-tree.cc
+@@ -459,6 +459,7 @@ struct chip_vpd_data
+   string product;
+   string serial;
+   string slot;
++  string vendor;
+ };
+ 
+ 
+@@ -486,6 +487,9 @@ static void add_chip_vpd(string path, string name,
+       if (exists("part-number"))
+         data->product = hw::strip(get_string("part-number"));
+ 
++      if (exists("vendor"))
++        data->vendor = hw::strip(get_string("vendor"));
++
+       if (exists("fru-number"))
+         data->product += " FRU# " + hw::strip(get_string("fru-number"));
+ 
+@@ -554,6 +558,7 @@ static void fill_core_vpd(hwNode & cpu, string & basepath,
+     cpu.setProduct(data->product);
+     cpu.setSerial(data->serial);
+     cpu.setSlot(data->slot);
++    cpu.setVendor(data->vendor);
+   }
+ 
+   if (xscom_path != "")
+-- 
+1.8.3.1
+
diff --git a/SPECS/lshw.spec b/SPECS/lshw.spec
index 31c8da8..c3d0ae2 100644
--- a/SPECS/lshw.spec
+++ b/SPECS/lshw.spec
@@ -1,7 +1,7 @@
 Summary:       HardWare LiSter
 Name:          lshw
 Version:       B.02.18
-Release:       7%{?dist}
+Release:       12%{?dist}
 License:       GPLv2
 Group:         Applications/System
 URL:           http://ezix.org/project/wiki/HardwareLiSter
@@ -72,11 +72,17 @@ Patch59:       0022-dmi-x86-64-is-a-misnomer-for-64-bit-CPU-capability-6.patch
 Patch60:       0023-dmi-avoid-creating-multiple-memory-nodes-700.patch
 Patch61:       0025-scsi-initialize-parent-inside-the-loop-692.patch
 Patch62:       0026-sysfs-businfo-for-USB-devices-692.patch
-Patch63:       0001-lshw-Parse-OPAL-firmware-properties-from-the-device-.patch
 Patch64:       0001-Add-a-new-element-vendor_id.patch
 Patch65:       0001-Revert-better-handling-of-whole-disk-volumes.patch
-Patch66:       0001-Proper-detect-vendor_id-device_id-for-virtual-functi.patch
+Patch66:       0001-merge-Petr-Oros-pull-request.patch
 Patch67:       0001-Show-right-version-number.patch
+Patch68:       0001-Escape-special-characters-in-html-output.patch
+Patch69:       0001-cpuinfo-Fix-compiler-warnings-in-cpuinfo-code.patch
+Patch70:       0001-devtree-Check-status-property-for-caches.patch
+Patch71:       0002-devtree-Revert-vendor-property-for-Power-System.patch
+Patch72:       0003-devtree-Parse-spd-data.patch
+Patch73:       0004-cpuinfo-Do-not-enable-cpu-node-on-IBM-Power-System.patch
+Patch74:       0005-devtree-Add-vendor-field-for-cpu-node.patch
 
 BuildRequires: sqlite-devel
 Requires:      hwdata
@@ -182,11 +188,17 @@ http://lshw.ezix.org/
 %patch60 -p1
 %patch61 -p1
 %patch62 -p1
-%patch63 -p1
 %patch64 -p1
 %patch65 -p1
 %patch66 -p1
 %patch67 -p1
+%patch68 -p1
+%patch69 -p1
+%patch70 -p1
+%patch71 -p1
+%patch72 -p1
+%patch73 -p1
+%patch74 -p1
 
 %build
 make %{?_smp_mflags} SBINDIR="%{_sbindir}" RPM_OPT_FLAGS="%{optflags}" SQLITE=1 gui
@@ -256,6 +268,28 @@ rm -rf %{buildroot}%{_datadir}/locale/fr/
 %{_datadir}/polkit-1/actions/org.ezix.lshw.gui.policy
 
 %changelog
+* Thu Feb 08 2018 Petr Oros <poros@redhat.com> - B.02.18-12
+- Put back Add parsed firmware version info patch
+- Resolves: #1536391
+
+* Wed Jan 31 2018 Petr Oros <poros@redhat.com> - B.02.18-11
+- Add fixes for POWER9 support
+- Resolves: #1537484
+
+* Wed Sep 13 2017 Petr Oros <poros@redhat.com> - B.02.18-10
+- Fix Petitboot System Information output
+- Fix compiler warnings
+- Resolves: #1536391
+
+* Mon Aug 21 2017 Petr Oros <poros@redhat.com> - B.02.18-9
+- Escape special characters in html output
+- Resolves: #1446765
+
+* Mon Aug 7 2017 Petr Oros <poros@redhat.com> - B.02.18-8
+- Proper detect vendor_id/device_id for virtual functions
+- Sync SMBIOS with latest specification
+- Resolves: #1445473
+
 * Tue May 16 2017 Petr Oros <poros@redhat.com> - B.02.18-7
 - Revert Fix JSON output format
 - Show right version number