From mboxrd@z Thu Jan 1 00:00:00 1970 From: Bruce Richardson Subject: Re: [PATCH 1/4] pci: allow access to PCI config space Date: Tue, 12 May 2015 10:56:25 +0100 Message-ID: <20150512095624.GA12516@bricha3-MOBL3> References: <1431041135-6289-1-git-send-email-stephen@networkplumber.org> <1431041135-6289-2-git-send-email-stephen@networkplumber.org> <38426478085b4e779e18967cd1b6ae4f@BRMWP-EXMB11.corp.brocade.com> <20150511103104.1c60565b@urahara> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Cc: "dev@dpdk.org" , Stephen Hemminger To: Stephen Hemminger Return-path: Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by dpdk.org (Postfix) with ESMTP id E91D72A07 for ; Tue, 12 May 2015 11:56:28 +0200 (CEST) Content-Disposition: inline In-Reply-To: <20150511103104.1c60565b@urahara> 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" On Mon, May 11, 2015 at 10:31:04AM -0700, Stephen Hemminger wrote: > On Mon, 11 May 2015 12:54:54 +0000 > Neil Horman wrote: > > > On Thu, May 07, 2015 at 04:25:32PM -0700, Stephen Hemminger wrote: > > > 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. > > > > > Could someone who has BSD infrastructure try this, not sure if it will even > build. No, it doesn't. :-) Version that compiles is below. However, I haven't tried testing it yet or anything. Is there any easy way for me to do so? /Bruce diff --git a/lib/librte_eal/bsdapp/eal/eal_pci.c b/lib/librte_eal/bsdapp/eal/eal_pci.c index 61e8921..4194199 100644 --- a/lib/librte_eal/bsdapp/eal/eal_pci.c +++ b/lib/librte_eal/bsdapp/eal/eal_pci.c @@ -490,6 +490,87 @@ 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 *dev, + void *buf, size_t len, off_t offset) +{ + int fd = -1; + + struct pci_io pi = { + .pi_sel = { + .pc_domain = dev->addr.domain, + .pc_bus = dev->addr.bus, + .pc_dev = dev->addr.devid, + .pc_func = dev->addr.function, + }, + .pi_reg = offset, + .pi_width = len, + }; + + if (len == 3 || len > sizeof(pi.pi_data)) { + RTE_LOG(ERR, EAL, "%s(): invalid pci read length\n", __func__); + goto error; + } + + fd = open("/dev/pci", O_RDONLY); + if (fd < 0) { + RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__); + goto error; + } + + if (ioctl(fd, PCIOCREAD, &pi) < 0) + goto error; + close(fd); + + memcpy(buf, &pi.pi_data, len); + return 0; + +error: + if (fd >= 0) + close(fd); + return -1; +} + +/* Write PCI config space. */ +int rte_eal_pci_write_config(const struct rte_pci_device *dev, + const void *buf, size_t len, off_t offset) +{ + int fd = -1; + + struct pci_io pi = { + .pi_sel = { + .pc_domain = dev->addr.domain, + .pc_bus = dev->addr.bus, + .pc_dev = dev->addr.devid, + .pc_func = dev->addr.function, + }, + .pi_reg = offset, + .pi_data = *(u_int32_t *)buf, + .pi_width = len, + }; + + if (len == 3 || len > sizeof(pi.pi_data)) { + RTE_LOG(ERR, EAL, "%s(): invalid pci read length\n", __func__); + goto error; + } + + fd = open("/dev/pci", O_RDONLY); + if (fd < 0) { + RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__); + goto error; + } + + if (ioctl(fd, PCIOCWRITE, &pi) < 0) + goto error; + close(fd); + return 0; + +error: + if (fd >= 0) + close(fd); + return -1; +} + /* Init the PCI EAL subsystem */ int rte_eal_pci_init(void)