diff options
Diffstat (limited to 'modules/devices')
| -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);  } | 
