get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/39405/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 39405,
    "url": "https://patches.dpdk.org/api/patches/39405/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/1525596044-84881-2-git-send-email-rosen.xu@intel.com/",
    "project": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<1525596044-84881-2-git-send-email-rosen.xu@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1525596044-84881-2-git-send-email-rosen.xu@intel.com",
    "date": "2018-05-06T08:40:40",
    "name": "[dpdk-dev,v8,1/5] bus/ifpga: Add Intel FPGA BUS Library",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "a1886e3682684bad1a1b715b47e62cfd67f2f33e",
    "submitter": {
        "id": 946,
        "url": "https://patches.dpdk.org/api/people/946/?format=api",
        "name": "Xu, Rosen",
        "email": "rosen.xu@intel.com"
    },
    "delegate": null,
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/1525596044-84881-2-git-send-email-rosen.xu@intel.com/mbox/",
    "series": [],
    "comments": "https://patches.dpdk.org/api/patches/39405/comments/",
    "check": "warning",
    "checks": "https://patches.dpdk.org/api/patches/39405/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id BD6A92C6E;\n\tSun,  6 May 2018 10:39:31 +0200 (CEST)",
            "from mga18.intel.com (mga18.intel.com [134.134.136.126])\n\tby dpdk.org (Postfix) with ESMTP id 8D6C823B\n\tfor <dev@dpdk.org>; Sun,  6 May 2018 10:39:29 +0200 (CEST)",
            "from fmsmga003.fm.intel.com ([10.253.24.29])\n\tby orsmga106.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t06 May 2018 01:39:29 -0700",
            "from dpdkx8602.sh.intel.com ([10.67.110.200])\n\tby FMSMGA003.fm.intel.com with ESMTP; 06 May 2018 01:39:27 -0700"
        ],
        "X-Amp-Result": "SKIPPED(no attachment in message)",
        "X-Amp-File-Uploaded": "False",
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.49,369,1520924400\"; d=\"scan'208\";a=\"47097989\"",
        "From": "\"Xu, Rosen\" <rosen.xu@intel.com>",
        "To": "dev@dpdk.org",
        "Cc": "rosen.xu@intel.com, declan.doherty@intel.com, bruce.richardson@intel.com,\n\tshreyansh.jain@nxp.com, ferruh.yigit@intel.com,\n\tkonstantin.ananyev@intel.com, tianfei.zhang@intel.com,\n\tsong.liu@intel.com, hao.wu@intel.com, gaetan.rivet@6wind.com",
        "Date": "Sun,  6 May 2018 16:40:40 +0800",
        "Message-Id": "<1525596044-84881-2-git-send-email-rosen.xu@intel.com>",
        "X-Mailer": "git-send-email 1.8.3.1",
        "In-Reply-To": "<1525596044-84881-1-git-send-email-rosen.xu@intel.com>",
        "References": "<1521553556-62982-1-git-send-email-rosen.xu@intel.com>\n\t<1525596044-84881-1-git-send-email-rosen.xu@intel.com>",
        "Subject": "[dpdk-dev] [PATCH v8 1/5] bus/ifpga: Add Intel FPGA BUS Library",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://dpdk.org/ml/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://dpdk.org/ml/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://dpdk.org/ml/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "From: Rosen Xu <rosen.xu@intel.com>\n\nDefined FPGA-BUS for Acceleration Drivers of AFUs\n\n1. FPGA PCI Scan (1st Scan) follows DPDK UIO/VFIO PCI Scan Process,\nprobe Intel FPGA Rawdev Driver, it will be covered in following patches.\n\n2. AFU Scan(2nd Scan) bind DPDK driver to FPGA Partial-Bitstream.\nThis scan is trigged by hotplug of IFPGA Rawdev probe, in this scan\nthe AFUs will be created and their drivers are also probed.\n\nThis patch will introduce rte_afu_device which describe the AFU device\nlisted in the FPGA-BUS.\n\nSigned-off-by: Rosen Xu <rosen.xu@intel.com>\nSigned-off-by: Figo zhang <tianfei.zhang@intel.com>\n---\n config/common_base                          |   5 +\n drivers/bus/Makefile                        |   1 +\n drivers/bus/ifpga/Makefile                  |  32 ++\n drivers/bus/ifpga/ifpga_bus.c               | 501 ++++++++++++++++++++++++++++\n drivers/bus/ifpga/ifpga_common.c            |  88 +++++\n drivers/bus/ifpga/ifpga_common.h            |  18 +\n drivers/bus/ifpga/ifpga_logs.h              |  31 ++\n drivers/bus/ifpga/meson.build               |   8 +\n drivers/bus/ifpga/rte_bus_ifpga.h           | 160 +++++++++\n drivers/bus/ifpga/rte_bus_ifpga_version.map |  10 +\n drivers/bus/meson.build                     |   2 +-\n mk/rte.app.mk                               |   1 +\n 12 files changed, 856 insertions(+), 1 deletion(-)\n create mode 100644 drivers/bus/ifpga/Makefile\n create mode 100644 drivers/bus/ifpga/ifpga_bus.c\n create mode 100644 drivers/bus/ifpga/ifpga_common.c\n create mode 100644 drivers/bus/ifpga/ifpga_common.h\n create mode 100644 drivers/bus/ifpga/ifpga_logs.h\n create mode 100644 drivers/bus/ifpga/meson.build\n create mode 100644 drivers/bus/ifpga/rte_bus_ifpga.h\n create mode 100644 drivers/bus/ifpga/rte_bus_ifpga_version.map",
    "diff": "diff --git a/config/common_base b/config/common_base\nindex 03a8688..bd4b356 100644\n--- a/config/common_base\n+++ b/config/common_base\n@@ -149,6 +149,11 @@ CONFIG_RTE_LIBRTE_PCI_BUS=y\n CONFIG_RTE_LIBRTE_VDEV_BUS=y\n \n #\n+# Compile the Intel FPGA bus\n+#\n+CONFIG_RTE_LIBRTE_IFPGA_BUS=y\n+\n+#\n # Compile ARK PMD\n #\n CONFIG_RTE_LIBRTE_ARK_PMD=y\ndiff --git a/drivers/bus/Makefile b/drivers/bus/Makefile\nindex c251b65..cff3567 100644\n--- a/drivers/bus/Makefile\n+++ b/drivers/bus/Makefile\n@@ -9,5 +9,6 @@ DIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc\n endif\n DIRS-$(CONFIG_RTE_LIBRTE_PCI_BUS) += pci\n DIRS-$(CONFIG_RTE_LIBRTE_VDEV_BUS) += vdev\n+DIRS-$(CONFIG_RTE_LIBRTE_IFPGA_BUS) += ifpga\n \n include $(RTE_SDK)/mk/rte.subdir.mk\ndiff --git a/drivers/bus/ifpga/Makefile b/drivers/bus/ifpga/Makefile\nnew file mode 100644\nindex 0000000..3ff3bdb\n--- /dev/null\n+++ b/drivers/bus/ifpga/Makefile\n@@ -0,0 +1,32 @@\n+# SPDX-License-Identifier: BSD-3-Clause\n+# Copyright(c) 2018 Intel Corporation\n+\n+include $(RTE_SDK)/mk/rte.vars.mk\n+\n+#\n+# library name\n+#\n+LIB = librte_bus_ifpga.a\n+\n+CFLAGS += -DALLOW_EXPERIMENTAL_API\n+CFLAGS += -O3\n+CFLAGS += $(WERROR_FLAGS)\n+LDLIBS += -lrte_eal\n+LDLIBS += -lrte_rawdev\n+LDLIBS += -lrte_kvargs\n+\n+# versioning export map\n+EXPORT_MAP := rte_bus_ifpga_version.map\n+\n+# library version\n+LIBABIVER := 1\n+\n+SRCS-$(CONFIG_RTE_LIBRTE_IFPGA_BUS) += ifpga_bus.c\n+SRCS-$(CONFIG_RTE_LIBRTE_IFPGA_BUS) += ifpga_common.c\n+\n+#\n+# Export include files\n+#\n+SYMLINK-$(CONFIG_RTE_LIBRTE_IFPGA_BUS)-include += rte_bus_ifpga.h\n+\n+include $(RTE_SDK)/mk/rte.lib.mk\ndiff --git a/drivers/bus/ifpga/ifpga_bus.c b/drivers/bus/ifpga/ifpga_bus.c\nnew file mode 100644\nindex 0000000..174ac54\n--- /dev/null\n+++ b/drivers/bus/ifpga/ifpga_bus.c\n@@ -0,0 +1,501 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2010-2018 Intel Corporation\n+ */\n+\n+#include <string.h>\n+#include <inttypes.h>\n+#include <stdint.h>\n+#include <stdlib.h>\n+#include <stdio.h>\n+#include <sys/queue.h>\n+#include <sys/mman.h>\n+#include <sys/types.h>\n+#include <unistd.h>\n+#include <fcntl.h>\n+\n+#include <rte_errno.h>\n+#include <rte_bus.h>\n+#include <rte_per_lcore.h>\n+#include <rte_memory.h>\n+#include <rte_memzone.h>\n+#include <rte_eal.h>\n+#include <rte_common.h>\n+\n+#include <rte_devargs.h>\n+#include <rte_kvargs.h>\n+#include <rte_alarm.h>\n+\n+#include \"rte_rawdev.h\"\n+#include \"rte_rawdev_pmd.h\"\n+#include \"rte_bus_ifpga.h\"\n+#include \"ifpga_logs.h\"\n+#include \"ifpga_common.h\"\n+\n+int ifpga_bus_logtype;\n+\n+/* Forward declaration to access Intel FPGA bus\n+ * on which iFPGA devices are connected\n+ */\n+static struct rte_bus rte_ifpga_bus;\n+\n+/** Double linked list of IFPGA device. */\n+TAILQ_HEAD(ifpga_device_list, rte_ifpga_device);\n+\n+static struct ifpga_device_list ifpga_device_list =\n+\tTAILQ_HEAD_INITIALIZER(ifpga_device_list);\n+static struct afu_driver_list afu_driver_list =\n+\tTAILQ_HEAD_INITIALIZER(afu_driver_list);\n+\n+\n+/* register a ifpga bus based driver */\n+void rte_ifpga_driver_register(struct rte_afu_driver *driver)\n+{\n+\tRTE_VERIFY(driver);\n+\n+\tTAILQ_INSERT_TAIL(&afu_driver_list, driver, next);\n+}\n+\n+/* un-register a fpga bus based driver */\n+void rte_ifpga_driver_unregister(struct rte_afu_driver *driver)\n+{\n+\tTAILQ_REMOVE(&afu_driver_list, driver, next);\n+}\n+\n+static struct rte_ifpga_device *\n+ifpga_find_ifpga_dev(const struct rte_rawdev *rdev)\n+{\n+\tstruct rte_ifpga_device *ifpga_dev = NULL;\n+\n+\tTAILQ_FOREACH(ifpga_dev, &ifpga_device_list, next) {\n+\t\tif (rdev &&\n+\t\t\tifpga_dev->rdev &&\n+\t\t\tifpga_dev->rdev == rdev)\n+\t\t\treturn ifpga_dev;\n+\t}\n+\treturn NULL;\n+}\n+\n+static struct rte_afu_device *\n+ifpga_find_afu_dev(const struct rte_ifpga_device *ifpga_dev,\n+\tconst struct rte_afu_id *afu_id)\n+{\n+\tstruct rte_afu_device *afu_dev = NULL;\n+\n+\tTAILQ_FOREACH(afu_dev, &ifpga_dev->afu_list, next) {\n+\t\tif (!ifpga_afu_id_cmp(&afu_dev->id, afu_id))\n+\t\t\treturn afu_dev;\n+\t}\n+\treturn NULL;\n+}\n+\n+static const char * const valid_args[] = {\n+#define IFPGA_ARG_NAME         \"ifpga\"\n+\tIFPGA_ARG_NAME,\n+#define IFPGA_ARG_PORT         \"port\"\n+\tIFPGA_ARG_PORT,\n+#define IFPGA_AFU_BTS          \"afu_bts\"\n+\tIFPGA_AFU_BTS,\n+\tNULL\n+};\n+\n+/*\n+ * Scan the content of the FPGA bus, and the devices in the devices\n+ * list\n+ */\n+static struct rte_afu_device *\n+ifpga_scan_one(struct rte_devargs *devargs,\n+\tstruct rte_ifpga_device *ifpga_dev)\n+{\n+\tstruct rte_kvargs *kvlist = NULL;\n+\tstruct rte_rawdev *rawdev = NULL;\n+\tstruct rte_afu_device *afu_dev = NULL;\n+\tstruct rte_afu_pr_conf afu_pr_conf;\n+\tint ret = 0;\n+\tchar *path = NULL;\n+\n+\tmemset(&afu_pr_conf, 0, sizeof(struct rte_afu_pr_conf));\n+\n+\tkvlist = rte_kvargs_parse(devargs->args, valid_args);\n+\tif (!kvlist) {\n+\t\tIFPGA_BUS_ERR(\"error when parsing param\");\n+\t\tgoto end;\n+\t}\n+\n+\tif (rte_kvargs_count(kvlist, IFPGA_ARG_PORT) == 1) {\n+\t\tif (rte_kvargs_process(kvlist, IFPGA_ARG_PORT,\n+\t\t&ifpga_get_integer32_arg, &afu_pr_conf.afu_id.port) < 0) {\n+\t\t\tIFPGA_BUS_ERR(\"error to parse %s\",\n+\t\t\t\t     IFPGA_ARG_PORT);\n+\t\t\tgoto end;\n+\t\t}\n+\t} else {\n+\t\tIFPGA_BUS_ERR(\"arg %s is mandatory for ifpga bus\",\n+\t\t\t  IFPGA_ARG_PORT);\n+\t\tgoto end;\n+\t}\n+\n+\tif (rte_kvargs_count(kvlist, IFPGA_AFU_BTS) == 1) {\n+\t\tif (rte_kvargs_process(kvlist, IFPGA_AFU_BTS,\n+\t\t\t\t       &ifpga_get_string_arg, &path) < 0) {\n+\t\t\tIFPGA_BUS_ERR(\"Failed to parse %s\",\n+\t\t\t\t     IFPGA_AFU_BTS);\n+\t\t\tgoto end;\n+\t\t}\n+\t} else {\n+\t\tIFPGA_BUS_ERR(\"arg %s is mandatory for ifpga bus\",\n+\t\t\t  IFPGA_AFU_BTS);\n+\t\tgoto end;\n+\t}\n+\n+\tafu_pr_conf.afu_id.uuid.uuid_low = 0;\n+\tafu_pr_conf.afu_id.uuid.uuid_high = 0;\n+\tafu_pr_conf.pr_enable = path?1:0;\n+\n+\trawdev = ifpga_dev->rdev;\n+\tif (ifpga_find_afu_dev(ifpga_dev, &afu_pr_conf.afu_id))\n+\t\tgoto end;\n+\n+\tafu_dev = calloc(1, sizeof(*afu_dev));\n+\tif (!afu_dev)\n+\t\tgoto end;\n+\n+\tafu_dev->device.devargs = devargs;\n+\tafu_dev->device.numa_node = SOCKET_ID_ANY;\n+\tafu_dev->device.name = devargs->name;\n+\tafu_dev->rawdev = rawdev;\n+\tafu_dev->id.uuid.uuid_low  = 0;\n+\tafu_dev->id.uuid.uuid_high = 0;\n+\tafu_dev->id.port      = afu_pr_conf.afu_id.port;\n+\tafu_dev->ifpga_dev    = ifpga_dev;\n+\n+\tif (rawdev->dev_ops && rawdev->dev_ops->dev_info_get)\n+\t\trawdev->dev_ops->dev_info_get(rawdev, afu_dev);\n+\n+\tif (rawdev->dev_ops &&\n+\t\trawdev->dev_ops->dev_start &&\n+\t\trawdev->dev_ops->dev_start(rawdev))\n+\t\tgoto free_dev;\n+\n+\tstrncpy(afu_pr_conf.bs_path, path, sizeof(afu_pr_conf.bs_path));\n+\tif (rawdev->dev_ops->firmware_load &&\n+\t\trawdev->dev_ops->firmware_load(rawdev,\n+\t\t\t\t&afu_pr_conf)){\n+\t\tIFPGA_BUS_ERR(\"firmware load error %d\\n\", ret);\n+\t\tgoto free_dev;\n+\t}\n+\tafu_dev->id.uuid.uuid_low  = afu_pr_conf.afu_id.uuid.uuid_low;\n+\tafu_dev->id.uuid.uuid_high = afu_pr_conf.afu_id.uuid.uuid_high;\n+\n+\treturn afu_dev;\n+\n+free_dev:\n+\tfree(afu_dev);\n+end:\n+\tif (kvlist)\n+\t\trte_kvargs_free(kvlist);\n+\tif (path)\n+\t\tfree(path);\n+\n+\treturn NULL;\n+}\n+\n+/*\n+ * Scan the content of the FPGA bus, and the devices in the devices\n+ * list\n+ */\n+static int\n+ifpga_scan(void)\n+{\n+\tstruct rte_ifpga_device *ifpga_dev;\n+\tstruct rte_devargs *devargs;\n+\tstruct rte_kvargs *kvlist = NULL;\n+\tstruct rte_rawdev *rawdev = NULL;\n+\tchar *name = NULL;\n+\tchar name1[RTE_RAWDEV_NAME_MAX_LEN];\n+\tstruct rte_afu_device *afu_dev = NULL;\n+\n+\t/* for FPGA devices we scan the devargs_list populated via cmdline */\n+\tRTE_EAL_DEVARGS_FOREACH(\"ifpga\", devargs) {\n+\t\tif (devargs->bus != &rte_ifpga_bus)\n+\t\t\tcontinue;\n+\n+\t\tkvlist = rte_kvargs_parse(devargs->args, valid_args);\n+\t\tif (!kvlist) {\n+\t\t\tIFPGA_BUS_ERR(\"error when parsing param\");\n+\t\t\tgoto end;\n+\t\t}\n+\n+\t\tif (rte_kvargs_count(kvlist, IFPGA_ARG_NAME) == 1) {\n+\t\t\tif (rte_kvargs_process(kvlist, IFPGA_ARG_NAME,\n+\t\t\t\t       &ifpga_get_string_arg, &name) < 0) {\n+\t\t\t\tIFPGA_BUS_ERR(\"error to parse %s\",\n+\t\t\t\t     IFPGA_ARG_NAME);\n+\t\t\t\tgoto end;\n+\t\t\t}\n+\t\t} else {\n+\t\t\tIFPGA_BUS_ERR(\"arg %s is mandatory for ifpga bus\",\n+\t\t\t  IFPGA_ARG_NAME);\n+\t\t\tgoto end;\n+\t\t}\n+\n+\t\tmemset(name1, 0, sizeof(name1));\n+\t\tsnprintf(name1, RTE_RAWDEV_NAME_MAX_LEN, \"IFPGA:%s\", name);\n+\n+\t\trawdev = rte_rawdev_pmd_get_named_dev(name1);\n+\t\tif (!rawdev)\n+\t\t\tgoto end;\n+\n+\t\tif (ifpga_find_ifpga_dev(rawdev))\n+\t\t\tcontinue;\n+\n+\t\tifpga_dev = calloc(1, sizeof(*ifpga_dev));\n+\t\tif (!ifpga_dev)\n+\t\t\tgoto end;\n+\n+\t\tifpga_dev->rdev = rawdev;\n+\t\tTAILQ_INIT(&ifpga_dev->afu_list);\n+\n+\t\tTAILQ_INSERT_TAIL(&ifpga_device_list, ifpga_dev, next);\n+\t\tafu_dev = ifpga_scan_one(devargs, ifpga_dev);\n+\t\tif (afu_dev != NULL)\n+\t\t\tTAILQ_INSERT_TAIL(&ifpga_dev->afu_list, afu_dev, next);\n+\t}\n+\n+end:\n+\tif (kvlist)\n+\t\trte_kvargs_free(kvlist);\n+\tif (name)\n+\t\tfree(name);\n+\n+\treturn 0;\n+}\n+\n+/*\n+ * Match the AFU Driver and AFU Device using the ID Table\n+ */\n+static int\n+rte_afu_match(const struct rte_afu_driver *afu_drv,\n+\t      const struct rte_afu_device *afu_dev)\n+{\n+\tconst struct rte_afu_uuid *id_table;\n+\n+\tfor (id_table = afu_drv->id_table;\n+\t\t((id_table->uuid_low != 0) && (id_table->uuid_high != 0));\n+\t     id_table++) {\n+\t\t/* check if device's identifiers match the driver's ones */\n+\t\tif ((id_table->uuid_low != afu_dev->id.uuid.uuid_low) ||\n+\t\t\t\tid_table->uuid_high !=\n+\t\t\t\t afu_dev->id.uuid.uuid_high)\n+\t\t\tcontinue;\n+\n+\t\treturn 1;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+ifpga_probe_one_driver(struct rte_afu_driver *drv,\n+\t\t\tstruct rte_afu_device *afu_dev)\n+{\n+\tint ret;\n+\n+\tif (!rte_afu_match(drv, afu_dev))\n+\t\t/* Match of device and driver failed */\n+\t\treturn 1;\n+\n+\t/* reference driver structure */\n+\tafu_dev->driver = drv;\n+\tafu_dev->device.driver = &drv->driver;\n+\n+\t/* call the driver probe() function */\n+\tret = drv->probe(afu_dev);\n+\tif (ret) {\n+\t\tafu_dev->driver = NULL;\n+\t\tafu_dev->device.driver = NULL;\n+\t}\n+\n+\treturn ret;\n+}\n+\n+static int\n+ifpga_probe_all_drivers(struct rte_afu_device *afu_dev)\n+{\n+\tstruct rte_afu_driver *drv = NULL;\n+\tint ret = 0;\n+\n+\tif (afu_dev == NULL)\n+\t\treturn -1;\n+\n+\t/* Check if a driver is already loaded */\n+\tif (afu_dev->driver != NULL)\n+\t\treturn 0;\n+\n+\tTAILQ_FOREACH(drv, &afu_driver_list, next) {\n+\t\tif (ifpga_probe_one_driver(drv, afu_dev)) {\n+\t\t\tret = -1;\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\treturn ret;\n+}\n+\n+/*\n+ * Scan the content of the Intel FPGA bus, and call the probe() function for\n+ * all registered drivers that have a matching entry in its id_table\n+ * for discovered devices.\n+ */\n+static int\n+ifpga_probe(void)\n+{\n+\tstruct rte_ifpga_device *ifpga_dev;\n+\tstruct rte_afu_device *afu_dev = NULL;\n+\tint ret = 0;\n+\n+\tTAILQ_FOREACH(ifpga_dev, &ifpga_device_list, next) {\n+\t\tTAILQ_FOREACH(afu_dev, &ifpga_dev->afu_list, next) {\n+\n+\t\t\tif (afu_dev->device.driver)\n+\t\t\t\tcontinue;\n+\n+\t\t\tret = ifpga_probe_all_drivers(afu_dev);\n+\t\t\tif (ret < 0)\n+\t\t\t\tIFPGA_BUS_ERR(\"failed to initialize %s device\\n\",\n+\t\t\t\t\trte_ifpga_device_name(afu_dev));\n+\t\t}\n+\t}\n+\n+\treturn ret;\n+}\n+\n+static int\n+ifpga_plug(struct rte_device *dev)\n+{\n+\treturn ifpga_probe_all_drivers(RTE_DEV_TO_AFU(dev));\n+}\n+\n+static int\n+ifpga_remove_driver(struct rte_afu_device *afu_dev)\n+{\n+\tconst char *name;\n+\tconst struct rte_afu_driver *driver;\n+\n+\tname = rte_ifpga_device_name(afu_dev);\n+\tif (!afu_dev->device.driver) {\n+\t\tIFPGA_BUS_DEBUG(\"no driver attach to device %s\\n\", name);\n+\t\treturn 1;\n+\t}\n+\n+\tdriver = RTE_DRV_TO_AFU_CONST(afu_dev->device.driver);\n+\treturn driver->remove(afu_dev);\n+}\n+\n+static int\n+ifpga_unplug(struct rte_device *dev)\n+{\n+\tstruct rte_ifpga_device *ifpga_dev = NULL;\n+\tstruct rte_afu_device *afu_dev = NULL;\n+\tstruct rte_devargs *devargs = NULL;\n+\tint ret;\n+\n+\tif (dev == NULL)\n+\t\treturn -EINVAL;\n+\n+\tafu_dev = RTE_DEV_TO_AFU(dev);\n+\tif (!dev)\n+\t\treturn -ENOENT;\n+\n+\tifpga_dev = afu_dev->ifpga_dev;\n+\tdevargs = dev->devargs;\n+\n+\tret = ifpga_remove_driver(afu_dev);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tTAILQ_REMOVE(&ifpga_dev->afu_list, afu_dev, next);\n+\n+\trte_devargs_remove(devargs->bus->name, devargs->name);\n+\tfree(afu_dev);\n+\treturn 0;\n+\n+}\n+\n+static struct rte_device *\n+ifpga_find_device(const struct rte_device *start,\n+\trte_dev_cmp_t cmp, const void *data)\n+{\n+\tstruct rte_ifpga_device *ifpga_dev;\n+\tstruct rte_afu_device *afu_dev;\n+\n+\tTAILQ_FOREACH(ifpga_dev, &ifpga_device_list, next) {\n+\t\tTAILQ_FOREACH(afu_dev, &ifpga_dev->afu_list, next) {\n+\t\t\tif (start && &afu_dev->device == start) {\n+\t\t\t\tstart = NULL;\n+\t\t\t\tcontinue;\n+\t\t\t}\n+\t\t\tif (cmp(&afu_dev->device, data) == 0)\n+\t\t\t\treturn &afu_dev->device;\n+\t\t}\n+\t}\n+\treturn NULL;\n+}\n+static int\n+ifpga_parse(const char *name, void *addr)\n+{\n+\tint *out = addr;\n+\tstruct rte_rawdev *rawdev = NULL;\n+\tchar rawdev_name[RTE_RAWDEV_NAME_MAX_LEN];\n+\tchar *c1 = NULL, *c2 = NULL;\n+\tint port = IFPGA_BUS_DEV_PORT_MAX;\n+\tchar str_port[8];\n+\tint str_port_len = 0;\n+\tint ret;\n+\n+\tmemset(str_port, 0, 8);\n+\tc1 = strchr(name, '|');\n+\tif (c1 != NULL) {\n+\t\tstr_port_len = c1-name;\n+\t\tc2 = c1+1;\n+\t}\n+\n+\tif (str_port_len < 8 &&\n+\t\tstr_port_len > 0) {\n+\t\tmemcpy(str_port, name, str_port_len);\n+\t\tret = sscanf(str_port, \"%d\", &port);\n+\t\tif (ret == -1)\n+\t\t\treturn 0;\n+\t}\n+\n+\tmemset(rawdev_name, 0, sizeof(rawdev_name));\n+\tsnprintf(rawdev_name, RTE_RAWDEV_NAME_MAX_LEN, \"IFPGA:%s\", c2);\n+\trawdev = rte_rawdev_pmd_get_named_dev(rawdev_name);\n+\n+\tif ((port < IFPGA_BUS_DEV_PORT_MAX) &&\n+\t\trawdev &&\n+\t\t(addr != NULL))\n+\t\t*out = port;\n+\n+\tif ((port < IFPGA_BUS_DEV_PORT_MAX) &&\n+\t\trawdev)\n+\t\treturn 0;\n+\telse\n+\t\treturn 1;\n+}\n+\n+static struct rte_bus rte_ifpga_bus = {\n+\t.scan        = ifpga_scan,\n+\t.probe       = ifpga_probe,\n+\t.find_device = ifpga_find_device,\n+\t.plug        = ifpga_plug,\n+\t.unplug      = ifpga_unplug,\n+\t.parse       = ifpga_parse,\n+};\n+\n+RTE_REGISTER_BUS(IFPGA_BUS_NAME, rte_ifpga_bus);\n+\n+RTE_INIT(ifpga_init_log)\n+{\n+\tifpga_bus_logtype = rte_log_register(\"bus.ifpga\");\n+\tif (ifpga_bus_logtype >= 0)\n+\t\trte_log_set_level(ifpga_bus_logtype, RTE_LOG_NOTICE);\n+}\ndiff --git a/drivers/bus/ifpga/ifpga_common.c b/drivers/bus/ifpga/ifpga_common.c\nnew file mode 100644\nindex 0000000..b4efc20\n--- /dev/null\n+++ b/drivers/bus/ifpga/ifpga_common.c\n@@ -0,0 +1,88 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2010-2018 Intel Corporation\n+ */\n+\n+#include <string.h>\n+#include <inttypes.h>\n+#include <stdint.h>\n+#include <stdlib.h>\n+#include <stdio.h>\n+#include <sys/queue.h>\n+#include <sys/mman.h>\n+#include <sys/types.h>\n+#include <unistd.h>\n+#include <fcntl.h>\n+\n+#include <rte_errno.h>\n+#include <rte_bus.h>\n+#include <rte_per_lcore.h>\n+#include <rte_memory.h>\n+#include <rte_memzone.h>\n+#include <rte_eal.h>\n+#include <rte_common.h>\n+\n+#include <rte_devargs.h>\n+#include <rte_kvargs.h>\n+#include <rte_alarm.h>\n+\n+#include \"rte_bus_ifpga.h\"\n+#include \"ifpga_logs.h\"\n+#include \"ifpga_common.h\"\n+\n+int ifpga_get_string_arg(const char *key __rte_unused,\n+\tconst char *value, void *extra_args)\n+{\n+\tif (!value || !extra_args)\n+\t\treturn -EINVAL;\n+\n+\t*(char **)extra_args = strdup(value);\n+\n+\tif (!*(char **)extra_args)\n+\t\treturn -ENOMEM;\n+\n+\treturn 0;\n+}\n+int ifpga_get_integer32_arg(const char *key __rte_unused,\n+\tconst char *value, void *extra_args)\n+{\n+\tif (!value || !extra_args)\n+\t\treturn -EINVAL;\n+\n+\t*(int *)extra_args = strtoull(value, NULL, 0);\n+\n+\treturn 0;\n+}\n+int ifpga_get_integer64_arg(const char *key __rte_unused,\n+\tconst char *value, void *extra_args)\n+{\n+\tif (!value || !extra_args)\n+\t\treturn -EINVAL;\n+\n+\t*(uint64_t *)extra_args = strtoull(value, NULL, 0);\n+\n+\treturn 0;\n+}\n+int ifpga_get_unsigned_long(const char *str, int base)\n+{\n+\tunsigned long num;\n+\tchar *end = NULL;\n+\n+\terrno = 0;\n+\n+\tnum = strtoul(str, &end, base);\n+\tif ((str[0] == '\\0') || (end == NULL) || (*end != '\\0') || (errno != 0))\n+\t\treturn -1;\n+\n+\treturn num;\n+}\n+\n+int ifpga_afu_id_cmp(const struct rte_afu_id *afu_id0,\n+\tconst struct rte_afu_id *afu_id1)\n+{\n+\tif ((afu_id0->uuid.uuid_low == afu_id1->uuid.uuid_low) &&\n+\t\t(afu_id0->uuid.uuid_high == afu_id1->uuid.uuid_high) &&\n+\t\t(afu_id0->port == afu_id1->port)) {\n+\t\treturn 0;\n+\t} else\n+\t\treturn 1;\n+}\ndiff --git a/drivers/bus/ifpga/ifpga_common.h b/drivers/bus/ifpga/ifpga_common.h\nnew file mode 100644\nindex 0000000..b6662c8\n--- /dev/null\n+++ b/drivers/bus/ifpga/ifpga_common.h\n@@ -0,0 +1,18 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2010-2018 Intel Corporation\n+ */\n+\n+#ifndef _IFPGA_COMMON_H_\n+#define _IFPGA_COMMON_H_\n+\n+int ifpga_get_string_arg(const char *key __rte_unused,\n+\tconst char *value, void *extra_args);\n+int ifpga_get_integer32_arg(const char *key __rte_unused,\n+\tconst char *value, void *extra_args);\n+int ifpga_get_integer64_arg(const char *key __rte_unused,\n+\tconst char *value, void *extra_args);\n+int ifpga_get_unsigned_long(const char *str, int base);\n+int ifpga_afu_id_cmp(const struct rte_afu_id *afu_id0,\n+\tconst struct rte_afu_id *afu_id1);\n+\n+#endif /* _IFPGA_COMMON_H_ */\ndiff --git a/drivers/bus/ifpga/ifpga_logs.h b/drivers/bus/ifpga/ifpga_logs.h\nnew file mode 100644\nindex 0000000..873e0a4\n--- /dev/null\n+++ b/drivers/bus/ifpga/ifpga_logs.h\n@@ -0,0 +1,31 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2010-2018 Intel Corporation\n+ */\n+\n+#ifndef _IFPGA_LOGS_H_\n+#define _IFPGA_LOGS_H_\n+\n+#include <rte_log.h>\n+\n+extern int ifpga_bus_logtype;\n+\n+#define IFPGA_LOG(level, fmt, args...) \\\n+\trte_log(RTE_LOG_ ## level, ifpga_bus_logtype, \"%s(): \" fmt \"\\n\", \\\n+\t\t__func__, ##args)\n+\n+#define IFPGA_BUS_LOG(level, fmt, args...) \\\n+\trte_log(RTE_LOG_ ## level, ifpga_bus_logtype, \"%s(): \" fmt \"\\n\", \\\n+\t\t__func__, ##args)\n+\n+#define IFPGA_BUS_FUNC_TRACE() IFPGA_BUS_LOG(DEBUG, \">>\")\n+\n+#define IFPGA_BUS_DEBUG(fmt, args...) \\\n+\tIFPGA_BUS_LOG(DEBUG, fmt, ## args)\n+#define IFPGA_BUS_INFO(fmt, args...) \\\n+\tIFPGA_BUS_LOG(INFO, fmt, ## args)\n+#define IFPGA_BUS_ERR(fmt, args...) \\\n+\tIFPGA_BUS_LOG(ERR, fmt, ## args)\n+#define IFPGA_BUS_WARN(fmt, args...) \\\n+\tIFPGA_BUS_LOG(WARNING, fmt, ## args)\n+\n+#endif /* _IFPGA_BUS_LOGS_H_ */\ndiff --git a/drivers/bus/ifpga/meson.build b/drivers/bus/ifpga/meson.build\nnew file mode 100644\nindex 0000000..c9b08c8\n--- /dev/null\n+++ b/drivers/bus/ifpga/meson.build\n@@ -0,0 +1,8 @@\n+# SPDX-License-Identifier: BSD-3-Clause\n+# Copyright(c) 2010-2018 Intel Corporation\n+\n+deps += ['pci', 'kvargs', 'rawdev']\n+install_headers('rte_bus_ifpga.h')\n+sources = files('ifpga_common.c', 'ifpga_bus.c')\n+\n+allow_experimental_apis = true\ndiff --git a/drivers/bus/ifpga/rte_bus_ifpga.h b/drivers/bus/ifpga/rte_bus_ifpga.h\nnew file mode 100644\nindex 0000000..5c559e1\n--- /dev/null\n+++ b/drivers/bus/ifpga/rte_bus_ifpga.h\n@@ -0,0 +1,160 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2010-2018 Intel Corporation\n+ */\n+\n+#ifndef _RTE_BUS_IFPGA_H_\n+#define _RTE_BUS_IFPGA_H_\n+\n+/**\n+ * @file\n+ *\n+ * RTE Intel FPGA Bus Interface\n+ */\n+\n+#ifdef __cplusplus\n+extern \"C\" {\n+#endif\n+\n+#include <rte_bus.h>\n+#include <rte_pci.h>\n+\n+/** Name of Intel FPGA Bus */\n+#define IFPGA_BUS_NAME ifpga\n+\n+/* Forward declarations */\n+struct rte_afu_device;\n+\n+/** List of Intel AFU devices */\n+TAILQ_HEAD(afu_device_list, rte_afu_device);\n+/** Double linked list of AFU device drivers. */\n+TAILQ_HEAD(afu_driver_list, rte_afu_driver);\n+\n+#define IFPGA_BUS_BITSTREAM_PATH_MAX_LEN 256\n+\n+struct rte_afu_uuid {\n+\tuint64_t uuid_low;\n+\tuint64_t uuid_high;\n+} __attribute__ ((packed));\n+\n+#define IFPGA_BUS_DEV_PORT_MAX 4\n+\n+/**\n+ * A structure describing an ID for a AFU driver. Each driver provides a\n+ * table of these IDs for each device that it supports.\n+ */\n+struct rte_afu_id {\n+\tstruct rte_afu_uuid uuid;\n+\tint      port; /**< port number */\n+} __attribute__ ((packed));\n+\n+/**\n+ * A structure PR (Partial Reconfiguration) configuration AFU driver.\n+ */\n+\n+struct rte_afu_pr_conf {\n+\tstruct rte_afu_id afu_id;\n+\tint pr_enable;\n+\tchar bs_path[IFPGA_BUS_BITSTREAM_PATH_MAX_LEN];\n+};\n+\n+#define AFU_PRI_STR_SIZE (PCI_PRI_STR_SIZE + 8)\n+\n+/**\n+ * A structure describing a fpga device.\n+ */\n+struct rte_ifpga_device {\n+\tTAILQ_ENTRY(rte_ifpga_device) next;       /**< Next in device list. */\n+\tstruct rte_rawdev *rdev;\n+\tstruct afu_device_list afu_list;  /**< List of AFU devices */\n+};\n+\n+/**\n+ * A structure describing a AFU device.\n+ */\n+struct rte_afu_device {\n+\tTAILQ_ENTRY(rte_afu_device) next;       /**< Next in device list. */\n+\tstruct rte_device device;               /**< Inherit core device */\n+\tstruct rte_rawdev *rawdev;    /**< Point Rawdev */\n+\tstruct rte_ifpga_device *ifpga_dev;    /**< Point ifpga device */\n+\tstruct rte_afu_id id;                   /**< AFU id within FPGA. */\n+\tuint32_t num_region;   /**< number of regions found */\n+\tstruct rte_mem_resource mem_resource[PCI_MAX_RESOURCE];\n+\t\t\t\t\t\t/**< AFU Memory Resource */\n+\tstruct rte_intr_handle intr_handle;     /**< Interrupt handle */\n+\tstruct rte_afu_driver *driver;          /**< Associated driver */\n+\tchar path[IFPGA_BUS_BITSTREAM_PATH_MAX_LEN];\n+} __attribute__ ((packed));\n+\n+/**\n+ * @internal\n+ * Helper macro for drivers that need to convert to struct rte_afu_device.\n+ */\n+#define RTE_DEV_TO_AFU(ptr) \\\n+\tcontainer_of(ptr, struct rte_afu_device, device)\n+\n+#define RTE_DRV_TO_AFU_CONST(ptr) \\\n+\tcontainer_of(ptr, const struct rte_afu_driver, driver)\n+\n+/**\n+ * Initialisation function for the driver called during FPGA BUS probing.\n+ */\n+typedef int (afu_probe_t)(struct rte_afu_device *);\n+\n+/**\n+ * Uninitialisation function for the driver called during hotplugging.\n+ */\n+typedef int (afu_remove_t)(struct rte_afu_device *);\n+\n+/**\n+ * A structure describing a AFU device.\n+ */\n+struct rte_afu_driver {\n+\tTAILQ_ENTRY(rte_afu_driver) next;       /**< Next afu driver. */\n+\tstruct rte_driver driver;               /**< Inherit core driver. */\n+\tafu_probe_t *probe;                     /**< Device Probe function. */\n+\tafu_remove_t *remove;                   /**< Device Remove function. */\n+\tconst struct rte_afu_uuid *id_table;    /**< AFU uuid within FPGA. */\n+\tuint32_t drv_flags;         /**< Flags contolling handling of device. */\n+};\n+\n+static inline const char *\n+rte_ifpga_device_name(const struct rte_afu_device *afu)\n+{\n+\tif (afu && afu->device.name)\n+\t\treturn afu->device.name;\n+\treturn NULL;\n+}\n+\n+/**\n+ * Register a ifpga afu device driver.\n+ *\n+ * @param driver\n+ *   A pointer to a rte_afu_driver structure describing the driver\n+ *   to be registered.\n+ */\n+void rte_ifpga_driver_register(struct rte_afu_driver *driver);\n+\n+/**\n+ * Unregister a ifpga afu device driver.\n+ *\n+ * @param driver\n+ *   A pointer to a rte_afu_driver structure describing the driver\n+ *   to be unregistered.\n+ */\n+void rte_ifpga_driver_unregister(struct rte_afu_driver *driver);\n+\n+#define RTE_PMD_REGISTER_AFU(nm, afudrv)\\\n+RTE_INIT(afudrvinitfn_ ##afudrv);\\\n+static const char *afudrvinit_ ## nm ## _alias;\\\n+static void afudrvinitfn_ ##afudrv(void)\\\n+{\\\n+\t(afudrv).driver.name = RTE_STR(nm);\\\n+\t(afudrv).driver.alias = afudrvinit_ ## nm ## _alias;\\\n+\trte_ifpga_driver_register(&afudrv);\\\n+} \\\n+RTE_PMD_EXPORT_NAME(nm, __COUNTER__)\n+\n+#define RTE_PMD_REGISTER_AFU_ALIAS(nm, alias)\\\n+static const char *afudrvinit_ ## nm ## _alias = RTE_STR(alias)\n+\n+#endif /* _RTE_BUS_IFPGA_H_ */\ndiff --git a/drivers/bus/ifpga/rte_bus_ifpga_version.map b/drivers/bus/ifpga/rte_bus_ifpga_version.map\nnew file mode 100644\nindex 0000000..1304caf\n--- /dev/null\n+++ b/drivers/bus/ifpga/rte_bus_ifpga_version.map\n@@ -0,0 +1,10 @@\n+DPDK_18.05 {\n+\tglobal:\n+\n+\tifpga_get_integer32_arg;\n+\tifpga_get_string_arg;\n+\trte_ifpga_driver_register;\n+\trte_ifpga_driver_unregister;\n+\n+\tlocal: *;\n+};\ndiff --git a/drivers/bus/meson.build b/drivers/bus/meson.build\nindex 58dfbe2..170df25 100644\n--- a/drivers/bus/meson.build\n+++ b/drivers/bus/meson.build\n@@ -1,7 +1,7 @@\n # SPDX-License-Identifier: BSD-3-Clause\n # Copyright(c) 2017 Intel Corporation\n \n-drivers = ['dpaa', 'fslmc', 'pci', 'vdev']\n+drivers = ['dpaa', 'fslmc', 'pci', 'vdev', 'ifpga']\n std_deps = ['eal']\n config_flag_fmt = 'RTE_LIBRTE_@0@_BUS'\n driver_name_fmt = 'rte_bus_@0@'\ndiff --git a/mk/rte.app.mk b/mk/rte.app.mk\nindex 29a2a60..8b10c2a 100644\n--- a/mk/rte.app.mk\n+++ b/mk/rte.app.mk\n@@ -251,6 +251,7 @@ endif # CONFIG_RTE_LIBRTE_EVENTDEV\n \n ifeq ($(CONFIG_RTE_LIBRTE_RAWDEV),y)\n _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += -lrte_pmd_skeleton_rawdev\n+_LDLIBS-$(CONFIG_RTE_LIBRTE_IFPGA_BUS)      += -lrte_bus_ifpga\n endif # CONFIG_RTE_LIBRTE_RAWDEV\n \n \n",
    "prefixes": [
        "dpdk-dev",
        "v8",
        "1/5"
    ]
}