[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