From patchwork Fri Feb 6 18:36:32 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Hemminger X-Patchwork-Id: 3024 Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [IPv6:::1]) by dpdk.org (Postfix) with ESMTP id 4D4D92A5B; Fri, 6 Feb 2015 19:36:41 +0100 (CET) Received: from mail-pa0-f51.google.com (mail-pa0-f51.google.com [209.85.220.51]) by dpdk.org (Postfix) with ESMTP id EA5F7255 for ; Fri, 6 Feb 2015 19:36:38 +0100 (CET) Received: by mail-pa0-f51.google.com with SMTP id hz1so14226359pad.10 for ; Fri, 06 Feb 2015 10:36:38 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=59S4x75lOHCQ6bX8g02aNwmZOEsz442fNlsL8Dro380=; b=gtyNl+joFuSQLiYwyxTHc5PMz7mTeMlPJSNDQQmau7kbfPtcnnO9rguMPQvYy3QeLf lIlfTaN+uRLsyapkPIjBYykhUeow9qLU8FHvpyXnBpIgaX7msl3ws+Q4LMQ8rUOKlNmG ytQHLDwANAbr6in13f4wXb0jp9LHKTAiaii8uBY1LhXi+OIcd6Qt0y6OtHPL0BjNLNy8 USNWVFGmWsbzcyAQiTFnuudkxqMA/8CRBcYM3OPLQYlxQWi6fYOWuQ0A1IaSNyrUKq6V 3DTx/ymJuh6UMIi+BwiMZ/RmRcjOLg3BK1fdHsg6Mk7uoEhMpOPj98QD9F87qUQf8SBm JH/Q== X-Gm-Message-State: ALoCoQmBE1gOqjCuIUAIVqoQzLWqg23XFvUCpB2ZH/hFRCF/X6GGZ4X/AelxV6An7e5EAj/ARx4Q X-Received: by 10.68.133.165 with SMTP id pd5mr8052519pbb.13.1423247798239; Fri, 06 Feb 2015 10:36:38 -0800 (PST) Received: from urahara.brocade.com (static-50-53-82-155.bvtn.or.frontiernet.net. [50.53.82.155]) by mx.google.com with ESMTPSA id sq6sm8517486pbc.40.2015.02.06.10.36.37 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 06 Feb 2015 10:36:37 -0800 (PST) From: Stephen Hemminger To: dev@dpdk.org Date: Fri, 6 Feb 2015 10:36:32 -0800 Message-Id: <1423247795-22399-2-git-send-email-stephen@networkplumber.org> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1423247795-22399-1-git-send-email-stephen@networkplumber.org> References: <1423247795-22399-1-git-send-email-stephen@networkplumber.org> Cc: Stephen Hemminger Subject: [dpdk-dev] [PATCH 1/4] pci: allow access to PCI config space X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Stephen Hemminger 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 --- 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;