Blob Blame History Raw
From 2c84941819da11626ecaee1d2a10abc852cfff3d Mon Sep 17 00:00:00 2001
From: Lyonel Vincent <lyonel@ezix.org>
Date: Sat, 9 May 2015 10:18:17 +0000
Subject: [PATCH 1/1] update PowerPC device-tree memory detection (cf. #686)

git-svn-id: http://ezix.org/source/packages/lshw/development@2576 811e2811-9fd9-0310-a116-b6e8ac943c8b
---
 src/core/device-tree.cc | 90 ++++++++++++++++++++++++++++++++++---------------
 1 file changed, 63 insertions(+), 27 deletions(-)

diff --git a/src/core/device-tree.cc b/src/core/device-tree.cc
index 6d93ab8..0b3d814 100644
--- a/src/core/device-tree.cc
+++ b/src/core/device-tree.cc
@@ -9,6 +9,7 @@
  *
  */
 
+#include <algorithm>
 #include <errno.h>
 #include "version.h"
 #include "device-tree.h"
@@ -35,6 +36,7 @@ struct dimminfo
 };
 
 #define DEVICETREE "/proc/device-tree"
+#define DEVICETREEVPD  "/proc/device-tree/vpd/"
 
 static unsigned long get_long(const string & path)
 {
@@ -284,46 +286,80 @@ static void scan_devtree_cpu(hwNode & core)
   }
 }
 
+void add_memory_bank(string name, string path, hwNode & core)
+{
+  struct dirent **dirlist;
+  string product;
+  int n;
+
+  pushd(path + name);
+  if(name.substr(0, 7) == "ms-dimm")
+  {
+    replace(name.begin(), name.end(), '@', ':');
+    hwNode *memory = core.getChild("memory");
+
+    hwNode bank("bank", hw::memory);
+    bank.claim(true);
+    bank.addHint("icon", string("memory"));
+
+    if(!memory)
+      memory = core.addChild(hwNode("memory", hw::memory));
+
+    if(exists("serial-number"))
+      bank.setSerial(get_string("serial-number"));
+
+    product = get_string("part-number");
+    if(exists("fru-number"))
+    {
+      product += " FRU#" + get_string("fru-number");
+    }
+    if(product != "")
+      bank.setProduct(product);
+
+    if(exists("description"))
+      bank.setDescription(get_string("description"));
+    if(exists("ibm,loc-code"))
+      bank.setSlot(get_string("ibm,loc-code"));
+    if(unsigned long size = get_number("size"))
+      bank.setSize(size*1024*1024);
+
+    memory->addChild(bank);
+  }
+
+  n = scandir(".", &dirlist, selectdir, alphasort);
+  popd();
+
+  if (n < 0)
+    return;
+
+  for (int i = 0; i < n; i++)
+  {
+    add_memory_bank(dirlist[i]->d_name, path + name + "/", core);
+    free(dirlist[i]);
+  }
+  free(dirlist);
+}
+
+
 static void scan_devtree_memory_powernv(hwNode & core)
 {
   struct dirent **namelist;
-  hwNode *memory = core.getChild("memory");
   int n;
+  string path = DEVICETREEVPD;
 
-  pushd(DEVICETREE "/vpd");
+  pushd(DEVICETREEVPD);
   n = scandir(".", &namelist, selectdir, alphasort);
   popd();
+
   if (n < 0)
     return;
+
   for (int i = 0; i < n; i++)
   {
-    string basepath;
-    unsigned long size = 0;
-    string sizestr;
-
-    if (strncmp(namelist[i]->d_name, "ms-dimm@", 8) == 0)
-    {
-      hwNode bank("bank", hw::memory);
-
-      if (!memory)
-        memory = core.addChild(hwNode("memory", hw::memory));
-
-      basepath = string(DEVICETREE "/vpd/") + string(namelist[i]->d_name);
-      bank.setSerial(get_string(basepath + string("/serial-number")));
-      bank.setProduct(get_string(basepath + string("/part-number")) + " FRU#" + get_string(basepath + string("/fru-number")));
-      bank.setDescription(get_string(basepath + string("/description")));
-      bank.setSlot(get_string(basepath + string("/ibm,loc-code")));
-      sizestr = get_string(basepath + string("/size"));
-      errno = 0;
-      size = strtoul(sizestr.c_str(), NULL, 10);
-      if (!errno)
-        bank.setSize(size*1024*1024);
-      bank.addHint("icon", string("memory"));
-
-      memory->addChild(bank);
-    }
+    add_memory_bank(namelist[i]->d_name, path, core);
     free(namelist[i]);
   }
+
   free(namelist);
 }
 
-- 
2.4.3