diff options
Diffstat (limited to 'modules')
| -rw-r--r-- | modules/devices/dmi_memory.c | 98 | 
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; | 
