[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

libpciaccess: Changes to 'upstream-unstable'



 configure.ac            |    8 
 include/pciaccess.h     |   12 +
 src/Makefile.am         |    8 
 src/common_init.c       |   13 +
 src/common_interface.c  |   21 ++
 src/common_iterator.c   |    3 
 src/common_map.c        |    1 
 src/linux_devmem.c      |    2 
 src/linux_sysfs.c       |   66 ++++++-
 src/openbsd_pci.c       |  406 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/pciaccess_private.h |    4 
 src/solx_devfs.c        |   14 -
 12 files changed, 528 insertions(+), 30 deletions(-)

New commits:
commit ed0555e4225aec26aaaa40f4f3c15fd914390817
Author: Adam Jackson <ajax@redhat.com>
Date:   Tue Jun 10 15:24:56 2008 -0400

    libpciaccess 0.10.3

diff --git a/configure.ac b/configure.ac
index 48f33c2..9293b4a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -40,7 +40,7 @@ dnl refers to ${prefix}.  Thus we have to use `eval' twice.
 
 AC_PREREQ([2.57])
 
-AC_INIT(libpciaccess, 0.10.2, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg&component=libpciaccess], libpciaccess)
+AC_INIT(libpciaccess, 0.10.3, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg&component=libpciaccess], libpciaccess)
 AM_INIT_AUTOMAKE([dist-bzip2])
 AM_MAINTAINER_MODE
 

commit 07577a875bc9996437cfe30e5a87ca6b1a0f7e4a
Author: Adam Jackson <ajax@redhat.com>
Date:   Tue Jun 10 15:23:06 2008 -0400

    libpciaccess 0.10.2

diff --git a/configure.ac b/configure.ac
index ed81dc4..48f33c2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -40,7 +40,7 @@ dnl refers to ${prefix}.  Thus we have to use `eval' twice.
 
 AC_PREREQ([2.57])
 
-AC_INIT(libpciaccess, 0.10.1, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg&component=libpciaccess], libpciaccess)
+AC_INIT(libpciaccess, 0.10.2, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg&component=libpciaccess], libpciaccess)
 AM_INIT_AUTOMAKE([dist-bzip2])
 AM_MAINTAINER_MODE
 
diff --git a/src/Makefile.am b/src/Makefile.am
index 8bec117..8c53de5 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -55,7 +55,7 @@ INCLUDES = -I$(top_srcdir)/include
 
 libpciaccess_la_LIBADD = @PCIACCESS_LIBS@
 
-libpciaccess_la_LDFLAGS = -version-number 0:10:1 -no-undefined
+libpciaccess_la_LDFLAGS = -version-number 0:10:2 -no-undefined
 
 libpciaccessincludedir = $(includedir)
 libpciaccessinclude_HEADERS = \

commit e3adc06b8b8214478aa1d3e85fd5f83b79d039b4
Author: Eric Anholt <eric@anholt.net>
Date:   Thu Jun 5 11:39:06 2008 -0700

    Catch and recover from yet another linux kernel bug in mprotect.

diff --git a/src/linux_sysfs.c b/src/linux_sysfs.c
index 9e53fac..b1d196c 100644
--- a/src/linux_sysfs.c
+++ b/src/linux_sysfs.c
@@ -537,12 +537,11 @@ pci_device_linux_sysfs_map_range(struct pci_device *dev,
 
     map->memory = mmap(NULL, map->size, prot, MAP_SHARED, fd, offset);
     if (map->memory == MAP_FAILED) {
-        err = errno;
         map->memory = NULL;
+	close(fd);
+	return errno;
     }
 
-    close(fd);
-
 #ifdef HAVE_MTRR
     if ((map->flags & PCI_DEV_MAP_FLAG_CACHABLE) != 0) {
         sentry.type = MTRR_TYPE_WRBACK;
@@ -562,11 +561,27 @@ pci_device_linux_sysfs_map_range(struct pci_device *dev,
 	}
 	/* KLUDGE ALERT -- rewrite the PTEs to turn off the CD and WT bits */
 	mprotect (map->memory, map->size, PROT_NONE);
-	mprotect (map->memory, map->size, PROT_READ|PROT_WRITE);
+	err = mprotect (map->memory, map->size, PROT_READ|PROT_WRITE);
+
+	if (err != 0) {
+	    fprintf(stderr, "mprotect(PROT_READ | PROT_WRITE) failed: %s\n",
+		    strerror(errno));
+	    fprintf(stderr, "remapping without mprotect performace kludge.\n");
+
+	    munmap(map->memory, map->size);
+	    map->memory = mmap(NULL, map->size, prot, MAP_SHARED, fd, offset);
+	    if (map->memory == MAP_FAILED) {
+		map->memory = NULL;
+		close(fd);
+		return errno;
+	    }
+	}
     }
 #endif
 
-    return err;
+    close(fd);
+
+    return 0;
 }
 
 /**

commit 4586bb6766983d040bff38b43dc458c47e0ca21f
Author: Adam Jackson <ajax@redhat.com>
Date:   Wed May 21 13:44:38 2008 -0400

    Linux: Fail gracefully on machines without PCI.

diff --git a/src/common_iterator.c b/src/common_iterator.c
index 73d2755..83cade3 100644
--- a/src/common_iterator.c
+++ b/src/common_iterator.c
@@ -158,6 +158,9 @@ pci_device_next( struct pci_device_iterator * iter )
 {
     struct pci_device_private * d = NULL;
 
+    if (!iter)
+	return NULL;
+
     switch( iter->mode ) {
     case match_any:
 	if ( iter->next_index < pci_sys->num_devices ) {
diff --git a/src/linux_sysfs.c b/src/linux_sysfs.c
index 5fa0ea1..9e53fac 100644
--- a/src/linux_sysfs.c
+++ b/src/linux_sysfs.c
@@ -114,6 +114,9 @@ pci_system_linux_sysfs_create( void )
 	pci_sys = calloc( 1, sizeof( struct pci_system ) );
 	if ( pci_sys != NULL ) {
 	    pci_sys->methods = & linux_sysfs_methods;
+#ifdef HAVE_MTRR
+	    pci_sys->mtrr_fd = open("/proc/mtrr", O_WRONLY);
+#endif
 	    err = populate_entries(pci_sys);
 	}
 	else {
@@ -124,10 +127,6 @@ pci_system_linux_sysfs_create( void )
 	err = errno;
     }
 
-#ifdef HAVE_MTRR
-    pci_sys->mtrr_fd = open("/proc/mtrr", O_WRONLY);
-#endif
-
     return err;
 }
 

commit 26400575a2a2d10b1014eaf0bfca6cfbf5d9b93b
Author: Dave Airlie <airlied@redhat.com>
Date:   Wed May 21 16:10:37 2008 +1000

    pciaccess: bump to 0.10.1

diff --git a/configure.ac b/configure.ac
index a5b9814..ed81dc4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -40,7 +40,7 @@ dnl refers to ${prefix}.  Thus we have to use `eval' twice.
 
 AC_PREREQ([2.57])
 
-AC_INIT(libpciaccess, 0.10, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg&component=libpciaccess], libpciaccess)
+AC_INIT(libpciaccess, 0.10.1, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg&component=libpciaccess], libpciaccess)
 AM_INIT_AUTOMAKE([dist-bzip2])
 AM_MAINTAINER_MODE
 
diff --git a/src/Makefile.am b/src/Makefile.am
index f60ccbd..8bec117 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -55,7 +55,7 @@ INCLUDES = -I$(top_srcdir)/include
 
 libpciaccess_la_LIBADD = @PCIACCESS_LIBS@
 
-libpciaccess_la_LDFLAGS = -version-number 0:10:0 -no-undefined
+libpciaccess_la_LDFLAGS = -version-number 0:10:1 -no-undefined
 
 libpciaccessincludedir = $(includedir)
 libpciaccessinclude_HEADERS = \

commit 4bc9292ff9338e759eb9a73f12edfa5ca87353e0
Author: Dave Airlie <airlied@redhat.com>
Date:   Wed May 21 16:10:24 2008 +1000

    linux: add pci_device_enable entrypoint and sysfs support for it

diff --git a/include/pciaccess.h b/include/pciaccess.h
index de8b4b3..cf32876 100644
--- a/include/pciaccess.h
+++ b/include/pciaccess.h
@@ -110,6 +110,8 @@ const char *pci_device_get_subdevice_name(const struct pci_device *dev);
 const char *pci_device_get_vendor_name(const struct pci_device *dev);
 const char *pci_device_get_subvendor_name(const struct pci_device *dev);
 
+void pci_device_enable(struct pci_device *dev);
+
 int pci_device_cfg_read    (struct pci_device *dev, void *data,
     pciaddr_t offset, pciaddr_t size, pciaddr_t *bytes_read);
 int pci_device_cfg_read_u8 (struct pci_device *dev, uint8_t  *data,
diff --git a/src/common_interface.c b/src/common_interface.c
index aee2754..663ab44 100644
--- a/src/common_interface.c
+++ b/src/common_interface.c
@@ -604,3 +604,14 @@ pci_device_cfg_write_bits( struct pci_device * dev, uint32_t mask,
 
     return err;
 }
+
+void
+pci_device_enable(struct pci_device *dev)
+{
+    if (dev == NULL) {
+	return;
+    }
+
+    if (pci_sys->methods->enable)
+	pci_sys->methods->enable(dev);
+}
diff --git a/src/linux_sysfs.c b/src/linux_sysfs.c
index 78584d6..5fa0ea1 100644
--- a/src/linux_sysfs.c
+++ b/src/linux_sysfs.c
@@ -55,6 +55,8 @@
 #include "pciaccess_private.h"
 #include "linux_devmem.h"
 
+static void pci_device_linux_sysfs_enable(struct pci_device *dev);
+
 static int pci_device_linux_sysfs_read_rom( struct pci_device * dev,
     void * buffer );
 
@@ -84,7 +86,8 @@ static const struct pci_system_methods linux_sysfs_methods = {
     .read = pci_device_linux_sysfs_read,
     .write = pci_device_linux_sysfs_write,
 
-    .fill_capabilities = pci_fill_capabilities_generic
+    .fill_capabilities = pci_fill_capabilities_generic,
+    .enable = pci_device_linux_sysfs_enable,
 };
 
 #define SYS_BUS_PCI "/sys/bus/pci/devices"
@@ -622,3 +625,23 @@ pci_device_linux_sysfs_unmap_range(struct pci_device *dev,
 
     return err;
 }
+
+static void pci_device_linux_sysfs_enable(struct pci_device *dev)
+{
+    char name[256];
+    int fd;
+
+    snprintf( name, 255, "%s/%04x:%02x:%02x.%1u/enable",
+	      SYS_BUS_PCI,
+	      dev->domain,
+	      dev->bus,
+	      dev->dev,
+	      dev->func );
+    
+    fd = open( name, O_RDWR );
+    if (fd == -1)
+       return;
+
+    write( fd, "1", 1 );
+    close(fd);
+}
diff --git a/src/pciaccess_private.h b/src/pciaccess_private.h
index 494f577..6048af1 100644
--- a/src/pciaccess_private.h
+++ b/src/pciaccess_private.h
@@ -59,6 +59,7 @@ struct pci_system_methods {
 		pciaddr_t size, pciaddr_t * bytes_written );
 
     int (*fill_capabilities)( struct pci_device * dev );
+    void (*enable)( struct pci_device *dev );
 };
 
 struct pci_device_mapping {

commit ded8326f2adadc773b34889474a0d4fc20ef387a
Author: Alan Coopersmith <alan.coopersmith@sun.com>
Date:   Fri May 9 15:15:42 2008 -0700

    Fix lint warnings in solx_devfs.c

diff --git a/src/solx_devfs.c b/src/solx_devfs.c
index eceb9af..a2daec1 100644
--- a/src/solx_devfs.c
+++ b/src/solx_devfs.c
@@ -108,12 +108,6 @@ static int pci_device_solx_devfs_read_rom( struct pci_device * dev,
 
 static int pci_device_solx_devfs_probe( struct pci_device * dev );
 
-static int pci_device_solx_devfs_map_region( struct pci_device * dev,
-    unsigned region, int write_enable );
-
-static int pci_device_solx_devfs_unmap_region( struct pci_device * dev,
-    unsigned region );
-
 static int pci_device_solx_devfs_read( struct pci_device * dev, void * data,
     pciaddr_t offset, pciaddr_t size, pciaddr_t * bytes_read );
 
@@ -600,7 +594,7 @@ pci_device_solx_devfs_probe( struct pci_device * dev )
 		 * using libdevinfo
 		 */
 		if ((rnode = di_init("/", DINFOCPYALL)) == DI_NODE_NIL) {
-			(void) fprintf(stderr, "di_init failed: $s\n",
+			(void) fprintf(stderr, "di_init failed: %s\n",
 			    strerror(errno));
 			err = errno;
 		} else {
@@ -759,7 +753,7 @@ pci_device_solx_devfs_read( struct pci_device * dev, void * data,
 		cfg_prg.offset = offset + i;
 		if ((err = ioctl(root_fd, PCITOOL_DEVICE_GET_REG,
 		    &cfg_prg)) != 0) {
-			fprintf(stderr, "read bdf<%x,%x,%x,%x> config space failure\n",
+			fprintf(stderr, "read bdf<%x,%x,%x,%llx> config space failure\n",
 			    cfg_prg.bus_no,
 			    cfg_prg.dev_no,
 			    cfg_prg.func_no,
@@ -867,7 +861,7 @@ pci_device_solx_devfs_map_range(struct pci_device *dev,
 	if (map->memory == MAP_FAILED) {
 		err = errno;
 
-		(void) fprintf(stderr, "map rom region =%x failed",
+		(void) fprintf(stderr, "map rom region =%llx failed",
 			       map->base);
 	}
 

commit 74c976a7bcee3102993cf788850d0b803cf15afd
Author: Alan Coopersmith <alan.coopersmith@sun.com>
Date:   Fri May 9 15:05:46 2008 -0700

    Add pci_system_solx_devfs_create prototype to pciaccess_private.h

diff --git a/src/pciaccess_private.h b/src/pciaccess_private.h
index 94b12bd..494f577 100644
--- a/src/pciaccess_private.h
+++ b/src/pciaccess_private.h
@@ -137,3 +137,4 @@ extern int pci_system_linux_sysfs_create( void );
 extern int pci_system_freebsd_create( void );
 extern int pci_system_openbsd_create( void );
 extern void pci_system_openbsd_init_dev_mem( int );
+extern int pci_system_solx_devfs_create( void );

commit 2ac461b2eca788fa0559312d45efd3caf6eea9bb
Author: Alan Coopersmith <alan.coopersmith@sun.com>
Date:   Fri May 9 14:49:32 2008 -0700

    Initialize err to 0 in pci_device_solx_devfs_map_range
    
    Prevents returning errors when mapping actually succeeds

diff --git a/src/solx_devfs.c b/src/solx_devfs.c
index 08de4d0..eceb9af 100644
--- a/src/solx_devfs.c
+++ b/src/solx_devfs.c
@@ -852,7 +852,7 @@ pci_device_solx_devfs_map_range(struct pci_device *dev,
 {
 	const int prot = ((map->flags & PCI_DEV_MAP_FLAG_WRITABLE) != 0) 
 		? (PROT_READ | PROT_WRITE) : PROT_READ;
-	int err;
+	int err = 0;
 
 
 	if (xsvc_fd < 0) {

commit b30d458202bc0304c705eb081b12ead860584bea
Author: Keith Packard <keithp@keithp.com>
Date:   Wed Apr 16 12:10:52 2008 -0700

    Kludge around linux bug and turn off write-through and cache-disable bits
    
    When mmaping the PCI device, the kernel turns on the write-through and
    cache-disable bits in the allocated PTEs. This disables write-combining mode
    and dramatically reduces write bandwidth to the frame buffer. While that
    should be fixed in the kernel, we'll kludge around it here by using mprotect
    to rewrite the PTEs and get those bits turned off.

diff --git a/src/linux_sysfs.c b/src/linux_sysfs.c
index 873dc02..78584d6 100644
--- a/src/linux_sysfs.c
+++ b/src/linux_sysfs.c
@@ -558,6 +558,9 @@ pci_device_linux_sysfs_map_range(struct pci_device *dev,
 		    strerror(errno), errno);
 /*            err = errno;*/
 	}
+	/* KLUDGE ALERT -- rewrite the PTEs to turn off the CD and WT bits */
+	mprotect (map->memory, map->size, PROT_NONE);
+	mprotect (map->memory, map->size, PROT_READ|PROT_WRITE);
     }
 #endif
 

commit a3b63c43b960e3b37e1b303214e63c5155192a5d
Author: Hasso Tepper <hasso@estpak.ee>
Date:   Mon Apr 7 15:28:44 2008 +0300

    Add DragonFly BSD support
    
    DragonFly behaves exactly like FreeBSD, so no problem here.

diff --git a/configure.ac b/configure.ac
index 6163577..a5b9814 100644
--- a/configure.ac
+++ b/configure.ac
@@ -71,7 +71,7 @@ if test "x$GCC" = "xyes"; then
 fi
 
 case $host_os in
-	*freebsd*)
+	*freebsd* | *dragonfly*)
 		freebsd=yes
 		;;
 	*linux*)
diff --git a/src/common_init.c b/src/common_init.c
index 7429518..ff24183 100644
--- a/src/common_init.c
+++ b/src/common_init.c
@@ -54,7 +54,7 @@ pci_system_init( void )
     
 #ifdef linux
     err = pci_system_linux_sysfs_create();
-#elif defined(__FreeBSD__)
+#elif defined(__FreeBSD__) || defined(__DragonFly__)
     err = pci_system_freebsd_create();
 #elif defined(__OpenBSD__)
     err = pci_system_openbsd_create();
diff --git a/src/common_interface.c b/src/common_interface.c
index d7e4b62..aee2754 100644
--- a/src/common_interface.c
+++ b/src/common_interface.c
@@ -64,7 +64,7 @@
 #define HTOLE_16(x)	htole16(x)
 #define HTOLE_32(x)	htole32(x)
 
-#ifdef __FreeBSD__
+#if defined(__FreeBSD__) || defined(__DragonFly__)
 #define LETOH_16(x)	le16toh(x)
 #define LETOH_32(x)	le32toh(x)
 #else

commit ec53d6ef2bdf0e7a087ffd45fe112290f2181656
Author: Danny van Dyk <danny.dyk@uni-dortmund.de>
Date:   Fri Mar 28 17:01:29 2008 -0700

    Fix function prototypes for C++

diff --git a/include/pciaccess.h b/include/pciaccess.h
index 3138877..de8b4b3 100644
--- a/include/pciaccess.h
+++ b/include/pciaccess.h
@@ -46,6 +46,10 @@ struct pci_device_iterator;
 struct pci_id_match;
 struct pci_slot_match;
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 int pci_device_read_rom(struct pci_device *dev, void *buffer);
 
 int  __deprecated pci_device_map_region(struct pci_device *dev,
@@ -126,6 +130,10 @@ int pci_device_cfg_write_u32(struct pci_device *dev, uint32_t data,
 int pci_device_cfg_write_bits(struct pci_device *dev, uint32_t mask,
     uint32_t data, pciaddr_t offset);
 
+#ifdef __cplusplus
+}
+#endif
+
 /**
  * \name Mapping flags passed to \c pci_device_map_range
  */

commit a5c862029846ddd5cecf44819f2a967e2a1672a9
Author: Stuart Bennett <sb476@cam.ac.uk>
Date:   Fri Mar 14 11:58:33 2008 -0400

    Bug #13988: Fix reads from "0"-sized ROMs.

diff --git a/src/linux_devmem.c b/src/linux_devmem.c
index a68ea11..21b45ef 100644
--- a/src/linux_devmem.c
+++ b/src/linux_devmem.c
@@ -124,7 +124,7 @@ pci_device_linux_devmem_read_rom(struct pci_device *dev, void *buffer)
     else {
 	size_t bytes;
 
-	for (bytes = 0; bytes < priv->base.rom_size; /* empty */) {
+	for (bytes = 0; bytes < rom_size; /* empty */) {
 	    const ssize_t got = pread(fd, buffer, rom_size - bytes, 
 				      rom_base + bytes);
 	    if (got == -1) {
diff --git a/src/linux_sysfs.c b/src/linux_sysfs.c
index 84cdb84..873dc02 100644
--- a/src/linux_sysfs.c
+++ b/src/linux_sysfs.c
@@ -307,6 +307,7 @@ pci_device_linux_sysfs_read_rom( struct pci_device * dev, void * buffer )
     int fd;
     struct stat  st;
     int err = 0;
+    size_t rom_size;
     size_t total_bytes;
 
 
@@ -331,6 +332,9 @@ pci_device_linux_sysfs_read_rom( struct pci_device * dev, void * buffer )
 	return errno;
     }
 
+    rom_size = st.st_size;
+    if ( rom_size == 0 )
+	rom_size = 0x10000;
 
     /* This is a quirky thing on Linux.  Even though the ROM and the file
      * for the ROM in sysfs are read-only, the string "1" must be written to
@@ -340,9 +344,9 @@ pci_device_linux_sysfs_read_rom( struct pci_device * dev, void * buffer )
     write( fd, "1", 1 );
     lseek( fd, 0, SEEK_SET );
 
-    for ( total_bytes = 0 ; total_bytes < st.st_size ; /* empty */ ) {
+    for ( total_bytes = 0 ; total_bytes < rom_size ; /* empty */ ) {
 	const int bytes = read( fd, (char *) buffer + total_bytes,
-				st.st_size - total_bytes );
+				rom_size - total_bytes );
 	if ( bytes == -1 ) {
 	    err = errno;
 	    break;

commit d898072e28ac35f5b3569f48f2e90a9ef8eee2ca
Author: Mark Kettenis <mark.kettenis@xs4all.nl>
Date:   Wed Mar 12 21:29:58 2008 +0100

    OpenBSD support for libpciaccess.
    
    xserver and libpciaccess both need to open /dev/xf86, which can only
    be opened once.  I implemented pci_system_init_dev_mem() like Ian
    suggested.  This requires some minor changes to the BSD-specific
    os-support code.  Since pci_system_init_dev_mem() is a no-op on
    FreeBSD this should be no problem.

diff --git a/configure.ac b/configure.ac
index 8f4e55d..6163577 100644
--- a/configure.ac
+++ b/configure.ac
@@ -77,6 +77,9 @@ case $host_os in
 	*linux*)
 		linux=yes
 		;;
+	*openbsd*)
+		openbsd=yes
+		;;
 	*solaris*)
 		solaris=yes
 		PCIACCESS_LIBS="$PCIACCESS_LIBS -ldevinfo"
@@ -85,6 +88,7 @@ esac
 
 AM_CONDITIONAL(LINUX, [test "x$linux" = xyes])
 AM_CONDITIONAL(FREEBSD, [test "x$freebsd" = xyes])
+AM_CONDITIONAL(OPENBSD, [test "x$openbsd" = xyes])
 AM_CONDITIONAL(SOLARIS, [test "x$solaris" = xyes])
 
 AC_CHECK_FILE([/usr/include/asm/mtrr.h],
diff --git a/include/pciaccess.h b/include/pciaccess.h
index dcc0122..3138877 100644
--- a/include/pciaccess.h
+++ b/include/pciaccess.h
@@ -81,6 +81,8 @@ int pci_device_get_bridge_buses(struct pci_device *dev, int *primary_bus,
 
 int pci_system_init(void);
 
+void pci_system_init_dev_mem(int fd);
+
 void pci_system_cleanup(void);
 
 struct pci_device_iterator *pci_slot_match_iterator_create(
diff --git a/src/Makefile.am b/src/Makefile.am
index f370920..f60ccbd 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -33,6 +33,10 @@ if FREEBSD
 OS_SUPPORT = freebsd_pci.c
 endif
 
+if OPENBSD
+OS_SUPPORT = openbsd_pci.c
+endif
+
 if SOLARIS
 OS_SUPPORT = solx_devfs.c pci_tools.h
 endif
diff --git a/src/common_init.c b/src/common_init.c
index 1092faf..7429518 100644
--- a/src/common_init.c
+++ b/src/common_init.c
@@ -56,13 +56,22 @@ pci_system_init( void )
     err = pci_system_linux_sysfs_create();
 #elif defined(__FreeBSD__)
     err = pci_system_freebsd_create();
+#elif defined(__OpenBSD__)
+    err = pci_system_openbsd_create();
 #elif defined(__sun)
-	err = pci_system_solx_devfs_create();
+    err = pci_system_solx_devfs_create();
 #endif
 
     return err;
 }
 
+void
+pci_system_init_dev_mem(int fd)
+{
+#ifdef __OpenBSD__
+    pci_system_openbsd_init_dev_mem(fd);
+#endif
+}
 
 /**
  * Shutdown all access to the PCI subsystem.
diff --git a/src/common_interface.c b/src/common_interface.c
index 7fae277..d7e4b62 100644
--- a/src/common_interface.c
+++ b/src/common_interface.c
@@ -61,11 +61,17 @@
 
 #include <sys/endian.h>
 
-#define LETOH_16(x)	le16toh(x)
 #define HTOLE_16(x)	htole16(x)
-#define LETOH_32(x)	le32toh(x)
 #define HTOLE_32(x)	htole32(x)
 
+#ifdef __FreeBSD__
+#define LETOH_16(x)	le16toh(x)
+#define LETOH_32(x)	le32toh(x)
+#else
+#define LETOH_16(x)	letoh16(x)
+#define LETOH_32(x)	letoh32(x)
+#endif
+
 #endif /* others */
 
 /**
diff --git a/src/common_map.c b/src/common_map.c
index ac1c668..8757151 100644
--- a/src/common_map.c
+++ b/src/common_map.c
@@ -22,6 +22,7 @@
  * DEALINGS IN THE SOFTWARE.
  */
 
+#include <sys/types.h>
 #include <sys/mman.h>
 #include <errno.h>
 
diff --git a/src/openbsd_pci.c b/src/openbsd_pci.c
new file mode 100644
index 0000000..5c06b47
--- /dev/null
+++ b/src/openbsd_pci.c
@@ -0,0 +1,406 @@
+/*
+ * Copyright (c) 2008 Mark Kettenis
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/ioctl.h>
+#include <sys/memrange.h>
+#include <sys/mman.h>
+#include <sys/pciio.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcidevs.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "pciaccess.h"
+#include "pciaccess_private.h"
+
+static int pcifd;
+static int aperturefd = -1;
+
+static int
+pci_read(int bus, int dev, int func, uint32_t reg, uint32_t *val)
+{
+	struct pci_io io;
+	int err;
+
+	bzero(&io, sizeof(io));
+	io.pi_sel.pc_bus = bus;
+	io.pi_sel.pc_dev = dev;
+	io.pi_sel.pc_func = func;
+	io.pi_reg = reg;
+	io.pi_width = 4;
+
+	err = ioctl(pcifd, PCIOCREAD, &io);
+	if (err)
+		return (err);
+
+	*val = io.pi_data;
+
+	return (0);
+}
+
+static int
+pci_write(int bus, int dev, int func, uint32_t reg, uint32_t val)
+{
+	struct pci_io io;
+
+	bzero(&io, sizeof(io));
+	io.pi_sel.pc_bus = bus;
+	io.pi_sel.pc_dev = dev;
+	io.pi_sel.pc_func = func;
+	io.pi_reg = reg;
+	io.pi_width = 4;
+	io.pi_data = val;
+
+	return ioctl(pcifd, PCIOCWRITE, &io);
+}
+
+static int
+pci_nfuncs(int bus, int dev)
+{
+	uint32_t hdr;
+
+	if (pci_read(bus, dev, 0, PCI_BHLC_REG, &hdr) != 0)
+		return -1;
+
+	return (PCI_HDRTYPE_MULTIFN(hdr) ? 8 : 1);
+}
+
+static int
+pci_device_openbsd_map_range(struct pci_device *dev,
+    struct pci_device_mapping *map)
+{
+	struct mem_range_desc mr;
+	struct mem_range_op mo;
+	int prot = PROT_READ;
+
+	if (map->flags & PCI_DEV_MAP_FLAG_WRITABLE)
+		prot |= PROT_WRITE;
+
+	map->memory = mmap(NULL, map->size, prot, MAP_SHARED, aperturefd,
+	    map->base);
+	if (map->memory == MAP_FAILED)
+		return  errno;
+
+	/* No need to set an MTRR if it's the default mode. */
+	if ((map->flags & PCI_DEV_MAP_FLAG_CACHABLE) ||
+	    (map->flags & PCI_DEV_MAP_FLAG_WRITE_COMBINE)) {
+		mr.mr_base = map->base;
+		mr.mr_len = map->size;
+		mr.mr_flags = 0;
+		if (map->flags & PCI_DEV_MAP_FLAG_CACHABLE)
+			mr.mr_flags |= MDF_WRITEBACK;
+		if (map->flags & PCI_DEV_MAP_FLAG_WRITE_COMBINE)
+			mr.mr_flags |= MDF_WRITECOMBINE;
+		strlcpy(mr.mr_owner, "pciaccess", sizeof(mr.mr_owner));
+
+		mo.mo_desc = &mr;
+		mo.mo_arg[0] = MEMRANGE_SET_UPDATE;
+
+		if (ioctl(aperturefd, MEMRANGE_SET, &mo))
+			return errno;
+	}
+
+	return 0;
+}
+
+static int
+pci_device_openbsd_unmap_range(struct pci_device *dev,
+    struct pci_device_mapping *map)
+{
+	struct mem_range_desc mr;
+	struct mem_range_op mo;
+
+	if ((map->flags & PCI_DEV_MAP_FLAG_CACHABLE) ||
+	    (map->flags & PCI_DEV_MAP_FLAG_WRITE_COMBINE)) {
+		mr.mr_base = map->base;
+		mr.mr_len = map->size;
+		mr.mr_flags = MDF_UNCACHEABLE;
+		strlcpy(mr.mr_owner, "pciaccess", sizeof(mr.mr_owner));
+
+		mo.mo_desc = &mr;
+		mo.mo_arg[0] = MEMRANGE_SET_REMOVE;
+
+		(void)ioctl(aperturefd, MEMRANGE_SET, &mo);
+	}
+
+	return pci_device_generic_unmap_range(dev, map);
+}
+
+static int
+pci_device_openbsd_read(struct pci_device *dev, void *data,
+    pciaddr_t offset, pciaddr_t size, pciaddr_t *bytes_read)
+{
+	struct pci_io io;
+
+	io.pi_sel.pc_bus = dev->bus;
+	io.pi_sel.pc_dev = dev->dev;
+	io.pi_sel.pc_func = dev->func;
+
+	*bytes_read = 0;
+	while (size > 0) {
+		int toread = MIN(size, 4 - (offset & 0x3));
+
+		io.pi_reg = (offset & ~0x3);
+		io.pi_width = 4;
+
+		if (ioctl(pcifd, PCIOCREAD, &io) == -1)
+			return errno;
+
+		io.pi_data = htole32(io.pi_data);
+		io.pi_data >>= ((offset & 0x3) * 8);
+
+		memcpy(data, &io.pi_data, toread);
+
+		offset += toread;
+		data = (char *)data + toread;
+		size -= toread;
+		*bytes_read += toread;
+	}
+
+	return 0;
+}
+
+static int
+pci_device_openbsd_write(struct pci_device *dev, const void *data,
+    pciaddr_t offset, pciaddr_t size, pciaddr_t *bytes_written)
+{
+	struct pci_io io;
+
+	if ((offset % 4) == 0 || (size % 4) == 0)
+		return EINVAL;
+
+	io.pi_sel.pc_bus = dev->bus;
+	io.pi_sel.pc_dev = dev->dev;
+	io.pi_sel.pc_func = dev->func;
+
+	*bytes_written = 0;
+	while (size > 0) {
+		io.pi_reg = offset;
+		io.pi_width = 4;
+		memcpy(&io.pi_data, data, 4);
+
+		if (ioctl(pcifd, PCIOCWRITE, &io) == -1) 
+			return errno;
+
+		offset += 4;
+		data = (char *)data + 4;
+		size -= 4;
+		*bytes_written += 4;
+	}
+
+	return 0;
+}
+
+static void
+pci_system_openbsd_destroy(void)
+{
+	close(aperturefd);
+	close(pcifd);
+	free(pci_sys);
+	pci_sys = NULL;
+}
+
+static int
+pci_device_openbsd_probe(struct pci_device *device)
+{
+	struct pci_device_private *priv = (struct pci_device_private *)device;
+	struct pci_mem_region *region;
+	uint64_t reg64, size64;
+	uint32_t bar, reg, size;
+	int bus, dev, func, err;
+
+	bus = device->bus;
+	dev = device->dev;
+	func = device->func;
+
+	err = pci_read(bus, dev, func, PCI_BHLC_REG, &reg);
+	if (err)
+		return err;
+
+	priv->header_type = PCI_HDRTYPE_TYPE(reg);
+	if (priv->header_type != 0)
+		return 0;
+
+	region = device->regions;
+	for (bar = PCI_MAPREG_START; bar < PCI_MAPREG_END;
+	     bar += sizeof(uint32_t), region++) {
+		err = pci_read(bus, dev, func, bar, &reg);
+		if (err)
+			return err;
+
+		/* Probe the size of the region. */
+		err = pci_write(bus, dev, func, bar, ~0);
+		if (err)
+			return err;
+		pci_read(bus, dev, func, bar, &size);
+		pci_write(bus, dev, func, bar, reg);
+
+		if (PCI_MAPREG_TYPE(reg) == PCI_MAPREG_TYPE_IO) {
+			region->is_IO = 1;
+			region->base_addr = PCI_MAPREG_IO_ADDR(reg);
+			region->size = PCI_MAPREG_IO_SIZE(size);
+		} else {
+			if (PCI_MAPREG_MEM_PREFETCHABLE(reg))
+				region->is_prefetchable = 1;
+			switch(PCI_MAPREG_MEM_TYPE(reg)) {
+			case PCI_MAPREG_MEM_TYPE_32BIT:
+			case PCI_MAPREG_MEM_TYPE_32BIT_1M:
+				region->base_addr = PCI_MAPREG_MEM_ADDR(reg);
+				region->size = PCI_MAPREG_MEM_SIZE(size);
+				break;
+			case PCI_MAPREG_MEM_TYPE_64BIT:
+				region->is_64 = 1;
+
+				reg64 = reg;
+				size64 = size;
+
+				bar += sizeof(uint32_t);
+
+				err = pci_read(bus, dev, func, bar, &reg);
+				if (err)
+					return err;
+				reg64 |= (uint64_t)reg << 32;
+
+				err = pci_write(bus, dev, func, bar, ~0);
+				if (err)
+					return err;
+				pci_read(bus, dev, func, bar, &size);
+				pci_write(bus, dev, func, bar, reg64 >> 32);
+				size64 |= (uint64_t)size << 32;
+
+				region->base_addr = PCI_MAPREG_MEM64_ADDR(reg64);
+				region->size = PCI_MAPREG_MEM64_SIZE(size64);
+				region++;
+				break;
+			}
+		}
+	}
+
+	return 0;
+}
+
+static const struct pci_system_methods openbsd_pci_methods = {
+	pci_system_openbsd_destroy,
+	NULL,
+	NULL,
+	pci_device_openbsd_probe,
+	pci_device_openbsd_map_range,
+	pci_device_openbsd_unmap_range,
+	pci_device_openbsd_read,
+	pci_device_openbsd_write,
+	pci_fill_capabilities_generic
+};
+
+int
+pci_system_openbsd_create(void)
+{


Reply to: