From: Stephen Hemminger <shemm...@brocade.com> Some drivers need ability to access PCI config (for example for power management). This adds an abstraction to do this; only implemented on Linux, but should be possible on BSD.
Signed-off-by: Stephen Hemminger <stephen at networkplumber.org> --- lib/librte_eal/common/include/rte_pci.h | 29 +++++++++++++++++++++++++ lib/librte_eal/linuxapp/eal/eal_pci.c | 15 +++++++++++++ lib/librte_eal/linuxapp/eal/eal_pci_uio.c | 10 +++++++++ lib/librte_eal/linuxapp/eal/rte_eal_version.map | 2 ++ 4 files changed, 56 insertions(+) diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h index 66ed793..a78081f 100644 --- a/lib/librte_eal/common/include/rte_pci.h +++ b/lib/librte_eal/common/include/rte_pci.h @@ -152,6 +152,7 @@ struct rte_pci_device { uint16_t max_vfs; /**< sriov enable if not zero */ int numa_node; /**< NUMA node connection */ struct rte_devargs *devargs; /**< Device user arguments */ + int config_fd; /**< PCI config access */ }; /** Any PCI device identifier (vendor, device, ...) */ @@ -298,6 +299,34 @@ void rte_eal_pci_register(struct rte_pci_driver *driver); */ void rte_eal_pci_unregister(struct rte_pci_driver *driver); +/** + * Read PCI config space. + * + * @param device + * A pointer to a rte_pci_device structure describing the device + * to use + * @param buf + * A data buffer where the bytes should be read into + * @param size + * The length of the data buffer. + */ +int rte_eal_pci_read_config(const struct rte_pci_device *device, + void *buf, size_t len, off_t offset); + +/** + * Write PCI config space. + * + * @param device + * A pointer to a rte_pci_device structure describing the device + * to use + * @param buf + * A data buffer containing the bytes should be written + * @param size + * The length of the data buffer. + */ +int rte_eal_pci_write_config(const struct rte_pci_device *device, + const void *buf, size_t len, off_t offset); + #ifdef __cplusplus } #endif diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c index b5f5410..5bcfffa 100644 --- a/lib/librte_eal/linuxapp/eal/eal_pci.c +++ b/lib/librte_eal/linuxapp/eal/eal_pci.c @@ -233,6 +233,7 @@ pci_scan_one(const char *dirname, uint16_t domain, uint8_t bus, dev->addr.bus = bus; dev->addr.devid = devid; dev->addr.function = function; + dev->config_fd = -1; /* get vendor id */ snprintf(filename, sizeof(filename), "%s/vendor", dirname); @@ -592,6 +593,20 @@ rte_eal_pci_probe_one_driver(struct rte_pci_driver *dr, struct rte_pci_device *d return 1; } +/* Read PCI config space. */ +int rte_eal_pci_read_config(const struct rte_pci_device *device, + void *buf, size_t len, off_t offset) +{ + return pread(device->config_fd, buf, len, offset); +} + +/* Write PCI config space. */ +int rte_eal_pci_write_config(const struct rte_pci_device *device, + const void *buf, size_t len, off_t offset) +{ + return pwrite(device->config_fd, buf, len, offset); +} + /* Init the PCI EAL subsystem */ int rte_eal_pci_init(void) diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c b/lib/librte_eal/linuxapp/eal/eal_pci_uio.c index e53f06b..0396eaa 100644 --- a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c +++ b/lib/librte_eal/linuxapp/eal/eal_pci_uio.c @@ -213,6 +213,7 @@ pci_get_uio_dev(struct rte_pci_device *dev, char *dstbuf, struct dirent *e; DIR *dir; char dirname[PATH_MAX]; + char filename[PATH_MAX]; /* depending on kernel version, uio can be located in uio/uioX * or uio:uioX */ @@ -268,6 +269,15 @@ pci_get_uio_dev(struct rte_pci_device *dev, char *dstbuf, if (e == NULL) return -1; + /* Open fd for access to PCI config */ + snprintf(filename, sizeof(filename), "%s/device/config", dirname); + dev->config_fd = open(filename, O_RDWR); + if (dev->config_fd < 0) { + RTE_LOG(ERR, EAL, "%s(): cannot open %s: %s\n", + __func__, filename, strerror(errno)); + return -1; + } + /* create uio device if we've been asked to */ if (internal_config.create_uio_dev && pci_mknod_uio_dev(dstbuf, uio_num) < 0) diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map index d36286e..626689c 100644 --- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map +++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map @@ -40,6 +40,8 @@ DPDK_2.0 { rte_eal_pci_probe; rte_eal_pci_register; rte_eal_pci_unregister; + rte_eal_pci_read_config; + rte_eal_pci_write_config; rte_eal_process_type; rte_eal_remote_launch; rte_eal_tailq_lookup; -- 2.1.4