Back to index

lshw  02.16
Defines | Functions | Variables
spd.cc File Reference
#include "version.h"
#include "spd.h"
#include "osutils.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <string>
#include <dirent.h>
#include <stdio.h>

Go to the source code of this file.

Defines

#define SPD_MAXSIZE   (2048/8)
#define SPD_BLKSIZE   0x10
#define TYPE_EDO   0x02
#define TYPE_SDRAM   0x04
#define PROCSENSORS   "/proc/sys/dev/sensors"
#define EEPROMPREFIX   "eeprom-"

Functions

 __ID ("@(#) $Id: spd.cc 2433 2012-01-10 22:01:30Z lyonel $")
static unsigned char get_spd_byte (unsigned int offset)
static int selecteeprom (const struct dirent *d)
static hwNodeget_current_bank (hwNode &memory)
static bool scan_eeprom (hwNode &memory, string name)
static bool scan_eeproms (hwNode &memory)
bool scan_spd (hwNode &n)

Variables

static unsigned char spd [SPD_MAXSIZE]
static bool spd_page_loaded [SPD_MAXSIZE/SPD_BLKSIZE]
static string current_eeprom = ""
static unsigned int current_bank = 0

Define Documentation

#define EEPROMPREFIX   "eeprom-"

Definition at line 23 of file spd.cc.

#define PROCSENSORS   "/proc/sys/dev/sensors"

Definition at line 22 of file spd.cc.

#define SPD_BLKSIZE   0x10

Definition at line 17 of file spd.cc.

#define SPD_MAXSIZE   (2048/8)

Definition at line 16 of file spd.cc.

#define TYPE_EDO   0x02

Definition at line 19 of file spd.cc.

#define TYPE_SDRAM   0x04

Definition at line 20 of file spd.cc.


Function Documentation

__ID ( "@(#) $Id: spd.cc 2433 2012-01-10 22:01:30Z lyonel $"  )
static hwNode* get_current_bank ( hwNode memory) [static]

Definition at line 81 of file spd.cc.

{
  char id[20];
  hwNode *result = NULL;

  if ((current_bank == 0) && (result = memory.getChild("bank")))
    return result;

  snprintf(id, sizeof(id), "bank:%d", current_bank);
  result = memory.getChild(id);

  if (!result)
    return memory.addChild(hwNode(id, hw::memory));
  else
    return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static unsigned char get_spd_byte ( unsigned int  offset) [static]

Definition at line 30 of file spd.cc.

{
  if ((offset < 0) || (offset >= SPD_MAXSIZE))
    return 0;

  if (!spd_page_loaded[offset / SPD_BLKSIZE])
  {
    char chunkname[10];
    string name = "";
    FILE *in = NULL;

    snprintf(chunkname, sizeof(chunkname), "%02x",
      (offset / SPD_BLKSIZE) * SPD_BLKSIZE);

    name = current_eeprom + "/" + string(chunkname);

    in = fopen(name.c_str(), "r");
    if (in)
    {
      for (int i = 0; i < SPD_BLKSIZE; i++)
        if(fscanf(in, "%d",
          (int *) &spd[i + (offset / SPD_BLKSIZE) * SPD_BLKSIZE]) < 1)
            break;
      fclose(in);
      spd_page_loaded[offset / SPD_BLKSIZE] = true;
    }
    else
      spd_page_loaded[offset / SPD_BLKSIZE] = false;
  }

  return spd[offset];
}

Here is the caller graph for this function:

static bool scan_eeprom ( hwNode memory,
string  name 
) [static]

Definition at line 99 of file spd.cc.

{
  int memory_type = -1;
  char buff[20];
  unsigned char checksum = 0;
  unsigned char rows = 0;
  unsigned char density = 0;
  unsigned long long size = 0;

  current_eeprom = string(PROCSENSORS) + "/" + name;
  memset(spd, 0, sizeof(spd));
  memset(spd_page_loaded, 0, sizeof(spd_page_loaded));

  for (int i = 0; i < 63; i++)
    checksum += get_spd_byte(i);

  if (checksum != get_spd_byte(63))
    return false;

  memory_type = get_spd_byte(0x02);

  hwNode *bank = get_current_bank(memory);

  if (!bank)
    return false;

  switch (memory_type)
  {
    case TYPE_SDRAM:
      bank->setDescription("SDRAM");
      break;
    case TYPE_EDO:
      bank->setDescription("EDO");
      break;
  }

  rows = get_spd_byte(5);
  snprintf(buff, sizeof(buff), "%d", rows);
  bank->setConfig("rows", buff);

  if (bank->getSize() == 0)
  {
    density = get_spd_byte(31);
    for (int j = 0; (j < 8) && (rows > 0); j++)
      if (density & (1 << j))
    {
      rows--;
      size += (4 << j) * 1024 * 1024;             // MB
      density ^= (1 << j);
      if (density == 0)
        size += rows * (4 << j) * 1024 * 1024;
    }
    bank->setSize(size);
  }

  switch (get_spd_byte(11))                       // error detection and correction scheme
  {
    case 0x00:
      bank->setConfig("errordetection", "none");
      break;
    case 0x01:
      bank->addCapability("parity");
      bank->setConfig("errordetection", "parity");
      break;
    case 0x02:
      bank->addCapability("ecc");
      bank->setConfig("errordetection", "ecc");
      break;
  }

  int version = get_spd_byte(62);

  snprintf(buff, sizeof(buff), "spd-%d.%d", (version & 0xF0) >> 4,
    version & 0x0F);
  bank->addCapability(buff);

  return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bool scan_eeproms ( hwNode memory) [static]

Definition at line 180 of file spd.cc.

{
  struct dirent **namelist;
  int n;

  current_bank = 0;

  pushd(PROCSENSORS);
  n = scandir(".", &namelist, selecteeprom, alphasort);
  popd();

  if (n < 0)
    return false;

  for (int i = 0; i < n; i++)
    if (scan_eeprom(memory, namelist[i]->d_name))
      current_bank++;

  return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool scan_spd ( hwNode n)

Definition at line 202 of file spd.cc.

{
  hwNode *memory = n.getChild("core/memory");

  current_bank = 0;

  if (!memory)
  {
    hwNode *core = n.getChild("core");

    if (!core)
    {
      n.addChild(hwNode("core", hw::bus));
      core = n.getChild("core");
    }

    if (core)
    {
      core->addChild(hwNode("memory", hw::memory));
      memory = core->getChild("memory");
    }
  }

  if (memory)
  {
    memory->claim();

    return scan_eeproms(*memory);
  }

  return false;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int selecteeprom ( const struct dirent *  d) [static]

Definition at line 64 of file spd.cc.

{
  struct stat buf;

  if (d->d_name[0] == '.')
    return 0;

  if (lstat(d->d_name, &buf) != 0)
    return 0;

  if (!S_ISDIR(buf.st_mode))
    return 0;

  return (strncmp(d->d_name, EEPROMPREFIX, strlen(EEPROMPREFIX)) == 0);
}

Here is the caller graph for this function:


Variable Documentation

unsigned int current_bank = 0 [static]

Definition at line 28 of file spd.cc.

string current_eeprom = "" [static]

Definition at line 27 of file spd.cc.

unsigned char spd[SPD_MAXSIZE] [static]

Definition at line 25 of file spd.cc.

Definition at line 26 of file spd.cc.