get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 71855,
    "url": "http://patches.dpdk.org/api/patches/71855/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20200621191200.28120-5-parav@mellanox.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": "<20200621191200.28120-5-parav@mellanox.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20200621191200.28120-5-parav@mellanox.com",
    "date": "2020-06-21T19:11:58",
    "name": "[v2,4/6] bus/mlx5_pci: register a PCI driver",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "4ff9c854d26a0cb47ccd769d4127e3effcabf899",
    "submitter": {
        "id": 1780,
        "url": "http://patches.dpdk.org/api/people/1780/?format=api",
        "name": "Parav Pandit",
        "email": "parav@mellanox.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/20200621191200.28120-5-parav@mellanox.com/mbox/",
    "series": [
        {
            "id": 10537,
            "url": "http://patches.dpdk.org/api/series/10537/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=10537",
            "date": "2020-06-21T19:11:54",
            "name": "Improve mlx5 PMD common driver framework for multiple classes",
            "version": 2,
            "mbox": "http://patches.dpdk.org/series/10537/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/71855/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/71855/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 dpdk.org (dpdk.org [92.243.14.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 053B4A0350;\n\tSun, 21 Jun 2020 21:12:57 +0200 (CEST)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 5C3081C1A9;\n\tSun, 21 Jun 2020 21:12:31 +0200 (CEST)",
            "from EUR05-AM6-obe.outbound.protection.outlook.com\n (mail-am6eur05on2081.outbound.protection.outlook.com [40.107.22.81])\n by dpdk.org (Postfix) with ESMTP id DC07A1C199\n for <dev@dpdk.org>; Sun, 21 Jun 2020 21:12:25 +0200 (CEST)",
            "from AM0PR05MB4866.eurprd05.prod.outlook.com (2603:10a6:208:c0::32)\n by AM0PR05MB6307.eurprd05.prod.outlook.com (2603:10a6:208:145::17)\n with Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3109.21; Sun, 21 Jun\n 2020 19:12:25 +0000",
            "from AM0PR05MB4866.eurprd05.prod.outlook.com\n ([fe80::d44d:a804:c730:d2b7]) by AM0PR05MB4866.eurprd05.prod.outlook.com\n ([fe80::d44d:a804:c730:d2b7%2]) with mapi id 15.20.3109.026; Sun, 21 Jun 2020\n 19:12:25 +0000",
            "from sw-mtx-036.mtx.labs.mlnx (208.176.44.194) by\n DM6PR02CA0105.namprd02.prod.outlook.com (2603:10b6:5:1f4::46) with Microsoft\n SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id\n 15.20.3109.22 via Frontend Transport; Sun, 21 Jun 2020 19:12:23 +0000"
        ],
        "ARC-Seal": "i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none;\n b=KzTXTF/B+3NEGz6A/NzoEJmwLWd5XKsStrSukl9/q2niTHD0/YUdyr3lRCaf1XOkPrUML1QLNlUjR5glOEoVGJBVBCHuyRwn1ozIQogIRINAAN30bIBhHe+aj0UXEJtqEkF3MlJ/SlR48viDtziVicEoKyHfShNVnIQWY4OfxxeLibKme2yxU3pa3YAkMbnOMcGG1XHXgI6Nx5ZXq/gqQB9FlwNOztZZzGQvVQ47bn1DrIPPSUcbzOjaL7WlUrY1LVjSkQuku0zRe8E/0jbVNZRFFdjl9ibXwMwDQNslBTTdcqFMXRQkFOUvciSNXISkSBj2ZOGFR5rQ/uUfNhJL8A==",
        "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=qvdMYKddghyYnHDDKT9MxmhSRsEWw5t+y8tKQ6YN5zM=;\n b=KSMHhcaE+FHwOz0Dm8VYDEVJEXTapoQR61KPkutJJ8Fu2cAXc+13UM4QR2j5oXoBUn0hE3X6u+e0gaCaLE6bw9tzHRSF5aYjypxlZzwIGLcg3kqtpgV3HOlZQiAoEKYBVDwcskF/G/AFs+F7EEkYigkuWYQ9Cx0cdbSJtVdLxu9x9NmqUBXWTXnHvOnSDt2cyKrOKx0AnrSlPkO6VbBUNZSUpnrsq387VNDbjDZoBdsXdleKNnb8lCm2apyZ62kF985IMI/iBhAph0mW9jp64N4pGw1WDiArpS8KMuRs54la9YSBcCrWWb7otdNmRmi0dQvwK692cm1+dvYvnLUSig==",
        "ARC-Authentication-Results": "i=1; mx.microsoft.com 1; spf=pass\n smtp.mailfrom=mellanox.com; dmarc=pass action=none header.from=mellanox.com;\n dkim=pass header.d=mellanox.com; arc=none",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=Mellanox.com;\n s=selector1;\n h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;\n bh=qvdMYKddghyYnHDDKT9MxmhSRsEWw5t+y8tKQ6YN5zM=;\n b=ewVPYHKskV9PuUIMCy4uMRfy65I6ccJfqguY4CykXXW08BmBDGLErqVayfPIeM8CrOSdEcy2YezqcT8bJSALwTtFQC97dGsAKsQYZR4Dt5ZjMphs+GCVtzF/aL/JqgdYCWNmDhkYFx5o91XBhk8hBQod8mNoEhZhgawcW9+pmZk=",
        "Authentication-Results": "u256.net; dkim=none (message not signed)\n header.d=none;u256.net; dmarc=none action=none header.from=mellanox.com;",
        "From": "Parav Pandit <parav@mellanox.com>",
        "To": "grive@u256.net, ferruh.yigit@intel.com, thomas@monjalon.net, dev@dpdk.org",
        "Cc": "orika@mellanox.com, matan@mellanox.com, Parav Pandit <parav@mellanox.com>",
        "Date": "Sun, 21 Jun 2020 19:11:58 +0000",
        "Message-Id": "<20200621191200.28120-5-parav@mellanox.com>",
        "X-Mailer": [
            "git-send-email 2.25.4",
            "git-send-email 2.25.4"
        ],
        "In-Reply-To": "<20200621191200.28120-1-parav@mellanox.com>",
        "References": "<20200610171728.89-2-parav@mellanox.com>\n <20200621191200.28120-1-parav@mellanox.com>",
        "Content-Transfer-Encoding": "8bit",
        "Content-Type": "text/plain",
        "X-ClientProxiedBy": "DM6PR02CA0105.namprd02.prod.outlook.com\n (2603:10b6:5:1f4::46) To AM0PR05MB4866.eurprd05.prod.outlook.com\n (2603:10a6:208:c0::32)",
        "MIME-Version": "1.0",
        "X-MS-Exchange-MessageSentRepresentingType": "1",
        "X-Originating-IP": "[208.176.44.194]",
        "X-MS-PublicTrafficType": "Email",
        "X-MS-Office365-Filtering-HT": "Tenant",
        "X-MS-Office365-Filtering-Correlation-Id": "a2274d04-ed6a-4a18-ac73-08d816170819",
        "X-MS-TrafficTypeDiagnostic": "AM0PR05MB6307:",
        "X-LD-Processed": "a652971c-7d2e-4d9b-a6a4-d149256f461b,ExtAddr",
        "X-MS-Exchange-Transport-Forked": "True",
        "X-Microsoft-Antispam-PRVS": "\n <AM0PR05MB63077D7494E2B7F942947466D1960@AM0PR05MB6307.eurprd05.prod.outlook.com>",
        "X-MS-Oob-TLC-OOBClassifiers": "OLM:5516;",
        "X-Forefront-PRVS": "04410E544A",
        "X-MS-Exchange-SenderADCheck": "1",
        "X-Microsoft-Antispam": "BCL:0;",
        "X-Microsoft-Antispam-Message-Info": "\n nLgO8ULZfuMUSBtS8/GruYN//h47qjkYhvkTMgHHCev71pf74gJLe7Ls14Lp7PajBLFbm7ii/Ncbd/MvSPnIkNUDCtxE7Jc/fQ2JUvwo3IrmDuudrNt1Co+N4k3DncnQDdlXbNF4OKsL4AWQMMQqrQlQRnxmsiPfbcFG2dzoVyErwGj3uEJXGvsWIw2KC1Ee1UryBeyGBs0GVx6LbQLR9rHgzSNpcv/e+yodbrSd2NPz3Ik6NCISuQvnZlb/o9C0cqv3agjq+zq3j8DrmdKOyxb/CBVIiocgzDhqtuovFnkMm3tUKRf6lDSoBQd6wQ5C",
        "X-Forefront-Antispam-Report": "CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:;\n IPV:NLI; SFV:NSPM; H:AM0PR05MB4866.eurprd05.prod.outlook.com; PTR:; CAT:NONE;\n SFTY:;\n SFS:(4636009)(376002)(366004)(39860400002)(396003)(346002)(136003)(36756003)(66556008)(66476007)(6506007)(4326008)(5660300002)(6486002)(66946007)(26005)(186003)(107886003)(16526019)(316002)(86362001)(6512007)(1076003)(478600001)(2616005)(6666004)(8676002)(83380400001)(956004)(52116002)(2906002)(8936002);\n DIR:OUT; SFP:1101;",
        "X-MS-Exchange-AntiSpam-MessageData": "\n jXel2MQtPK6fS+KEEzYpglZLmC6pJETdy6GU+PBqV2PRNuX6G+VLva6REaPzzYfz2qIxl/gbmkMajPrmiY90Y1rkyX4mq09LTPTuZAw91c5eTWnANmQnWw1nKiQ0VakmXnHPhm9HMoU4MkQAoBrGKyT11ZNpYAHWWWVrOQ8gSLKtPt5dBKI8W/PlzK7OvNj7pvwUVR/xSma/IsyogVquq/ylOGUhrDJs+K7+lS/qraZJwJzhtJ+EkfIqWAnlWri+Vx/rYrmRCCOoE+xR75oOY6/MaRosfEXcjrbuU1fvxfNvcYWGX1XRQt14c+2UwKpcSGtZHijGMEIDAAwqFMHIc0J9JQRhY6+0IFC165f9bvGNvgTQUmY0TYzgC/lvgrRV22UPVCoidV8MbhzElMxyW//pN6OqpMWAXnzO0u5Y159UsdG5zKu2gmnoTjPArEvi2o/D5Q/oGj/xsA89dFIz8EcCUEUeXdBFM20YwUB7wyWii6Qcd5Umd4ehYw7JN7Wr",
        "X-OriginatorOrg": "Mellanox.com",
        "X-MS-Exchange-CrossTenant-Network-Message-Id": "\n a2274d04-ed6a-4a18-ac73-08d816170819",
        "X-MS-Exchange-CrossTenant-OriginalArrivalTime": "21 Jun 2020 19:12:25.0803 (UTC)",
        "X-MS-Exchange-CrossTenant-FromEntityHeader": "Hosted",
        "X-MS-Exchange-CrossTenant-Id": "a652971c-7d2e-4d9b-a6a4-d149256f461b",
        "X-MS-Exchange-CrossTenant-MailboxType": "HOSTED",
        "X-MS-Exchange-CrossTenant-UserPrincipalName": "\n /E/VHfxZPHoGn1kty5zlmOWOZ150zQlCwyO/WThXjJnlIpR5k0XXGXqgpWIOIAI2Li6sIxapSlPmlNO0RbKR7A==",
        "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "AM0PR05MB6307",
        "Subject": "[dpdk-dev] [PATCH v2 4/6] bus/mlx5_pci: register a PCI driver",
        "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://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": "Create a mlx5 bus driver framework for invoking drivers of\nmultiple classes who have registered with the mlx5_pci bus\ndriver.\n\nValidate user class arguments for supported class combinations.\n\nSigned-off-by: Parav Pandit <parav@mellanox.com>\n---\nChangelog:\nv1->v2:\n - Address comments from Thomas and Gaetan\n - Enhanced driver to honor RTE_PCI_DRV_PROBE_AGAIN drv_flag\n - Use anonymous structure for class search and code changes around it\n - Define static for class comination array\n - Use RTE_DIM to find array size\n - Added OOM check for strdup()\n - Renamed copy variable to nstr_orig\n - Returning negagive error code\n - Returning directly if match entry found\n - Use compat condition check\n - Avoided cutting error message string\n - USe uint32_t datatype instead of enum mlx5_class\n - Changed logic to parse device arguments only once during probe()\n - Added check to fail driver probe if multiple classes register with\n   DMA ops\n - Renamed function to parse_class_options\n---\n drivers/bus/mlx5_pci/Makefile           |   2 +\n drivers/bus/mlx5_pci/meson.build        |   2 +-\n drivers/bus/mlx5_pci/mlx5_pci_bus.c     | 290 ++++++++++++++++++++++++\n drivers/bus/mlx5_pci/rte_bus_mlx5_pci.h |   1 +\n 4 files changed, 294 insertions(+), 1 deletion(-)",
    "diff": "diff --git a/drivers/bus/mlx5_pci/Makefile b/drivers/bus/mlx5_pci/Makefile\nindex 7db977ba8..e53ed8856 100644\n--- a/drivers/bus/mlx5_pci/Makefile\n+++ b/drivers/bus/mlx5_pci/Makefile\n@@ -13,7 +13,9 @@ CFLAGS += $(WERROR_FLAGS)\n CFLAGS += -I$(RTE_SDK)/drivers/common/mlx5\n CFLAGS += -I$(BUILDDIR)/drivers/common/mlx5\n CFLAGS += -I$(RTE_SDK)/drivers/bus/pci\n+CFLAGS += -D_DEFAULT_SOURCE\n LDLIBS += -lrte_eal\n+LDLIBS += -lrte_kvargs\n LDLIBS += -lrte_common_mlx5\n LDLIBS += -lrte_pci -lrte_bus_pci\n \ndiff --git a/drivers/bus/mlx5_pci/meson.build b/drivers/bus/mlx5_pci/meson.build\nindex cc4a84e23..5111baa4e 100644\n--- a/drivers/bus/mlx5_pci/meson.build\n+++ b/drivers/bus/mlx5_pci/meson.build\n@@ -1,6 +1,6 @@\n # SPDX-License-Identifier: BSD-3-Clause\n # Copyright(c) 2020 Mellanox Technologies Ltd\n \n-deps += ['pci', 'bus_pci', 'common_mlx5']\n+deps += ['pci', 'bus_pci', 'common_mlx5', 'kvargs']\n install_headers('rte_bus_mlx5_pci.h')\n sources = files('mlx5_pci_bus.c')\ndiff --git a/drivers/bus/mlx5_pci/mlx5_pci_bus.c b/drivers/bus/mlx5_pci/mlx5_pci_bus.c\nindex 66db3c7b0..e8f1649a3 100644\n--- a/drivers/bus/mlx5_pci/mlx5_pci_bus.c\n+++ b/drivers/bus/mlx5_pci/mlx5_pci_bus.c\n@@ -3,12 +3,302 @@\n  */\n \n #include \"rte_bus_mlx5_pci.h\"\n+#include <mlx5_common_utils.h>\n \n static TAILQ_HEAD(mlx5_pci_bus_drv_head, rte_mlx5_pci_driver) drv_list =\n \t\t\t\tTAILQ_HEAD_INITIALIZER(drv_list);\n \n+static const struct {\n+\tconst char *name;\n+\tunsigned int dev_class;\n+} mlx5_classes[] = {\n+\t{ .name = \"vdpa\", .dev_class = MLX5_CLASS_VDPA },\n+\t{ .name = \"net\", .dev_class = MLX5_CLASS_NET },\n+};\n+\n+static const unsigned int mlx5_valid_class_combo[] = {\n+\tMLX5_CLASS_NET,\n+\tMLX5_CLASS_VDPA,\n+\t/* New class combination should be added here */\n+};\n+\n+static int class_name_to_val(const char *class_name)\n+{\n+\tunsigned int i;\n+\n+\tfor (i = 0; i < RTE_DIM(mlx5_classes); i++) {\n+\t\tif (strcmp(class_name, mlx5_classes[i].name) == 0)\n+\t\t\treturn mlx5_classes[i].dev_class;\n+\n+\t}\n+\treturn -EINVAL;\n+}\n+\n+static int\n+mlx5_bus_opt_handler(__rte_unused const char *key, const char *class_names,\n+\t\t     void *opaque)\n+{\n+\tint *ret = opaque;\n+\tchar *nstr_org;\n+\tint class_val;\n+\tchar *found;\n+\tchar *nstr;\n+\n+\t*ret = 0;\n+\tnstr = strdup(class_names);\n+\tif (!nstr) {\n+\t\t*ret = -ENOMEM;\n+\t\treturn *ret;\n+\t}\n+\n+\tnstr_org = nstr;\n+\twhile (nstr) {\n+\t\t/* Extract each individual class name */\n+\t\tfound = strsep(&nstr, \":\");\n+\t\tif (!found)\n+\t\t\tcontinue;\n+\n+\t\t/* Check if its a valid class */\n+\t\tclass_val = class_name_to_val(found);\n+\t\tif (class_val < 0) {\n+\t\t\t*ret = -EINVAL;\n+\t\t\tgoto err;\n+\t\t}\n+\n+\t\t*ret |= class_val;\n+\t}\n+err:\n+\tfree(nstr_org);\n+\tif (*ret < 0)\n+\t\tDRV_LOG(ERR, \"Invalid mlx5 class options %s. Maybe typo in device class argument setting?\",\n+\t\t\tclass_names);\n+\treturn *ret;\n+}\n+\n+static int\n+parse_class_options(const struct rte_devargs *devargs)\n+{\n+\tconst char *key = MLX5_CLASS_ARG_NAME;\n+\tstruct rte_kvargs *kvlist;\n+\tint ret = 0;\n+\n+\tif (devargs == NULL)\n+\t\treturn 0;\n+\tkvlist = rte_kvargs_parse(devargs->args, NULL);\n+\tif (kvlist == NULL)\n+\t\treturn 0;\n+\tif (rte_kvargs_count(kvlist, key))\n+\t\trte_kvargs_process(kvlist, key, mlx5_bus_opt_handler, &ret);\n+\trte_kvargs_free(kvlist);\n+\treturn ret;\n+}\n+\n void\n rte_mlx5_pci_driver_register(struct rte_mlx5_pci_driver *driver)\n {\n \tTAILQ_INSERT_TAIL(&drv_list, driver, next);\n }\n+\n+static bool\n+mlx5_bus_match(const struct rte_mlx5_pci_driver *drv,\n+\t       const struct rte_pci_device *pci_dev)\n+{\n+\tconst struct rte_pci_id *id_table;\n+\n+\tfor (id_table = drv->pci_driver.id_table; id_table->vendor_id != 0;\n+\t     id_table++) {\n+\t\t/* check if device's ids match the class driver's ones */\n+\t\tif (id_table->vendor_id != pci_dev->id.vendor_id &&\n+\t\t\t\tid_table->vendor_id != PCI_ANY_ID)\n+\t\t\tcontinue;\n+\t\tif (id_table->device_id != pci_dev->id.device_id &&\n+\t\t\t\tid_table->device_id != PCI_ANY_ID)\n+\t\t\tcontinue;\n+\t\tif (id_table->subsystem_vendor_id !=\n+\t\t    pci_dev->id.subsystem_vendor_id &&\n+\t\t    id_table->subsystem_vendor_id != PCI_ANY_ID)\n+\t\t\tcontinue;\n+\t\tif (id_table->subsystem_device_id !=\n+\t\t    pci_dev->id.subsystem_device_id &&\n+\t\t    id_table->subsystem_device_id != PCI_ANY_ID)\n+\t\t\tcontinue;\n+\t\tif (id_table->class_id != pci_dev->id.class_id &&\n+\t\t\t\tid_table->class_id != RTE_CLASS_ANY_ID)\n+\t\t\tcontinue;\n+\n+\t\treturn true;\n+\t}\n+\treturn false;\n+}\n+\n+static int is_valid_class_combo(uint32_t user_classes)\n+{\n+\tunsigned int i;\n+\n+\t/* Verify if user specified valid supported combination */\n+\tfor (i = 0; i < RTE_DIM(mlx5_valid_class_combo); i++) {\n+\t\tif (mlx5_valid_class_combo[i] == user_classes)\n+\t\t\treturn 0;\n+\t}\n+\t/* Not found any valid class combination */\n+\treturn -EINVAL;\n+}\n+\n+static int validate_single_class_dma_ops(void)\n+{\n+\tstruct rte_mlx5_pci_driver *class;\n+\tint dma_map_classes = 0;\n+\n+\tTAILQ_FOREACH(class, &drv_list, next) {\n+\t\tif (class->pci_driver.dma_map)\n+\t\t\tdma_map_classes++;\n+\t}\n+\tif (dma_map_classes > 1) {\n+\t\tDRV_LOG(ERR, \"Multiple classes with DMA ops is unsupported\");\n+\t\treturn -EINVAL;\n+\t}\n+\treturn 0;\n+}\n+\n+/**\n+ * DPDK callback to register to probe multiple PCI class devices.\n+ *\n+ * @param[in] pci_drv\n+ *   PCI driver structure.\n+ * @param[in] dev\n+ *   PCI device information.\n+ *\n+ * @return\n+ *   0 on success, 1 to skip this driver, a negative errno value otherwise\n+ *   and rte_errno is set.\n+ */\n+static int\n+mlx5_bus_pci_probe(struct rte_pci_driver *drv __rte_unused,\n+\t\t   struct rte_pci_device *dev)\n+{\n+\tstruct rte_mlx5_pci_driver *class;\n+\tuint32_t user_classes = 0;\n+\tint ret;\n+\n+\tret = validate_single_class_dma_ops();\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tret = parse_class_options(dev->device.devargs);\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\tuser_classes = ret;\n+\tif (user_classes) {\n+\t\t/* Validate combination here */\n+\t\tret = is_valid_class_combo(user_classes);\n+\t\tif (ret) {\n+\t\t\tDRV_LOG(ERR, \"Unsupported mlx5 classes supplied\");\n+\t\t\treturn ret;\n+\t\t}\n+\t}\n+\n+\t/* Default to net class */\n+\tif (user_classes == 0)\n+\t\tuser_classes = MLX5_CLASS_NET;\n+\n+\tTAILQ_FOREACH(class, &drv_list, next) {\n+\t\tif (!mlx5_bus_match(class, dev))\n+\t\t\tcontinue;\n+\n+\t\tif ((class->dev_class & user_classes) == 0)\n+\t\t\tcontinue;\n+\n+\t\tret = -EINVAL;\n+\t\tif (class->loaded) {\n+\t\t\t/* If already loaded and class driver can handle\n+\t\t\t * reprobe, probe such class driver again.\n+\t\t\t */\n+\t\t\tif (class->pci_driver.drv_flags & RTE_PCI_DRV_PROBE_AGAIN)\n+\t\t\t\tret = class->pci_driver.probe(drv, dev);\n+\t\t} else {\n+\t\t\tret = class->pci_driver.probe(drv, dev);\n+\t\t}\n+\t\tif (!ret)\n+\t\t\tclass->loaded = true;\n+\t}\n+\treturn 0;\n+}\n+\n+/**\n+ * DPDK callback to remove one or more class devices for a PCI device.\n+ *\n+ * This function removes all class devices belong to a given PCI device.\n+ *\n+ * @param[in] pci_dev\n+ *   Pointer to the PCI device.\n+ *\n+ * @return\n+ *   0 on success, the function cannot fail.\n+ */\n+static int\n+mlx5_bus_pci_remove(struct rte_pci_device *dev)\n+{\n+\tstruct rte_mlx5_pci_driver *class;\n+\n+\t/* Remove each class driver in reverse order */\n+\tTAILQ_FOREACH_REVERSE(class, &drv_list, mlx5_pci_bus_drv_head, next) {\n+\t\tif (class->loaded)\n+\t\t\tclass->pci_driver.remove(dev);\n+\t}\n+\treturn 0;\n+}\n+\n+static int\n+mlx5_bus_pci_dma_map(struct rte_pci_device *dev, void *addr,\n+\t\t     uint64_t iova, size_t len)\n+{\n+\tstruct rte_mlx5_pci_driver *class;\n+\tint ret = -EINVAL;\n+\n+\tTAILQ_FOREACH(class, &drv_list, next) {\n+\t\tif (!class->pci_driver.dma_map)\n+\t\t\tcontinue;\n+\n+\t\treturn class->pci_driver.dma_map(dev, addr, iova, len);\n+\t}\n+\treturn ret;\n+}\n+\n+static int\n+mlx5_bus_pci_dma_unmap(struct rte_pci_device *dev, void *addr,\n+\t\t       uint64_t iova, size_t len)\n+{\n+\tstruct rte_mlx5_pci_driver *class;\n+\tint ret = -EINVAL;\n+\n+\tTAILQ_FOREACH_REVERSE(class, &drv_list, mlx5_pci_bus_drv_head, next) {\n+\t\tif (!class->pci_driver.dma_unmap)\n+\t\t\tcontinue;\n+\n+\t\treturn class->pci_driver.dma_unmap(dev, addr, iova, len);\n+\t}\n+\treturn ret;\n+}\n+\n+static const struct rte_pci_id mlx5_bus_pci_id_map[] = {\n+\t{\n+\t\t.vendor_id = 0\n+\t}\n+};\n+\n+static struct rte_pci_driver mlx5_bus_driver = {\n+\t.driver = {\n+\t\t.name = \"mlx5_bus_pci\",\n+\t},\n+\t.id_table = mlx5_bus_pci_id_map,\n+\t.probe = mlx5_bus_pci_probe,\n+\t.remove = mlx5_bus_pci_remove,\n+\t.dma_map = mlx5_bus_pci_dma_map,\n+\t.dma_unmap = mlx5_bus_pci_dma_unmap,\n+\t.drv_flags = RTE_PCI_DRV_INTR_LSC | RTE_PCI_DRV_INTR_RMV |\n+\t\t     RTE_PCI_DRV_PROBE_AGAIN,\n+};\n+\n+RTE_PMD_REGISTER_PCI(mlx5_bus, mlx5_bus_driver);\n+RTE_PMD_REGISTER_PCI_TABLE(mlx5_bus, mlx5_bus_pci_id_map);\ndiff --git a/drivers/bus/mlx5_pci/rte_bus_mlx5_pci.h b/drivers/bus/mlx5_pci/rte_bus_mlx5_pci.h\nindex 571f7dfd6..c8cd7187b 100644\n--- a/drivers/bus/mlx5_pci/rte_bus_mlx5_pci.h\n+++ b/drivers/bus/mlx5_pci/rte_bus_mlx5_pci.h\n@@ -55,6 +55,7 @@ struct rte_mlx5_pci_driver {\n \tenum mlx5_class dev_class;\t\t/**< Class of this driver */\n \tstruct rte_pci_driver pci_driver;\t/**< Inherit core pci driver. */\n \tTAILQ_ENTRY(rte_mlx5_pci_driver) next;\n+\tbool loaded;\n };\n \n /**\n",
    "prefixes": [
        "v2",
        "4/6"
    ]
}