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.
};
#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,