From 9a9db98089717990cd5e0eef529f6bb0819ebe46 Mon Sep 17 00:00:00 2001 From: Simon Quigley Date: Wed, 16 Aug 2017 04:32:39 -0500 Subject: New upstream version 0.5.1+git20170815 --- modules/devices.c | 389 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 244 insertions(+), 145 deletions(-) (limited to 'modules/devices.c') diff --git a/modules/devices.c b/modules/devices.c index 87bb8a80..9c7a184d 100644 --- a/modules/devices.c +++ b/modules/devices.c @@ -37,6 +37,7 @@ #include #include "devices.h" +#include "dt_util.h" gchar *callback_processors(); gchar *callback_memory(); @@ -51,6 +52,7 @@ gchar *callback_usb(); gchar *callback_dmi(); gchar *callback_spd(); #endif +gchar *callback_dtree(); gchar *callback_device_resources(); void scan_processors(gboolean reload); @@ -66,6 +68,7 @@ void scan_usb(gboolean reload); void scan_dmi(gboolean reload); void scan_spd(gboolean reload); #endif +void scan_dtree(gboolean reload); void scan_device_resources(gboolean reload); gboolean root_required_for_resources(void); @@ -73,6 +76,7 @@ gboolean root_required_for_resources(void); gchar *hi_more_info(gchar *entry); enum { + ENTRY_DTREE, ENTRY_PROCESSOR, ENTRY_MEMORY, ENTRY_PCI, @@ -100,9 +104,14 @@ static ModuleEntry entries[] = { #if defined(ARCH_x86) || defined(ARCH_x86_64) [ENTRY_DMI] = {N_("DMI"), "computer.png", callback_dmi, scan_dmi, MODULE_FLAG_NONE}, [ENTRY_SPD] = {N_("Memory SPD"), "memory.png", callback_spd, scan_spd, MODULE_FLAG_NONE}, + [ENTRY_DTREE] = {"#"}, +#else + [ENTRY_DMI] = {"#"}, + [ENTRY_SPD] = {"#"}, + [ENTRY_DTREE] = {N_("Device Tree"), "devices.png", callback_dtree, scan_dtree, MODULE_FLAG_NONE}, #endif /* x86 or x86_64 */ [ENTRY_RESOURCES] = {N_("Resources"), "resources.png", callback_device_resources, scan_device_resources, MODULE_FLAG_NONE}, - {NULL} + { NULL } }; static GSList *processors = NULL; @@ -117,21 +126,127 @@ gchar *lginterval = NULL; #include -gchar *get_processor_name(void) +static gint proc_cmp_model_name(Processor *a, Processor *b) { + return g_strcmp0(a->model_name, b->model_name); +} + +static gint proc_cmp_max_freq(Processor *a, Processor *b) { + if (a->cpu_mhz == b->cpu_mhz) + return 0; + if (a->cpu_mhz > b->cpu_mhz) + return -1; + return 1; +} + +gchar *processor_describe_default(GSList * processors) { - scan_processors(FALSE); + int packs, cores, threads; + const gchar *packs_fmt, *cores_fmt, *threads_fmt; + gchar *ret, *full_fmt; - Processor *p = (Processor *) processors->data; + cpu_procs_cores_threads(&packs, &cores, &threads); - if (g_slist_length(processors) > 1) { - return idle_free(g_strdup_printf("%dx %s", - g_slist_length(processors), - p->model_name)); + /* if topology info was available, else fallback to old method */ + if (cores > 0) { + packs_fmt = ngettext("%d physical processor", "%d physical processors", packs); + cores_fmt = ngettext("%d core", "%d cores", cores); + threads_fmt = ngettext("%d thread", "%d threads", threads); + full_fmt = g_strdup_printf(_(/*/NP procs; NC cores; NT threads*/ "%s; %s; %s"), packs_fmt, cores_fmt, threads_fmt); + ret = g_strdup_printf(full_fmt, packs, cores, threads); + g_free(full_fmt); + return ret; } else { - return p->model_name; + return processor_describe_by_counting_names(processors); + } +} + +gchar *processor_name_default(GSList * processors) +{ + gchar *ret = g_strdup(""); + GSList *tmp, *l; + Processor *p; + gchar *cur_str = NULL; + gint cur_count = 0; + + tmp = g_slist_copy(processors); + tmp = g_slist_sort(tmp, (GCompareFunc)proc_cmp_model_name); + + for (l = tmp; l; l = l->next) { + p = (Processor*)l->data; + if (cur_str == NULL) { + cur_str = p->model_name; + cur_count = 1; + } else { + if(g_strcmp0(cur_str, p->model_name)) { + ret = h_strdup_cprintf("%s%s", ret, strlen(ret) ? "; " : "", cur_str); + cur_str = p->model_name; + cur_count = 1; + } else { + cur_count++; + } + } + } + ret = h_strdup_cprintf("%s%s", ret, strlen(ret) ? "; " : "", cur_str); + g_slist_free(tmp); + return ret; +} + +/* TODO: prefix counts are threads when they should be cores. */ +gchar *processor_describe_by_counting_names(GSList * processors) +{ + gchar *ret = g_strdup(""); + GSList *tmp, *l; + Processor *p; + gchar *cur_str = NULL; + gint cur_count = 0; + + tmp = g_slist_copy(processors); + tmp = g_slist_sort(tmp, (GCompareFunc)proc_cmp_model_name); + + for (l = tmp; l; l = l->next) { + p = (Processor*)l->data; + if (cur_str == NULL) { + cur_str = p->model_name; + cur_count = 1; + } else { + if(g_strcmp0(cur_str, p->model_name)) { + ret = h_strdup_cprintf("%s%dx %s", ret, strlen(ret) ? " + " : "", cur_count, cur_str); + cur_str = p->model_name; + cur_count = 1; + } else { + cur_count++; + } + } } + ret = h_strdup_cprintf("%s%dx %s", ret, strlen(ret) ? " + " : "", cur_count, cur_str); + g_slist_free(tmp); + return ret; +} + +gchar *get_processor_name(void) +{ + scan_processors(FALSE); + return processor_name(processors); +} + +gchar *get_processor_desc(void) +{ + scan_processors(FALSE); + return processor_describe(processors); +} + +gchar *get_processor_name_and_desc(void) +{ + scan_processors(FALSE); + gchar* name = processor_name(processors); + gchar* desc = processor_describe(processors); + gchar* nd = g_strdup_printf("%s\n%s", name, desc); + g_free(name); + g_free(desc); + return nd; } + gchar *get_storage_devices(void) { scan_storage(FALSE); @@ -160,175 +275,127 @@ gchar *get_processor_count(void) return g_strdup_printf("%d", g_slist_length(processors)); } -gchar *get_processor_frequency(void) +/* TODO: maybe move into processor.c along with processor_name() etc. + * Could mention the big.LITTLE cluster arangement for ARM that kind of thing. + * TODO: prefix counts are threads when they should be cores. */ +gchar *processor_frequency_desc(GSList * processors) +{ + gchar *ret = g_strdup(""); + GSList *tmp, *l; + Processor *p; + float cur_val = -1; + gint cur_count = 0; + + tmp = g_slist_copy(processors); + tmp = g_slist_sort(tmp, (GCompareFunc)proc_cmp_max_freq); + + for (l = tmp; l; l = l->next) { + p = (Processor*)l->data; + if (cur_val == -1) { + cur_val = p->cpu_mhz; + cur_count = 1; + } else { + if(cur_val != p->cpu_mhz) { + ret = h_strdup_cprintf("%s%dx %.2f %s", ret, strlen(ret) ? " + " : "", cur_count, cur_val, _("MHz") ); + cur_val = p->cpu_mhz; + cur_count = 1; + } else { + cur_count++; + } + } + } + ret = h_strdup_cprintf("%s%dx %.2f %s", ret, strlen(ret) ? " + " : "", cur_count, cur_val, _("MHz")); + g_slist_free(tmp); + return ret; +} + +gchar *get_processor_frequency_desc(void) +{ + scan_processors(FALSE); + return processor_frequency_desc(processors); +} + +gchar *get_processor_max_frequency(void) { + GSList *l; Processor *p; + float max_freq = 0; scan_processors(FALSE); - p = (Processor *)processors->data; - if (p->cpu_mhz == 0.0f) { + for (l = processors; l; l = l->next) { + p = (Processor*)l->data; + if (p->cpu_mhz > max_freq) + max_freq = p->cpu_mhz; + } + + if (max_freq == 0.0f) { return g_strdup(N_("Unknown")); } else { - return g_strdup_printf("%.0f", p->cpu_mhz); + return g_strdup_printf("%.2f %s", max_freq, _("MHz") ); } } gchar *get_pci_device_description(gchar *pci_id) { gchar *description; - + if (!_pci_devices) { scan_pci(FALSE); } - + if ((description = g_hash_table_lookup(_pci_devices, pci_id))) { return g_strdup(description); } - + return NULL; } gchar *get_memory_total(void) { scan_memory(FALSE); - return moreinfo_lookup ("DEV:Total Memory"); //hi_more_info(N_("Total Memory")); -} - -/* information table from: http://elinux.org/RPi_HardwareHistory */ -static struct { - char *value, *intro, *model, *pcb, *mem, *mfg; -} rpi_boardinfo[] = { -/* Value Introduction Model Name PCB rev. Memory Manufacturer * - * Raspberry Pi %s */ - { "Beta", "Q1 2012", "B (Beta)", "?", "256MB", "(Beta board)" }, - { "0002", "Q1 2012", "B", "1.0", "256MB", "?" }, - { "0003", "Q3 2012", "B (ECN0001)", "1.0", "256MB", "(Fuses mod and D14 removed)" }, - { "0004", "Q3 2012", "B", "2.0", "256MB", "Sony" }, - { "0005", "Q4 2012", "B", "2.0", "256MB", "Qisda" }, - { "0006", "Q4 2012", "B", "2.0", "256MB", "Egoman" }, - { "0007", "Q1 2013", "A", "2.0", "256MB", "Egoman" }, - { "0008", "Q1 2013", "A", "2.0", "256MB", "Sony" }, - { "0009", "Q1 2013", "A", "2.0", "256MB", "Qisda" }, - { "000d", "Q4 2012", "B", "2.0", "512MB", "Egoman" }, - { "000e", "Q4 2012", "B", "2.0", "512MB", "Sony" }, - { "000f", "Q4 2012", "B", "2.0", "512MB", "Qisda" }, - { "0010", "Q3 2014", "B+", "1.0", "512MB", "Sony" }, - { "0011", "Q2 2014", "Compute Module 1", "1.0", "512MB", "Sony" }, - { "0012", "Q4 2014", "A+", "1.1", "256MB", "Sony" }, - { "0013", "Q1 2015", "B+", "1.2", "512MB", "?" }, - { "0014", "Q2 2014", "Compute Module 1", "1.0", "512MB", "Embest" }, - { "0015", "?", "A+", "1.1", "256MB/512MB", "Embest" }, - { "a01040", "Unknown", "2 Model B", "1.0", "1GB", "Sony" }, - { "a01041", "Q1 2015", "2 Model B", "1.1", "1GB", "Sony" }, - { "a21041", "Q1 2015", "2 Model B", "1.1", "1GB", "Embest" }, - { "a22042", "Q3 2016", "2 Model B", "1.2", "1GB", "Embest" }, /* (with BCM2837) */ - { "900021", "Q3 2016", "A+", "1.1", "512MB", "Sony" }, - { "900032", "Q2 2016?", "B+", "1.2", "512MB", "Sony" }, - { "900092", "Q4 2015", "Zero", "1.2", "512MB", "Sony" }, - { "900093", "Q2 2016", "Zero", "1.3", "512MB", "Sony" }, - { "920093", "Q4 2016?", "Zero", "1.3", "512MB", "Embest" }, - { "9000c1", "Q1 2017", "Zero W", "1.1", "512MB", "Sony" }, - { "a02082", "Q1 2016", "3 Model B", "1.2", "1GB", "Sony" }, - { "a020a0", "Q1 2017", "Compute Module 3 or CM3 Lite", "1.0", "1GB", "Sony" }, - { "a22082", "Q1 2016", "3 Model B", "1.2", "1GB", "Embest" }, - { "a32082", "Q4 2016", "3 Model B", "1.2", "1GB", "Sony Japan" }, - { NULL, NULL, NULL, NULL, NULL, NULL } -}; - -static gchar *rpi_get_boardname(void) { - int i = 0, c = 0; - gchar *ret = NULL; - gchar *soc = NULL; - gchar *revision = NULL; - int overvolt = 0; - FILE *cpuinfo; - gchar buffer[128]; - - cpuinfo = fopen("/proc/cpuinfo", "r"); - if (!cpuinfo) - return NULL; - while (fgets(buffer, 128, cpuinfo)) { - gchar **tmp = g_strsplit(buffer, ":", 2); - tmp[0] = g_strstrip(tmp[0]); - tmp[1] = g_strstrip(tmp[1]); - get_str("Revision", revision); - get_str("Hardware", soc); - } - fclose(cpuinfo); - - if (revision == NULL || soc == NULL) { - g_free(soc); - g_free(revision); - return NULL; - } - - if (g_str_has_prefix(revision, "1000")) - overvolt = 1; - - while (rpi_boardinfo[i].value != NULL) { - if (overvolt) - /* +4 to ignore the 1000 prefix */ - c = g_strcmp0(revision+4, rpi_boardinfo[i].value); - else - c = g_strcmp0(revision, rpi_boardinfo[i].value); - - if (c == 0) { - ret = g_strdup_printf("Raspberry Pi %s (%s) pcb-rev:%s soc:%s mem:%s mfg-by:%s%s", - rpi_boardinfo[i].model, rpi_boardinfo[i].intro, - rpi_boardinfo[i].pcb, soc, - rpi_boardinfo[i].mem, rpi_boardinfo[i].mfg, - (overvolt) ? " (over-volted)" : "" ); - break; - } - i++; - } - g_free(soc); - g_free(revision); - return ret; + return moreinfo_lookup ("DEV:MemTotal"); } gchar *get_motherboard(void) { - char *board_name, *board_vendor; + char *board_name, *board_vendor, *product_version; + #if defined(ARCH_x86) || defined(ARCH_x86_64) scan_dmi(FALSE); board_name = moreinfo_lookup("DEV:DMI:Board:Name"); board_vendor = moreinfo_lookup("DEV:DMI:Board:Vendor"); - - if (board_name && board_vendor && *board_name && *board_vendor) - return g_strconcat(board_vendor, " ", board_name, NULL); - else if (board_name && *board_name) - return g_strconcat(board_name, _(" (vendor unknown)"), NULL); - else if (board_vendor && *board_vendor) - return g_strconcat(board_vendor, _(" (model unknown)"), NULL); -#else - /* use device tree "model" */ - if (g_file_get_contents("/proc/device-tree/model", &board_vendor, NULL, NULL)) { - - /* if a raspberry pi, try and get a more detailed name */ - if (g_str_has_prefix(board_vendor, "Raspberry Pi")) { - board_name = rpi_get_boardname(); - if (board_name != NULL) { - g_free(board_vendor); - return board_name; - } - } + product_version = moreinfo_lookup("DEV:DMI:Product:Version#1"); - return board_vendor; - } + if (!board_name || !*board_name) + board_name = _(" (model unknown)"); + if (!board_vendor || !*board_vendor) + board_vendor = _(" (vendor unknown)"); + + if (product_version && *product_version) + return g_strdup_printf("%s / %s (%s)", product_version, board_name, board_vendor); + + return g_strconcat(board_vendor, " ", board_name, NULL); #endif + /* use device tree "model" */ + board_vendor = dtr_get_string("/model", 0); + if (board_vendor != NULL) + return board_vendor; + return g_strdup(_("Unknown")); } ShellModuleMethod *hi_exported_methods(void) { static ShellModuleMethod m[] = { - {"getProcessorCount", get_processor_count}, + {"getProcessorCount", get_processor_count}, {"getProcessorName", get_processor_name}, - {"getProcessorFrequency", get_processor_frequency}, + {"getProcessorDesc", get_processor_desc}, + {"getProcessorNameAndDesc", get_processor_name_and_desc}, + {"getProcessorFrequency", get_processor_max_frequency}, + {"getProcessorFrequencyDesc", get_processor_frequency_desc}, {"getMemoryTotal", get_memory_total}, {"getStorageDevices", get_storage_devices}, {"getPrinters", get_printers}, @@ -344,7 +411,7 @@ ShellModuleMethod *hi_exported_methods(void) gchar *hi_more_info(gchar * entry) { gchar *info = moreinfo_lookup_with_prefix("DEV", entry); - + if (info) return g_strdup(info); @@ -377,6 +444,13 @@ void scan_spd(gboolean reload) } #endif +void scan_dtree(gboolean reload) +{ + SCAN_START(); + __scan_dtree(); + SCAN_END(); +} + void scan_processors(gboolean reload) { SCAN_START(); @@ -462,15 +536,28 @@ gchar *callback_spd() } #endif +gchar *callback_dtree() +{ + return g_strdup_printf("%s" + "[$ShellParam$]\n" + "ViewType=1\n", dtree_info); +} + gchar *callback_memory() { return g_strdup_printf("[Memory]\n" - "%s\n" - "[$ShellParam$]\n" - "ViewType=2\n" - "LoadGraphSuffix= kB\n" - "RescanInterval=2000\n" - "%s\n", meminfo, lginterval); + "%s\n" + "[$ShellParam$]\n" + "ViewType=2\n" + "LoadGraphSuffix= kB\n" + "RescanInterval=2000\n" + "ColumnTitle$TextValue=%s\n" + "ColumnTitle$Extra1=%s\n" + "ColumnTitle$Value=%s\n" + "ShowColumnHeaders=true\n" + "%s\n", meminfo, + _("Field"), _("Description"), _("Value"), /* column labels */ + lginterval); } gchar *callback_battery() @@ -489,8 +576,20 @@ gchar *callback_pci() gchar *callback_sensors() { - return g_strdup_printf("[$ShellParam$]\n" - "ReloadInterval=5000\n" "%s", sensors); + return g_strdup_printf("[Sensors]\n" + "%s\n" + "[$ShellParam$]\n" + "ViewType=2\n" + "LoadGraphSuffix=\n" + "ColumnTitle$TextValue=%s\n" + "ColumnTitle$Value=%s\n" + "ColumnTitle$Extra1=%s\n" + "ShowColumnHeaders=true\n" + "RescanInterval=5000\n" + "%s", + sensors, + _("Sensor"), _("Value"), _("Type"), /* column labels */ + lginterval); } gchar *callback_printers() @@ -564,7 +663,7 @@ void hi_module_init(void) .save_to = "cpuflags.conf", .get_data = NULL }; - + sync_manager_add_entry(&se); } #endif /* defined(ARCH_x86) */ @@ -606,7 +705,7 @@ const gchar *hi_note_func(gint entry) { if (entry == ENTRY_RESOURCES) { if (root_required_for_resources()) { - return g_strdup_printf(_("Resource information requires superuser privileges")); + return g_strdup(_("Resource information requires superuser privileges")); } } return NULL; -- cgit v1.2.3