[PATCH libpciaccess 2/2] linux: Implement map_legacy
Adam Jackson
ajax at redhat.com
Tue May 10 14:56:35 PDT 2011
Signed-off-by: Adam Jackson <ajax at redhat.com>
---
src/linux_sysfs.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 46 insertions(+), 0 deletions(-)
diff --git a/src/linux_sysfs.c b/src/linux_sysfs.c
index 1832ee7..850f92f 100644
--- a/src/linux_sysfs.c
+++ b/src/linux_sysfs.c
@@ -836,6 +836,50 @@ pci_device_linux_sysfs_write8(struct pci_io_handle *handle, uint32_t port,
pwrite(handle->fd, &data, 1, port + handle->base);
}
+static int
+pci_device_linux_sysfs_map_legacy(struct pci_device *dev, pciaddr_t base,
+ pciaddr_t size, int write_enable, void **addr)
+{
+ char name[PATH_MAX];
+ int flags = O_RDONLY;
+ int prot = PROT_READ;
+ int fd;
+
+ if (write_enable) {
+ flags |= O_WRONLY;
+ prot |= PROT_WRITE;
+ }
+
+ /* First check if there's a legacy memory method for the device */
+ while (dev) {
+ snprintf(name, PATH_MAX, "/sys/class/pci_bus/%04x:%02x/legacy_mem",
+ dev->domain, dev->bus);
+
+ fd = open(name, O_RDWR);
+ if (fd >= 0)
+ break;
+
+ dev = pci_device_get_parent_bridge(dev);
+ }
+
+ /* If not, /dev/mem is the best we can do */
+ if (!dev)
+ fd = open("/dev/mem", flags);
+
+ if (fd < 0)
+ return errno;
+
+ *addr = mmap(NULL, size, prot, MAP_SHARED, fd, base);
+ if (*addr == MAP_FAILED) {
+ int ret = errno;
+ close(fd);
+ return ret;
+ }
+
+ close(fd);
+ return 0;
+}
+
static const struct pci_system_methods linux_sysfs_methods = {
.destroy = NULL,
.destroy_device = NULL,
@@ -861,4 +905,6 @@ static const struct pci_system_methods linux_sysfs_methods = {
.write32 = pci_device_linux_sysfs_write32,
.write16 = pci_device_linux_sysfs_write16,
.write8 = pci_device_linux_sysfs_write8,
+
+ .map_legacy = pci_device_linux_sysfs_map_legacy,
};
--
1.7.5
More information about the xorg-devel
mailing list