get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 37073,
    "url": "http://patches.dpdk.org/api/patches/37073/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1522824677-86958-2-git-send-email-rosen.xu@intel.com/",
    "project": {
        "id": 1,
        "url": "http://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": "<1522824677-86958-2-git-send-email-rosen.xu@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1522824677-86958-2-git-send-email-rosen.xu@intel.com",
    "date": "2018-04-04T06:51:15",
    "name": "[dpdk-dev,v5,1/3] Add Intel FPGA BUS Library",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "90e6c7ff8fdd6390908f12fc2c053d7cb17fa3cf",
    "submitter": {
        "id": 946,
        "url": "http://patches.dpdk.org/api/people/946/?format=api",
        "name": "Xu, Rosen",
        "email": "rosen.xu@intel.com"
    },
    "delegate": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/1522824677-86958-2-git-send-email-rosen.xu@intel.com/mbox/",
    "series": [],
    "comments": "http://patches.dpdk.org/api/patches/37073/comments/",
    "check": "warning",
    "checks": "http://patches.dpdk.org/api/patches/37073/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 4CD3F1BBC8;\n\tWed,  4 Apr 2018 08:49:09 +0200 (CEST)",
            "from mga02.intel.com (mga02.intel.com [134.134.136.20])\n\tby dpdk.org (Postfix) with ESMTP id 58C611BBC5\n\tfor <dev@dpdk.org>; Wed,  4 Apr 2018 08:49:07 +0200 (CEST)",
            "from orsmga005.jf.intel.com ([10.7.209.41])\n\tby orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t03 Apr 2018 23:49:07 -0700",
            "from dpdkx8602.sh.intel.com ([10.67.110.200])\n\tby orsmga005.jf.intel.com with ESMTP; 03 Apr 2018 23:49:05 -0700"
        ],
        "X-Amp-Result": "SKIPPED(no attachment in message)",
        "X-Amp-File-Uploaded": "False",
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.48,405,1517904000\"; d=\"scan'208\";a=\"213779520\"",
        "From": "Rosen Xu <rosen.xu@intel.com>",
        "To": "dev@dpdk.org",
        "Cc": "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, hao.wu@intel.com, \n\tgaetan.rivet@6wind.com",
        "Date": "Wed,  4 Apr 2018 14:51:15 +0800",
        "Message-Id": "<1522824677-86958-2-git-send-email-rosen.xu@intel.com>",
        "X-Mailer": "git-send-email 1.8.3.1",
        "In-Reply-To": "<1522824677-86958-1-git-send-email-rosen.xu@intel.com>",
        "References": "<1521553556-62982-1-git-send-email-rosen.xu@intel.com>\n\t<1522824677-86958-1-git-send-email-rosen.xu@intel.com>",
        "Subject": "[dpdk-dev] [PATCH v5 1/3] 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": "Signed-off-by: Rosen Xu <rosen.xu@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               | 504 ++++++++++++++++++++++++++++\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/rte_bus_ifpga.h           | 168 ++++++++++\n drivers/bus/ifpga/rte_bus_ifpga_version.map |  10 +\n mk/rte.app.mk                               |   2 +\n 10 files changed, 859 insertions(+)\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/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 ad03cf4..49f6b09 100644\n--- a/config/common_base\n+++ b/config/common_base\n@@ -134,6 +134,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 7ef2593..55d2dfe 100644\n--- a/drivers/bus/Makefile\n+++ b/drivers/bus/Makefile\n@@ -7,5 +7,6 @@ DIRS-$(CONFIG_RTE_LIBRTE_DPAA_BUS) += dpaa\n DIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc\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..84d32ad\n--- /dev/null\n+++ b/drivers/bus/ifpga/ifpga_bus.c\n@@ -0,0 +1,504 @@\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 declare to access Intel FPGA bus name */\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+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+rte_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((char *)(&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(\"error 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_low = 0;\n+\tafu_pr_conf.afu_id.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_low  = 0;\n+\tafu_dev->id.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, strlen(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\tprintf(\"firmware load error %d\\n\", ret);\n+\t\tgoto free_dev;\n+\t}\n+\tafu_dev->id.uuid_low  = afu_pr_conf.afu_id.uuid_low;\n+\tafu_dev->id.uuid_high = afu_pr_conf.afu_id.uuid_high;\n+\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+rte_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+\tTAILQ_FOREACH(devargs, &devargs_list, next) {\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 = rte_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_low) ||\n+\t\t\t\t(id_table->uuid_high != afu_dev->id.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+\t/* return positive value if driver doesn't support this device */\n+\treturn 0;\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 rc;\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\trc = ifpga_probe_one_driver(drv, afu_dev);\n+\t\tif (rc < 0)\n+\t\t\t/* negative value is an error */\n+\t\t\treturn -1;\n+\t\tif (rc > 0)\n+\t\t\t/* positive value means driver doesn't support it */\n+\t\t\tcontinue;\n+\t\treturn 0;\n+\t}\n+\treturn 1;\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+rte_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 0;\n+}\n+\n+static int\n+rte_ifpga_plug(struct rte_device *dev)\n+{\n+\treturn ifpga_probe_all_drivers(RTE_DEV_TO_AFU(dev));\n+}\n+\n+static int 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+rte_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+\tTAILQ_REMOVE(&devargs_list, devargs, next);\n+\n+\tfree(devargs->args);\n+\tfree(devargs);\n+\tfree(afu_dev);\n+\treturn 0;\n+\n+}\n+\n+static struct rte_device *\n+rte_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+rte_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+\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\tsscanf(str_port, \"%d\", &port);\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        = rte_ifpga_scan,\n+\t.probe       = rte_ifpga_probe,\n+\t.find_device = rte_ifpga_find_device,\n+\t.plug        = rte_ifpga_plug,\n+\t.unplug      = rte_ifpga_unplug,\n+\t.parse       = rte_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+}\n+\ndiff --git a/drivers/bus/ifpga/ifpga_common.c b/drivers/bus/ifpga/ifpga_common.c\nnew file mode 100644\nindex 0000000..26fee27\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_low           == afu_id1->uuid_low) &&\n+\t\t(afu_id0->uuid_high          == afu_id1->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/rte_bus_ifpga.h b/drivers/bus/ifpga/rte_bus_ifpga.h\nnew file mode 100644\nindex 0000000..53e7183\n--- /dev/null\n+++ b/drivers/bus/ifpga/rte_bus_ifpga.h\n@@ -0,0 +1,168 @@\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+\tuint64_t uuid_low;\n+\tuint64_t uuid_high;\n+\tint      port;\n+} __attribute__ ((packed));\n+\n+/**\n+ * A structure pr 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+/**\n+ * Structure describing the Intel FPGA bus\n+ */\n+struct rte_ifpga_bus {\n+\tstruct rte_bus bus;               /**< Inherit the generic class */\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..7e46261\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+\trte_ifpga_driver_register;\n+\trte_ifpga_driver_unregister;\n+\tifpga_get_string_arg;\n+\tifpga_get_integer32_arg;\n+\n+\tlocal: *;\n+};\ndiff --git a/mk/rte.app.mk b/mk/rte.app.mk\nindex 3eb41d1..929c3d8 100644\n--- a/mk/rte.app.mk\n+++ b/mk/rte.app.mk\n@@ -107,6 +107,8 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_CMDLINE)        += -lrte_cmdline\n _LDLIBS-$(CONFIG_RTE_LIBRTE_REORDER)        += -lrte_reorder\n _LDLIBS-$(CONFIG_RTE_LIBRTE_SCHED)          += -lrte_sched\n \n+_LDLIBS-$(CONFIG_RTE_LIBRTE_IFPGA_BUS)      += -lrte_bus_ifpga\n+\n ifeq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)\n _LDLIBS-$(CONFIG_RTE_LIBRTE_KNI)            += -lrte_kni\n endif\n",
    "prefixes": [
        "dpdk-dev",
        "v5",
        "1/3"
    ]
}