summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthieu Herrb <matthieu@herrb.eu>2017-10-22 18:31:07 +0200
committerMatthieu Herrb <matthieu@herrb.eu>2017-10-22 18:31:07 +0200
commit479a7a6ffaf61a223348e5653bd8b96c686e57c1 (patch)
tree24849c7c81d8e06c79e0e88bc9195bce6f15145f
parent64740791daf57cae85ceb6ef9689d2771c9288ee (diff)
parenta167bd6474522a709ff3cbb00476c0e4309cb66f (diff)
Merge remote-tracking branch 'origin/master' into obsd
-rw-r--r--configure.ac4
-rw-r--r--include/pciaccess.h15
-rw-r--r--src/linux_sysfs.c26
-rw-r--r--src/netbsd_pci.c4
-rw-r--r--src/openbsd_pci.c4
-rw-r--r--src/solx_devfs.c55
-rw-r--r--src/x86_pci.c2
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;