get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 136255,
    "url": "http://patches.dpdk.org/api/patches/136255/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20240201100219.26677-2-hkalra@marvell.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": "<20240201100219.26677-2-hkalra@marvell.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20240201100219.26677-2-hkalra@marvell.com",
    "date": "2024-02-01T10:02:18",
    "name": "[v5,1/2] ethdev: parsing multiple representor devargs string",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "caad9d1ec4ea12329a3225eafebf48229e8bc4ee",
    "submitter": {
        "id": 1182,
        "url": "http://patches.dpdk.org/api/people/1182/?format=api",
        "name": "Harman Kalra",
        "email": "hkalra@marvell.com"
    },
    "delegate": {
        "id": 319,
        "url": "http://patches.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20240201100219.26677-2-hkalra@marvell.com/mbox/",
    "series": [
        {
            "id": 30963,
            "url": "http://patches.dpdk.org/api/series/30963/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=30963",
            "date": "2024-02-01T10:02:17",
            "name": "multiple representors in one device",
            "version": 5,
            "mbox": "http://patches.dpdk.org/series/30963/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/136255/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/136255/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 3F3C743A35;\n\tThu,  1 Feb 2024 11:02:45 +0100 (CET)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 0A8B842DF2;\n\tThu,  1 Feb 2024 11:02:41 +0100 (CET)",
            "from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com\n [67.231.156.173])\n by mails.dpdk.org (Postfix) with ESMTP id 6EAEA42DED\n for <dev@dpdk.org>; Thu,  1 Feb 2024 11:02:39 +0100 (CET)",
            "from pps.filterd (m0045851.ppops.net [127.0.0.1])\n by mx0b-0016f401.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id\n 4119u9Oa001853; Thu, 1 Feb 2024 02:02:34 -0800",
            "from dc5-exch01.marvell.com ([199.233.59.181])\n by mx0b-0016f401.pphosted.com (PPS) with ESMTPS id 3w0937g0m6-1\n (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT);\n Thu, 01 Feb 2024 02:02:34 -0800 (PST)",
            "from DC5-EXCH02.marvell.com (10.69.176.39) by DC5-EXCH01.marvell.com\n (10.69.176.38) with Microsoft SMTP Server (TLS) id 15.0.1497.48;\n Thu, 1 Feb 2024 02:02:31 -0800",
            "from maili.marvell.com (10.69.176.80) by DC5-EXCH02.marvell.com\n (10.69.176.39) with Microsoft SMTP Server id 15.0.1497.48 via Frontend\n Transport; Thu, 1 Feb 2024 02:02:31 -0800",
            "from localhost.localdomain (unknown [10.29.52.211])\n by maili.marvell.com (Postfix) with ESMTP id 6EA003F7044;\n Thu,  1 Feb 2024 02:02:26 -0800 (PST)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h=\n from:to:cc:subject:date:message-id:in-reply-to:references\n :mime-version:content-type; s=pfpt0220; bh=nhByxeHPHP6+PhyZnM0lf\n FO1VmawINPccFqIkh86ihc=; b=cUidnLQFOUPqKTPCMit3eHY9dqJ1zXTfFjg5W\n H+b/Y/56WLdSkXIi5i06yxS459LlcDqpINPSb9QWi1E7T8jQIqLufAJiPy+r7O0F\n y8Av0Mwigzh4gZRf4UhvCtLDvXMiDvySKNq19AuKPx4nowOieXhNYuJ6EmMDs51S\n euQZssFFS6F2X2KYpnC9b4Co/rlf8fkFG3hMSeDZL2ICiouB2EbKSKK0sQp6CbSr\n +Vi7zHoQP9tbbeRj+VXgHXDUhIpgRQI8Zddf/pqWmhCtNyttiPEkM9IUctMv7fq7\n qGwtw/Ejh+QrR4pHvo3GJ+tTsRdU2pLq107xlLjyHXCz8aEXQ==",
        "From": "Harman Kalra <hkalra@marvell.com>",
        "To": "Thomas Monjalon <thomas@monjalon.net>,\n Ferruh Yigit <ferruh.yigit@amd.com>,\n Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>,\n Ajit Khaparde <ajit.khaparde@broadcom.com>, Somnath Kotur\n <somnath.kotur@broadcom.com>,\n John Daley <johndale@cisco.com>, Hyong Youb Kim <hyonkim@cisco.com>,\n Yuying Zhang <Yuying.Zhang@intel.com>, Beilei Xing <beilei.xing@intel.com>,\n Qiming Yang <qiming.yang@intel.com>, Qi Zhang <qi.z.zhang@intel.com>,\n Wenjun Wu <wenjun1.wu@intel.com>, Dariusz Sosnowski\n <dsosnowski@nvidia.com>, Viacheslav Ovsiienko <viacheslavo@nvidia.com>,\n \"Ori Kam\" <orika@nvidia.com>, Suanming Mou <suanmingm@nvidia.com>,\n Matan Azrad <matan@nvidia.com>, Chaoyong He <chaoyong.he@corigine.com>",
        "CC": "<dev@dpdk.org>, Harman Kalra <hkalra@marvell.com>",
        "Subject": "[PATCH v5 1/2] ethdev: parsing multiple representor devargs string",
        "Date": "Thu, 1 Feb 2024 15:32:18 +0530",
        "Message-ID": "<20240201100219.26677-2-hkalra@marvell.com>",
        "X-Mailer": "git-send-email 2.18.0",
        "In-Reply-To": "<20240201100219.26677-1-hkalra@marvell.com>",
        "References": "<20240111064432.193119-1-hkalra@marvell.com>\n <20240201100219.26677-1-hkalra@marvell.com>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain",
        "X-Proofpoint-ORIG-GUID": "uwRwo0BozNjVwRkYDFZPEjvo5nk-ixgs",
        "X-Proofpoint-GUID": "uwRwo0BozNjVwRkYDFZPEjvo5nk-ixgs",
        "X-Proofpoint-Virus-Version": "vendor=baseguard\n engine=ICAP:2.0.272,Aquarius:18.0.1011,Hydra:6.0.619,FMLib:17.11.176.26\n definitions=2024-01-31_10,2024-01-31_01,2023-05-22_02",
        "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"
    },
    "content": "Adding support for parsing multiple representor devargs strings\npassed to a PCI BDF. There may be scenario where port representors\nfor various PFs or VFs under PFs are required and all these are\nrepresentor ports shall be backed by single pci device. In such\ncase port representors can be created using devargs string:\n<PCI BDF>,representor=[pf[0-1],pf2vf[1,2-3],[4-5]]\n\nSigned-off-by: Harman Kalra <hkalra@marvell.com>\n---\n doc/guides/prog_guide/poll_mode_drv.rst       |   4 +-\n .../prog_guide/switch_representation.rst      |   1 +\n drivers/net/bnxt/bnxt_ethdev.c                |   4 +-\n drivers/net/enic/enic_ethdev.c                |   4 +-\n drivers/net/i40e/i40e_ethdev.c                |   4 +-\n drivers/net/ice/ice_dcf_ethdev.c              |   4 +-\n drivers/net/ixgbe/ixgbe_ethdev.c              |   4 +-\n drivers/net/mlx5/linux/mlx5_os.c              |   8 +-\n .../net/nfp/flower/nfp_flower_representor.c   |   4 +-\n drivers/net/sfc/sfc_ethdev.c                  |   4 +-\n lib/ethdev/ethdev_driver.c                    | 175 ++++++++++++++++--\n lib/ethdev/ethdev_driver.h                    |   9 +-\n 12 files changed, 189 insertions(+), 36 deletions(-)",
    "diff": "diff --git a/doc/guides/prog_guide/poll_mode_drv.rst b/doc/guides/prog_guide/poll_mode_drv.rst\nindex c145a9066c..5008b41c60 100644\n--- a/doc/guides/prog_guide/poll_mode_drv.rst\n+++ b/doc/guides/prog_guide/poll_mode_drv.rst\n@@ -376,7 +376,7 @@ parameters to those ports.\n \n * ``representor`` for a device which supports the creation of representor ports\n   this argument allows user to specify which switch ports to enable port\n-  representors for. Multiple representors in one device argument is invalid::\n+  representors for::\n \n    -a DBDF,representor=vf0\n    -a DBDF,representor=vf[0,4,6,9]\n@@ -389,6 +389,8 @@ parameters to those ports.\n    -a DBDF,representor=pf1vf0\n    -a DBDF,representor=pf[0-1]sf[0-127]\n    -a DBDF,representor=pf1\n+   -a DBDF,representor=[pf[0-1],pf2vf[0-2],pf3[3,5-8]]\n+   (Multiple representors in one device argument can be represented as a list)\n \n Note: PMDs are not required to support the standard device arguments and users\n should consult the relevant PMD documentation to see support devargs.\ndiff --git a/doc/guides/prog_guide/switch_representation.rst b/doc/guides/prog_guide/switch_representation.rst\nindex 6fd7b98bdc..46e0ca85a5 100644\n--- a/doc/guides/prog_guide/switch_representation.rst\n+++ b/doc/guides/prog_guide/switch_representation.rst\n@@ -77,6 +77,7 @@ thought as a software \"patch panel\" front-end for applications.\n    -a pci:dbdf,representor=sf1\n    -a pci:dbdf,representor=sf[0-1023]\n    -a pci:dbdf,representor=sf[0,2-1023]\n+   -a pci:dbdf,representor=[pf[0-1],pf2vf[0-2],pf3[3,5]]\n \n - As virtual devices, they may be more limited than their physical\n   counterparts, for instance by exposing only a subset of device\ndiff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c\nindex acf7e6e46e..5d4f599044 100644\n--- a/drivers/net/bnxt/bnxt_ethdev.c\n+++ b/drivers/net/bnxt/bnxt_ethdev.c\n@@ -6383,8 +6383,8 @@ static int bnxt_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,\n \n \tif (pci_dev->device.devargs) {\n \t\tret = rte_eth_devargs_parse(pci_dev->device.devargs->args,\n-\t\t\t\t\t    &eth_da);\n-\t\tif (ret)\n+\t\t\t\t\t    &eth_da, 1);\n+\t\tif (ret < 0)\n \t\t\treturn ret;\n \t}\n \ndiff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c\nindex b04b6c9aa1..33d96ec07a 100644\n--- a/drivers/net/enic/enic_ethdev.c\n+++ b/drivers/net/enic/enic_ethdev.c\n@@ -1317,8 +1317,8 @@ static int eth_enic_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,\n \tENICPMD_FUNC_TRACE();\n \tif (pci_dev->device.devargs) {\n \t\tretval = rte_eth_devargs_parse(pci_dev->device.devargs->args,\n-\t\t\t\t&eth_da);\n-\t\tif (retval)\n+\t\t\t\t&eth_da, 1);\n+\t\tif (retval < 0)\n \t\t\treturn retval;\n \t}\n \tif (eth_da.nb_representor_ports > 0 &&\ndiff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c\nindex 3ca226156b..4d21341382 100644\n--- a/drivers/net/i40e/i40e_ethdev.c\n+++ b/drivers/net/i40e/i40e_ethdev.c\n@@ -646,8 +646,8 @@ eth_i40e_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,\n \n \tif (pci_dev->device.devargs) {\n \t\tretval = rte_eth_devargs_parse(pci_dev->device.devargs->args,\n-\t\t\t\t&eth_da);\n-\t\tif (retval)\n+\t\t\t\t&eth_da, 1);\n+\t\tif (retval < 0)\n \t\t\treturn retval;\n \t}\n \ndiff --git a/drivers/net/ice/ice_dcf_ethdev.c b/drivers/net/ice/ice_dcf_ethdev.c\nindex 5d845bba31..0e991fe4b8 100644\n--- a/drivers/net/ice/ice_dcf_ethdev.c\n+++ b/drivers/net/ice/ice_dcf_ethdev.c\n@@ -2041,8 +2041,8 @@ eth_ice_dcf_pci_probe(__rte_unused struct rte_pci_driver *pci_drv,\n \tif (!ice_devargs_check(pci_dev->device.devargs, ICE_DCF_DEVARG_CAP))\n \t\treturn 1;\n \n-\tret = rte_eth_devargs_parse(pci_dev->device.devargs->args, &eth_da);\n-\tif (ret)\n+\tret = rte_eth_devargs_parse(pci_dev->device.devargs->args, &eth_da, 1);\n+\tif (ret < 0)\n \t\treturn ret;\n \n \tret = rte_eth_dev_pci_generic_probe(pci_dev,\ndiff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c\nindex d6cf00317e..98e9b8a031 100644\n--- a/drivers/net/ixgbe/ixgbe_ethdev.c\n+++ b/drivers/net/ixgbe/ixgbe_ethdev.c\n@@ -1765,8 +1765,8 @@ eth_ixgbe_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,\n \n \tif (pci_dev->device.devargs) {\n \t\tretval = rte_eth_devargs_parse(pci_dev->device.devargs->args,\n-\t\t\t\t&eth_da);\n-\t\tif (retval)\n+\t\t\t\t&eth_da, 1);\n+\t\tif (retval < 0)\n \t\t\treturn retval;\n \t} else\n \t\tmemset(&eth_da, 0, sizeof(eth_da));\ndiff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c\nindex ae82e1e5d8..17061126d5 100644\n--- a/drivers/net/mlx5/linux/mlx5_os.c\n+++ b/drivers/net/mlx5/linux/mlx5_os.c\n@@ -2733,16 +2733,16 @@ mlx5_os_parse_eth_devargs(struct rte_device *dev,\n \tmemset(eth_da, 0, sizeof(*eth_da));\n \t/* Parse representor information first from class argument. */\n \tif (dev->devargs->cls_str)\n-\t\tret = rte_eth_devargs_parse(dev->devargs->cls_str, eth_da);\n-\tif (ret != 0) {\n+\t\tret = rte_eth_devargs_parse(dev->devargs->cls_str, eth_da, 1);\n+\tif (ret < 0) {\n \t\tDRV_LOG(ERR, \"failed to parse device arguments: %s\",\n \t\t\tdev->devargs->cls_str);\n \t\treturn -rte_errno;\n \t}\n \tif (eth_da->type == RTE_ETH_REPRESENTOR_NONE && dev->devargs->args) {\n \t\t/* Parse legacy device argument */\n-\t\tret = rte_eth_devargs_parse(dev->devargs->args, eth_da);\n-\t\tif (ret) {\n+\t\tret = rte_eth_devargs_parse(dev->devargs->args, eth_da, 1);\n+\t\tif (ret < 0) {\n \t\t\tDRV_LOG(ERR, \"failed to parse device arguments: %s\",\n \t\t\t\tdev->devargs->args);\n \t\t\treturn -rte_errno;\ndiff --git a/drivers/net/nfp/flower/nfp_flower_representor.c b/drivers/net/nfp/flower/nfp_flower_representor.c\nindex 5f7c1fa737..63fe37c8d7 100644\n--- a/drivers/net/nfp/flower/nfp_flower_representor.c\n+++ b/drivers/net/nfp/flower/nfp_flower_representor.c\n@@ -792,8 +792,8 @@ nfp_flower_repr_create(struct nfp_app_fw_flower *app_fw_flower)\n \n \t/* Now parse PCI device args passed for representor info */\n \tif (pci_dev->device.devargs != NULL) {\n-\t\tret = rte_eth_devargs_parse(pci_dev->device.devargs->args, &eth_da);\n-\t\tif (ret != 0) {\n+\t\tret = rte_eth_devargs_parse(pci_dev->device.devargs->args, &eth_da, 1);\n+\t\tif (ret < 0) {\n \t\t\tPMD_INIT_LOG(ERR, \"devarg parse failed\");\n \t\t\treturn -EINVAL;\n \t\t}\ndiff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c\nindex 6d57b2ba26..0bbcb80365 100644\n--- a/drivers/net/sfc/sfc_ethdev.c\n+++ b/drivers/net/sfc/sfc_ethdev.c\n@@ -3305,8 +3305,8 @@ sfc_parse_rte_devargs(const char *args, struct rte_eth_devargs *devargs)\n \tint rc;\n \n \tif (args != NULL) {\n-\t\trc = rte_eth_devargs_parse(args, &eth_da);\n-\t\tif (rc != 0) {\n+\t\trc = rte_eth_devargs_parse(args, &eth_da, 1);\n+\t\tif (rc < 0) {\n \t\t\tSFC_GENERIC_LOG(ERR,\n \t\t\t\t\t\"Failed to parse generic devargs '%s'\",\n \t\t\t\t\targs);\ndiff --git a/lib/ethdev/ethdev_driver.c b/lib/ethdev/ethdev_driver.c\nindex bd917a15fc..7e683bcaa1 100644\n--- a/lib/ethdev/ethdev_driver.c\n+++ b/lib/ethdev/ethdev_driver.c\n@@ -2,6 +2,7 @@\n  * Copyright(c) 2022 Intel Corporation\n  */\n \n+#include <ctype.h>\n #include <stdlib.h>\n #include <pthread.h>\n \n@@ -459,26 +460,157 @@ eth_dev_devargs_tokenise(struct rte_kvargs *arglist, const char *str_in)\n \t\t\tbreak;\n \n \t\tcase 3: /* Parsing list */\n-\t\t\tif (*letter == ']')\n-\t\t\t\tstate = 2;\n-\t\t\telse if (*letter == '\\0')\n+\t\t\tif (*letter == ']') {\n+\t\t\t\t/* For devargs having singles lists move to state 2 once letter\n+\t\t\t\t * becomes ']' so each can be considered as different pair key\n+\t\t\t\t * value. But in nested lists case e.g. multiple representors\n+\t\t\t\t * case i.e. [pf[0-3],pfvf[3,4-6]], complete nested list should\n+\t\t\t\t * be considered as one pair value, hence checking if end of outer\n+\t\t\t\t * list ']' is reached else stay on state 3.\n+\t\t\t\t */\n+\t\t\t\tif ((strcmp(\"representor\", pair->key) == 0) &&\n+\t\t\t\t    (*(letter + 1) != '\\0' && *(letter + 2) != '\\0' &&\n+\t\t\t\t     *(letter + 3) != '\\0')\t\t\t    &&\n+\t\t\t\t    ((*(letter + 2) == 'p' && *(letter + 3) == 'f')   ||\n+\t\t\t\t     (*(letter + 2) == 'v' && *(letter + 3) == 'f')   ||\n+\t\t\t\t     (*(letter + 2) == 's' && *(letter + 3) == 'f')   ||\n+\t\t\t\t     (*(letter + 2) == 'c' && isdigit(*(letter + 3))) ||\n+\t\t\t\t     (*(letter + 2) == '[' && isdigit(*(letter + 3))) ||\n+\t\t\t\t     (isdigit(*(letter + 2)))))\n+\t\t\t\t\tstate = 3;\n+\t\t\t\telse\n+\t\t\t\t\tstate = 2;\n+\t\t\t} else if (*letter == '\\0') {\n \t\t\t\treturn -EINVAL;\n+\t\t\t}\n \t\t\tbreak;\n \t\t}\n \t\tletter++;\n \t}\n }\n \n+static int\n+devargs_parse_representor_ports(struct rte_eth_devargs *eth_devargs, char\n+\t\t\t\t*da_val, unsigned int da_idx, unsigned int nb_da)\n+{\n+\tstruct rte_eth_devargs *eth_da;\n+\tint result = 0;\n+\n+\tif (da_idx + 1 > nb_da) {\n+\t\tRTE_ETHDEV_LOG_LINE(ERR, \"Devargs parsed %d > max array size %d\",\n+\t\t\t       da_idx + 1, nb_da);\n+\t\tresult = -1;\n+\t\tgoto parse_cleanup;\n+\t}\n+\teth_da = &eth_devargs[da_idx];\n+\tmemset(eth_da, 0, sizeof(*eth_da));\n+\tRTE_ETHDEV_LOG_LINE(DEBUG, \"\t  Devargs idx %d value %s\", da_idx, da_val);\n+\tresult = rte_eth_devargs_parse_representor_ports(da_val, eth_da);\n+\n+parse_cleanup:\n+\treturn result;\n+}\n+\n+static int\n+eth_dev_tokenise_representor_list(char *p_val, struct rte_eth_devargs *eth_devargs,\n+\t\t\t\t  unsigned int nb_da)\n+{\n+\tchar da_val[BUFSIZ], str[BUFSIZ];\n+\tbool is_rep_portid_list = true;\n+\tunsigned int devargs = 0;\n+\tint result = 0, len = 0;\n+\tint i = 0, j = 0;\n+\tchar *pos;\n+\n+\tpos = p_val;\n+\t/* Length of consolidated list */\n+\twhile (*pos++ != '\\0') {\n+\t\tlen++;\n+\t\tif (isalpha(*pos))\n+\t\t\tis_rep_portid_list = false;\n+\t}\n+\n+\t/* List of representor portIDs i.e.[1,2,3] should be considered as single representor case*/\n+\tif (is_rep_portid_list) {\n+\t\tresult = devargs_parse_representor_ports(eth_devargs, p_val, 0, 1);\n+\t\tif (result < 0)\n+\t\t\treturn result;\n+\n+\t\tdevargs++;\n+\t\treturn devargs;\n+\t}\n+\n+\tmemset(str, 0, BUFSIZ);\n+\t/* Remove the exterior [] of the consolidated list */\n+\tstrncpy(str, &p_val[1], len - 2);\n+\twhile (1) {\n+\t\tif (str[i] == '\\0') {\n+\t\t\tif (da_val[0] != '\\0') {\n+\t\t\t\tresult = devargs_parse_representor_ports(eth_devargs, da_val,\n+\t\t\t\t\t\t\t\t\t devargs, nb_da);\n+\t\t\t\tif (result < 0)\n+\t\t\t\t\tgoto parse_cleanup;\n+\n+\t\t\t\tdevargs++;\n+\t\t\t}\n+\t\t\tbreak;\n+\t\t}\n+\t\tif (str[i] == ',' || str[i] == '[') {\n+\t\t\tif (str[i] == ',') {\n+\t\t\t\tif (da_val[0] != '\\0') {\n+\t\t\t\t\tda_val[j + 1] = '\\0';\n+\t\t\t\t\tresult = devargs_parse_representor_ports(eth_devargs,\n+\t\t\t\t\t\t\t\t\t\t da_val, devargs,\n+\t\t\t\t\t\t\t\t\t\t nb_da);\n+\t\t\t\t\tif (result < 0)\n+\t\t\t\t\t\tgoto parse_cleanup;\n+\n+\t\t\t\t\tdevargs++;\n+\t\t\t\t\tj = 0;\n+\t\t\t\t\tmemset(da_val, 0, BUFSIZ);\n+\t\t\t\t}\n+\t\t\t}\n+\n+\t\t\tif (str[i] == '[') {\n+\t\t\t\twhile (str[i] != ']' || isalpha(str[i + 1])) {\n+\t\t\t\t\tda_val[j] = str[i];\n+\t\t\t\t\tj++;\n+\t\t\t\t\ti++;\n+\t\t\t\t}\n+\t\t\t\tda_val[j] = ']';\n+\t\t\t\tda_val[j + 1] = '\\0';\n+\t\t\t\tresult = devargs_parse_representor_ports(eth_devargs, da_val,\n+\t\t\t\t\t\t\t\t\t devargs, nb_da);\n+\t\t\t\tif (result < 0)\n+\t\t\t\t\tgoto parse_cleanup;\n+\n+\t\t\t\tdevargs++;\n+\t\t\t\tj = 0;\n+\t\t\t\tmemset(da_val, 0, BUFSIZ);\n+\t\t\t}\n+\t\t} else {\n+\t\t\tda_val[j] = str[i];\n+\t\t\tj++;\n+\t\t}\n+\t\ti++;\n+\t}\n+\tresult = devargs;\n+\n+parse_cleanup:\n+\treturn result;\n+}\n+\n int\n-rte_eth_devargs_parse(const char *dargs, struct rte_eth_devargs *eth_da)\n+rte_eth_devargs_parse(const char *dargs, struct rte_eth_devargs *eth_devargs,\n+\t\t      unsigned int nb_da)\n {\n-\tstruct rte_kvargs args;\n \tstruct rte_kvargs_pair *pair;\n+\tstruct rte_kvargs args;\n+\tbool dup_rep = false;\n+\tint devargs = 0;\n \tunsigned int i;\n \tint result = 0;\n \n-\tmemset(eth_da, 0, sizeof(*eth_da));\n-\n \tresult = eth_dev_devargs_tokenise(&args, dargs);\n \tif (result < 0)\n \t\tgoto parse_cleanup;\n@@ -486,18 +618,33 @@ rte_eth_devargs_parse(const char *dargs, struct rte_eth_devargs *eth_da)\n \tfor (i = 0; i < args.count; i++) {\n \t\tpair = &args.pairs[i];\n \t\tif (strcmp(\"representor\", pair->key) == 0) {\n-\t\t\tif (eth_da->type != RTE_ETH_REPRESENTOR_NONE) {\n-\t\t\t\tRTE_ETHDEV_LOG_LINE(ERR, \"duplicated representor key: %s\",\n-\t\t\t\t\tdargs);\n+\t\t\tif (dup_rep) {\n+\t\t\t\tRTE_ETHDEV_LOG_LINE(ERR, \"Duplicated representor key: %s\",\n+\t\t\t\t\t\t    pair->value);\n \t\t\t\tresult = -1;\n \t\t\t\tgoto parse_cleanup;\n \t\t\t}\n-\t\t\tresult = rte_eth_devargs_parse_representor_ports(\n-\t\t\t\t\tpair->value, eth_da);\n-\t\t\tif (result < 0)\n-\t\t\t\tgoto parse_cleanup;\n+\n+\t\t\tRTE_ETHDEV_LOG_LINE(DEBUG, \"Devarg pattern: %s\", pair->value);\n+\t\t\tif (pair->value[0] == '[') {\n+\t\t\t\t/* Multiple representor list case */\n+\t\t\t\tdevargs = eth_dev_tokenise_representor_list(pair->value,\n+\t\t\t\t\t\t\t\t\t    eth_devargs, nb_da);\n+\t\t\t\tif (devargs < 0)\n+\t\t\t\t\tgoto parse_cleanup;\n+\t\t\t} else {\n+\t\t\t\t/* Single representor case */\n+\t\t\t\tdevargs = devargs_parse_representor_ports(eth_devargs, pair->value,\n+\t\t\t\t\t\t\t\t\t  0, 1);\n+\t\t\t\tif (devargs < 0)\n+\t\t\t\t\tgoto parse_cleanup;\n+\t\t\t\tdevargs++;\n+\t\t\t}\n+\t\t\tdup_rep = true;\n \t\t}\n \t}\n+\tRTE_ETHDEV_LOG_LINE(DEBUG, \"Total devargs parsed %d\", devargs);\n+\tresult = devargs;\n \n parse_cleanup:\n \tfree(args.str);\ndiff --git a/lib/ethdev/ethdev_driver.h b/lib/ethdev/ethdev_driver.h\nindex f05f68a67c..23df06d289 100644\n--- a/lib/ethdev/ethdev_driver.h\n+++ b/lib/ethdev/ethdev_driver.h\n@@ -1802,14 +1802,17 @@ rte_eth_representor_id_get(uint16_t port_id,\n  * @param devargs\n  *  device arguments\n  * @param eth_devargs\n- *  parsed ethdev specific arguments.\n+ *  contiguous memory populated with parsed ethdev specific arguments.\n+ * @param nb_da\n+ *  size of eth_devargs array passed\n  *\n  * @return\n- *   Negative errno value on error, 0 on success.\n+ *   Negative errno value on error, no of devargs parsed on success.\n  */\n __rte_internal\n int\n-rte_eth_devargs_parse(const char *devargs, struct rte_eth_devargs *eth_devargs);\n+rte_eth_devargs_parse(const char *devargs, struct rte_eth_devargs *eth_devargs,\n+\t\t      unsigned int nb_da);\n \n \n typedef int (*ethdev_init_t)(struct rte_eth_dev *ethdev, void *init_params);\n",
    "prefixes": [
        "v5",
        "1/2"
    ]
}