aboutsummaryrefslogtreecommitdiff
path: root/modules/devices
diff options
context:
space:
mode:
Diffstat (limited to 'modules/devices')
-rw-r--r--modules/devices/dmi_memory.c98
1 files changed, 83 insertions, 15 deletions
diff --git a/modules/devices/dmi_memory.c b/modules/devices/dmi_memory.c
index b024dc98..213d3dfb 100644
--- a/modules/devices/dmi_memory.c
+++ b/modules/devices/dmi_memory.c
@@ -26,18 +26,24 @@ gboolean no_handles = FALSE;
/* strings from dmidecode */
static const char empty_mem_str[] = "No Module Installed";
static const char unknown_mfgr_str[] = "<BAD INDEX>";
-static const unsigned long dtm = 17;
+static const char mobo_location[] = "System Board Or Motherboard";
+static const char mobo_shorter[] = "Mainboard";
+static const unsigned long dta = 16; /* array */
+static const unsigned long dtm = 17; /* socket */
#define UNKIFNULL2(f) ((f) ? f : _("(Unknown)"))
typedef struct {
unsigned long handle;
+ unsigned long array_handle;
gboolean populated;
gchar *locator;
+ gchar *full_locator;
gchar *size_str;
gchar *type;
gchar *type_detail;
+ gchar *array_locator;
gchar *bank_locator;
gchar *form_factor;
gchar *speed_str;
@@ -59,10 +65,27 @@ dmi_mem *dmi_mem_new(unsigned long h) {
s->handle = h;
s->locator = dmidecode_match("Locator", &dtm, &h);
s->size_str = dmidecode_match("Size", &dtm, &h);
+ s->bank_locator = dmidecode_match("Bank Locator", &dtm, &h);
+ gchar *ah = dmidecode_match("Array Handle", &dtm, &h);
+ if (ah) {
+ s->array_handle = strtol(ah, NULL, 16);
+ g_free(ah);
+ s->array_locator = dmidecode_match("Location", &dta, &s->array_handle);
+ if (g_str_has_prefix(s->array_locator, mobo_location)) {
+ g_free(s->array_locator);
+ s->array_locator = g_strdup(mobo_shorter);
+ }
+ }
+
+ gchar *h_str = g_strdup_printf("(0x%lx)", s->handle);
+ s->full_locator = g_strdup_printf("%s/%s",
+ s->array_locator ? s->array_locator : ".",
+ s->locator ? s->locator : h_str);
+ g_free(h_str);
+
if (!g_str_has_prefix(s->size_str, empty_mem_str)) {
s->populated = 1;
- s->bank_locator = dmidecode_match("Bank Locator", &dtm, &h);
s->form_factor = dmidecode_match("Form Factor", &dtm, &h);
s->type = dmidecode_match("Type", &dtm, &h);
s->type_detail = dmidecode_match("Type Detail", &dtm, &h);
@@ -93,10 +116,12 @@ dmi_mem *dmi_mem_new(unsigned long h) {
void dmi_mem_free(dmi_mem* s) {
if (s) {
g_free(s->locator);
+ g_free(s->full_locator);
g_free(s->size_str);
g_free(s->type);
g_free(s->type_detail);
g_free(s->bank_locator);
+ g_free(s->array_locator);
g_free(s->form_factor);
g_free(s->speed_str);
g_free(s->configured_clock_str);
@@ -121,17 +146,58 @@ GSList *get_dmi_mem_list() {
unsigned long h = hlm->handles[i];
ret = g_slist_append(ret, dmi_mem_new(h));
}
+ dmi_handle_list_free(hlm);
}
return ret;
}
gchar *dmi_mem_socket_info() {
- unsigned long i = 0;
gchar *ret = strdup("");
+
+ /* Arrays */
+ dmi_handle_list *hla = dmidecode_handles(&dta);
+ if (hla) {
+ unsigned long i = 0;
+ for(i = 0; i < hla->count; i++) {
+ unsigned long h = hla->handles[i];
+ gchar *array_locator = dmidecode_match("Location", &dta, &h);
+ gchar *array_use = dmidecode_match("Use", &dta, &h);
+ gchar *array_ecc = dmidecode_match("Error Correction Type", &dta, &h);
+ gchar *array_devs = dmidecode_match("Number Of Devices", &dta, &h);
+ if (g_str_has_prefix(array_locator, mobo_location)) {
+ g_free(array_locator);
+ array_locator = g_strdup(mobo_shorter);
+ }
+ gchar *array_max_size = dmidecode_match("Maximum Capacity", &dta, &h);
+ ret = h_strdup_cprintf("[%s %s]\n"
+ "%s=0x%x\n"
+ "%s=%s\n"
+ "%s=%s\n"
+ "%s=%s\n"
+ "%s=%s\n",
+ ret,
+ _("Memory Array"), array_locator ? array_locator : ".",
+ _("Array DMI Handle"), h,
+ _("Use"), UNKIFNULL2(array_use),
+ _("Error Correction Type"), UNKIFNULL2(array_ecc),
+ _("Max Size"), UNKIFNULL2(array_max_size),
+ _("Devices (Sockets)"), UNKIFNULL2(array_devs)
+ );
+ g_free(array_locator);
+ g_free(array_use);
+ g_free(array_ecc);
+ g_free(array_devs);
+ g_free(array_max_size);
+ }
+ dmi_handle_list_free(hla);
+ }
+
+ /* Sockets */
GSList *mems = get_dmi_mem_list();
GSList *l = mems;
for(; l; l = l->next) {
dmi_mem *s = (dmi_mem*)l->data;
+
if (s->populated) {
gchar *vendor_str = NULL;
if (s->vendor) {
@@ -140,8 +206,9 @@ gchar *dmi_mem_socket_info() {
s->vendor->name, s->vendor->url );
}
- ret = h_strdup_cprintf("[%s (%lu) %s]\n"
- "%s=0x%lx\n"
+ ret = h_strdup_cprintf("[%s %s]\n"
+ "%s=0x%lx, 0x%lx\n"
+ "%s=%s\n"
"%s=%s\n"
"%s=%s%s\n"
"%s=%s\n"
@@ -149,20 +216,19 @@ gchar *dmi_mem_socket_info() {
"%s=%s\n"
"%s=%s\n"
"%s=%s\n"
- "%s=%s\n"
"%s=%s / %s\n"
"%s=%s\n"
"%s=%s\n"
"%s=%s\n",
ret,
- _("Memory Socket"), i, s->locator,
- _("DMI Handle"), s->handle,
+ _("Memory Socket"), s->full_locator,
+ _("DMI Handles (Array, Socket)"), s->array_handle, s->handle,
+ _("Bank Locator"), UNKIFNULL2(s->bank_locator),
_("Form Factor"), UNKIFNULL2(s->form_factor),
_("Manufacturer"), UNKIFNULL2(s->mfgr), vendor_str ? vendor_str : "",
_("Part Number"), UNKIFNULL2(s->partno),
_("Type"), UNKIFNULL2(s->type), UNKIFNULL2(s->type_detail),
_("Size"), UNKIFNULL2(s->size_str),
- _("Bank Locator"), UNKIFNULL2(s->bank_locator),
_("Speed"), UNKIFNULL2(s->speed_str),
_("Configured Speed"), UNKIFNULL2(s->configured_clock_str),
_("Data Width/Total Width"), UNKIFNULL2(s->data_width), UNKIFNULL2(s->total_width),
@@ -173,15 +239,17 @@ gchar *dmi_mem_socket_info() {
g_free(vendor_str);
} else {
- ret = h_strdup_cprintf("[%s (%lu) %s]\n"
- "%s=0x%x\n"
+ ret = h_strdup_cprintf("[%s %s]\n"
+ "%s=0x%x, 0x%x\n"
+ "%s=%s\n"
"%s=%s\n",
ret,
- _("Memory Socket"), i, s->locator,
- _("DMI Handle"), s->handle,
- _("Size"), _("(Empty)") );
+ _("Memory Socket"), s->full_locator,
+ _("DMI Handles (Array, Socket)"), s->array_handle, s->handle,
+ _("Bank Locator"), UNKIFNULL2(s->bank_locator),
+ _("Size"), _("(Empty)")
+ );
}
- i++;
}
no_handles = FALSE;