diff options
author | Matthieu Herrb <matthieu.herrb@laas.fr> | 2008-08-09 12:14:30 +0200 |
---|---|---|
committer | Matthieu Herrb <matthieu@bluenote.herrb.net> | 2008-08-09 12:14:30 +0200 |
commit | 81e2ee60b8bab0b8046acfa95b95f56ddc5d943a (patch) | |
tree | 8858903e315a7ff8d6969b69c5eec5be3dc80b2e | |
parent | 15b27bc2d50aa6fb4b129fe1ebc10a865804d828 (diff) | |
parent | 45015ab30b36bdaefd3f3aeab73d287023928826 (diff) |
Merge branch 'master' into obsd
-rw-r--r-- | configure.ac | 15 | ||||
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/common_device_name.c | 39 | ||||
-rw-r--r-- | src/freebsd_pci.c | 1 | ||||
-rw-r--r-- | src/linux_sysfs.c | 64 |
5 files changed, 104 insertions, 17 deletions
diff --git a/configure.ac b/configure.ac index ed81dc4..67b18f4 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.3, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg&component=libpciaccess], libpciaccess) AM_INIT_AUTOMAKE([dist-bzip2]) AM_MAINTAINER_MODE @@ -59,6 +59,19 @@ AC_ARG_WITH(pciids-path, [PCIIDS_PATH="$DEFAULT_PCIIDS_PATH"]) AC_DEFINE_DIR(PCIIDS_PATH, PCIIDS_PATH, [Path to pci.ids]) +AC_ARG_WITH(zlib, + AS_HELP_STRING([--with-zlib], [Enable zlib support to read gzip compressed pci.ids]), + [use_zlib="yes"], + [use_zlib="no"]) +if test "x$use_zlib" = xyes; then + AC_CHECK_LIB(z, gzopen, + [PCIACCESS_LIBS="$PCIACCESS_LIBS -lz"], + [AC_MSG_ERROR(Check for zlib library failed)]) + AC_CHECK_HEADER([zlib.h], + [AC_DEFINE(HAVE_ZLIB, 1, [Use zlib to read gzip compressed pci.ids])], + [AC_MSG_ERROR(Check for zlib.h header file failed)]) +fi + if test "x$GCC" = "xyes"; then GCC_WARNINGS1="-Wall -Wpointer-arith -Wstrict-prototypes" GCC_WARNINGS2="-Wmissing-prototypes -Wmissing-declarations" 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 = \ diff --git a/src/common_device_name.c b/src/common_device_name.c index b105187..877f218 100644 --- a/src/common_device_name.c +++ b/src/common_device_name.c @@ -50,6 +50,31 @@ #define DO_MATCH(a,b) (((a) == PCI_MATCH_ANY) || ((a) == (b))) +#ifdef HAVE_ZLIB +#include <zlib.h> +typedef gzFile pci_id_file; + +static pci_id_file +pci_id_file_open() +{ + pci_id_file result; + + result = gzopen(PCIIDS_PATH "/pci.ids.gz", "rb"); + if (result) + return result; + + return gzopen(PCIIDS_PATH "/pci.ids", "rb"); +} + +#define pci_id_file_gets(l, s, f) gzgets(f, l, s) +#define pci_id_file_close(f) gzclose(f) +#else +typedef FILE pci_id_file; +#define pci_id_file_open() fopen(PCIIDS_PATH "/pci.ids", "r") +#define pci_id_file_gets(l, s, f) fgets(l, s, f) +#define pci_id_file_close(f) fclose(f) +#endif + /** * Node for sorting vendor IDs. * @@ -96,12 +121,6 @@ struct pci_device_leaf { _pci_hidden struct pci_id_node * tree = NULL; /** - * Name of the file containing the PCI ID information. - */ -static const char pci_id_file[] = PCIIDS_PATH "/pci.ids"; - - -/** * Get a pointer to the leaf node for a vendor ID. * * If the vendor ID does not exist in the tree, it is added. @@ -170,7 +189,7 @@ insert( uint16_t vendor ) static void populate_vendor( struct pci_id_leaf * vend, int fill_device_data ) { - FILE * f = fopen( pci_id_file, "r" ); + pci_id_file * f = pci_id_file_open(); char buf[128]; unsigned vendor = PCI_MATCH_ANY; @@ -186,12 +205,12 @@ populate_vendor( struct pci_id_leaf * vend, int fill_device_data ) * anything. This avoids wasted processing and potential memory leaks. */ if (vend->num_devices != 0) { - fclose(f); + pci_id_file_close( f ); return; } - while( fgets( buf, sizeof( buf ), f ) != NULL ) { + while( pci_id_file_gets( buf, sizeof( buf ), f ) != NULL ) { unsigned num_tabs; char * new_line; size_t length; @@ -284,7 +303,7 @@ populate_vendor( struct pci_id_leaf * vend, int fill_device_data ) } } - fclose( f ); + pci_id_file_close( f ); } diff --git a/src/freebsd_pci.c b/src/freebsd_pci.c index 67ca9e3..4b8f7ba 100644 --- a/src/freebsd_pci.c +++ b/src/freebsd_pci.c @@ -64,6 +64,7 @@ * * It is initialized once and used as a global, just as pci_system is used. */ +_pci_hidden struct freebsd_pci_system { /* This must be the first entry in the structure, as pci_system_cleanup() * frees pci_sys. diff --git a/src/linux_sysfs.c b/src/linux_sysfs.c index 9e53fac..ca4d3ef 100644 --- a/src/linux_sysfs.c +++ b/src/linux_sysfs.c @@ -484,6 +484,40 @@ pci_device_linux_sysfs_write( struct pci_device * dev, const void * data, return err; } +static int +pci_device_linux_sysfs_map_range_wc(struct pci_device *dev, + struct pci_device_mapping *map) +{ + char name[256]; + int fd; + const int prot = ((map->flags & PCI_DEV_MAP_FLAG_WRITABLE) != 0) + ? (PROT_READ | PROT_WRITE) : PROT_READ; + const int open_flags = ((map->flags & PCI_DEV_MAP_FLAG_WRITABLE) != 0) + ? O_RDWR : O_RDONLY; + const off_t offset = map->base - dev->regions[map->region].base_addr; + + snprintf(name, 255, "%s/%04x:%02x:%02x.%1u/resource%u_wc", + SYS_BUS_PCI, + dev->domain, + dev->bus, + dev->dev, + dev->func, + map->region); + fd = open(name, open_flags); + if (fd == -1) + return errno; + + map->memory = mmap(NULL, map->size, prot, MAP_SHARED, fd, offset); + if (map->memory == MAP_FAILED) { + map->memory = NULL; + close(fd); + return errno; + } + + close(fd); + + return 0; +} /** * Map a memory region for a device using the Linux sysfs interface. @@ -521,6 +555,11 @@ pci_device_linux_sysfs_map_range(struct pci_device *dev, }; #endif + /* For WC mappings, try sysfs resourceN_wc file first */ + if ((map->flags & PCI_DEV_MAP_FLAG_WRITE_COMBINE) && + !pci_device_linux_sysfs_map_range_wc(dev, map)) + return 0; + snprintf(name, 255, "%s/%04x:%02x:%02x.%1u/resource%u", SYS_BUS_PCI, dev->domain, @@ -537,12 +576,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 +600,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 performance 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; } /** |