From 7282b53c47c2435c1ea23948272c9ccf1798178a Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Mon, 23 Jun 2008 11:24:04 -0700 Subject: [PATCH] Support write combine resource files in Linux sysfs Starting with version 2.6.26, Linux will support resourceN_wc files which export write combining mappings of PCI resource ranges, so support them if present in libpciaccess. --- src/linux_sysfs.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/linux_sysfs.c b/src/linux_sysfs.c index 3cbed76..ca4d3ef 100644 --- a/src/linux_sysfs.c +++ b/src/linux_sysfs.c @@ -484,6 +484,40 @@ pci_device_linux_sysfs_write( struct pci_device * dev, const void * data, return err; } +static int +pci_device_linux_sysfs_map_range_wc(struct pci_device *dev, + struct pci_device_mapping *map) +{ + char name[256]; + int fd; + const int prot = ((map->flags & PCI_DEV_MAP_FLAG_WRITABLE) != 0) + ? (PROT_READ | PROT_WRITE) : PROT_READ; + const int open_flags = ((map->flags & PCI_DEV_MAP_FLAG_WRITABLE) != 0) + ? O_RDWR : O_RDONLY; + const off_t offset = map->base - dev->regions[map->region].base_addr; + + snprintf(name, 255, "%s/%04x:%02x:%02x.%1u/resource%u_wc", + SYS_BUS_PCI, + dev->domain, + dev->bus, + dev->dev, + dev->func, + map->region); + fd = open(name, open_flags); + if (fd == -1) + return errno; + + map->memory = mmap(NULL, map->size, prot, MAP_SHARED, fd, offset); + if (map->memory == MAP_FAILED) { + map->memory = NULL; + close(fd); + return errno; + } + + close(fd); + + return 0; +} /** * Map a memory region for a device using the Linux sysfs interface. @@ -521,6 +555,11 @@ pci_device_linux_sysfs_map_range(struct pci_device *dev, }; #endif + /* For WC mappings, try sysfs resourceN_wc file first */ + if ((map->flags & PCI_DEV_MAP_FLAG_WRITE_COMBINE) && + !pci_device_linux_sysfs_map_range_wc(dev, map)) + return 0; + snprintf(name, 255, "%s/%04x:%02x:%02x.%1u/resource%u", SYS_BUS_PCI, dev->domain, -- 2.7.4