diff options
author | Matthieu Herrb <matthieu@herrb.eu> | 2017-10-22 18:31:07 +0200 |
---|---|---|
committer | Matthieu Herrb <matthieu@herrb.eu> | 2017-10-22 18:31:07 +0200 |
commit | 479a7a6ffaf61a223348e5653bd8b96c686e57c1 (patch) | |
tree | 24849c7c81d8e06c79e0e88bc9195bce6f15145f | |
parent | 64740791daf57cae85ceb6ef9689d2771c9288ee (diff) | |
parent | a167bd6474522a709ff3cbb00476c0e4309cb66f (diff) |
Merge remote-tracking branch 'origin/master' into obsd
-rw-r--r-- | configure.ac | 4 | ||||
-rw-r--r-- | include/pciaccess.h | 15 | ||||
-rw-r--r-- | src/linux_sysfs.c | 26 | ||||
-rw-r--r-- | src/netbsd_pci.c | 4 | ||||
-rw-r--r-- | src/openbsd_pci.c | 4 | ||||
-rw-r--r-- | src/solx_devfs.c | 55 | ||||
-rw-r--r-- | src/x86_pci.c | 2 |
7 files changed, 65 insertions, 45 deletions
diff --git a/configure.ac b/configure.ac index 888330b..aac02c1 100644 --- a/configure.ac +++ b/configure.ac @@ -23,10 +23,10 @@ # Initialize Autoconf AC_PREREQ([2.60]) -AC_INIT([libpciaccess],[0.13.4], +AC_INIT([libpciaccess],[0.13.5], [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg&component=libpciaccess],[libpciaccess]) -AC_CONFIG_SRCDIR([Makefile.am]) AC_CONFIG_HEADERS([config.h]) +AC_CONFIG_AUX_DIR([.]) # Initialize Automake AM_INIT_AUTOMAKE([foreign dist-bzip2]) diff --git a/include/pciaccess.h b/include/pciaccess.h index 1d7aa4b..8167be6 100644 --- a/include/pciaccess.h +++ b/include/pciaccess.h @@ -311,6 +311,10 @@ struct pci_mem_region { * PCI device. * * Contains all of the information about a particular PCI device. + * + * This structure - like everything else in libpciaccess - is allocated + * by the library itself. Do not embed this structure in other structs, + * or otherwise allocate them yourself. */ struct pci_device { /** @@ -319,9 +323,12 @@ struct pci_device { * Complete bus identification, including domain, of the device. On * platforms that do not support PCI domains (e.g., 32-bit x86 hardware), * the domain will always be zero. + * + * The domain_16 field is provided for binary compatibility with older + * libpciaccess. */ /*@{*/ - uint16_t domain; + uint16_t domain_16; uint8_t bus; uint8_t dev; uint8_t func; @@ -385,6 +392,12 @@ struct pci_device { * Used by the VGA arbiter. Type of resource decoded by the device and * the file descriptor (/dev/vga_arbiter). */ int vgaarb_rsrc; + + + /** + * PCI domain value (full 32 bits) + */ + uint32_t domain; }; diff --git a/src/linux_sysfs.c b/src/linux_sysfs.c index 8055e8d..a8bc2e1 100644 --- a/src/linux_sysfs.c +++ b/src/linux_sysfs.c @@ -49,7 +49,6 @@ #include <sys/mman.h> #include <dirent.h> #include <errno.h> -#include <limits.h> #if defined(__i386__) || defined(__x86_64__) || defined(__arm__) #include <sys/io.h> @@ -119,28 +118,18 @@ pci_system_linux_sysfs_create( void ) /** - * Filter out the names "." and ".." from the scanned sysfs entries, and - * domains requiring 32-bits. + * Filter out the names "." and ".." from the scanned sysfs entries. * * \param d Directory entry being processed by \c scandir. * * \return - * Zero if the entry name matches either "." or "..", or the domain requires - * 32 bits, non-zero otherwise. + * Zero if the entry name matches either "." or ".." * * \sa scandir, populate_entries */ static int scan_sys_pci_filter( const struct dirent * d ) { - if (d->d_name[0] != '.') { - unsigned dom = 0; - - sscanf(d->d_name, "%x:", &dom); - if (dom > USHRT_MAX) - return 0; - } - return !((strcmp( d->d_name, "." ) == 0) || (strcmp( d->d_name, ".." ) == 0)); } @@ -219,10 +208,19 @@ populate_entries( struct pci_system * p ) (struct pci_device_private *) &p->devices[i]; - sscanf(devices[i]->d_name, "%04x:%02x:%02x.%1u", + sscanf(devices[i]->d_name, "%x:%02x:%02x.%1u", & dom, & bus, & dev, & func); device->base.domain = dom; + /* + * Applications compiled with older versions do not expect + * 32-bit domain numbers. To keep them working, we keep a 16-bit + * version of the domain number at the previous location. + */ + if (dom > 0xffff) + device->base.domain_16 = 0xffff; + else + device->base.domain_16 = dom; device->base.bus = bus; device->base.dev = dev; device->base.func = func; diff --git a/src/netbsd_pci.c b/src/netbsd_pci.c index f972f94..1f3bcea 100644 --- a/src/netbsd_pci.c +++ b/src/netbsd_pci.c @@ -959,6 +959,10 @@ pci_system_netbsd_create(void) continue; device->base.domain = domain; + if (domain > 0xffff) + device->base.domain_16 = 0xffff; + else + device->base.domain_16 = domain & 0xffff; device->base.bus = bus; device->base.dev = dev; device->base.func = func; diff --git a/src/openbsd_pci.c b/src/openbsd_pci.c index 15cd900..0412726 100644 --- a/src/openbsd_pci.c +++ b/src/openbsd_pci.c @@ -668,6 +668,10 @@ pci_system_openbsd_create(void) continue; device->base.domain = domain; + if (domain > 0xffff) + device->base.domain_16 = 0xffff; + else + device->base.domain_16 = domain & 0xffff; device->base.bus = bus; device->base.dev = dev; device->base.func = func; diff --git a/src/solx_devfs.c b/src/solx_devfs.c index cf96467..dc1464d 100644 --- a/src/solx_devfs.c +++ b/src/solx_devfs.c @@ -1,6 +1,6 @@ /* * (C) Copyright IBM Corporation 2006 - * Copyright (c) 2007, 2009, 2011, 2012, 2013 Oracle and/or its affiliates. + * Copyright (c) 2007, 2009, 2011, 2012, 2016 Oracle and/or its affiliates. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -62,11 +62,10 @@ typedef struct i_devnode { } i_devnode_t; typedef struct nexus { - int fd; int first_bus; int last_bus; int domain; - char *path; /* for errors/debugging; fd is all we need */ + char *path; /* for open */ char *dev_path; struct nexus *next; } nexus_t; @@ -146,7 +145,6 @@ pci_system_solx_devfs_destroy( void ) for (nexus = nexus_list ; nexus != NULL ; nexus = next) { next = nexus->next; - close(nexus->fd); free(nexus->path); free(nexus->dev_path); free(nexus); @@ -215,6 +213,11 @@ probe_device_node(di_node_t node, void *arg) pci_base->dev = PCI_REG_DEV_G(retbuf[0]); pci_base->func = PCI_REG_FUNC_G(retbuf[0]); + if (nexus->domain > 0xffff) + pci_base->domain_16 = 0xffff; + else + pci_base->domain_16 = nexus->domain; + /* Get property values */ for (i = 0; i < NUM_PROPERTIES; i++) { len = di_prop_lookup_ints(DDI_DEV_T_ANY, node, @@ -299,14 +302,12 @@ probe_nexus_node(di_node_t di_node, di_minor_t minor, void *arg) int pci_node = 0; int first_bus = 0, last_bus = PCI_REG_BUS_G(PCI_REG_BUS_M); int domain = 0; - di_node_t rnode = DI_NODE_NIL; #ifdef __sparc int bus_range_found = 0; int device_type_found = 0; di_prom_prop_t prom_prop; #endif - #ifdef DEBUG nexus_name = di_devfs_minor_path(minor); fprintf(stderr, "-- device name: %s\n", nexus_name); @@ -421,33 +422,24 @@ probe_nexus_node(di_node_t di_node, di_minor_t minor, void *arg) if ((fd = open(nexus_path, O_RDWR | O_CLOEXEC)) >= 0) { probe_args_t args; - nexus->fd = fd; nexus->path = strdup(nexus_path); nexus_dev_path = di_devfs_path(di_node); nexus->dev_path = strdup(nexus_dev_path); di_devfs_path_free(nexus_dev_path); - if ((rnode = di_init(nexus->dev_path, DINFOCPYALL)) == DI_NODE_NIL) { - (void) fprintf(stderr, "di_init failed: %s\n", strerror(errno)); - close(nexus->fd); - free(nexus->path); - free(nexus->dev_path); - free(nexus); - return (DI_WALK_TERMINATE); - } - /* Walk through devices under the rnode */ args.pinfo = pinfo; args.nexus = nexus; args.ret = 0; - (void) di_walk_node(rnode, DI_WALK_CLDFIRST, (void *)&args, probe_device_node); + (void) di_walk_node(di_node, DI_WALK_CLDFIRST, (void *)&args, probe_device_node); + + close(fd); + if (args.ret) { - close(nexus->fd); free(nexus->path); free(nexus->dev_path); free(nexus); - di_fini(rnode); return (DI_WALK_TERMINATE); } @@ -459,10 +451,6 @@ probe_nexus_node(di_node_t di_node, di_minor_t minor, void *arg) free(nexus); } - if (rnode != DI_NODE_NIL) { - di_fini(rnode); - } - return DI_WALK_CONTINUE; } @@ -555,7 +543,7 @@ pci_device_solx_devfs_probe( struct pci_device * dev ) * starting to find if it is MEM/MEM64/IO * using libdevinfo */ - if ((rnode = di_init(nexus->dev_path, DINFOCPYALL)) == DI_NODE_NIL) { + if ((rnode = di_init(nexus->dev_path, DINFOCACHE)) == DI_NODE_NIL) { err = errno; (void) fprintf(stderr, "di_init failed: %s\n", strerror(errno)); } else { @@ -790,6 +778,7 @@ pci_device_solx_devfs_read( struct pci_device * dev, void * data, int err = 0; unsigned int i = 0; nexus_t *nexus; + int fd; nexus = find_nexus_for_bus(dev->domain, dev->bus); @@ -807,11 +796,14 @@ pci_device_solx_devfs_read( struct pci_device * dev, void * data, cfg_prg.barnum = 0; cfg_prg.user_version = PCITOOL_USER_VERSION; + if ((fd = open(nexus->path, O_RDWR | O_CLOEXEC)) < 0) + return ENOENT; + for (i = 0; i < size; i += PCITOOL_ACC_ATTR_SIZE(PCITOOL_ACC_ATTR_SIZE_1)) { cfg_prg.offset = offset + i; - if ((err = ioctl(nexus->fd, PCITOOL_DEVICE_GET_REG, &cfg_prg)) != 0) { + if ((err = ioctl(fd, PCITOOL_DEVICE_GET_REG, &cfg_prg)) != 0) { fprintf(stderr, "read bdf<%s,%x,%x,%x,%llx> config space failure\n", nexus->path, cfg_prg.bus_no, @@ -829,6 +821,8 @@ pci_device_solx_devfs_read( struct pci_device * dev, void * data, } *bytes_read = i; + close(fd); + return (err); } @@ -844,6 +838,7 @@ pci_device_solx_devfs_write( struct pci_device * dev, const void * data, int err = 0; int cmd; nexus_t *nexus; + int fd; nexus = find_nexus_for_bus(dev->domain, dev->bus); @@ -891,11 +886,17 @@ pci_device_solx_devfs_write( struct pci_device * dev, const void * data, */ cmd = PCITOOL_DEVICE_SET_REG; - if ((err = ioctl(nexus->fd, cmd, &cfg_prg)) != 0) { + if ((fd = open(nexus->path, O_RDWR | O_CLOEXEC)) < 0) + return ENOENT; + + if ((err = ioctl(fd, cmd, &cfg_prg)) != 0) { + close(fd); return (err); } *bytes_written = size; + close(fd); + return (err); } @@ -1074,7 +1075,7 @@ pci_system_solx_devfs_create( void ) return 0; } - if ((di_node = di_init("/", DINFOCPYALL)) == DI_NODE_NIL) { + if ((di_node = di_init("/", DINFOCACHE)) == DI_NODE_NIL) { err = errno; (void) fprintf(stderr, "di_init() failed: %s\n", strerror(errno)); diff --git a/src/x86_pci.c b/src/x86_pci.c index 32daa04..6b6a026 100644 --- a/src/x86_pci.c +++ b/src/x86_pci.c @@ -915,7 +915,7 @@ pci_system_x86_create(void) if (PCI_VENDOR(reg) == PCI_VENDOR_INVALID || PCI_VENDOR(reg) == 0) continue; - device->base.domain = 0; + device->base.domain = device->base.domain_16 = 0; device->base.bus = bus; device->base.dev = dev; device->base.func = func; |