diff options
-rw-r--r-- | src/linux_sysfs.c | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/src/linux_sysfs.c b/src/linux_sysfs.c index cd2713d..8055e8d 100644 --- a/src/linux_sysfs.c +++ b/src/linux_sysfs.c @@ -146,6 +146,56 @@ scan_sys_pci_filter( const struct dirent * d ) } +static int +parse_separate_sysfs_files(struct pci_device * dev) +{ + static const char *attrs[] = { + "vendor", + "device", + "class", + "revision", + "subsystem_vendor", + "subsystem_device", + }; + char name[256]; + char resource[512]; + uint64_t data[6]; + int fd; + int i; + + for (i = 0; i < 6; i++) { + snprintf(name, 255, "%s/%04x:%02x:%02x.%1u/%s", + SYS_BUS_PCI, + dev->domain, + dev->bus, + dev->dev, + dev->func, + attrs[i]); + + fd = open(name, O_RDONLY | O_CLOEXEC); + if (fd == -1) { + return errno; + } + + read(fd, resource, 512); + resource[511] = '\0'; + + close(fd); + + data[i] = strtoull(resource, NULL, 16); + } + + dev->vendor_id = data[0] & 0xffff; + dev->device_id = data[1] & 0xffff; + dev->device_class = data[2] & 0xffffff; + dev->revision = data[3] & 0xff; + dev->subvendor_id = data[4] & 0xffff; + dev->subdevice_id = data[5] & 0xffff; + + return 0; +} + + int populate_entries( struct pci_system * p ) { @@ -178,6 +228,10 @@ populate_entries( struct pci_system * p ) device->base.func = func; + err = parse_separate_sysfs_files(& device->base); + if (!err) + continue; + err = pci_device_linux_sysfs_read(& device->base, config, 0, 48, & bytes); if ((bytes == 48) && !err) { |