[PATCH] Fix IO access functions on linux+sysfs.

Marcin Kościelnicki koriakin at 0x04.net
Wed Feb 5 00:01:25 PST 2014


The offsets on the resourceX files are relative to BAR base - don't add
the base address ourselves.
---
 src/freebsd_pci.c       |  2 ++
 src/linux_sysfs.c       | 62 +++++++++++++++++++++++++++++++++++--------------
 src/netbsd_pci.c        |  2 ++
 src/openbsd_pci.c       |  3 +++
 src/pciaccess_private.h |  1 +
 src/solx_devfs.c        |  1 +
 src/x86_pci.c           |  1 +
 7 files changed, 54 insertions(+), 18 deletions(-)

diff --git a/src/freebsd_pci.c b/src/freebsd_pci.c
index 14ec3bc..7f5f56b 100644
--- a/src/freebsd_pci.c
+++ b/src/freebsd_pci.c
@@ -579,6 +579,7 @@ pci_device_freebsd_open_legacy_io(struct pci_io_handle *ret,
 
 	ret->base = base;
 	ret->size = size;
+	ret->is_legacy = 1;
 	return ret;
 #elif defined(PCI_MAGIC_IO_RANGE)
 	ret->memory = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED,
@@ -588,6 +589,7 @@ pci_device_freebsd_open_legacy_io(struct pci_io_handle *ret,
 
 	ret->base = base;
 	ret->size = size;
+	ret->is_legacy = 1;
 	return ret;
 #else
 	return NULL;
diff --git a/src/linux_sysfs.c b/src/linux_sysfs.c
index 97fcf36..8fca65e 100644
--- a/src/linux_sysfs.c
+++ b/src/linux_sysfs.c
@@ -759,6 +759,7 @@ pci_device_linux_sysfs_open_device_io(struct pci_io_handle *ret,
 
     ret->base = base;
     ret->size = size;
+    ret->is_legacy = 0;
 
     return ret;
 }
@@ -796,6 +797,7 @@ pci_device_linux_sysfs_open_legacy_io(struct pci_io_handle *ret,
 
     ret->base = base;
     ret->size = size;
+    ret->is_legacy = 1;
 
     return ret;
 }
@@ -813,10 +815,14 @@ pci_device_linux_sysfs_read32(struct pci_io_handle *handle, uint32_t port)
 {
     uint32_t ret;
 
-    if (handle->fd > -1)
-	pread(handle->fd, &ret, 4, port + handle->base);
-    else
+    if (handle->fd > -1) {
+	if (handle->is_legacy)
+	    pread(handle->fd, &ret, 4, port + handle->base);
+	else
+	    pread(handle->fd, &ret, 4, port);
+    } else {
 	ret = inl(port + handle->base);
+    }
 	
     return ret;
 }
@@ -826,10 +832,14 @@ pci_device_linux_sysfs_read16(struct pci_io_handle *handle, uint32_t port)
 {
     uint16_t ret;
 
-    if (handle->fd > -1)
-	pread(handle->fd, &ret, 2, port + handle->base);
-    else
+    if (handle->fd > -1) {
+	if (handle->is_legacy)
+	    pread(handle->fd, &ret, 2, port + handle->base);
+	else
+	    pread(handle->fd, &ret, 2, port);
+    } else {
 	ret = inw(port + handle->base);
+    }
 
     return ret;
 }
@@ -839,10 +849,14 @@ pci_device_linux_sysfs_read8(struct pci_io_handle *handle, uint32_t port)
 {
     uint8_t ret;
 
-    if (handle->fd > -1)
-	pread(handle->fd, &ret, 1, port + handle->base);
-    else
+    if (handle->fd > -1) {
+	if (handle->is_legacy)
+	    pread(handle->fd, &ret, 1, port + handle->base);
+	else
+	    pread(handle->fd, &ret, 1, port);
+    } else {
 	ret = inb(port + handle->base);
+    }
 
     return ret;
 }
@@ -851,30 +865,42 @@ static void
 pci_device_linux_sysfs_write32(struct pci_io_handle *handle, uint32_t port,
 			       uint32_t data)
 {
-    if (handle->fd > -1)
-	pwrite(handle->fd, &data, 4, port + handle->base);
-    else
+    if (handle->fd > -1) {
+	if (handle->is_legacy)
+	    pwrite(handle->fd, &data, 4, port + handle->base);
+	else
+	    pwrite(handle->fd, &data, 4, port);
+    } else {
 	outl(data, port + handle->base);
+    }
 }
 
 static void
 pci_device_linux_sysfs_write16(struct pci_io_handle *handle, uint32_t port,
 			       uint16_t data)
 {
-    if (handle->fd > -1)
-	pwrite(handle->fd, &data, 2, port + handle->base);
-    else
+    if (handle->fd > -1) {
+	if (handle->is_legacy)
+	    pwrite(handle->fd, &data, 2, port + handle->base);
+	else
+	    pwrite(handle->fd, &data, 2, port);
+    } else {
 	outw(data, port + handle->base);
+    }
 }
 
 static void
 pci_device_linux_sysfs_write8(struct pci_io_handle *handle, uint32_t port,
 			      uint8_t data)
 {
-    if (handle->fd > -1)
-	pwrite(handle->fd, &data, 1, port + handle->base);
-    else
+    if (handle->fd > -1) {
+	if (handle->is_legacy)
+	    pwrite(handle->fd, &data, 1, port + handle->base);
+	else
+	    pwrite(handle->fd, &data, 1, port);
+    } else {
 	outb(data, port + handle->base);
+    }
 }
 
 static int
diff --git a/src/netbsd_pci.c b/src/netbsd_pci.c
index b3f7f2d..e6dae4c 100644
--- a/src/netbsd_pci.c
+++ b/src/netbsd_pci.c
@@ -733,6 +733,7 @@ pci_device_netbsd_open_legacy_io(struct pci_io_handle *ret,
 
 	ret->base = base;
 	ret->size = size;
+	ret->is_legacy = 1;
 	return ret;
 #elif defined(__amd64__)
 	struct x86_64_iopl_args ia;
@@ -743,6 +744,7 @@ pci_device_netbsd_open_legacy_io(struct pci_io_handle *ret,
 
 	ret->base = base;
 	ret->size = size;
+	ret->is_legacy = 1;
 	return ret;
 #else
 	return NULL;
diff --git a/src/openbsd_pci.c b/src/openbsd_pci.c
index 73c68f4..fe034f3 100644
--- a/src/openbsd_pci.c
+++ b/src/openbsd_pci.c
@@ -412,6 +412,7 @@ pci_device_openbsd_open_legacy_io(struct pci_io_handle *ret,
 
 	ret->base = base;
 	ret->size = size;
+	ret->is_legacy = 1;
 	return ret;
 #elif defined(__amd64__)
 	struct amd64_iopl_args ia;
@@ -422,6 +423,7 @@ pci_device_openbsd_open_legacy_io(struct pci_io_handle *ret,
 
 	ret->base = base;
 	ret->size = size;
+	ret->is_legacy = 1;
 	return ret;
 #elif defined(PCI_MAGIC_IO_RANGE)
 	ret->memory = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED,
@@ -431,6 +433,7 @@ pci_device_openbsd_open_legacy_io(struct pci_io_handle *ret,
 
 	ret->base = base;
 	ret->size = size;
+	ret->is_legacy = 1;
 	return ret;
 #else
 	return NULL;
diff --git a/src/pciaccess_private.h b/src/pciaccess_private.h
index 339ec0f..9f4e8f9 100644
--- a/src/pciaccess_private.h
+++ b/src/pciaccess_private.h
@@ -109,6 +109,7 @@ struct pci_io_handle {
     pciaddr_t size;
     void *memory;
     int fd;
+    int is_legacy;
 };
 
 struct pci_device_private {
diff --git a/src/solx_devfs.c b/src/solx_devfs.c
index 41f5c19..8e7ea9b 100644
--- a/src/solx_devfs.c
+++ b/src/solx_devfs.c
@@ -911,6 +911,7 @@ pci_device_solx_devfs_open_legacy_io(struct pci_io_handle *ret,
     if (sysi86(SI86V86, V86SC_IOPL, PS_IOPL) == 0) {
 	ret->base = base;
 	ret->size = size;
+	ret->is_legacy = 1;
 	return ret;
     }
 #endif
diff --git a/src/x86_pci.c b/src/x86_pci.c
index 1075367..49c1cab 100644
--- a/src/x86_pci.c
+++ b/src/x86_pci.c
@@ -729,6 +729,7 @@ pci_device_x86_open_legacy_io(struct pci_io_handle *ret,
 
     ret->base = base;
     ret->size = size;
+    ret->is_legacy = 1;
 
     return ret;
 }
-- 
1.8.5.3



More information about the xorg-devel mailing list