diff options
Diffstat (limited to 'arch/linux/common/pci.h')
-rw-r--r-- | arch/linux/common/pci.h | 56 |
1 files changed, 49 insertions, 7 deletions
diff --git a/arch/linux/common/pci.h b/arch/linux/common/pci.h index 388ce9aa..a1ea1021 100644 --- a/arch/linux/common/pci.h +++ b/arch/linux/common/pci.h @@ -1,6 +1,6 @@ /* * HardInfo - Displays System Information - * Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@linuxmag.com.br> + * Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@hardinfo.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,25 +16,47 @@ * 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). + */ + +GHashTable *_pci_devices = NULL; + void __scan_pci(void) { FILE *lspci; gchar buffer[256], *buf, *strhash = NULL, *strdevice = NULL; - gchar *category = NULL, *name = NULL, *icon; + gchar *category = NULL, *name = NULL, *icon, *lspci_path, *command_line; gint n = 0, x = 0; + + if ((lspci_path = find_program("lspci")) == NULL) { + goto pci_error; + } else { + command_line = g_strdup_printf("%s -v", lspci_path); + } + + if (!_pci_devices) { + _pci_devices = g_hash_table_new(g_str_hash, g_str_equal); + } 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(LSPCI, "r"))) { + if (!(lspci = popen(command_line, "r"))) { goto pci_error; } } else { gchar *tmp; - tmp = g_strdup_printf("%s -i '%s'", LSPCI, buf); + tmp = g_strdup_printf("%s -i '%s'", command_line, buf); g_free(buf); buf = tmp; @@ -83,10 +105,21 @@ __scan_pci(void) strdevice = h_strdup_cprintf("Latency=%d\n", strdevice, latency); strdevice = h_strdup_cprintf("Bus Master=%s\n", strdevice, bus_master ? "Yes" : "No"); + } else if (!strncmp(buf, "Kernel modules", 14)) { + WALK_UNTIL(' '); + WALK_UNTIL(':'); + buf++; + + strdevice = h_strdup_cprintf("Kernel modules=%s\n", strdevice, buf); } else if (!strncmp(buf, "Subsystem", 9)) { WALK_UNTIL(' '); buf++; - strdevice = h_strdup_cprintf("OEM Vendor=%s\n", strdevice, buf); + const gchar *oem_vendor_url = vendor_get_url(buf); + if (oem_vendor_url) + strdevice = h_strdup_cprintf("OEM Vendor=%s (%s)\n", + strdevice, + vendor_get_name(buf), + oem_vendor_url); } else if (!strncmp(buf, "Capabilities", 12) && !strstr(buf, "only to root") && !strstr(buf, "access denied")) { @@ -114,7 +147,7 @@ __scan_pci(void) prefetch ? "prefetchable" : "non-prefetchable"); - } else if (!strncmp(buf, "I/O", 3)) { + } 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); @@ -122,7 +155,7 @@ __scan_pci(void) strdevice = h_strdup_cprintf("I/O ports at#%d=0x%x - 0x%x\n", strdevice, ++x, io_addr, - io_addr + io_size); + 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; @@ -164,6 +197,9 @@ __scan_pci(void) 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("[Device Information]\n" @@ -182,6 +218,9 @@ __scan_pci(void) 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); @@ -199,4 +238,7 @@ pci_error: g_free(category); g_free(name); } + + g_free(lspci_path); + g_free(command_line); } |