Index: lshw-02.17/src/core/dmi.cc
===================================================================
--- lshw-02.17.orig/src/core/dmi.cc	2014-10-31 17:15:12.774047555 +0000
+++ lshw-02.17/src/core/dmi.cc	2014-10-31 17:17:08.832295909 +0000
@@ -1717,9 +1717,56 @@
 }
 
 
-long get_efi_systab_smbios()
+struct dmi_info {
+  u8 smmajver;
+  u8 smminver;
+  u16 dmimaj;
+  u16 dmimin;
+};
+
+
+static bool parse_dmi_header(u32 addr, int fd, hwNode & n, struct dmi_info *dmi)
+{
+  unsigned char buf[20];
+  u32 mmoffset = 0;
+  void *mmp = NULL;
+
+  mmoffset = addr % getpagesize();
+  mmp = mmap(0, mmoffset + 0x20, PROT_READ, MAP_SHARED, fd, addr - mmoffset);
+  memset(buf, 0, sizeof(buf));
+  if (mmp != MAP_FAILED)
+  {
+    memcpy(buf, (u8 *) mmp + mmoffset, sizeof(buf));
+    munmap(mmp, mmoffset + 0x20);
+  }
+  if (mmp == MAP_FAILED)
+  {
+    return false;
+  }
+  else if (memcmp(buf, "_SM_", 4) == 0)
+  {
+    // SMBIOS
+    dmi->smmajver = buf[6];
+    dmi->smminver = buf[7];
+  }
+  else if (dmi->smmajver && (memcmp(buf, "_DMI_", 5) == 0)
+           && checksum(buf, 0x0F))
+  {
+    u16 num = buf[13] << 8 | buf[12];
+    u16 len = buf[7] << 8 | buf[6];
+    u32 base = buf[11] << 24 | buf[10] << 16 | buf[9] << 8 | buf[8];
+    dmi->dmimaj = buf[14] ? buf[14] >> 4 : dmi->smmajver;
+    dmi->dmimin = buf[14] ? buf[14] & 0x0F : dmi->smminver;
+    dmi_table(fd, base, len, num, n, dmi->dmimaj, dmi->dmimin);
+  }
+
+  return true;
+}
+
+
+u32 get_efi_systab_smbios()
 {
-  long result = 0;
+  u32 result = 0;
   vector < string > sysvars;
 
   if (loadfile("/sys/firmware/efi/systab", sysvars) || loadfile("/proc/efi/systab", sysvars))
@@ -1731,7 +1778,8 @@
 
     if ((variable[0] == "SMBIOS") && (variable.size() == 2))
     {
-      sscanf(variable[1].c_str(), "%lx", &result);
+      sscanf(variable[1].c_str(), "%x", &result);
+      break;
     }
   }
 
@@ -1741,20 +1789,11 @@
 
 bool scan_dmi(hwNode & n)
 {
-  unsigned char buf[20];
-  int fd = open("/dev/mem",
-    O_RDONLY);
-  long fp = get_efi_systab_smbios();
-  u32 mmoffset = 0;
-  void *mmp = NULL;
-  bool efi = true;
-  u8 smmajver = 0, smminver = 0;
-  u16 dmimaj = 0, dmimin = 0;
+  int fd = open("/dev/mem", O_RDONLY);
+  u32 fp = get_efi_systab_smbios();
+  struct dmi_info dmi = {0, 0, 0, 0};
   currentcpu = 0;
-
-#if defined(__arm__) || defined (__hppa__) 
-  return false;		// SMBIOS not supported on PA-RISC and ARM machines
-#endif
+  bool ret = false;
 
   if (sizeof(u8) != 1 || sizeof(u16) != 2 || sizeof(u32) != 4)
 // compiler incompatibility
@@ -1762,61 +1801,40 @@
   if (fd == -1)
     return false;
 
-  if (fp <= 0)
+  if (fp != 0)
   {
-    efi = false;
-    fp = 0xE0000L;                                /* default value for non-EFI capable platforms */
+    ret = parse_dmi_header(fp, fd, n, &dmi);
   }
-
-  fp -= 16;
-  while (efi || (fp < 0xFFFE0))
+  else
   {
-    fp += 16;
-    mmoffset = fp % getpagesize();
-    mmp = mmap(0, mmoffset + 0x20, PROT_READ, MAP_SHARED, fd, fp - mmoffset);
-    memset(buf, 0, sizeof(buf));
-    if (mmp != MAP_FAILED)
-    {
-      memcpy(buf, (u8 *) mmp + mmoffset, sizeof(buf));
-      munmap(mmp, mmoffset + 0x20);
-    }
-    if (mmp == MAP_FAILED)
+#if defined(__i386__) || defined (__x86_64__)
+    // 0xF0000-0xFFFF0 is the search tange for non-(U)EFI platforms,
+    for (fp = 0xF0000L; fp <= 0xFFFF0 ; fp +=0x10)
     {
-      close(fd);
-      return false;
-    }
-    else if (memcmp(buf, "_SM_", 4) == 0)
-    {
-// SMBIOS
-      smmajver = buf[6];
-      smminver = buf[7];
-    }
-    else if (smmajver && (memcmp(buf, "_DMI_", 5) == 0) && checksum(buf, 0x0F))
-    {
-      u16 num = buf[13] << 8 | buf[12];
-      u16 len = buf[7] << 8 | buf[6];
-      u32 base = buf[11] << 24 | buf[10] << 16 | buf[9] << 8 | buf[8];
-      dmimaj = buf[14] ? buf[14] >> 4 : smmajver;
-      dmimin = buf[14] ? buf[14] & 0x0F : smminver;
-      dmi_table(fd, base, len, num, n, dmimaj, dmimin);
-
-      if (efi)
-        break;                                    // we don't need to search the memory for EFI systems
+      ret = parse_dmi_header(fp, fd, n, &dmi);
+      if (dmi.smmajver + dmi.dmimaj != 0)
+        break;
     }
+#else // ! (defined(__i386__) || defined (__x86_64__))
+    // Only x86 platforms can scan memory for table
+    ret = false;
+#endif
   }
+
   close(fd);
-  if (smmajver != 0)
+
+  if (dmi.smmajver != 0)
   {
     char buffer[20];
-    snprintf(buffer, sizeof(buffer), "%d.%d", smmajver, smminver);
+    snprintf(buffer, sizeof(buffer), "%d.%d", dmi.smmajver, dmi.smminver);
     n.addCapability("smbios-"+string(buffer), "SMBIOS version "+string(buffer));
   }
-  if (dmimaj != 0)
+  if (dmi.dmimaj != 0)
   {
     char buffer[20];
-    snprintf(buffer, sizeof(buffer), "%d.%d", dmimaj, dmimin);
+    snprintf(buffer, sizeof(buffer), "%d.%d", dmi.dmimaj, dmi.dmimin);
     n.addCapability("dmi-"+string(buffer), "DMI version "+string(buffer));
   }
 
-  return true;
+  return ret;
 }
