Commit 73db249c authored by Emil Velikov's avatar Emil Velikov Committed by Adam Jackson
Browse files

linux sysfs: retrieve vendor, device... info via separate sysfs files



Currently the kernel does not expose the revision file. With that about
to change (due in 4.10) we can read all the information required from
separate files and avoid opening the config one.

The latter has the [negative] side effect of waking up the device, which
in some cases can be quite costly.
Reviewed-by: Adam Jackson's avatarAdam Jackson <ajax@redhat.com>
Signed-off-by: Emil Velikov's avatarEmil Velikov <emil.velikov@collabora.com>
parent 099489b7
......@@ -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) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment