This implementation just acts as a simple wrapper around pci-vfio.
This could grow if other pci access (such as user-io) get involved.

Signed-off-by: Christophe Milard <christophe.mil...@linaro.org>
---
 platform/linux-generic/Makefile.am |   1 +
 platform/linux-generic/odp_pci.c   | 190 +++++++++++++++++++++++++++++++++++++
 2 files changed, 191 insertions(+)
 create mode 100644 platform/linux-generic/odp_pci.c

diff --git a/platform/linux-generic/Makefile.am 
b/platform/linux-generic/Makefile.am
index 6a08811..999c932 100644
--- a/platform/linux-generic/Makefile.am
+++ b/platform/linux-generic/Makefile.am
@@ -139,6 +139,7 @@ __LIB__libodp_la_SOURCES = \
                           odp_packet.c \
                           odp_packet_flags.c \
                           odp_packet_io.c \
+                          odp_pci.c \
                           odp_pci_vfio.c \
                           pktio/io_ops.c \
                           pktio/pktio_common.c \
diff --git a/platform/linux-generic/odp_pci.c b/platform/linux-generic/odp_pci.c
new file mode 100644
index 0000000..7cce69f
--- /dev/null
+++ b/platform/linux-generic/odp_pci.c
@@ -0,0 +1,190 @@
+/* Copyright (c) 2015, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:     BSD-3-Clause
+ */
+
+#include <stdio.h>
+#include <linux/limits.h>
+#include <stdlib.h>
+#include <odp/dma.h>
+#include <odp/pci.h>
+#include <odp_debug_internal.h>
+#include <odp_pci_internal.h>
+#include <odp_pci_vfio_internal.h>
+
+#define SYSFS_PCI_DEVICES "/sys/bus/pci/devices"
+
+/* operations on PCI devices: */
+
+uint16_t odp_pci_get_vendor(odp_pci_dev_t dev_hdl)
+{
+       return ((pci_dev_t *)dev_hdl)->pci_id.vendor_id;
+}
+
+uint16_t odp_pci_get_device(odp_pci_dev_t dev_hdl)
+{
+       return ((pci_dev_t *)dev_hdl)->pci_id.device_id;
+}
+
+uint16_t odp_pci_get_subsystem_vendor(odp_pci_dev_t dev_hdl)
+{
+       return ((pci_dev_t *)dev_hdl)->pci_id.subsystem_vendor_id;
+}
+
+uint16_t odp_pci_get_subsystem_device(odp_pci_dev_t dev_hdl)
+{
+       return ((pci_dev_t *)dev_hdl)->pci_id.subsystem_device_id;
+}
+
+void *odp_pci_get_resource_addr(odp_pci_dev_t dev_hdl, int bar)
+{
+       return ((pci_dev_t *)dev_hdl)->bar_maps[bar].addr;
+}
+
+char *odp_pci_get_addr_str(odp_pci_dev_t dev_hdl)
+{
+       return ((pci_dev_t *)dev_hdl)->pci_address;
+}
+
+/*
+ * parse a sysfs (or other) file containing one integer value
+ */
+static int parse_sysfs_value(const char *filename, unsigned long *val)
+{
+       FILE *f;
+       char buf[BUFSIZ];
+       char *end = NULL;
+
+       f = fopen(filename, "r");
+       if (!f) {
+               ODP_ERR("%s(): cannot open sysfs value %s\n",
+                       __func__, filename);
+               return -1;
+       }
+
+       if (fgets(buf, sizeof(buf), f) == NULL) {
+               ODP_ERR("%s(): cannot read sysfs value %s\n",
+                       __func__, filename);
+               fclose(f);
+               return -1;
+       }
+       *val = strtoul(buf, &end, 0);
+       if ((buf[0] == '\0') || (end == NULL) || (*end != '\n')) {
+               ODP_ERR("%s(): cannot parse sysfs value %s\n",
+                       __func__, filename);
+               fclose(f);
+               return -1;
+       }
+       fclose(f);
+       return 0;
+}
+
+odp_pci_dev_t _odp_pci_init(const char *pci_addr)
+{
+       char filename[PATH_MAX];
+       unsigned long tmp;
+       pci_dev_t *dev;
+
+       dev = malloc(sizeof(pci_dev_t));
+       if (!dev)
+               return NULL;
+
+       /* currentely only vfio is supported */
+       if (_odp_pci_vfio_init(pci_addr, dev) < 0)
+               goto pci_init_err;
+
+       /* get vendor id */
+       snprintf(filename, sizeof(filename), SYSFS_PCI_DEVICES "/%s/vendor",
+                pci_addr);
+       if (parse_sysfs_value(filename, &tmp) < 0)
+               goto pci_init_err;
+
+       dev->pci_id.vendor_id = (uint16_t)tmp;
+
+       /* get device id */
+       snprintf(filename, sizeof(filename), SYSFS_PCI_DEVICES "/%s/device",
+                pci_addr);
+       if (parse_sysfs_value(filename, &tmp) < 0)
+               goto pci_init_err;
+
+       dev->pci_id.device_id = (uint16_t)tmp;
+
+       /* get subsystem_vendor id */
+       snprintf(filename, sizeof(filename),
+                SYSFS_PCI_DEVICES "/%s/subsystem_vendor",
+                pci_addr);
+       if (parse_sysfs_value(filename, &tmp) < 0)
+               goto pci_init_err;
+
+       dev->pci_id.subsystem_vendor_id = (uint16_t)tmp;
+
+       /* get subsystem_device id */
+       snprintf(filename, sizeof(filename),
+                SYSFS_PCI_DEVICES "/%s/subsystem_device",
+                pci_addr);
+       if (parse_sysfs_value(filename, &tmp) < 0)
+               goto pci_init_err;
+
+       dev->pci_id.subsystem_device_id = (uint16_t)tmp;
+
+       return (odp_pci_dev_t)dev;
+
+pci_init_err:
+       free(dev);
+       return NULL;
+}
+
+void _odp_pci_release(odp_pci_dev_t pci_dev)
+{
+       /* currentely only vfio is supported */
+       _odp_pci_vfio_release((pci_dev_t *)pci_dev);
+       free(pci_dev);
+}
+
+int odp_pci_map_dma_region(odp_pci_dev_t dev_hdl,
+                          odp_dma_map_t region)
+{
+       pci_dev_t *dev = (pci_dev_t *)dev_hdl;
+       dma_map_t *map_s = dma_map_handle_to_map(region);
+
+       /* map fragments one by one */
+       /* currentely only vfio is supported */
+       do {
+               if (_odp_pci_vfio_map_dma_region_f(dev, map_s)) {
+                       /* remove partially mapped region: */
+                       odp_pci_unmap_dma_region(dev_hdl, region);
+                       return -1;
+               }
+               map_s = map_s->next;
+       } while (map_s);
+
+       return 0;
+}
+
+int odp_pci_unmap_dma_region(odp_pci_dev_t dev_hdl,
+                            odp_dma_map_t region)
+{
+       pci_dev_t *dev = (pci_dev_t *)dev_hdl;
+       dma_map_t *map_s = dma_map_handle_to_map(region);
+
+       /* unmap fragments one by one */
+       /* currentely only vfio is supported */
+       do {
+               _odp_pci_vfio_unmap_dma_region_f(dev, map_s);
+               map_s = map_s->next;
+       } while (map_s);
+
+       return 0;
+}
+
+int odp_pci_read_config(odp_pci_dev_t dev, void *buf, size_t len, int offs)
+{
+       return _odp_pci_vfio_read_config((pci_dev_t *)dev, buf, len, offs);
+}
+
+int odp_pci_write_config(odp_pci_dev_t dev, const void *buf,
+                        size_t len, int offs)
+{
+       return _odp_pci_vfio_write_config((pci_dev_t *)dev, buf, len, offs);
+}
-- 
2.1.4

_______________________________________________
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp

Reply via email to