libpciaccess problem with new IO interface

Michael Cree mcree at
Fri Feb 12 19:23:57 PST 2010

I have been trying out the new IO interface routines 
(pci_device_open_io, etc.) in libpciaccess with a view that they might 
solve the problem of MMIO on idiosyncratic architectures such as the old 

In short, those routines do not work, at least not in the Linux sysfs 

In that implementation libpciaccess opens the sysfs PCI resource file as 
a file then reads and writes (via pread and pwrite) are performed on the 
resource file for IO byte, word and longword access.

The trouble with this implementation is that reading and writing the PCI 
resource files in the Linux sysfs does not appear to be supported by the 
kernel.  Only memory mapping the resource files is supported.

If I modify the read I/O routines in the file linux-sysfs.c to report 
any IO errors as in:

static uint32_t
pci_device_linux_sysfs_read32(struct pci_io_handle *handle, uint32_t port)
     uint32_t ret;

     if (pread(handle->fd, &ret, 4, port) != 4) {
	fprintf(stderr, "ERROR: pread failed %d (%s)\n",errno, strerror(errno));

     return ret;

then error number 5 (Input/output error) is returned. Oh, In that 
routine I have also modified the offset passed to pread() to be port 
only as the offset should be from the start of the resource file, not 
the start of memory, methinks.

I test on amd64 architecture a Radeon RV710 card, in particular the 
resource at bar 2 which is a 65535 byte region of IO ports. 
Interestingly the PCI config reports this resource as memory but it is 
obviously IO ports by the way the radeon video driver uses it.  So for 
my tests I modified pci_device_open_io() in libpciaccess to allow access 
to PCI resources indicated as memory.

I attach my test code.  I run it as so:

./test-libpci 2:00.0 2 7200 ff

where 2:00.0 is the Radeon card, 2 is the bar, and it will access ports 
at 0x7200 through to 0x72ff (which might be recognised by some to be the 
default range the radeonhd project's rhd_dump utility dumps).  The 
utility prints that memory range using the  pci_device_map_range() and 
direct memory access first, then prints it out using 
pci_device_open_io() and pci_io_read32().  Output is:

Found bar 2 at 0xfdde0000 of size 65536.

7200:        0        0        0        0
7210:        0        0        0        0
7220:        0        0        0        0
7230:        0        0  65a2000        0
7240:        0        0        0        0
7250:        0        0        0        0
7260:        0        0        0        0
7270:        0        0        0        0
7280:        0        0        0        0
7290:        0        4        0        0
72a0:        0        0        0        0
72b0:        0        0        0       40
72c0:        0        0        0        0
72d0:        0        0        0        0
72e0:        0        0        0        0
72f0:        0        0        0        0

ERROR: pread failed 5 (Input/output error)
ERROR: pread failed 5 (Input/output error)
ERROR: pread failed 5 (Input/output error)
ERROR: pread failed 5 (Input/output error)
7200:     7f7a     7f7a     7f7a     7f7a

And so on with more pread errors.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: test-libpci.c
Type: text/x-csrc
Size: 3238 bytes
Desc: not available
Url : 

More information about the xorg-devel mailing list