Blob Blame History Raw
From 20872dd40742dc7f59c338e1575765cb2c88e6c6 Mon Sep 17 00:00:00 2001
From: Jack Miller <jack@codezen.org>
Date: Tue, 16 Aug 2016 14:03:47 -0500
Subject: [PATCH 34/43] devtree: Refactor SPD handling code

Some variants of IBM Power Systems has SPD property in device tree.
Hence move SPD reading code to separate function. Following patch
makes use of this changes.

Also minor cleanup included, mostly trying to reduce nested scopes.

No functionality changes.

Signed-off-by: Jack Miller <jack@codezen.org>
[Fixed minor issues, updated description - Vasant]
Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
---
 src/core/device-tree.cc | 227 ++++++++++++++++++++++++------------------------
 1 file changed, 114 insertions(+), 113 deletions(-)

diff --git a/src/core/device-tree.cc b/src/core/device-tree.cc
index 05db9f3..2d908d2 100644
--- a/src/core/device-tree.cc
+++ b/src/core/device-tree.cc
@@ -752,6 +752,98 @@ static void scan_devtree_cpu_power(hwNode & core)
     delete it->second;
 }
 
+static void add_memory_bank_spd(string path, hwNode & bank)
+{
+  char dimmversion[20];
+  unsigned char mfg_loc_offset;
+  unsigned char rev_offset1;
+  unsigned char rev_offset2;
+  unsigned char year_offset;
+  unsigned char week_offset;
+  unsigned char partno_offset;
+  unsigned char ver_offset;
+  int fd;
+  dimminfo_buf dimminfo;
+
+  fd = open(path.c_str(), O_RDONLY);
+  if (fd < 0)
+    return;
+
+  if (read(fd, &dimminfo, 0x80) != 0x80)
+  {
+    close(fd);
+    return;
+  }
+
+  /* Read entire SPD eeprom */
+  if (dimminfo[2] >= 9) /* DDR3 */
+  {
+    read(fd, &dimminfo[0x80], (64 << ((dimminfo[0] & 0x70) >> 4)));
+  } else if (dimminfo[0] < 15) { /* DDR 2 */
+    read(fd, &dimminfo[0x80], (1 << (dimminfo[1])));
+  }
+
+  close(fd);
+
+  if (dimminfo[2] >= 9) {
+    mfg_loc_offset = 0x77;
+    rev_offset1 = 0x92;
+    rev_offset2 = 0x93;
+    year_offset = 0x78;
+    week_offset = 0x79;
+    partno_offset = 0x80;
+    ver_offset = 0x01;
+
+    switch ((dimminfo[0x8] >> 3) & 0x3) // DDR3 error detection and correction scheme
+    {
+      case 0x00:
+        bank.setConfig("errordetection", "none");
+        break;
+      case 0x01:
+        bank.addCapability("ecc");
+        bank.setConfig("errordetection", "ecc");
+        break;
+    }
+  } else {
+    mfg_loc_offset = 0x48;
+    rev_offset1 = 0x5b;
+    rev_offset2 = 0x5c;
+    year_offset = 0x5d;
+    week_offset = 0x5e;
+    partno_offset = 0x49;
+    ver_offset = 0x3e;
+
+    switch (dimminfo[0xb] & 0x3) // DDR2 error detection and correction scheme
+    {
+      case 0x00:
+        bank.setConfig("errordetection", "none");
+        break;
+      case 0x01:
+        bank.addCapability("parity");
+        bank.setConfig("errordetection", "parity");
+        break;
+      case 0x02:
+      case 0x03:
+        bank.addCapability("ecc");
+        bank.setConfig("errordetection", "ecc");
+        break;
+    }
+  }
+
+  snprintf(dimmversion, sizeof(dimmversion),
+    "%02X%02X,%02X %02X,%02X", dimminfo[rev_offset1],
+    dimminfo[rev_offset2], dimminfo[year_offset], dimminfo[week_offset],
+    dimminfo[mfg_loc_offset]);
+  bank.setSerial(string((char *) &dimminfo[partno_offset], 18));
+  bank.setVersion(dimmversion);
+
+  int version = dimminfo[ver_offset];
+  char buff[32];
+
+  snprintf(buff, sizeof(buff), "spd-%d.%d", (version & 0xF0) >> 4, version & 0x0F);
+  bank.addCapability(buff);
+}
+
 static void add_memory_bank(string name, string path, hwNode & core)
 {
   struct dirent **dirlist;
@@ -872,123 +964,32 @@ static void scan_devtree_memory(hwNode & core)
       memory = core.addChild(hwNode("memory", hw::memory));
     }
 
-    if (memory)
-    {
-      int fd = open(dimminfo.c_str(), O_RDONLY);
+    if (!memory)
+      break;
 
-      if (regs.size() == slotnames.size())
+    if (regs.size() == slotnames.size())
+    {
+      for (unsigned int i = 0; i < slotnames.size(); i++)
       {
-        for (unsigned int i = 0; i < slotnames.size(); i++)
-        {
-          uint64_t size = regs[i].size;
-          hwNode bank("bank",
-            hw::memory);
-
-          if (fd >= 0)
-          {
-            dimminfo_buf dimminfo;
-	    
-            if (read(fd, &dimminfo, 0x80) == 0x80)
-            {
-
-              /* Read entire SPD eeprom */
-              if (dimminfo[2] >= 9) /* DDR3 */
-              {
-                read(fd, &dimminfo[0x80], (64 << ((dimminfo[0] & 0x70) >> 4)));
-              } else if (dimminfo[0] < 15) { /* DDR 2 */
-                read(fd, &dimminfo[0x80], (1 << (dimminfo[1]) ));
-              }
-
-              if (size > 0)
-              {
-                char dimmversion[20];
-                unsigned char mfg_loc_offset;
-                unsigned char rev_offset1;
-                unsigned char rev_offset2;
-                unsigned char year_offset;
-                unsigned char week_offset;
-                unsigned char partno_offset;
-                unsigned char ver_offset;
-
-                if (dimminfo[2] >= 9) {
-                  mfg_loc_offset = 0x77;
-                  rev_offset1 = 0x92;
-                  rev_offset2 = 0x93;
-                  year_offset = 0x78;
-                  week_offset = 0x79;
-                  partno_offset = 0x80;
-                  ver_offset = 0x01;
-
-                  switch ((dimminfo[0x8] >> 3) & 0x3) // DDR3 error detection and correction scheme
-                  {
-                    case 0x00:
-                      bank.setConfig("errordetection", "none");
-                      break;
-                    case 0x01:
-                      bank.addCapability("ecc");
-                      bank.setConfig("errordetection", "ecc");
-                      break;
-                  }
-                } else {
-                  mfg_loc_offset = 0x48;
-                  rev_offset1 = 0x5b;
-                  rev_offset2 = 0x5c;
-                  year_offset = 0x5d;
-                  week_offset = 0x5e;
-                  partno_offset = 0x49;
-                  ver_offset = 0x3e;
-
-                  switch (dimminfo[0xb] & 0x3) // DDR2 error detection and correction scheme
-                  {
-                    case 0x00:
-                      bank.setConfig("errordetection", "none");
-                      break;
-                    case 0x01:
-                      bank.addCapability("parity");
-                      bank.setConfig("errordetection", "parity");
-                      break;
-                    case 0x02:
-                    case 0x03:
-                      bank.addCapability("ecc");
-                      bank.setConfig("errordetection", "ecc");
-                      break;
-                  }
-                }
-                snprintf(dimmversion, sizeof(dimmversion),
-                  "%02X%02X,%02X %02X,%02X", dimminfo[rev_offset1],
-                  dimminfo[rev_offset2], dimminfo[year_offset], dimminfo[week_offset],
-                  dimminfo[mfg_loc_offset]);
-                bank.setSerial(string((char *) &dimminfo[partno_offset], 18));
-                bank.setVersion(dimmversion);
-
-                int version = dimminfo[ver_offset];
-                char buff[32];
-
-                snprintf(buff, sizeof(buff), "spd-%d.%d", (version & 0xF0) >> 4, version & 0x0F);
-                bank.addCapability(buff);
-              }
-            }
-          }
-
-          if(size>0)
-            bank.addHint("icon", string("memory"));
-          bank.setDescription("Memory bank");
-          bank.setSlot(slotnames[i]);
-          if (i < dimmtypes.size())
-            bank.setDescription(dimmtypes[i]);
-          if (i < dimmspeeds.size())
-            bank.setProduct(hw::strip(dimmspeeds[i]));
-          bank.setSize(size);
-          memory->addChild(bank);
-        }
+        uint64_t size = regs[i].size;
+        hwNode bank("bank", hw::memory);
+
+	// Parse Memory SPD data
+        add_memory_bank_spd(dimminfo, bank);
+
+        if (size > 0)
+          bank.addHint("icon", string("memory"));
+        bank.setDescription("Memory bank");
+        bank.setSlot(slotnames[i]);
+        if (i < dimmtypes.size())
+          bank.setDescription(dimmtypes[i]);
+        if (i < dimmspeeds.size())
+          bank.setProduct(hw::strip(dimmspeeds[i]));
+        bank.setSize(size);
+        memory->addChild(bank);
       }
-
-      if (fd >= 0)
-        close(fd);
-      currentmc++;
     }
-    else
-      break;
+    currentmc++;
 
     memory = NULL;
   }
-- 
2.10.2