summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Jackson <ajax@redhat.com>2011-05-10 17:56:35 -0400
committerJeremy Huddleston <jeremyhu@apple.com>2011-10-07 11:32:36 -0700
commit58e87933b3286f33cdeedd3a6b21f4ea795bea47 (patch)
tree03c914f989f34f96f49c4f4ad8d62805b56923e3
parent8cc9a8fe57adfb52abaa90a8a2ac2316de8eb898 (diff)
linux: Implement map_legacy
Signed-off-by: Adam Jackson <ajax@redhat.com> Reviewed-by: Jeremy Huddleston <jeremyhu@apple.com>
-rw-r--r--src/linux_sysfs.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/src/linux_sysfs.c b/src/linux_sysfs.c
index 0ed6862..876abb1 100644
--- a/src/linux_sysfs.c
+++ b/src/linux_sysfs.c
@@ -840,6 +840,55 @@ 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, unsigned map_flags, void **addr)
+{
+ char name[PATH_MAX];
+ int flags = O_RDONLY;
+ int prot = PROT_READ;
+ int fd;
+ int ret=0;
+
+ if (map_flags & PCI_DEV_MAP_FLAG_WRITABLE) {
+ 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, flags);
+ 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) {
+ ret = errno;
+ }
+
+ close(fd);
+ return ret;
+}
+
+static int
+pci_device_linux_sysfs_unmap_legacy(struct pci_device *dev, void *addr, pciaddr_t size)
+{
+ return munmap(addr, size);
+}
+
static const struct pci_system_methods linux_sysfs_methods = {
.destroy = NULL,
.destroy_device = NULL,
@@ -865,4 +914,7 @@ 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,
+ .unmap_legacy = pci_device_linux_sysfs_unmap_legacy,
};