DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [RFC] PCI config access for drivers
@ 2014-08-26  0:44 Stephen Hemminger
  2014-08-27 10:37 ` Burakov, Anatoly
  0 siblings, 1 reply; 2+ messages in thread
From: Stephen Hemminger @ 2014-08-26  0:44 UTC (permalink / raw)
  To: dev

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@networkplumber.org>

--- a/lib/librte_eal/common/include/rte_pci.h	2014-06-24 09:20:05.651993525 -0700
+++ b/lib/librte_eal/common/include/rte_pci.h	2014-06-24 09:25:42.150616572 -0700
@@ -151,6 +151,7 @@ struct rte_pci_device {
 	const struct rte_pci_driver *driver;    /**< Associated driver */
 	uint16_t max_vfs;                       /**< sriov enable if not zero */
 	int numa_node;                          /**< NUMA node connection */
+	int config_fd;				/**< PCI config access */
 	struct rte_devargs *devargs;            /**< Device user arguments */
 };
 
@@ -298,6 +299,34 @@ void rte_eal_pci_register(struct rte_pci
  */
 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
--- a/lib/librte_eal/linuxapp/eal/eal_pci.c	2014-06-24 09:20:05.651993525 -0700
+++ b/lib/librte_eal/linuxapp/eal/eal_pci.c	2014-06-24 09:20:05.651993525 -0700
@@ -219,6 +219,7 @@ pci_scan_one(const char *dirname, uint16
 	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);
@@ -578,6 +579,20 @@ rte_eal_pci_probe_one_driver(struct rte_
 	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)
--- a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c	2014-06-24 08:35:31.832146544 -0700
+++ b/lib/librte_eal/linuxapp/eal/eal_pci_uio.c	2014-06-24 09:37:44.892296443 -0700
@@ -280,6 +280,7 @@ pci_uio_map_resource(struct rte_pci_devi
 	int i, j;
 	char dirname[PATH_MAX];
 	char devname[PATH_MAX]; /* contains the /dev/uioX */
+	char cfgname[PATH_MAX];
 	void *mapaddr;
 	int uio_num;
 	uint64_t phaddr;
@@ -326,11 +327,23 @@ pci_uio_map_resource(struct rte_pci_devi
 	snprintf(uio_res->path, sizeof(uio_res->path), "%s", devname);
 	memcpy(&uio_res->pci_addr, &dev->addr, sizeof(uio_res->pci_addr));
 
+	/* Open fd for access to PCI config */
+	snprintf(cfgname, sizeof(cfgname),
+		 "%s/device/config", dirname);
+	dev->config_fd = open(cfgname, O_RDWR);
+	if (dev->config_fd < 0) {
+		RTE_LOG(ERR, EAL, "%s(): cannot open %s: %s\n",
+			__func__, cfgname, strerror(errno));
+		rte_free(uio_res);
+		return -1;
+	}
+
 	/* collect info about device mappings */
 	nb_maps = pci_uio_get_mappings(dirname, uio_res->maps,
 				       RTE_DIM(uio_res->maps));
 	if (nb_maps < 0) {
 		rte_free(uio_res);
+		close(dev->config_fd);
 		return nb_maps;
 	}
 
@@ -379,6 +392,7 @@ pci_uio_map_resource(struct rte_pci_devi
 
 			if (fail) {
 				rte_free(uio_res);
+				close(dev->config_fd);
 				close(fd);
 				return -1;
 			}

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [dpdk-dev] [RFC] PCI config access for drivers
  2014-08-26  0:44 [dpdk-dev] [RFC] PCI config access for drivers Stephen Hemminger
@ 2014-08-27 10:37 ` Burakov, Anatoly
  0 siblings, 0 replies; 2+ messages in thread
From: Burakov, Anatoly @ 2014-08-27 10:37 UTC (permalink / raw)
  To: Stephen Hemminger, dev

Hi Stephen,

> 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.

Since VFIO has to go to PCI config space too for some things, could you please amend your patch to make VFIO use this generic API also? Currently, it uses VFIO to read and write from PCI config.

Thanks,
Anatoly

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2014-08-27 10:34 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-08-26  0:44 [dpdk-dev] [RFC] PCI config access for drivers Stephen Hemminger
2014-08-27 10:37 ` Burakov, Anatoly

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).