diff options
author | Burt P <pburt0@gmail.com> | 2018-03-23 13:15:14 -0500 |
---|---|---|
committer | Leandro A. F. Pereira <leandro@hardinfo.org> | 2018-04-24 07:43:43 -0700 |
commit | 3fa490a87d4d0b553c1b83f34fe1886af8b3a0e0 (patch) | |
tree | fba45d7e740ff97d8c2067581d79b6968f5792bc /modules/devices/pci.c | |
parent | c31e6b4dcd31d0d1c622062589b38a4e2a8150b4 (diff) |
devices/pci: replace old pci scanner with pci_util-based version
Signed-off-by: Burt P <pburt0@gmail.com>
Diffstat (limited to 'modules/devices/pci.c')
-rw-r--r-- | modules/devices/pci.c | 344 |
1 files changed, 125 insertions, 219 deletions
diff --git a/modules/devices/pci.c b/modules/devices/pci.c index c1965a63..c91ec449 100644 --- a/modules/devices/pci.c +++ b/modules/devices/pci.c @@ -16,239 +16,145 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -/* - * TODO: This thing must be rewritten. We really should have a struct with all the - * PCI stuff we'll present to the user, and hash them by the PCI ID - * (domain:bus:device.function). - * This way we'll have ways to better organize the output, instead of relying - * on the order the information appears on lspci's output. - * Also, the "Resources" thing might be better implemented (and we won't need - * copies of information scattered everywhere like we do today). - */ - #include <string.h> #include "hardinfo.h" #include "devices.h" +#include "pci_util.h" + +#define UNKIFNULL_AC(f) (f != NULL) ? f : _("(Unknown)"); + +static void _pci_dev(const pcid *p) { + gchar *str; + gchar *class, *vendor, *svendor, *v_str, *sv_str, *product, *sproduct; + gchar *name, *key; + + class = UNKIFNULL_AC(p->class_str); + vendor = UNKIFNULL_AC(p->vendor_id_str); + svendor = UNKIFNULL_AC(p->sub_vendor_id_str); + product = UNKIFNULL_AC(p->device_id_str); + sproduct = UNKIFNULL_AC(p->sub_device_id_str); + +#define USE_HARDINFO_VENDOR_THING 0 + if (USE_HARDINFO_VENDOR_THING) { + const gchar *v_url = vendor_get_url(vendor); + const gchar *v_name = vendor_get_name(vendor); + if (v_url != NULL) { + v_str = g_strdup_printf("%s (%s)", v_name, v_url); + } else { + v_str = g_strdup(vendor); + } + v_url = vendor_get_url(svendor); + v_name = vendor_get_name(svendor); + if (v_url != NULL) { + sv_str = g_strdup_printf("%s (%s)", v_name, v_url); + } else { + sv_str = g_strdup(svendor); + } + } else { + v_str = g_strdup(vendor); + sv_str = g_strdup(svendor); + } -GHashTable *_pci_devices = NULL; + name = g_strdup_printf("%s %s", vendor, product); + key = g_strdup_printf("PCI%04x:%02x:%02x.%01x", p->domain, p->bus, p->device, p->function); -void -scan_pci_do(void) -{ - FILE *lspci; - gchar buffer[256], *buf, *strhash = NULL, *strdevice = NULL; - gchar *category = NULL, *name = NULL, *icon, *lspci_path, *command_line = NULL; - gint n = 0, x = 0; + pci_list = h_strdup_cprintf("$%s$%04x:%02x:%02x.%01x=%s\n", pci_list, key, p->domain, p->bus, p->device, p->function, name); - if ((lspci_path = find_program("lspci")) == NULL) { - goto pci_error; + gchar *vendor_device_str; + if (p->vendor_id == p->sub_vendor_id && p->device_id == p->sub_device_id) { + vendor_device_str = g_strdup_printf( + /* Vendor */ "%s=[%04x] %s\n" + /* Device */ "%s=[%04x] %s\n", + _("Vendor"), p->vendor_id, v_str, + _("Device"), p->device_id, product); } else { - command_line = g_strdup_printf("%s -v", lspci_path); + vendor_device_str = g_strdup_printf( + /* Vendor */ "%s=[%04x] %s\n" + /* Device */ "%s=[%04x] %s\n" + /* Sub-device vendor */ "%s=[%04x] %s\n" + /* Sub-device */ "%s=[%04x] %s\n", + _("Vendor"), p->vendor_id, v_str, + _("Device"), p->device_id, product, + _("SVendor"), p->sub_vendor_id, sv_str, + _("SDevice"), p->sub_device_id, sproduct); } - if (!_pci_devices) { - _pci_devices = g_hash_table_new(g_str_hash, g_str_equal); - } + gchar *pcie_str; + if (p->pcie_width_curr) { + pcie_str = g_strdup_printf("[%s]\n" + /* Width */ "%s=x%u\n" + /* Width (max) */ "%s=x%u\n" + /* Speed */ "%s=%0.1f %s\n" + /* Speed (max) */ "%s=%0.1f %s\n", + _("PCI Express"), + _("Link Width"), p->pcie_width_curr, + _("Maximum Link Width"), p->pcie_width_max, + _("Link Speed"), p->pcie_speed_curr, _("GT/s"), + _("Maximum Link Speed"), p->pcie_speed_max, _("GT/s") ); + } else + pcie_str = strdup(""); + + str = g_strdup_printf("[%s]\n" + /* Class */ "%s=[%04x] %s\n" + "%s" + /* Revision */ "%s=%02x\n" + /* PCIE? */ "%s" + "[%s]\n" + /* Driver */ "%s=%s\n" + /* Modules */ "%s=%s\n" + "[%s]\n" + /* Domain */ "%s=%04x\n" + /* Bus */ "%s=%02x\n" + /* Device */ "%s=%02x\n" + /* Function */ "%s=%01x\n", + _("Device Information"), + _("Class"), p->class, class, + vendor_device_str, + _("Revision"), p->revision, + pcie_str, + _("Driver"), + _("In Use"), (p->driver) ? p->driver : _("(Unknown)"), + _("Kernel Modules"), (p->driver_list) ? p->driver_list : _("(Unknown)"), + _("Connection"), + _("Domain"), p->domain, + _("Bus"), p->bus, + _("Device"), p->device, + _("Function"), p->function + ); + + moreinfo_add_with_prefix("DEV", key, str); /* str now owned by morinfo */ + + g_free(vendor_device_str); + g_free(v_str); + g_free(sv_str); + g_free(name); + g_free(key); +} - buf = g_build_filename(g_get_home_dir(), ".hardinfo", "pci.ids", NULL); - if (!g_file_test(buf, G_FILE_TEST_EXISTS)) { - DEBUG("using system-provided PCI IDs"); - g_free(buf); - if (!(lspci = popen(command_line, "r"))) { - goto pci_error; - } - } else { - gchar *tmp; - - tmp = g_strdup_printf("%s -i '%s'", command_line, buf); - g_free(buf); - buf = tmp; - - DEBUG("using updated PCI IDs (from %s)", buf); - if (!(lspci = popen(tmp, "r"))) { - g_free(buf); - goto pci_error; - } else { - g_free(buf); - } - } +void scan_pci_do(void) { - while (fgets(buffer, 256, lspci)) { - buf = g_strstrip(buffer); - - if (!strncmp(buf, "Flags", 5)) { - gint irq = 0, freq = 0, latency = 0, i; - gchar **list; - gboolean bus_master; - - buf += 7; - - bus_master = FALSE; - - list = g_strsplit(buf, ", ", 10); - for (i = 0; i <= 10; i++) { - if (!list[i]) - break; - - if (!strncmp(list[i], "IRQ", 3)) - sscanf(list[i], "IRQ %d", &irq); - else if (strstr(list[i], "Mhz")) - sscanf(list[i], "%dMhz", &freq); - else if (!strncmp(list[i], "bus master", 10)) - bus_master = TRUE; - else if (!strncmp(list[i], "latency", 7)) - sscanf(list[i], "latency %d", &latency); - } - g_strfreev(list); - - if (irq) - strdevice = h_strdup_cprintf("%s=%d\n", strdevice, _("IRQ"), irq); - if (freq) - strdevice = h_strdup_cprintf("%s=%d %s\n", strdevice, _("Frequency"), freq, _("MHz") ); - if (latency) - strdevice = h_strdup_cprintf("%s=%d\n", strdevice, _("Latency"), latency); - - strdevice = h_strdup_cprintf("%s=%s\n", strdevice, _("Bus Master"), bus_master ? _("Yes") : _("No") ); - } else if (!strncmp(buf, "Kernel modules", 14)) { - WALK_UNTIL(' '); - WALK_UNTIL(':'); - buf++; - - strdevice = h_strdup_cprintf("%s=%s\n", strdevice, _("Kernel modules"), buf); - } else if (!strncmp(buf, "Subsystem", 9)) { - WALK_UNTIL(' '); - buf++; - const gchar *oem_vendor_url = vendor_get_url(buf); - if (oem_vendor_url) - strdevice = h_strdup_cprintf(_("%s=%s (%s)\n"), - strdevice, - _("OEM Vendor"), - vendor_get_name(buf), - oem_vendor_url); - } else if (!strncmp(buf, "Capabilities", 12) - && !strstr(buf, "only to root") && - !strstr(buf, "access denied")) { - WALK_UNTIL(' '); - WALK_UNTIL(']'); - buf++; - strdevice = h_strdup_cprintf("Capability#%d=%s\n", strdevice, ++x, buf); - } else if (!strncmp(buf, "Memory at", 9) && strstr(buf, "[size=")) { - gint mem; - gchar unit; - gboolean prefetch; - gboolean _32bit; - - prefetch = strstr(buf, "non-prefetchable") ? FALSE : TRUE; - _32bit = strstr(buf, "32-bit") ? TRUE : FALSE; - - WALK_UNTIL('['); - sscanf(buf, "[size=%d%c", &mem, &unit); - - strdevice = h_strdup_cprintf("%s#%d=%d%cB (%s%s)\n", - strdevice, _("Memory"), ++x, - mem, - (unit == ']') ? ' ' : unit, - _32bit ? "32-bit, " : "", - prefetch ? _("prefetchable") : - _("non-prefetchable") ); - - } else if (!strncmp(buf, "I/O ports at", 12)) { - guint io_addr, io_size; - - sscanf(buf, "I/O ports at %x [size=%d]", &io_addr, &io_size); - - strdevice = - h_strdup_cprintf("%s#%d=0x%x - 0x%x\n", - strdevice, _("I/O ports at"), ++x, io_addr, - io_addr + io_size - 1); - } else if ((buf[0] >= '0' && buf[0] <= '9') && (buf[4] == ':' || buf[2] == ':')) { - gint bus, device, function, domain; - gpointer start, end; - - if (strdevice != NULL && strhash != NULL) { - moreinfo_add_with_prefix("DEV", strhash, strdevice); - g_free(strhash); - g_free(category); - g_free(name); - } - - if (buf[4] == ':') { - sscanf(buf, "%x:%x:%x.%d", &domain, &bus, &device, &function); - } else { - /* lspci without domain field */ - sscanf(buf, "%x:%x.%x", &bus, &device, &function); - domain = 0; - } - - WALK_UNTIL(' '); - - start = buf; - - WALK_UNTIL(':'); - end = buf + 1; - *buf = 0; - - buf = start + 1; - category = g_strdup(buf); - - buf = end; - - if (strstr(category, "RAM memory")) icon = "mem"; - else if (strstr(category, "Multimedia")) icon = "media"; - else if (strstr(category, "USB")) icon = "usb"; - else icon = "pci"; - - name = g_strdup(buf); - g_hash_table_insert(_pci_devices, - g_strdup_printf("0000:%02x:%02x.%x", bus, device, function), - name); - - strhash = g_strdup_printf("PCI%d", n); - strdevice = g_strdup_printf("[%s]\n" - /* Name */ "%s=%s\n" - /* Class */ "%s=%s\n" - /* Domain */ "%s=%d\n" - /* Bus, device, function */ - "%s=%d, %d, %d\n", - _("Device Information"), - _("Name"), name, - _("Class"), category, - _("Domain"), domain, - _("Bus, device, function"), - bus, device, function); - - const gchar *url = vendor_get_url(name); - if (url) { - strdevice = h_strdup_cprintf("%s=%s (%s)\n", - strdevice, - _("Vendor"), - vendor_get_name(name), - url); - } - - g_hash_table_insert(_pci_devices, - g_strdup_printf("0000:%02x:%02x.%x", bus, device, function), - g_strdup(name)); - - pci_list = h_strdup_cprintf("$PCI%d$%s=%s\n", pci_list, n, category, name); - - n++; - } + if (pci_list) { + moreinfo_del_with_prefix("DEV:PCI"); + g_free(pci_list); } + pci_list = g_strdup_printf("[%s]\n", _("PCI Devices")); + + pcid *list = pci_get_device_list(0,0); + pcid *curr = list; + + int c = pcid_list_count(list); + + if (c > 0) { + while(curr) { + _pci_dev(curr); + curr=curr->next; + } - if (pclose(lspci)) { -pci_error: - /* error (no pci, perhaps?) */ - pci_list = g_strconcat(pci_list, _("No PCI devices found"), "=\n", NULL); - } else if (strhash) { - /* insert the last device */ - moreinfo_add_with_prefix("DEV", strhash, strdevice); - g_free(strhash); - g_free(category); - g_free(name); + pcid_list_free(list); + return; } - g_free(lspci_path); - g_free(command_line); + /* NO PCI? */ + pci_list = g_strconcat(pci_list, _("No PCI devices found"), "=\n", NULL); } |