get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 94863,
    "url": "https://patches.dpdk.org/api/patches/94863/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/20210625114726.776425-2-xuemingl@nvidia.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": "<20210625114726.776425-2-xuemingl@nvidia.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20210625114726.776425-2-xuemingl@nvidia.com",
    "date": "2021-06-25T11:47:25",
    "name": "[v6,2/2] bus/auxiliary: introduce auxiliary bus",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "2d2c3983d8b62919f3d7d2084fef4649b6150ab8",
    "submitter": {
        "id": 1904,
        "url": "https://patches.dpdk.org/api/people/1904/?format=api",
        "name": "Xueming Li",
        "email": "xuemingl@nvidia.com"
    },
    "delegate": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/20210625114726.776425-2-xuemingl@nvidia.com/mbox/",
    "series": [
        {
            "id": 17488,
            "url": "https://patches.dpdk.org/api/series/17488/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=17488",
            "date": "2021-06-25T11:47:24",
            "name": "[v6,1/2] devargs: add common key definition",
            "version": 6,
            "mbox": "https://patches.dpdk.org/series/17488/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/94863/comments/",
    "check": "warning",
    "checks": "https://patches.dpdk.org/api/patches/94863/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 67F13A0547;\n\tFri, 25 Jun 2021 13:48:09 +0200 (CEST)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id E0C83410DD;\n\tFri, 25 Jun 2021 13:48:02 +0200 (CEST)",
            "from NAM12-DM6-obe.outbound.protection.outlook.com\n (mail-dm6nam12on2043.outbound.protection.outlook.com [40.107.243.43])\n by mails.dpdk.org (Postfix) with ESMTP id 173E24068A\n for <dev@dpdk.org>; Fri, 25 Jun 2021 13:48:00 +0200 (CEST)",
            "from BN6PR16CA0043.namprd16.prod.outlook.com (2603:10b6:405:14::29)\n by DM5PR12MB1722.namprd12.prod.outlook.com (2603:10b6:3:107::18) with\n Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4242.21; Fri, 25 Jun\n 2021 11:47:58 +0000",
            "from BN8NAM11FT050.eop-nam11.prod.protection.outlook.com\n (2603:10b6:405:14:cafe::b) by BN6PR16CA0043.outlook.office365.com\n (2603:10b6:405:14::29) with Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4264.18 via Frontend\n Transport; Fri, 25 Jun 2021 11:47:58 +0000",
            "from mail.nvidia.com (216.228.112.34) by\n BN8NAM11FT050.mail.protection.outlook.com (10.13.177.5) with Microsoft SMTP\n Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id\n 15.20.4264.18 via Frontend Transport; Fri, 25 Jun 2021 11:47:57 +0000",
            "from nvidia.com (172.20.187.5) by HQMAIL107.nvidia.com\n (172.20.187.13) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Fri, 25 Jun\n 2021 11:47:55 +0000"
        ],
        "ARC-Seal": "i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none;\n b=l0X/nnhaE/lvGAO++xTn2hHRj5hgRFXeLmZdDJ08HbZLq5gXaKUe36pN3TbkEtyU9g1UQH28LwNup5rXsT3eqNKA+RhnlH8tvCH3gsrzdYZEv8wq6hk3MJzOEQ2bEvPQ5uvyPOIdyqUTkhDjWrSD5zYyc+PTP9Fi7tjzJZKZts6Lwtsl1G2QMs4EqIP77SjHp61/aC4/sNqzCH1Ruc4xWeBfWhNOs+eQxr1LU/QykP6IY6eK/6urebgnExRYN3cBezDpcBh6KjeXtT4DKJGqQ068/CsVOkgd64ghSVkD0yiVyZCWcm9p0iQIuVpTI9/8UR8nALauhGfoholDPlJJ3A==",
        "ARC-Message-Signature": "i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com;\n s=arcselector9901;\n h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;\n bh=p2L7GVC6hiOFIcKwQeZ6sf9j92D/LCQwJBJYqwsWEUI=;\n b=nxXRQiLk+XGCYUgSObUIexCdkhYSoFytzUlO1CUSjhld1n4V1kExVbV194wXxHhF1lM+ai2NpLWT0fM53jpJ8sIm/LKwdDqD4Q8afP9fiWC9P1GQ2fwqlBayHsUX589d1ciR/Jsu96isSdAHuEn1MX3Aggu3Ii0vJaljUl+CS7ukfQICVZU1wBWwNrvcML4ktQBTbWdCBkB2JAbcOz50ZMj67pPrmuZJ6c98disG4wiuWKerB1RCcpWBYJ7jpecIXpyzxYUPiN0OvPBp/4iNFcA6d9zaZWMgTR8umO8H963s2y2YR1B7cFlzHyXljy4aQR+hOZgPn4F2UK8GtlffCQ==",
        "ARC-Authentication-Results": "i=1; mx.microsoft.com 1; spf=pass (sender ip is\n 216.228.112.34) smtp.rcpttodomain=ashroe.eu smtp.mailfrom=nvidia.com;\n dmarc=pass (p=none sp=none pct=100) action=none header.from=nvidia.com;\n dkim=none (message not signed); arc=none",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com;\n s=selector2;\n h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;\n bh=p2L7GVC6hiOFIcKwQeZ6sf9j92D/LCQwJBJYqwsWEUI=;\n b=kP0cOvpnOWRttanrpNmRFXN4B/okdACJ8lsswZBsIEfICRO5Z3CJ2/6byssj5jctDt7mMBsd5JYb3GDM1KwBwRGWRc6EVAQk/jIE6MBVHIiF1vyCHNI0h9LjHi+uKlIz0XI+4H3lH4IzfxAdKvekWVs8/C1wIwkxk1xV/g6lqEvC0qQvUPF92mKgD+JBDuPd/G4U63K7lkNwzWAYD8rOkaY5F/0mD/jo+8ZtCHQqb/LHgKyM27iHZWD+cETcMtxkWkaTkOLR4Ns57TvJ2ql5+yScAmYQsDu3zq2HOEovZoAetQOuYzwKpfIpgpIljtitaIW/Ls5YjKAuAuT3VuKLYw==",
        "X-MS-Exchange-Authentication-Results": "spf=pass (sender IP is 216.228.112.34)\n smtp.mailfrom=nvidia.com; ashroe.eu; dkim=none (message not signed)\n header.d=none;ashroe.eu; dmarc=pass action=none header.from=nvidia.com;",
        "Received-SPF": "Pass (protection.outlook.com: domain of nvidia.com designates\n 216.228.112.34 as permitted sender) receiver=protection.outlook.com;\n client-ip=216.228.112.34; helo=mail.nvidia.com;",
        "From": "Xueming Li <xuemingl@nvidia.com>",
        "To": "",
        "CC": "<dev@dpdk.org>, <xuemingl@nvidia.com>, Wang Haiyue\n <haiyue.wang@intel.com>, Thomas Monjalon <thomas@monjalon.net>, Kinsella Ray\n <mdr@ashroe.eu>, Neil Horman <nhorman@tuxdriver.com>",
        "Date": "Fri, 25 Jun 2021 14:47:25 +0300",
        "Message-ID": "<20210625114726.776425-2-xuemingl@nvidia.com>",
        "X-Mailer": "git-send-email 2.27.0",
        "In-Reply-To": "<20210623000349.631468-2-xuemingl@nvidia.com>",
        "References": "<20210623000349.631468-2-xuemingl@nvidia.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Content-Type": "text/plain",
        "X-Originating-IP": "[172.20.187.5]",
        "X-ClientProxiedBy": "HQMAIL111.nvidia.com (172.20.187.18) To\n HQMAIL107.nvidia.com (172.20.187.13)",
        "X-EOPAttributedMessage": "0",
        "X-MS-PublicTrafficType": "Email",
        "X-MS-Office365-Filtering-Correlation-Id": "f1b6eacb-5ffa-4bbe-aa1d-08d937cf1386",
        "X-MS-TrafficTypeDiagnostic": "DM5PR12MB1722:",
        "X-LD-Processed": "43083d15-7273-40c1-b7db-39efd9ccc17a,ExtAddr",
        "X-Microsoft-Antispam-PRVS": "\n <DM5PR12MB17229898CFEF62CF9079833CA1069@DM5PR12MB1722.namprd12.prod.outlook.com>",
        "X-MS-Oob-TLC-OOBClassifiers": "OLM:5797;",
        "X-MS-Exchange-SenderADCheck": "1",
        "X-Microsoft-Antispam": "BCL:0;",
        "X-Microsoft-Antispam-Message-Info": "\n CQLYnUfJOgv1OgWJfWnwo8Zlqmmx2JR0v4uBaEpSev92mmuOFeGheD4ci8M9JmImYhMVBWW9xTTkPzdmBEKwEUsA+lpDWgfPGbzIoyFIhLInnr2L8ey7DZTLoVgm4edqSW0EhQ7LYDpR6nq4dSczpHAZVmgUxKalWCPvPJRZ+Ej+yxj/6UDtJmVzDEU4xSc6FDuc8gkMesLmrC1ZWof6T9DBDlIPChLgaWU7dqJmZJ2MExxQfUu/kcbsfAg2o8C/jJPjjZ3Zh+KTyGT1awYtgs9l9orFtpjsTn0XHqZqe+oIjYXv2UScjtwCnBXQdvPCRpn8/c5sRe24xXtns9mZQ1nwKp19gt0MVzpGtxy8c1o/M4agJV8lvPJTkg52MVqaEkdrzhBkBgRyi4e3i2y3pF7RKLrHJXEymwPI4QV9gQILudhNQYnRxaiwk82I0OnvWR1GlNvRKyW6Z8pEudkF9/8XrwQDbrdv2hvXnEcjuKtG0UlSjpKLL+Gh8lxGMQ16uvK0Jhw1HDjEEOXtDeAxPZURgbB433nB1he28QDyc4iOw4J+gcgZkSp5uUDxU3yiTQwi7YN+2e7senZ6iC75FwrdCZEUCYJwmufn9twfmnfPGYwjeQ4pF9wFABpw3qYEhL5EFleurubOO3ruWz4OBVQxnfkkGzyel153HzVRMWZXZ/pr4rqLq1Pu23nuGs9o48Kuco6ITWZJCtbZBODnGye5dI2T6f8LAEdhbQiUTZnXOcVC8k42sc/JRM/m9k1u52Y89tR1UkQAX8X+hfbZC6MEGcRVu9IDq5SIjo2XNIWExxEj5xxyZwhkfutuTMXYa3AIeuHAQhlq16q7ZAivyilwCD1hQRhGxOeDVaEQtoI=",
        "X-Forefront-Antispam-Report": "CIP:216.228.112.34; CTRY:US; LANG:en; SCL:1;\n SRV:;\n IPV:NLI; SFV:NSPM; H:mail.nvidia.com; PTR:schybrid03.nvidia.com; CAT:NONE;\n SFS:(4636009)(376002)(396003)(39860400002)(136003)(346002)(46966006)(36840700001)(6286002)(82740400003)(36756003)(47076005)(109986005)(30864003)(5660300002)(336012)(16526019)(2616005)(4326008)(7696005)(426003)(26005)(186003)(86362001)(8936002)(6666004)(1076003)(8676002)(966005)(83380400001)(55016002)(70206006)(70586007)(2906002)(36860700001)(54906003)(82310400003)(7636003)(478600001)(316002)(356005)(266003);\n DIR:OUT; SFP:1101;",
        "X-OriginatorOrg": "Nvidia.com",
        "X-MS-Exchange-CrossTenant-OriginalArrivalTime": "25 Jun 2021 11:47:57.2167 (UTC)",
        "X-MS-Exchange-CrossTenant-Network-Message-Id": "\n f1b6eacb-5ffa-4bbe-aa1d-08d937cf1386",
        "X-MS-Exchange-CrossTenant-Id": "43083d15-7273-40c1-b7db-39efd9ccc17a",
        "X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp": "\n TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a; Ip=[216.228.112.34];\n Helo=[mail.nvidia.com]",
        "X-MS-Exchange-CrossTenant-AuthSource": "\n BN8NAM11FT050.eop-nam11.prod.protection.outlook.com",
        "X-MS-Exchange-CrossTenant-AuthAs": "Anonymous",
        "X-MS-Exchange-CrossTenant-FromEntityHeader": "HybridOnPrem",
        "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "DM5PR12MB1722",
        "Subject": "[dpdk-dev] [PATCH v6 2/2] bus/auxiliary: introduce auxiliary bus",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "Auxiliary bus [1] provides a way to split function into child-devices\nrepresenting sub-domains of functionality. Each auxiliary device\nrepresents a part of its parent functionality.\n\nAuxiliary device is identified by unique device name, sysfs path:\n  /sys/bus/auxiliary/devices/<name>\n\nDevargs legacy syntax ofauxiliary device:\n  -a auxiliary:<name>[,args...]\nDevargs generic syntax of auxiliary device:\n  -a bus=auxiliary,name=<name>,,/class=<classs>,,/driver=<driver>,,\n\n[1] kernel auxiliary bus document:\nhttps://www.kernel.org/doc/html/latest/driver-api/auxiliary_bus.html\n\nSigned-off-by: Xueming Li <xuemingl@nvidia.com>\nCc: Wang Haiyue <haiyue.wang@intel.com>\nCc: Thomas Monjalon <thomas@monjalon.net>\nCc: Kinsella Ray <mdr@ashroe.eu>\n---\n MAINTAINERS                               |   5 +\n doc/guides/rel_notes/release_21_08.rst    |   6 +\n drivers/bus/auxiliary/auxiliary_common.c  | 411 ++++++++++++++++++++++\n drivers/bus/auxiliary/auxiliary_params.c  |  59 ++++\n drivers/bus/auxiliary/linux/auxiliary.c   | 141 ++++++++\n drivers/bus/auxiliary/meson.build         |  16 +\n drivers/bus/auxiliary/private.h           |  74 ++++\n drivers/bus/auxiliary/rte_bus_auxiliary.h | 201 +++++++++++\n drivers/bus/auxiliary/version.map         |   7 +\n drivers/bus/meson.build                   |   1 +\n 10 files changed, 921 insertions(+)\n create mode 100644 drivers/bus/auxiliary/auxiliary_common.c\n create mode 100644 drivers/bus/auxiliary/auxiliary_params.c\n create mode 100644 drivers/bus/auxiliary/linux/auxiliary.c\n create mode 100644 drivers/bus/auxiliary/meson.build\n create mode 100644 drivers/bus/auxiliary/private.h\n create mode 100644 drivers/bus/auxiliary/rte_bus_auxiliary.h\n create mode 100644 drivers/bus/auxiliary/version.map",
    "diff": "diff --git a/MAINTAINERS b/MAINTAINERS\nindex 5877a16971..eaf691ca6a 100644\n--- a/MAINTAINERS\n+++ b/MAINTAINERS\n@@ -525,6 +525,11 @@ F: doc/guides/mempool/octeontx2.rst\n Bus Drivers\n -----------\n \n+Auxiliary bus driver\n+M: Parav Pandit <parav@nvidia.com>\n+M: Xueming Li <xuemingl@nvidia.com>\n+F: drivers/bus/auxiliary/\n+\n Intel FPGA bus\n M: Rosen Xu <rosen.xu@intel.com>\n F: drivers/bus/ifpga/\ndiff --git a/doc/guides/rel_notes/release_21_08.rst b/doc/guides/rel_notes/release_21_08.rst\nindex a6ecfdf3ce..e7ef4c8a05 100644\n--- a/doc/guides/rel_notes/release_21_08.rst\n+++ b/doc/guides/rel_notes/release_21_08.rst\n@@ -55,6 +55,12 @@ New Features\n      Also, make sure to start the actual text at the margin.\n      =======================================================\n \n+* **Added auxiliary bus support.**\n+\n+  Auxiliary bus provides a way to split function into child-devices\n+  representing sub-domains of functionality. Each auxiliary device\n+  represents a part of its parent functionality.\n+\n \n Removed Items\n -------------\ndiff --git a/drivers/bus/auxiliary/auxiliary_common.c b/drivers/bus/auxiliary/auxiliary_common.c\nnew file mode 100644\nindex 0000000000..8a75306da5\n--- /dev/null\n+++ b/drivers/bus/auxiliary/auxiliary_common.c\n@@ -0,0 +1,411 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright (c) 2021 NVIDIA Corporation & Affiliates\n+ */\n+\n+#include <string.h>\n+#include <inttypes.h>\n+#include <stdint.h>\n+#include <stdbool.h>\n+#include <stdlib.h>\n+#include <stdio.h>\n+#include <sys/queue.h>\n+#include <rte_errno.h>\n+#include <rte_interrupts.h>\n+#include <rte_log.h>\n+#include <rte_bus.h>\n+#include <rte_per_lcore.h>\n+#include <rte_memory.h>\n+#include <rte_eal.h>\n+#include <rte_eal_paging.h>\n+#include <rte_string_fns.h>\n+#include <rte_common.h>\n+#include <rte_devargs.h>\n+\n+#include \"private.h\"\n+#include \"rte_bus_auxiliary.h\"\n+\n+static struct rte_devargs *\n+auxiliary_devargs_lookup(const char *name)\n+{\n+\tstruct rte_devargs *devargs;\n+\n+\tRTE_EAL_DEVARGS_FOREACH(RTE_BUS_AUXILIARY_NAME, devargs) {\n+\t\tif (strcmp(devargs->name, name) == 0)\n+\t\t\treturn devargs;\n+\t}\n+\treturn NULL;\n+}\n+\n+/*\n+ * Test whether the auxiliary device exist\n+ *\n+ * Stub for OS not supporting auxiliary bus.\n+ */\n+__rte_weak bool\n+auxiliary_dev_exists(const char *name)\n+{\n+\tRTE_SET_USED(name);\n+\treturn false;\n+}\n+\n+/*\n+ * Scan the devices in the auxiliary bus.\n+ *\n+ * Stub for OS not supporting auxiliary bus.\n+ */\n+__rte_weak int\n+auxiliary_scan(void)\n+{\n+\treturn 0;\n+}\n+\n+/*\n+ * Update a device's devargs being scanned.\n+ *\n+ * @param aux_dev\n+ *\tAUXILIARY device.\n+ */\n+void\n+auxiliary_on_scan(struct rte_auxiliary_device *aux_dev)\n+{\n+\taux_dev->device.devargs = auxiliary_devargs_lookup(aux_dev->name);\n+}\n+\n+/*\n+ * Match the auxiliary driver and device using driver function.\n+ */\n+bool\n+auxiliary_match(const struct rte_auxiliary_driver *aux_drv,\n+\t\tconst struct rte_auxiliary_device *aux_dev)\n+{\n+\tif (aux_drv->match == NULL)\n+\t\treturn false;\n+\treturn aux_drv->match(aux_dev->name);\n+}\n+\n+/*\n+ * Call the probe() function of the driver.\n+ */\n+static int\n+rte_auxiliary_probe_one_driver(struct rte_auxiliary_driver *drv,\n+\t\t\t       struct rte_auxiliary_device *dev)\n+{\n+\tenum rte_iova_mode iova_mode;\n+\tint ret;\n+\n+\tif ((drv == NULL) || (dev == NULL))\n+\t\treturn -EINVAL;\n+\n+\t/* Check if driver supports it. */\n+\tif (!auxiliary_match(drv, dev))\n+\t\t/* Match of device and driver failed */\n+\t\treturn 1;\n+\n+\t/* No initialization when marked as blocked, return without error. */\n+\tif (dev->device.devargs != NULL &&\n+\t    dev->device.devargs->policy == RTE_DEV_BLOCKED) {\n+\t\tAUXILIARY_LOG(INFO, \"Device is blocked, not initializing\");\n+\t\treturn -1;\n+\t}\n+\n+\tif (dev->device.numa_node < 0) {\n+\t\tAUXILIARY_LOG(INFO, \"Device is not NUMA-aware, defaulting socket to 0\");\n+\t\tdev->device.numa_node = 0;\n+\t}\n+\n+\tiova_mode = rte_eal_iova_mode();\n+\tif ((drv->drv_flags & RTE_AUXILIARY_DRV_NEED_IOVA_AS_VA) > 0 &&\n+\t    iova_mode != RTE_IOVA_VA) {\n+\t\tAUXILIARY_LOG(ERR, \"Driver %s expecting VA IOVA mode but current mode is PA, not initializing\",\n+\t\t\t      drv->driver.name);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tdev->driver = drv;\n+\n+\tAUXILIARY_LOG(INFO, \"Probe auxiliary driver: %s device: %s (socket %i)\",\n+\t\t      drv->driver.name, dev->name, dev->device.numa_node);\n+\tret = drv->probe(drv, dev);\n+\tif (ret != 0)\n+\t\tdev->driver = NULL;\n+\telse\n+\t\tdev->device.driver = &drv->driver;\n+\n+\treturn ret;\n+}\n+\n+/*\n+ * Call the remove() function of the driver.\n+ */\n+static int\n+rte_auxiliary_driver_remove_dev(struct rte_auxiliary_device *dev)\n+{\n+\tstruct rte_auxiliary_driver *drv;\n+\tint ret = 0;\n+\n+\tif (dev == NULL)\n+\t\treturn -EINVAL;\n+\n+\tdrv = dev->driver;\n+\n+\tAUXILIARY_LOG(DEBUG, \"Driver %s remove auxiliary device %s on NUMA socket %i\",\n+\t\t      drv->driver.name, dev->name, dev->device.numa_node);\n+\n+\tif (drv->remove != NULL) {\n+\t\tret = drv->remove(dev);\n+\t\tif (ret < 0)\n+\t\t\treturn ret;\n+\t}\n+\n+\t/* clear driver structure */\n+\tdev->driver = NULL;\n+\tdev->device.driver = NULL;\n+\n+\treturn 0;\n+}\n+\n+/*\n+ * Call the probe() function of all registered driver for the given device.\n+ * Return < 0 if initialization failed.\n+ * Return 1 if no driver is found for this device.\n+ */\n+static int\n+auxiliary_probe_all_drivers(struct rte_auxiliary_device *dev)\n+{\n+\tstruct rte_auxiliary_driver *drv;\n+\tint rc;\n+\n+\tif (dev == NULL)\n+\t\treturn -EINVAL;\n+\n+\tFOREACH_DRIVER_ON_AUXILIARY_BUS(drv) {\n+\t\tif (!drv->match(dev->name))\n+\t\t\tcontinue;\n+\n+\t\trc = rte_auxiliary_probe_one_driver(drv, dev);\n+\t\tif (rc < 0)\n+\t\t\t/* negative value is an error */\n+\t\t\treturn rc;\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 auxiliary bus, and call the probe function for\n+ * all registered drivers to try to probe discovered devices.\n+ */\n+static int\n+auxiliary_probe(void)\n+{\n+\tstruct rte_auxiliary_device *dev = NULL;\n+\tsize_t probed = 0, failed = 0;\n+\tint ret = 0;\n+\n+\tFOREACH_DEVICE_ON_AUXILIARY_BUS(dev) {\n+\t\tprobed++;\n+\n+\t\tret = auxiliary_probe_all_drivers(dev);\n+\t\tif (ret < 0) {\n+\t\t\tif (ret != -EEXIST) {\n+\t\t\t\tAUXILIARY_LOG(ERR, \"Requested device %s cannot be used\",\n+\t\t\t\t\t      dev->name);\n+\t\t\t\trte_errno = errno;\n+\t\t\t\tfailed++;\n+\t\t\t}\n+\t\t\tret = 0;\n+\t\t}\n+\t}\n+\n+\treturn (probed && probed == failed) ? -1 : 0;\n+}\n+\n+static int\n+auxiliary_parse(const char *name, void *addr)\n+{\n+\tstruct rte_auxiliary_driver *drv = NULL;\n+\tconst char **out = addr;\n+\n+\t/* Allow empty device name \"auxiliary:\" to bypass entire bus scan. */\n+\tif (strlen(name) == 0)\n+\t\treturn 0;\n+\n+\tFOREACH_DRIVER_ON_AUXILIARY_BUS(drv) {\n+\t\tif (drv->match(name))\n+\t\t\tbreak;\n+\t}\n+\tif (drv != NULL && addr != NULL)\n+\t\t*out = name;\n+\treturn drv != NULL ? 0 : -1;\n+}\n+\n+/* Register a driver */\n+void\n+rte_auxiliary_register(struct rte_auxiliary_driver *driver)\n+{\n+\tTAILQ_INSERT_TAIL(&auxiliary_bus.driver_list, driver, next);\n+\tdriver->bus = &auxiliary_bus;\n+}\n+\n+/* Unregister a driver */\n+void\n+rte_auxiliary_unregister(struct rte_auxiliary_driver *driver)\n+{\n+\tTAILQ_REMOVE(&auxiliary_bus.driver_list, driver, next);\n+\tdriver->bus = NULL;\n+}\n+\n+/* Add a device to auxiliary bus */\n+void\n+auxiliary_add_device(struct rte_auxiliary_device *aux_dev)\n+{\n+\tTAILQ_INSERT_TAIL(&auxiliary_bus.device_list, aux_dev, next);\n+}\n+\n+/* Insert a device into a predefined position in auxiliary bus */\n+void\n+auxiliary_insert_device(struct rte_auxiliary_device *exist_aux_dev,\n+\t\t\tstruct rte_auxiliary_device *new_aux_dev)\n+{\n+\tTAILQ_INSERT_BEFORE(exist_aux_dev, new_aux_dev, next);\n+}\n+\n+/* Remove a device from auxiliary bus */\n+static void\n+rte_auxiliary_remove_device(struct rte_auxiliary_device *auxiliary_dev)\n+{\n+\tTAILQ_REMOVE(&auxiliary_bus.device_list, auxiliary_dev, next);\n+}\n+\n+static struct rte_device *\n+auxiliary_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,\n+\t\t      const void *data)\n+{\n+\tconst struct rte_auxiliary_device *pstart;\n+\tstruct rte_auxiliary_device *adev;\n+\n+\tif (start != NULL) {\n+\t\tpstart = RTE_DEV_TO_AUXILIARY_CONST(start);\n+\t\tadev = TAILQ_NEXT(pstart, next);\n+\t} else {\n+\t\tadev = TAILQ_FIRST(&auxiliary_bus.device_list);\n+\t}\n+\twhile (adev != NULL) {\n+\t\tif (cmp(&adev->device, data) == 0)\n+\t\t\treturn &adev->device;\n+\t\tadev = TAILQ_NEXT(adev, next);\n+\t}\n+\treturn NULL;\n+}\n+\n+static int\n+auxiliary_plug(struct rte_device *dev)\n+{\n+\tif (!auxiliary_dev_exists(dev->name))\n+\t\treturn -ENOENT;\n+\treturn auxiliary_probe_all_drivers(RTE_DEV_TO_AUXILIARY(dev));\n+}\n+\n+static int\n+auxiliary_unplug(struct rte_device *dev)\n+{\n+\tstruct rte_auxiliary_device *adev;\n+\tint ret;\n+\n+\tadev = RTE_DEV_TO_AUXILIARY(dev);\n+\tret = rte_auxiliary_driver_remove_dev(adev);\n+\tif (ret == 0) {\n+\t\trte_auxiliary_remove_device(adev);\n+\t\trte_devargs_remove(dev->devargs);\n+\t\tfree(adev);\n+\t}\n+\treturn ret;\n+}\n+\n+static int\n+auxiliary_dma_map(struct rte_device *dev, void *addr, uint64_t iova, size_t len)\n+{\n+\tstruct rte_auxiliary_device *aux_dev = RTE_DEV_TO_AUXILIARY(dev);\n+\n+\tif (dev == NULL || aux_dev->driver == NULL) {\n+\t\trte_errno = EINVAL;\n+\t\treturn -1;\n+\t}\n+\tif (aux_dev->driver->dma_map == NULL) {\n+\t\trte_errno = ENOTSUP;\n+\t\treturn -1;\n+\t}\n+\treturn aux_dev->driver->dma_map(aux_dev, addr, iova, len);\n+}\n+\n+static int\n+auxiliary_dma_unmap(struct rte_device *dev, void *addr, uint64_t iova,\n+\t\t    size_t len)\n+{\n+\tstruct rte_auxiliary_device *aux_dev = RTE_DEV_TO_AUXILIARY(dev);\n+\n+\tif (dev == NULL || aux_dev->driver == NULL) {\n+\t\trte_errno = EINVAL;\n+\t\treturn -1;\n+\t}\n+\tif (aux_dev->driver->dma_unmap == NULL) {\n+\t\trte_errno = ENOTSUP;\n+\t\treturn -1;\n+\t}\n+\treturn aux_dev->driver->dma_unmap(aux_dev, addr, iova, len);\n+}\n+\n+bool\n+auxiliary_is_ignored_device(const char *name)\n+{\n+\tstruct rte_devargs *devargs = auxiliary_devargs_lookup(name);\n+\n+\tswitch (auxiliary_bus.bus.conf.scan_mode) {\n+\tcase RTE_BUS_SCAN_ALLOWLIST:\n+\t\tif (devargs && devargs->policy == RTE_DEV_ALLOWED)\n+\t\t\treturn false;\n+\t\tbreak;\n+\tcase RTE_BUS_SCAN_UNDEFINED:\n+\tcase RTE_BUS_SCAN_BLOCKLIST:\n+\t\tif (devargs == NULL || devargs->policy != RTE_DEV_BLOCKED)\n+\t\t\treturn false;\n+\t\tbreak;\n+\t}\n+\treturn true;\n+}\n+\n+static enum rte_iova_mode\n+auxiliary_get_iommu_class(void)\n+{\n+\tconst struct rte_auxiliary_driver *drv;\n+\n+\tFOREACH_DRIVER_ON_AUXILIARY_BUS(drv) {\n+\t\tif ((drv->drv_flags & RTE_AUXILIARY_DRV_NEED_IOVA_AS_VA) > 0)\n+\t\t\treturn RTE_IOVA_VA;\n+\t}\n+\n+\treturn RTE_IOVA_DC;\n+}\n+\n+struct rte_auxiliary_bus auxiliary_bus = {\n+\t.bus = {\n+\t\t.scan = auxiliary_scan,\n+\t\t.probe = auxiliary_probe,\n+\t\t.find_device = auxiliary_find_device,\n+\t\t.plug = auxiliary_plug,\n+\t\t.unplug = auxiliary_unplug,\n+\t\t.parse = auxiliary_parse,\n+\t\t.dma_map = auxiliary_dma_map,\n+\t\t.dma_unmap = auxiliary_dma_unmap,\n+\t\t.get_iommu_class = auxiliary_get_iommu_class,\n+\t\t.dev_iterate = auxiliary_dev_iterate,\n+\t},\n+\t.device_list = TAILQ_HEAD_INITIALIZER(auxiliary_bus.device_list),\n+\t.driver_list = TAILQ_HEAD_INITIALIZER(auxiliary_bus.driver_list),\n+};\n+\n+RTE_REGISTER_BUS(auxiliary, auxiliary_bus.bus);\n+RTE_LOG_REGISTER_DEFAULT(auxiliary_bus_logtype, NOTICE);\ndiff --git a/drivers/bus/auxiliary/auxiliary_params.c b/drivers/bus/auxiliary/auxiliary_params.c\nnew file mode 100644\nindex 0000000000..cd3fa56cb4\n--- /dev/null\n+++ b/drivers/bus/auxiliary/auxiliary_params.c\n@@ -0,0 +1,59 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright (c) 2021 NVIDIA Corporation & Affiliates\n+ */\n+\n+#include <string.h>\n+\n+#include <rte_bus.h>\n+#include <rte_dev.h>\n+#include <rte_errno.h>\n+#include <rte_kvargs.h>\n+\n+#include \"private.h\"\n+#include \"rte_bus_auxiliary.h\"\n+\n+enum auxiliary_params {\n+\tRTE_AUXILIARY_PARAM_NAME,\n+};\n+\n+static const char * const auxiliary_params_keys[] = {\n+\t[RTE_AUXILIARY_PARAM_NAME] = \"name\",\n+};\n+\n+static int\n+auxiliary_dev_match(const struct rte_device *dev,\n+\t      const void *_kvlist)\n+{\n+\tconst struct rte_kvargs *kvlist = _kvlist;\n+\tint ret;\n+\n+\tret = rte_kvargs_process(kvlist,\n+\t\t\tauxiliary_params_keys[RTE_AUXILIARY_PARAM_NAME],\n+\t\t\trte_kvargs_strcmp, (void *)(uintptr_t)dev->name);\n+\n+\treturn ret != 0 ? -1 : 0;\n+}\n+\n+void *\n+auxiliary_dev_iterate(const void *start,\n+\t\t    const char *str,\n+\t\t    const struct rte_dev_iterator *it __rte_unused)\n+{\n+\trte_bus_find_device_t find_device;\n+\tstruct rte_kvargs *kvargs = NULL;\n+\tstruct rte_device *dev;\n+\n+\tif (str != NULL) {\n+\t\tkvargs = rte_kvargs_parse(str, auxiliary_params_keys);\n+\t\tif (kvargs == NULL) {\n+\t\t\tAUXILIARY_LOG(ERR, \"cannot parse argument list %s\",\n+\t\t\t\t      str);\n+\t\t\trte_errno = EINVAL;\n+\t\t\treturn NULL;\n+\t\t}\n+\t}\n+\tfind_device = auxiliary_bus.bus.find_device;\n+\tdev = find_device(start, auxiliary_dev_match, kvargs);\n+\trte_kvargs_free(kvargs);\n+\treturn dev;\n+}\ndiff --git a/drivers/bus/auxiliary/linux/auxiliary.c b/drivers/bus/auxiliary/linux/auxiliary.c\nnew file mode 100644\nindex 0000000000..8464487971\n--- /dev/null\n+++ b/drivers/bus/auxiliary/linux/auxiliary.c\n@@ -0,0 +1,141 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright (c) 2021 NVIDIA Corporation & Affiliates\n+ */\n+\n+#include <string.h>\n+#include <dirent.h>\n+\n+#include <rte_log.h>\n+#include <rte_bus.h>\n+#include <rte_malloc.h>\n+#include <rte_devargs.h>\n+#include <rte_memcpy.h>\n+#include <eal_filesystem.h>\n+\n+#include \"../rte_bus_auxiliary.h\"\n+#include \"../private.h\"\n+\n+#define AUXILIARY_SYSFS_PATH \"/sys/bus/auxiliary/devices\"\n+\n+/* Scan one auxiliary sysfs entry, and fill the devices list from it. */\n+static int\n+auxiliary_scan_one(const char *dirname, const char *name)\n+{\n+\tstruct rte_auxiliary_device *dev;\n+\tstruct rte_auxiliary_device *dev2;\n+\tchar filename[PATH_MAX];\n+\tunsigned long tmp;\n+\tint ret;\n+\n+\tdev = malloc(sizeof(*dev));\n+\tif (dev == NULL)\n+\t\treturn -1;\n+\n+\tmemset(dev, 0, sizeof(*dev));\n+\tif (rte_strscpy(dev->name, name, sizeof(dev->name)) < 0) {\n+\t\tfree(dev);\n+\t\treturn -1;\n+\t}\n+\tdev->device.name = dev->name;\n+\tdev->device.bus = &auxiliary_bus.bus;\n+\n+\t/* Get NUMA node, default to 0 if not present */\n+\tsnprintf(filename, sizeof(filename), \"%s/%s/numa_node\",\n+\t\t dirname, name);\n+\tif (access(filename, F_OK) != -1) {\n+\t\tif (eal_parse_sysfs_value(filename, &tmp) == 0)\n+\t\t\tdev->device.numa_node = tmp;\n+\t\telse\n+\t\t\tdev->device.numa_node = -1;\n+\t} else {\n+\t\tdev->device.numa_node = 0;\n+\t}\n+\n+\tauxiliary_on_scan(dev);\n+\n+\t/* Device is valid, add in list (sorted) */\n+\tTAILQ_FOREACH(dev2, &auxiliary_bus.device_list, next) {\n+\t\tret = strcmp(dev->name, dev2->name);\n+\t\tif (ret > 0)\n+\t\t\tcontinue;\n+\t\tif (ret < 0) {\n+\t\t\tauxiliary_insert_device(dev2, dev);\n+\t\t} else { /* already registered */\n+\t\t\tif (rte_dev_is_probed(&dev2->device) &&\n+\t\t\t    dev2->device.devargs != dev->device.devargs) {\n+\t\t\t\t/* To probe device with new devargs. */\n+\t\t\t\trte_devargs_remove(dev2->device.devargs);\n+\t\t\t\tauxiliary_on_scan(dev2);\n+\t\t\t}\n+\t\t\tfree(dev);\n+\t\t}\n+\t\treturn 0;\n+\t}\n+\tauxiliary_add_device(dev);\n+\treturn 0;\n+}\n+\n+/*\n+ * Test whether the auxiliary device exist\n+ */\n+bool\n+auxiliary_dev_exists(const char *name)\n+{\n+\tDIR *dir;\n+\tchar dirname[PATH_MAX];\n+\n+\tsnprintf(dirname, sizeof(dirname), \"%s/%s\",\n+\t\t AUXILIARY_SYSFS_PATH, name);\n+\tdir = opendir(dirname);\n+\tif (dir == NULL)\n+\t\treturn false;\n+\tclosedir(dir);\n+\treturn true;\n+}\n+\n+/*\n+ * Scan the devices in the auxiliary bus\n+ */\n+int\n+auxiliary_scan(void)\n+{\n+\tstruct dirent *e;\n+\tDIR *dir;\n+\tchar dirname[PATH_MAX];\n+\tstruct rte_auxiliary_driver *drv;\n+\n+\tdir = opendir(AUXILIARY_SYSFS_PATH);\n+\tif (dir == NULL) {\n+\t\tAUXILIARY_LOG(INFO, \"%s not found, is auxiliary module loaded?\",\n+\t\t\t      AUXILIARY_SYSFS_PATH);\n+\t\treturn 0;\n+\t}\n+\n+\twhile ((e = readdir(dir)) != NULL) {\n+\t\tif (e->d_name[0] == '.')\n+\t\t\tcontinue;\n+\n+\t\tif (auxiliary_is_ignored_device(e->d_name))\n+\t\t\tcontinue;\n+\n+\t\tsnprintf(dirname, sizeof(dirname), \"%s/%s\",\n+\t\t\t AUXILIARY_SYSFS_PATH, e->d_name);\n+\n+\t\t/* Ignore if no driver can handle. */\n+\t\tFOREACH_DRIVER_ON_AUXILIARY_BUS(drv) {\n+\t\t\tif (drv->match(e->d_name))\n+\t\t\t\tbreak;\n+\t\t}\n+\t\tif (drv == NULL)\n+\t\t\tcontinue;\n+\n+\t\tif (auxiliary_scan_one(dirname, e->d_name) < 0)\n+\t\t\tgoto error;\n+\t}\n+\tclosedir(dir);\n+\treturn 0;\n+\n+error:\n+\tclosedir(dir);\n+\treturn -1;\n+}\ndiff --git a/drivers/bus/auxiliary/meson.build b/drivers/bus/auxiliary/meson.build\nnew file mode 100644\nindex 0000000000..357550eff7\n--- /dev/null\n+++ b/drivers/bus/auxiliary/meson.build\n@@ -0,0 +1,16 @@\n+# SPDX-License-Identifier: BSD-3-Clause\n+# Copyright (c) 2021 NVIDIA Corporation & Affiliates\n+\n+headers = files(\n+        'rte_bus_auxiliary.h',\n+)\n+sources = files(\n+        'auxiliary_common.c',\n+        'auxiliary_params.c',\n+)\n+if is_linux\n+    sources += files(\n+        'linux/auxiliary.c',\n+    )\n+endif\n+deps += ['kvargs']\ndiff --git a/drivers/bus/auxiliary/private.h b/drivers/bus/auxiliary/private.h\nnew file mode 100644\nindex 0000000000..cb3e849993\n--- /dev/null\n+++ b/drivers/bus/auxiliary/private.h\n@@ -0,0 +1,74 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright (c) 2021 NVIDIA Corporation & Affiliates\n+ */\n+\n+#ifndef AUXILIARY_PRIVATE_H\n+#define AUXILIARY_PRIVATE_H\n+\n+#include <stdbool.h>\n+#include <stdio.h>\n+\n+#include \"rte_bus_auxiliary.h\"\n+\n+extern struct rte_auxiliary_bus auxiliary_bus;\n+extern int auxiliary_bus_logtype;\n+\n+#define AUXILIARY_LOG(level, ...) \\\n+\trte_log(RTE_LOG_ ## level, auxiliary_bus_logtype, \\\n+\t\tRTE_FMT(\"auxiliary bus: \" RTE_FMT_HEAD(__VA_ARGS__,) \"\\n\", \\\n+\t\t\tRTE_FMT_TAIL(__VA_ARGS__,)))\n+\n+/* Auxiliary bus iterators */\n+#define FOREACH_DEVICE_ON_AUXILIARY_BUS(p) \\\n+\t\tTAILQ_FOREACH(p, &(auxiliary_bus.device_list), next)\n+\n+#define FOREACH_DRIVER_ON_AUXILIARY_BUS(p) \\\n+\t\tTAILQ_FOREACH(p, &(auxiliary_bus.driver_list), next)\n+\n+bool auxiliary_dev_exists(const char *name);\n+\n+/*\n+ * Scan the content of the auxiliary bus, and the devices in the devices\n+ * list.\n+ */\n+int auxiliary_scan(void);\n+\n+/*\n+ * Update a device being scanned.\n+ */\n+void auxiliary_on_scan(struct rte_auxiliary_device *aux_dev);\n+\n+/*\n+ * Validate whether a device with given auxiliary device should be ignored\n+ * or not.\n+ */\n+bool auxiliary_is_ignored_device(const char *name);\n+\n+/*\n+ * Add an auxiliary device to the auxiliary bus (append to auxiliary device\n+ * list). This function also updates the bus references of the auxiliary\n+ * device and the generic device object embedded within.\n+ */\n+void auxiliary_add_device(struct rte_auxiliary_device *aux_dev);\n+\n+/*\n+ * Insert an auxiliary device in the auxiliary bus at a particular location\n+ * in the device list. It also updates the auxiliary bus reference of the\n+ * new devices to be inserted.\n+ */\n+void auxiliary_insert_device(struct rte_auxiliary_device *exist_aux_dev,\n+\t\t\t     struct rte_auxiliary_device *new_aux_dev);\n+\n+/*\n+ * Match the auxiliary driver and device by driver function\n+ */\n+bool auxiliary_match(const struct rte_auxiliary_driver *aux_drv,\n+\t\t     const struct rte_auxiliary_device *aux_dev);\n+\n+/*\n+ * Iterate over devices, matching any device against the provided string\n+ */\n+void *auxiliary_dev_iterate(const void *start, const char *str,\n+\t\t\t    const struct rte_dev_iterator *it);\n+\n+#endif /* AUXILIARY_PRIVATE_H */\ndiff --git a/drivers/bus/auxiliary/rte_bus_auxiliary.h b/drivers/bus/auxiliary/rte_bus_auxiliary.h\nnew file mode 100644\nindex 0000000000..16b147e387\n--- /dev/null\n+++ b/drivers/bus/auxiliary/rte_bus_auxiliary.h\n@@ -0,0 +1,201 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright (c) 2021 NVIDIA Corporation & Affiliates\n+ */\n+\n+#ifndef RTE_BUS_AUXILIARY_H\n+#define RTE_BUS_AUXILIARY_H\n+\n+/**\n+ * @file\n+ *\n+ * Auxiliary Bus Interface.\n+ */\n+\n+#ifdef __cplusplus\n+extern \"C\" {\n+#endif\n+\n+#include <stdio.h>\n+#include <stdlib.h>\n+#include <limits.h>\n+#include <errno.h>\n+#include <sys/queue.h>\n+#include <stdint.h>\n+#include <inttypes.h>\n+\n+#include <rte_debug.h>\n+#include <rte_interrupts.h>\n+#include <rte_dev.h>\n+#include <rte_bus.h>\n+#include <rte_kvargs.h>\n+\n+#define RTE_BUS_AUXILIARY_NAME \"auxiliary\"\n+\n+/* Forward declarations */\n+struct rte_auxiliary_driver;\n+struct rte_auxiliary_bus;\n+struct rte_auxiliary_device;\n+\n+/**\n+ * Match function for the driver to decide if device can be handled.\n+ *\n+ * @param name\n+ *   Pointer to the auxiliary device name.\n+ * @return\n+ *   Whether the driver can handle the auxiliary device.\n+ */\n+typedef bool(rte_auxiliary_match_t)(const char *name);\n+\n+/**\n+ * Initialization function for the driver called during auxiliary probing.\n+ *\n+ * @param drv\n+ *   Pointer to the auxiliary driver.\n+ * @param dev\n+ *   Pointer to the auxiliary device.\n+ * @return\n+ *   - 0 On success.\n+ *   - Negative value and rte_errno is set otherwise.\n+ */\n+typedef int(rte_auxiliary_probe_t)(struct rte_auxiliary_driver *drv,\n+\t\t\t\t    struct rte_auxiliary_device *dev);\n+\n+/**\n+ * Uninitialization function for the driver called during hotplugging.\n+ *\n+ * @param dev\n+ *   Pointer to the auxiliary device.\n+ * @return\n+ *   - 0 On success.\n+ *   - Negative value and rte_errno is set otherwise.\n+ */\n+typedef int (rte_auxiliary_remove_t)(struct rte_auxiliary_device *dev);\n+\n+/**\n+ * Driver-specific DMA mapping. After a successful call the device\n+ * will be able to read/write from/to this segment.\n+ *\n+ * @param dev\n+ *   Pointer to the auxiliary device.\n+ * @param addr\n+ *   Starting virtual address of memory to be mapped.\n+ * @param iova\n+ *   Starting IOVA address of memory to be mapped.\n+ * @param len\n+ *   Length of memory segment being mapped.\n+ * @return\n+ *   - 0 On success.\n+ *   - Negative value and rte_errno is set otherwise.\n+ */\n+typedef int (rte_auxiliary_dma_map_t)(struct rte_auxiliary_device *dev,\n+\t\t\t\t       void *addr, uint64_t iova, size_t len);\n+\n+/**\n+ * Driver-specific DMA un-mapping. After a successful call the device\n+ * will not be able to read/write from/to this segment.\n+ *\n+ * @param dev\n+ *   Pointer to the auxiliary device.\n+ * @param addr\n+ *   Starting virtual address of memory to be unmapped.\n+ * @param iova\n+ *   Starting IOVA address of memory to be unmapped.\n+ * @param len\n+ *   Length of memory segment being unmapped.\n+ * @return\n+ *   - 0 On success.\n+ *   - Negative value and rte_errno is set otherwise.\n+ */\n+typedef int (rte_auxiliary_dma_unmap_t)(struct rte_auxiliary_device *dev,\n+\t\t\t\t\t void *addr, uint64_t iova, size_t len);\n+\n+/**\n+ * A structure describing an auxiliary device.\n+ */\n+struct rte_auxiliary_device {\n+\tTAILQ_ENTRY(rte_auxiliary_device) next;   /**< Next probed device. */\n+\tstruct rte_device device;                 /**< Inherit core device */\n+\tchar name[RTE_DEV_NAME_MAX_LEN + 1];      /**< ASCII device name */\n+\tstruct rte_intr_handle intr_handle;       /**< Interrupt handle */\n+\tstruct rte_auxiliary_driver *driver;      /**< Device driver */\n+};\n+\n+/** List of auxiliary devices */\n+TAILQ_HEAD(rte_auxiliary_device_list, rte_auxiliary_device);\n+/** List of auxiliary drivers */\n+TAILQ_HEAD(rte_auxiliary_driver_list, rte_auxiliary_driver);\n+\n+/**\n+ * Structure describing the auxiliary bus\n+ */\n+struct rte_auxiliary_bus {\n+\tstruct rte_bus bus;                  /**< Inherit the generic class */\n+\tstruct rte_auxiliary_device_list device_list;  /**< List of devices */\n+\tstruct rte_auxiliary_driver_list driver_list;  /**< List of drivers */\n+};\n+\n+/**\n+ * A structure describing an auxiliary driver.\n+ */\n+struct rte_auxiliary_driver {\n+\tTAILQ_ENTRY(rte_auxiliary_driver) next; /**< Next in list. */\n+\tstruct rte_driver driver;             /**< Inherit core driver. */\n+\tstruct rte_auxiliary_bus *bus;        /**< Auxiliary bus reference. */\n+\trte_auxiliary_match_t *match;         /**< Device match function. */\n+\trte_auxiliary_probe_t *probe;         /**< Device probe function. */\n+\trte_auxiliary_remove_t *remove;       /**< Device remove function. */\n+\trte_auxiliary_dma_map_t *dma_map;     /**< Device DMA map function. */\n+\trte_auxiliary_dma_unmap_t *dma_unmap; /**< Device DMA unmap function. */\n+\tuint32_t drv_flags;                   /**< Flags RTE_AUXILIARY_DRV_*. */\n+};\n+\n+/**\n+ * @internal\n+ * Helper macro for drivers that need to convert to struct rte_auxiliary_device.\n+ */\n+#define RTE_DEV_TO_AUXILIARY(ptr) \\\n+\tcontainer_of(ptr, struct rte_auxiliary_device, device)\n+\n+#define RTE_DEV_TO_AUXILIARY_CONST(ptr) \\\n+\tcontainer_of(ptr, const struct rte_auxiliary_device, device)\n+\n+#define RTE_ETH_DEV_TO_AUXILIARY(eth_dev) \\\n+\tRTE_DEV_TO_AUXILIARY((eth_dev)->device)\n+\n+/** Device driver needs IOVA as VA and cannot work with IOVA as PA */\n+#define RTE_AUXILIARY_DRV_NEED_IOVA_AS_VA 0x002\n+\n+/**\n+ * Register an auxiliary driver.\n+ *\n+ * @param driver\n+ *   A pointer to a rte_auxiliary_driver structure describing the driver\n+ *   to be registered.\n+ */\n+__rte_experimental\n+void rte_auxiliary_register(struct rte_auxiliary_driver *driver);\n+\n+/** Helper for auxiliary device registration from driver instance */\n+#define RTE_PMD_REGISTER_AUXILIARY(nm, auxiliary_drv) \\\n+\tRTE_INIT(auxiliaryinitfn_ ##nm) \\\n+\t{ \\\n+\t\t(auxiliary_drv).driver.name = RTE_STR(nm); \\\n+\t\trte_auxiliary_register(&(auxiliary_drv)); \\\n+\t} \\\n+\tRTE_PMD_EXPORT_NAME(nm, __COUNTER__)\n+\n+/**\n+ * Unregister an auxiliary driver.\n+ *\n+ * @param driver\n+ *   A pointer to a rte_auxiliary_driver structure describing the driver\n+ *   to be unregistered.\n+ */\n+__rte_experimental\n+void rte_auxiliary_unregister(struct rte_auxiliary_driver *driver);\n+\n+#ifdef __cplusplus\n+}\n+#endif\n+\n+#endif /* RTE_BUS_AUXILIARY_H */\ndiff --git a/drivers/bus/auxiliary/version.map b/drivers/bus/auxiliary/version.map\nnew file mode 100644\nindex 0000000000..a52260657c\n--- /dev/null\n+++ b/drivers/bus/auxiliary/version.map\n@@ -0,0 +1,7 @@\n+EXPERIMENTAL {\n+\tglobal:\n+\n+\t# added in 21.08\n+\trte_auxiliary_register;\n+\trte_auxiliary_unregister;\n+};\ndiff --git a/drivers/bus/meson.build b/drivers/bus/meson.build\nindex 410058de3a..45eab5233d 100644\n--- a/drivers/bus/meson.build\n+++ b/drivers/bus/meson.build\n@@ -2,6 +2,7 @@\n # Copyright(c) 2017 Intel Corporation\n \n drivers = [\n+        'auxiliary',\n         'dpaa',\n         'fslmc',\n         'ifpga',\n",
    "prefixes": [
        "v6",
        "2/2"
    ]
}