get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 100916,
    "url": "http://patches.dpdk.org/api/patches/100916/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20211009093340.43237-3-fengchengwen@huawei.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": "<20211009093340.43237-3-fengchengwen@huawei.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20211009093340.43237-3-fengchengwen@huawei.com",
    "date": "2021-10-09T09:33:36",
    "name": "[v24,2/6] dmadev: add control plane API support",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "f16f6fc4b7ee053662617dc871b6bed79f23b731",
    "submitter": {
        "id": 2146,
        "url": "http://patches.dpdk.org/api/people/2146/?format=api",
        "name": "fengchengwen",
        "email": "fengchengwen@huawei.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/20211009093340.43237-3-fengchengwen@huawei.com/mbox/",
    "series": [
        {
            "id": 19486,
            "url": "http://patches.dpdk.org/api/series/19486/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=19486",
            "date": "2021-10-09T09:33:34",
            "name": "support dmadev",
            "version": 24,
            "mbox": "http://patches.dpdk.org/series/19486/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/100916/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/100916/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 887A1A0C41;\n\tSat,  9 Oct 2021 11:38:06 +0200 (CEST)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id E5CFB4067E;\n\tSat,  9 Oct 2021 11:38:01 +0200 (CEST)",
            "from szxga01-in.huawei.com (szxga01-in.huawei.com [45.249.212.187])\n by mails.dpdk.org (Postfix) with ESMTP id 9945140042\n for <dev@dpdk.org>; Sat,  9 Oct 2021 11:37:59 +0200 (CEST)",
            "from dggemv703-chm.china.huawei.com (unknown [172.30.72.55])\n by szxga01-in.huawei.com (SkyGuard) with ESMTP id 4HRKgs4MN2zWNbR;\n Sat,  9 Oct 2021 17:36:25 +0800 (CST)",
            "from dggpeml500024.china.huawei.com (7.185.36.10) by\n dggemv703-chm.china.huawei.com (10.3.19.46) with Microsoft SMTP Server\n (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id\n 15.1.2308.8; Sat, 9 Oct 2021 17:37:57 +0800",
            "from localhost.localdomain (10.67.165.24) by\n dggpeml500024.china.huawei.com (7.185.36.10) with Microsoft SMTP Server\n (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id\n 15.1.2308.8; Sat, 9 Oct 2021 17:37:57 +0800"
        ],
        "From": "Chengwen Feng <fengchengwen@huawei.com>",
        "To": "<thomas@monjalon.net>, <ferruh.yigit@intel.com>,\n <bruce.richardson@intel.com>, <jerinj@marvell.com>, <jerinjacobk@gmail.com>,\n <andrew.rybchenko@oktetlabs.ru>",
        "CC": "<dev@dpdk.org>, <mb@smartsharesystems.com>, <nipun.gupta@nxp.com>,\n <hemant.agrawal@nxp.com>, <maxime.coquelin@redhat.com>,\n <honnappa.nagarahalli@arm.com>, <david.marchand@redhat.com>,\n <sburla@marvell.com>, <pkapoor@marvell.com>, <konstantin.ananyev@intel.com>,\n <conor.walsh@intel.com>, <kevin.laatz@intel.com>",
        "Date": "Sat, 9 Oct 2021 17:33:36 +0800",
        "Message-ID": "<20211009093340.43237-3-fengchengwen@huawei.com>",
        "X-Mailer": "git-send-email 2.33.0",
        "In-Reply-To": "<20211009093340.43237-1-fengchengwen@huawei.com>",
        "References": "<1625231891-2963-1-git-send-email-fengchengwen@huawei.com>\n <20211009093340.43237-1-fengchengwen@huawei.com>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain; charset=\"UTF-8\"",
        "Content-Transfer-Encoding": "8bit",
        "X-Originating-IP": "[10.67.165.24]",
        "X-ClientProxiedBy": "dggems705-chm.china.huawei.com (10.3.19.182) To\n dggpeml500024.china.huawei.com (7.185.36.10)",
        "X-CFilter-Loop": "Reflected",
        "Subject": "[dpdk-dev] [PATCH v24 2/6] dmadev: add control plane API support",
        "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": "This patch add control plane API for dmadev.\n\nSigned-off-by: Chengwen Feng <fengchengwen@huawei.com>\nAcked-by: Bruce Richardson <bruce.richardson@intel.com>\nAcked-by: Morten Brørup <mb@smartsharesystems.com>\nReviewed-by: Kevin Laatz <kevin.laatz@intel.com>\nReviewed-by: Conor Walsh <conor.walsh@intel.com>\n---\n doc/guides/prog_guide/dmadev.rst       |  38 ++\n doc/guides/rel_notes/release_21_11.rst |   1 +\n lib/dmadev/rte_dmadev.c                | 360 +++++++++++++++++++\n lib/dmadev/rte_dmadev.h                | 464 +++++++++++++++++++++++++\n lib/dmadev/rte_dmadev_pmd.h            |  61 ++++\n lib/dmadev/version.map                 |   9 +\n 6 files changed, 933 insertions(+)",
    "diff": "diff --git a/doc/guides/prog_guide/dmadev.rst b/doc/guides/prog_guide/dmadev.rst\nindex 90bda28f33..5c70ad3d6a 100644\n--- a/doc/guides/prog_guide/dmadev.rst\n+++ b/doc/guides/prog_guide/dmadev.rst\n@@ -58,3 +58,41 @@ identifiers:\n \n - A device name used to designate the DMA device in console messages, for\n   administration or debugging purposes.\n+\n+\n+Device Configuration\n+~~~~~~~~~~~~~~~~~~~~\n+\n+The rte_dma_configure API is used to configure a DMA device.\n+\n+.. code-block:: c\n+\n+   int rte_dma_configure(int16_t dev_id,\n+                         const struct rte_dma_conf *dev_conf);\n+\n+The ``rte_dma_conf`` structure is used to pass the configuration parameters\n+for the DMA device.\n+\n+\n+Configuration of Virtual DMA Channels\n+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n+\n+The rte_dma_vchan_setup API is used to configure a virtual DMA channel.\n+\n+.. code-block:: c\n+\n+   int rte_dma_vchan_setup(int16_t dev_id, uint16_t vchan,\n+                           const struct rte_dma_vchan_conf *conf);\n+\n+The ``rte_dma_vchan_conf`` structure is used to pass the configuration\n+parameters for the virtual DMA channel.\n+\n+\n+Device Features and Capabilities\n+--------------------------------\n+\n+DMA devices may support different feature sets. The ``rte_dma_info_get`` API\n+can be used to get the device info and supported features.\n+\n+Silent mode is a special device capability which does not require the\n+application to invoke dequeue APIs.\ndiff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst\nindex 929c0d6113..f935a3f395 100644\n--- a/doc/guides/rel_notes/release_21_11.rst\n+++ b/doc/guides/rel_notes/release_21_11.rst\n@@ -144,6 +144,7 @@ New Features\n * **Introduced dmadev library with:**\n \n   * Device allocation functions.\n+  * Control plane API.\n \n \n Removed Items\ndiff --git a/lib/dmadev/rte_dmadev.c b/lib/dmadev/rte_dmadev.c\nindex 42a4693bd9..a6a5680d2b 100644\n--- a/lib/dmadev/rte_dmadev.c\n+++ b/lib/dmadev/rte_dmadev.c\n@@ -201,6 +201,9 @@ rte_dma_pmd_release(const char *name)\n \tif (dev == NULL)\n \t\treturn -EINVAL;\n \n+\tif (dev->state == RTE_DMA_DEV_READY)\n+\t\treturn rte_dma_close(dev->dev_id);\n+\n \tdma_release(dev);\n \treturn 0;\n }\n@@ -244,3 +247,360 @@ rte_dma_count_avail(void)\n \n \treturn count;\n }\n+\n+int\n+rte_dma_info_get(int16_t dev_id, struct rte_dma_info *dev_info)\n+{\n+\tconst struct rte_dma_dev *dev = &rte_dma_devices[dev_id];\n+\tint ret;\n+\n+\tif (!rte_dma_is_valid(dev_id) || dev_info == NULL)\n+\t\treturn -EINVAL;\n+\n+\tRTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_info_get, -ENOTSUP);\n+\tmemset(dev_info, 0, sizeof(struct rte_dma_info));\n+\tret = (*dev->dev_ops->dev_info_get)(dev, dev_info,\n+\t\t\t\t\t    sizeof(struct rte_dma_info));\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tdev_info->numa_node = dev->device->numa_node;\n+\tdev_info->nb_vchans = dev->dev_conf.nb_vchans;\n+\n+\treturn 0;\n+}\n+\n+int\n+rte_dma_configure(int16_t dev_id, const struct rte_dma_conf *dev_conf)\n+{\n+\tstruct rte_dma_dev *dev = &rte_dma_devices[dev_id];\n+\tstruct rte_dma_info dev_info;\n+\tint ret;\n+\n+\tif (!rte_dma_is_valid(dev_id) || dev_conf == NULL)\n+\t\treturn -EINVAL;\n+\n+\tif (dev->dev_started != 0) {\n+\t\tRTE_DMA_LOG(ERR,\n+\t\t\t\"Device %d must be stopped to allow configuration\",\n+\t\t\tdev_id);\n+\t\treturn -EBUSY;\n+\t}\n+\n+\tret = rte_dma_info_get(dev_id, &dev_info);\n+\tif (ret != 0) {\n+\t\tRTE_DMA_LOG(ERR, \"Device %d get device info fail\", dev_id);\n+\t\treturn -EINVAL;\n+\t}\n+\tif (dev_conf->nb_vchans == 0) {\n+\t\tRTE_DMA_LOG(ERR,\n+\t\t\t\"Device %d configure zero vchans\", dev_id);\n+\t\treturn -EINVAL;\n+\t}\n+\tif (dev_conf->nb_vchans > dev_info.max_vchans) {\n+\t\tRTE_DMA_LOG(ERR,\n+\t\t\t\"Device %d configure too many vchans\", dev_id);\n+\t\treturn -EINVAL;\n+\t}\n+\tif (dev_conf->enable_silent &&\n+\t    !(dev_info.dev_capa & RTE_DMA_CAPA_SILENT)) {\n+\t\tRTE_DMA_LOG(ERR, \"Device %d don't support silent\", dev_id);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tRTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_configure, -ENOTSUP);\n+\tret = (*dev->dev_ops->dev_configure)(dev, dev_conf,\n+\t\t\t\t\t     sizeof(struct rte_dma_conf));\n+\tif (ret == 0)\n+\t\tmemcpy(&dev->dev_conf, dev_conf, sizeof(struct rte_dma_conf));\n+\n+\treturn ret;\n+}\n+\n+int\n+rte_dma_start(int16_t dev_id)\n+{\n+\tstruct rte_dma_dev *dev = &rte_dma_devices[dev_id];\n+\tint ret;\n+\n+\tif (!rte_dma_is_valid(dev_id))\n+\t\treturn -EINVAL;\n+\n+\tif (dev->dev_conf.nb_vchans == 0) {\n+\t\tRTE_DMA_LOG(ERR, \"Device %d must be configured first\", dev_id);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (dev->dev_started != 0) {\n+\t\tRTE_DMA_LOG(WARNING, \"Device %d already started\", dev_id);\n+\t\treturn 0;\n+\t}\n+\n+\tif (dev->dev_ops->dev_start == NULL)\n+\t\tgoto mark_started;\n+\n+\tret = (*dev->dev_ops->dev_start)(dev);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+mark_started:\n+\tdev->dev_started = 1;\n+\treturn 0;\n+}\n+\n+int\n+rte_dma_stop(int16_t dev_id)\n+{\n+\tstruct rte_dma_dev *dev = &rte_dma_devices[dev_id];\n+\tint ret;\n+\n+\tif (!rte_dma_is_valid(dev_id))\n+\t\treturn -EINVAL;\n+\n+\tif (dev->dev_started == 0) {\n+\t\tRTE_DMA_LOG(WARNING, \"Device %d already stopped\", dev_id);\n+\t\treturn 0;\n+\t}\n+\n+\tif (dev->dev_ops->dev_stop == NULL)\n+\t\tgoto mark_stopped;\n+\n+\tret = (*dev->dev_ops->dev_stop)(dev);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+mark_stopped:\n+\tdev->dev_started = 0;\n+\treturn 0;\n+}\n+\n+int\n+rte_dma_close(int16_t dev_id)\n+{\n+\tstruct rte_dma_dev *dev = &rte_dma_devices[dev_id];\n+\tint ret;\n+\n+\tif (!rte_dma_is_valid(dev_id))\n+\t\treturn -EINVAL;\n+\n+\t/* Device must be stopped before it can be closed */\n+\tif (dev->dev_started == 1) {\n+\t\tRTE_DMA_LOG(ERR,\n+\t\t\t\"Device %d must be stopped before closing\", dev_id);\n+\t\treturn -EBUSY;\n+\t}\n+\n+\tRTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_close, -ENOTSUP);\n+\tret = (*dev->dev_ops->dev_close)(dev);\n+\tif (ret == 0)\n+\t\tdma_release(dev);\n+\n+\treturn ret;\n+}\n+\n+int\n+rte_dma_vchan_setup(int16_t dev_id, uint16_t vchan,\n+\t\t    const struct rte_dma_vchan_conf *conf)\n+{\n+\tstruct rte_dma_dev *dev = &rte_dma_devices[dev_id];\n+\tstruct rte_dma_info dev_info;\n+\tbool src_is_dev, dst_is_dev;\n+\tint ret;\n+\n+\tif (!rte_dma_is_valid(dev_id) || conf == NULL)\n+\t\treturn -EINVAL;\n+\n+\tif (dev->dev_started != 0) {\n+\t\tRTE_DMA_LOG(ERR,\n+\t\t\t\"Device %d must be stopped to allow configuration\",\n+\t\t\tdev_id);\n+\t\treturn -EBUSY;\n+\t}\n+\n+\tret = rte_dma_info_get(dev_id, &dev_info);\n+\tif (ret != 0) {\n+\t\tRTE_DMA_LOG(ERR, \"Device %d get device info fail\", dev_id);\n+\t\treturn -EINVAL;\n+\t}\n+\tif (dev->dev_conf.nb_vchans == 0) {\n+\t\tRTE_DMA_LOG(ERR, \"Device %d must be configured first\", dev_id);\n+\t\treturn -EINVAL;\n+\t}\n+\tif (vchan >= dev_info.nb_vchans) {\n+\t\tRTE_DMA_LOG(ERR, \"Device %d vchan out range!\", dev_id);\n+\t\treturn -EINVAL;\n+\t}\n+\tif (conf->direction != RTE_DMA_DIR_MEM_TO_MEM &&\n+\t    conf->direction != RTE_DMA_DIR_MEM_TO_DEV &&\n+\t    conf->direction != RTE_DMA_DIR_DEV_TO_MEM &&\n+\t    conf->direction != RTE_DMA_DIR_DEV_TO_DEV) {\n+\t\tRTE_DMA_LOG(ERR, \"Device %d direction invalid!\", dev_id);\n+\t\treturn -EINVAL;\n+\t}\n+\tif (conf->direction == RTE_DMA_DIR_MEM_TO_MEM &&\n+\t    !(dev_info.dev_capa & RTE_DMA_CAPA_MEM_TO_MEM)) {\n+\t\tRTE_DMA_LOG(ERR,\n+\t\t\t\"Device %d don't support mem2mem transfer\", dev_id);\n+\t\treturn -EINVAL;\n+\t}\n+\tif (conf->direction == RTE_DMA_DIR_MEM_TO_DEV &&\n+\t    !(dev_info.dev_capa & RTE_DMA_CAPA_MEM_TO_DEV)) {\n+\t\tRTE_DMA_LOG(ERR,\n+\t\t\t\"Device %d don't support mem2dev transfer\", dev_id);\n+\t\treturn -EINVAL;\n+\t}\n+\tif (conf->direction == RTE_DMA_DIR_DEV_TO_MEM &&\n+\t    !(dev_info.dev_capa & RTE_DMA_CAPA_DEV_TO_MEM)) {\n+\t\tRTE_DMA_LOG(ERR,\n+\t\t\t\"Device %d don't support dev2mem transfer\", dev_id);\n+\t\treturn -EINVAL;\n+\t}\n+\tif (conf->direction == RTE_DMA_DIR_DEV_TO_DEV &&\n+\t    !(dev_info.dev_capa & RTE_DMA_CAPA_DEV_TO_DEV)) {\n+\t\tRTE_DMA_LOG(ERR,\n+\t\t\t\"Device %d don't support dev2dev transfer\", dev_id);\n+\t\treturn -EINVAL;\n+\t}\n+\tif (conf->nb_desc < dev_info.min_desc ||\n+\t    conf->nb_desc > dev_info.max_desc) {\n+\t\tRTE_DMA_LOG(ERR,\n+\t\t\t\"Device %d number of descriptors invalid\", dev_id);\n+\t\treturn -EINVAL;\n+\t}\n+\tsrc_is_dev = conf->direction == RTE_DMA_DIR_DEV_TO_MEM ||\n+\t\t     conf->direction == RTE_DMA_DIR_DEV_TO_DEV;\n+\tif ((conf->src_port.port_type == RTE_DMA_PORT_NONE && src_is_dev) ||\n+\t    (conf->src_port.port_type != RTE_DMA_PORT_NONE && !src_is_dev)) {\n+\t\tRTE_DMA_LOG(ERR, \"Device %d source port type invalid\", dev_id);\n+\t\treturn -EINVAL;\n+\t}\n+\tdst_is_dev = conf->direction == RTE_DMA_DIR_MEM_TO_DEV ||\n+\t\t     conf->direction == RTE_DMA_DIR_DEV_TO_DEV;\n+\tif ((conf->dst_port.port_type == RTE_DMA_PORT_NONE && dst_is_dev) ||\n+\t    (conf->dst_port.port_type != RTE_DMA_PORT_NONE && !dst_is_dev)) {\n+\t\tRTE_DMA_LOG(ERR,\n+\t\t\t\"Device %d destination port type invalid\", dev_id);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tRTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vchan_setup, -ENOTSUP);\n+\treturn (*dev->dev_ops->vchan_setup)(dev, vchan, conf,\n+\t\t\t\t\tsizeof(struct rte_dma_vchan_conf));\n+}\n+\n+int\n+rte_dma_stats_get(int16_t dev_id, uint16_t vchan, struct rte_dma_stats *stats)\n+{\n+\tconst struct rte_dma_dev *dev = &rte_dma_devices[dev_id];\n+\n+\tif (!rte_dma_is_valid(dev_id) || stats == NULL)\n+\t\treturn -EINVAL;\n+\n+\tif (vchan >= dev->dev_conf.nb_vchans &&\n+\t    vchan != RTE_DMA_ALL_VCHAN) {\n+\t\tRTE_DMA_LOG(ERR,\n+\t\t\t\"Device %d vchan %u out of range\", dev_id, vchan);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tRTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->stats_get, -ENOTSUP);\n+\tmemset(stats, 0, sizeof(struct rte_dma_stats));\n+\treturn (*dev->dev_ops->stats_get)(dev, vchan, stats,\n+\t\t\t\t\t  sizeof(struct rte_dma_stats));\n+}\n+\n+int\n+rte_dma_stats_reset(int16_t dev_id, uint16_t vchan)\n+{\n+\tstruct rte_dma_dev *dev = &rte_dma_devices[dev_id];\n+\n+\tif (!rte_dma_is_valid(dev_id))\n+\t\treturn -EINVAL;\n+\n+\tif (vchan >= dev->dev_conf.nb_vchans &&\n+\t    vchan != RTE_DMA_ALL_VCHAN) {\n+\t\tRTE_DMA_LOG(ERR,\n+\t\t\t\"Device %d vchan %u out of range\", dev_id, vchan);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tRTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->stats_reset, -ENOTSUP);\n+\treturn (*dev->dev_ops->stats_reset)(dev, vchan);\n+}\n+\n+static const char *\n+dma_capability_name(uint64_t capability)\n+{\n+\tstatic const struct {\n+\t\tuint64_t capability;\n+\t\tconst char *name;\n+\t} capa_names[] = {\n+\t\t{ RTE_DMA_CAPA_MEM_TO_MEM,  \"mem2mem\" },\n+\t\t{ RTE_DMA_CAPA_MEM_TO_DEV,  \"mem2dev\" },\n+\t\t{ RTE_DMA_CAPA_DEV_TO_MEM,  \"dev2mem\" },\n+\t\t{ RTE_DMA_CAPA_DEV_TO_DEV,  \"dev2dev\" },\n+\t\t{ RTE_DMA_CAPA_SVA,         \"sva\"     },\n+\t\t{ RTE_DMA_CAPA_SILENT,      \"silent\"  },\n+\t\t{ RTE_DMA_CAPA_OPS_COPY,    \"copy\"    },\n+\t\t{ RTE_DMA_CAPA_OPS_COPY_SG, \"copy_sg\" },\n+\t\t{ RTE_DMA_CAPA_OPS_FILL,    \"fill\"    },\n+\t};\n+\n+\tconst char *name = \"unknown\";\n+\tuint32_t i;\n+\n+\tfor (i = 0; i < RTE_DIM(capa_names); i++) {\n+\t\tif (capability == capa_names[i].capability) {\n+\t\t\tname = capa_names[i].name;\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\treturn name;\n+}\n+\n+static void\n+dma_dump_capability(FILE *f, uint64_t dev_capa)\n+{\n+\tuint64_t capa;\n+\n+\t(void)fprintf(f, \"  dev_capa: 0x%\" PRIx64 \" -\", dev_capa);\n+\twhile (dev_capa > 0) {\n+\t\tcapa = 1ull << __builtin_ctzll(dev_capa);\n+\t\t(void)fprintf(f, \" %s\", dma_capability_name(capa));\n+\t\tdev_capa &= ~capa;\n+\t}\n+\t(void)fprintf(f, \"\\n\");\n+}\n+\n+int\n+rte_dma_dump(int16_t dev_id, FILE *f)\n+{\n+\tconst struct rte_dma_dev *dev = &rte_dma_devices[dev_id];\n+\tstruct rte_dma_info dev_info;\n+\tint ret;\n+\n+\tif (!rte_dma_is_valid(dev_id) || f == NULL)\n+\t\treturn -EINVAL;\n+\n+\tret = rte_dma_info_get(dev_id, &dev_info);\n+\tif (ret != 0) {\n+\t\tRTE_DMA_LOG(ERR, \"Device %d get device info fail\", dev_id);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t(void)fprintf(f, \"DMA Dev %d, '%s' [%s]\\n\",\n+\t\tdev->dev_id,\n+\t\tdev->dev_name,\n+\t\tdev->dev_started ? \"started\" : \"stopped\");\n+\tdma_dump_capability(f, dev_info.dev_capa);\n+\t(void)fprintf(f, \"  max_vchans_supported: %u\\n\", dev_info.max_vchans);\n+\t(void)fprintf(f, \"  nb_vchans_configured: %u\\n\", dev_info.nb_vchans);\n+\t(void)fprintf(f, \"  silent_mode: %s\\n\",\n+\t\tdev->dev_conf.enable_silent ? \"on\" : \"off\");\n+\n+\tif (dev->dev_ops->dev_dump != NULL)\n+\t\treturn (*dev->dev_ops->dev_dump)(dev, f);\n+\n+\treturn 0;\n+}\ndiff --git a/lib/dmadev/rte_dmadev.h b/lib/dmadev/rte_dmadev.h\nindex 87810f2f08..34a4c26851 100644\n--- a/lib/dmadev/rte_dmadev.h\n+++ b/lib/dmadev/rte_dmadev.h\n@@ -48,6 +48,29 @@\n  * This framework uses 'int16_t dev_id' as the device identifier of a dmadev,\n  * and 'uint16_t vchan' as the virtual DMA channel identifier in one dmadev.\n  *\n+ * The functions exported by the dmadev API to setup a device designated by its\n+ * device identifier must be invoked in the following order:\n+ *     - rte_dma_configure()\n+ *     - rte_dma_vchan_setup()\n+ *     - rte_dma_start()\n+ *\n+ * Then, the application can invoke dataplane functions to process jobs.\n+ *\n+ * If the application wants to change the configuration (i.e. invoke\n+ * rte_dma_configure() or rte_dma_vchan_setup()), it must invoke\n+ * rte_dma_stop() first to stop the device and then do the reconfiguration\n+ * before invoking rte_dma_start() again. The dataplane functions should not\n+ * be invoked when the device is stopped.\n+ *\n+ * Finally, an application can close a dmadev by invoking the rte_dma_close()\n+ * function.\n+ *\n+ * About MT-safe, all the functions of the dmadev API implemented by a PMD are\n+ * lock-free functions which assume to not be invoked in parallel on different\n+ * logical cores to work on the same target dmadev object.\n+ * @note Different virtual DMA channels on the same dmadev *DO NOT* support\n+ * parallel invocation because these virtual DMA channels share the same\n+ * HW-DMA-channel.\n  */\n \n #include <stdint.h>\n@@ -126,6 +149,447 @@ bool rte_dma_is_valid(int16_t dev_id);\n __rte_experimental\n uint16_t rte_dma_count_avail(void);\n \n+/**@{@name DMA capability\n+ * @see struct rte_dma_info::dev_capa\n+ */\n+#define RTE_DMA_CAPA_MEM_TO_MEM\t\tRTE_BIT64(0)\n+/**< Support memory-to-memory transfer */\n+#define RTE_DMA_CAPA_MEM_TO_DEV\t\tRTE_BIT64(1)\n+/**< Support memory-to-device transfer. */\n+#define RTE_DMA_CAPA_DEV_TO_MEM\t\tRTE_BIT64(2)\n+/**< Support device-to-memory transfer. */\n+#define RTE_DMA_CAPA_DEV_TO_DEV\t\tRTE_BIT64(3)\n+/**< Support device-to-device transfer. */\n+#define RTE_DMA_CAPA_SVA\t\tRTE_BIT64(4)\n+/**< Support SVA which could use VA as DMA address.\n+ * If device support SVA then application could pass any VA address like memory\n+ * from rte_malloc(), rte_memzone(), malloc, stack memory.\n+ * If device don't support SVA, then application should pass IOVA address which\n+ * from rte_malloc(), rte_memzone().\n+ */\n+#define RTE_DMA_CAPA_SILENT\t\tRTE_BIT64(5)\n+/**< Support work in silent mode.\n+ * In this mode, application don't required to invoke rte_dma_completed*()\n+ * API.\n+ * @see struct rte_dma_conf::silent_mode\n+ */\n+#define RTE_DMA_CAPA_OPS_COPY\t\tRTE_BIT64(32)\n+/**< Support copy operation.\n+ * This capability start with index of 32, so that it could leave gap between\n+ * normal capability and ops capability.\n+ */\n+#define RTE_DMA_CAPA_OPS_COPY_SG\tRTE_BIT64(33)\n+/**< Support scatter-gather list copy operation. */\n+#define RTE_DMA_CAPA_OPS_FILL\t\tRTE_BIT64(34)\n+/**< Support fill operation. */\n+/**@}*/\n+\n+/**\n+ * A structure used to retrieve the information of a DMA device.\n+ *\n+ * @see rte_dma_info_get\n+ */\n+struct rte_dma_info {\n+\t/** Device capabilities (RTE_DMA_CAPA_*). */\n+\tuint64_t dev_capa;\n+\t/** Maximum number of virtual DMA channels supported. */\n+\tuint16_t max_vchans;\n+\t/** Maximum allowed number of virtual DMA channel descriptors. */\n+\tuint16_t max_desc;\n+\t/** Minimum allowed number of virtual DMA channel descriptors. */\n+\tuint16_t min_desc;\n+\t/** Maximum number of source or destination scatter-gather entry\n+\t * supported.\n+\t * If the device does not support COPY_SG capability, this value can be\n+\t * zero.\n+\t * If the device supports COPY_SG capability, then rte_dma_copy_sg()\n+\t * parameter nb_src/nb_dst should not exceed this value.\n+\t */\n+\tuint16_t max_sges;\n+\t/** NUMA node connection, -1 if unknown. */\n+\tint16_t numa_node;\n+\t/** Number of virtual DMA channel configured. */\n+\tuint16_t nb_vchans;\n+};\n+\n+/**\n+ * @warning\n+ * @b EXPERIMENTAL: this API may change without prior notice.\n+ *\n+ * Retrieve information of a DMA device.\n+ *\n+ * @param dev_id\n+ *   The identifier of the device.\n+ * @param[out] dev_info\n+ *   A pointer to a structure of type *rte_dma_info* to be filled with the\n+ *   information of the device.\n+ *\n+ * @return\n+ *   0 on success. Otherwise negative value is returned.\n+ */\n+__rte_experimental\n+int rte_dma_info_get(int16_t dev_id, struct rte_dma_info *dev_info);\n+\n+/**\n+ * A structure used to configure a DMA device.\n+ *\n+ * @see rte_dma_configure\n+ */\n+struct rte_dma_conf {\n+\t/** The number of virtual DMA channels to set up for the DMA device.\n+\t * This value cannot be greater than the field 'max_vchans' of struct\n+\t * rte_dma_info which get from rte_dma_info_get().\n+\t */\n+\tuint16_t nb_vchans;\n+\t/** Indicates whether to enable silent mode.\n+\t * false-default mode, true-silent mode.\n+\t * This value can be set to true only when the SILENT capability is\n+\t * supported.\n+\t *\n+\t * @see RTE_DMA_CAPA_SILENT\n+\t */\n+\tbool enable_silent;\n+};\n+\n+/**\n+ * @warning\n+ * @b EXPERIMENTAL: this API may change without prior notice.\n+ *\n+ * Configure a DMA device.\n+ *\n+ * This function must be invoked first before any other function in the\n+ * API. This function can also be re-invoked when a device is in the\n+ * stopped state.\n+ *\n+ * @param dev_id\n+ *   The identifier of the device to configure.\n+ * @param dev_conf\n+ *   The DMA device configuration structure encapsulated into rte_dma_conf\n+ *   object.\n+ *\n+ * @return\n+ *   0 on success. Otherwise negative value is returned.\n+ */\n+__rte_experimental\n+int rte_dma_configure(int16_t dev_id, const struct rte_dma_conf *dev_conf);\n+\n+/**\n+ * @warning\n+ * @b EXPERIMENTAL: this API may change without prior notice.\n+ *\n+ * Start a DMA device.\n+ *\n+ * The device start step is the last one and consists of setting the DMA\n+ * to start accepting jobs.\n+ *\n+ * @param dev_id\n+ *   The identifier of the device.\n+ *\n+ * @return\n+ *   0 on success. Otherwise negative value is returned.\n+ */\n+__rte_experimental\n+int rte_dma_start(int16_t dev_id);\n+\n+/**\n+ * @warning\n+ * @b EXPERIMENTAL: this API may change without prior notice.\n+ *\n+ * Stop a DMA device.\n+ *\n+ * The device can be restarted with a call to rte_dma_start().\n+ *\n+ * @param dev_id\n+ *   The identifier of the device.\n+ *\n+ * @return\n+ *   0 on success. Otherwise negative value is returned.\n+ */\n+__rte_experimental\n+int rte_dma_stop(int16_t dev_id);\n+\n+/**\n+ * @warning\n+ * @b EXPERIMENTAL: this API may change without prior notice.\n+ *\n+ * Close a DMA device.\n+ *\n+ * The device cannot be restarted after this call.\n+ *\n+ * @param dev_id\n+ *   The identifier of the device.\n+ *\n+ * @return\n+ *   0 on success. Otherwise negative value is returned.\n+ */\n+__rte_experimental\n+int rte_dma_close(int16_t dev_id);\n+\n+/**\n+ * DMA transfer direction defines.\n+ *\n+ * @see struct rte_dma_vchan_conf::direction\n+ */\n+enum rte_dma_direction {\n+\t/** DMA transfer direction - from memory to memory.\n+\t *\n+\t * @see struct rte_dma_vchan_conf::direction\n+\t */\n+\tRTE_DMA_DIR_MEM_TO_MEM,\n+\t/** DMA transfer direction - from memory to device.\n+\t * In a typical scenario, the SoCs are installed on host servers as\n+\t * iNICs through the PCIe interface. In this case, the SoCs works in\n+\t * EP(endpoint) mode, it could initiate a DMA move request from memory\n+\t * (which is SoCs memory) to device (which is host memory).\n+\t *\n+\t * @see struct rte_dma_vchan_conf::direction\n+\t */\n+\tRTE_DMA_DIR_MEM_TO_DEV,\n+\t/** DMA transfer direction - from device to memory.\n+\t * In a typical scenario, the SoCs are installed on host servers as\n+\t * iNICs through the PCIe interface. In this case, the SoCs works in\n+\t * EP(endpoint) mode, it could initiate a DMA move request from device\n+\t * (which is host memory) to memory (which is SoCs memory).\n+\t *\n+\t * @see struct rte_dma_vchan_conf::direction\n+\t */\n+\tRTE_DMA_DIR_DEV_TO_MEM,\n+\t/** DMA transfer direction - from device to device.\n+\t * In a typical scenario, the SoCs are installed on host servers as\n+\t * iNICs through the PCIe interface. In this case, the SoCs works in\n+\t * EP(endpoint) mode, it could initiate a DMA move request from device\n+\t * (which is host memory) to the device (which is another host memory).\n+\t *\n+\t * @see struct rte_dma_vchan_conf::direction\n+\t */\n+\tRTE_DMA_DIR_DEV_TO_DEV,\n+};\n+\n+/**\n+ * DMA access port type defines.\n+ *\n+ * @see struct rte_dma_port_param::port_type\n+ */\n+enum rte_dma_port_type {\n+\tRTE_DMA_PORT_NONE,\n+\tRTE_DMA_PORT_PCIE, /**< The DMA access port is PCIe. */\n+};\n+\n+/**\n+ * A structure used to descript DMA access port parameters.\n+ *\n+ * @see struct rte_dma_vchan_conf::src_port\n+ * @see struct rte_dma_vchan_conf::dst_port\n+ */\n+struct rte_dma_port_param {\n+\t/** The device access port type.\n+\t *\n+\t * @see enum rte_dma_port_type\n+\t */\n+\tenum rte_dma_port_type port_type;\n+\tRTE_STD_C11\n+\tunion {\n+\t\t/** PCIe access port parameters.\n+\t\t *\n+\t\t * The following model shows SoC's PCIe module connects to\n+\t\t * multiple PCIe hosts and multiple endpoints. The PCIe module\n+\t\t * has an integrated DMA controller.\n+\t\t *\n+\t\t * If the DMA wants to access the memory of host A, it can be\n+\t\t * initiated by PF1 in core0, or by VF0 of PF0 in core0.\n+\t\t *\n+\t\t * \\code{.unparsed}\n+\t\t * System Bus\n+\t\t *    |     ----------PCIe module----------\n+\t\t *    |     Bus\n+\t\t *    |     Interface\n+\t\t *    |     -----        ------------------\n+\t\t *    |     |   |        | PCIe Core0     |\n+\t\t *    |     |   |        |                |        -----------\n+\t\t *    |     |   |        |   PF-0 -- VF-0 |        | Host A  |\n+\t\t *    |     |   |--------|        |- VF-1 |--------| Root    |\n+\t\t *    |     |   |        |   PF-1         |        | Complex |\n+\t\t *    |     |   |        |   PF-2         |        -----------\n+\t\t *    |     |   |        ------------------\n+\t\t *    |     |   |\n+\t\t *    |     |   |        ------------------\n+\t\t *    |     |   |        | PCIe Core1     |\n+\t\t *    |     |   |        |                |        -----------\n+\t\t *    |     |   |        |   PF-0 -- VF-0 |        | Host B  |\n+\t\t *    |-----|   |--------|   PF-1 -- VF-0 |--------| Root    |\n+\t\t *    |     |   |        |        |- VF-1 |        | Complex |\n+\t\t *    |     |   |        |   PF-2         |        -----------\n+\t\t *    |     |   |        ------------------\n+\t\t *    |     |   |\n+\t\t *    |     |   |        ------------------\n+\t\t *    |     |DMA|        |                |        ------\n+\t\t *    |     |   |        |                |--------| EP |\n+\t\t *    |     |   |--------| PCIe Core2     |        ------\n+\t\t *    |     |   |        |                |        ------\n+\t\t *    |     |   |        |                |--------| EP |\n+\t\t *    |     |   |        |                |        ------\n+\t\t *    |     -----        ------------------\n+\t\t *\n+\t\t * \\endcode\n+\t\t *\n+\t\t * @note If some fields can not be supported by the\n+\t\t * hardware/driver, then the driver ignores those fields.\n+\t\t * Please check driver-specific documentation for limitations\n+\t\t * and capablites.\n+\t\t */\n+\t\t__extension__\n+\t\tstruct {\n+\t\t\tuint64_t coreid : 4; /**< PCIe core id used. */\n+\t\t\tuint64_t pfid : 8; /**< PF id used. */\n+\t\t\tuint64_t vfen : 1; /**< VF enable bit. */\n+\t\t\tuint64_t vfid : 16; /**< VF id used. */\n+\t\t\t/** The pasid filed in TLP packet. */\n+\t\t\tuint64_t pasid : 20;\n+\t\t\t/** The attributes filed in TLP packet. */\n+\t\t\tuint64_t attr : 3;\n+\t\t\t/** The processing hint filed in TLP packet. */\n+\t\t\tuint64_t ph : 2;\n+\t\t\t/** The steering tag filed in TLP packet. */\n+\t\t\tuint64_t st : 16;\n+\t\t} pcie;\n+\t};\n+\tuint64_t reserved[2]; /**< Reserved for future fields. */\n+};\n+\n+/**\n+ * A structure used to configure a virtual DMA channel.\n+ *\n+ * @see rte_dma_vchan_setup\n+ */\n+struct rte_dma_vchan_conf {\n+\t/** Transfer direction\n+\t *\n+\t * @see enum rte_dma_direction\n+\t */\n+\tenum rte_dma_direction direction;\n+\t/** Number of descriptor for the virtual DMA channel */\n+\tuint16_t nb_desc;\n+\t/** 1) Used to describes the device access port parameter in the\n+\t * device-to-memory transfer scenario.\n+\t * 2) Used to describes the source device access port parameter in the\n+\t * device-to-device transfer scenario.\n+\t *\n+\t * @see struct rte_dma_port_param\n+\t */\n+\tstruct rte_dma_port_param src_port;\n+\t/** 1) Used to describes the device access port parameter in the\n+\t * memory-to-device transfer scenario.\n+\t * 2) Used to describes the destination device access port parameter in\n+\t * the device-to-device transfer scenario.\n+\t *\n+\t * @see struct rte_dma_port_param\n+\t */\n+\tstruct rte_dma_port_param dst_port;\n+};\n+\n+/**\n+ * @warning\n+ * @b EXPERIMENTAL: this API may change without prior notice.\n+ *\n+ * Allocate and set up a virtual DMA channel.\n+ *\n+ * @param dev_id\n+ *   The identifier of the device.\n+ * @param vchan\n+ *   The identifier of virtual DMA channel. The value must be in the range\n+ *   [0, nb_vchans - 1] previously supplied to rte_dma_configure().\n+ * @param conf\n+ *   The virtual DMA channel configuration structure encapsulated into\n+ *   rte_dma_vchan_conf object.\n+ *\n+ * @return\n+ *   0 on success. Otherwise negative value is returned.\n+ */\n+__rte_experimental\n+int rte_dma_vchan_setup(int16_t dev_id, uint16_t vchan,\n+\t\t\tconst struct rte_dma_vchan_conf *conf);\n+\n+/**\n+ * A structure used to retrieve statistics.\n+ *\n+ * @see rte_dma_stats_get\n+ */\n+struct rte_dma_stats {\n+\t/** Count of operations which were submitted to hardware. */\n+\tuint64_t submitted;\n+\t/** Count of operations which were completed, including successful and\n+\t * failed completions.\n+\t */\n+\tuint64_t completed;\n+\t/** Count of operations which failed to complete. */\n+\tuint64_t errors;\n+};\n+\n+/**\n+ * Special ID, which is used to represent all virtual DMA channels.\n+ *\n+ * @see rte_dma_stats_get\n+ * @see rte_dma_stats_reset\n+ */\n+#define RTE_DMA_ALL_VCHAN\t0xFFFFu\n+\n+/**\n+ * @warning\n+ * @b EXPERIMENTAL: this API may change without prior notice.\n+ *\n+ * Retrieve basic statistics of a or all virtual DMA channel(s).\n+ *\n+ * @param dev_id\n+ *   The identifier of the device.\n+ * @param vchan\n+ *   The identifier of virtual DMA channel.\n+ *   If equal RTE_DMA_ALL_VCHAN means all channels.\n+ * @param[out] stats\n+ *   The basic statistics structure encapsulated into rte_dma_stats\n+ *   object.\n+ *\n+ * @return\n+ *   0 on success. Otherwise negative value is returned.\n+ */\n+__rte_experimental\n+int rte_dma_stats_get(int16_t dev_id, uint16_t vchan,\n+\t\t      struct rte_dma_stats *stats);\n+\n+/**\n+ * @warning\n+ * @b EXPERIMENTAL: this API may change without prior notice.\n+ *\n+ * Reset basic statistics of a or all virtual DMA channel(s).\n+ *\n+ * @param dev_id\n+ *   The identifier of the device.\n+ * @param vchan\n+ *   The identifier of virtual DMA channel.\n+ *   If equal RTE_DMA_ALL_VCHAN means all channels.\n+ *\n+ * @return\n+ *   0 on success. Otherwise negative value is returned.\n+ */\n+__rte_experimental\n+int rte_dma_stats_reset(int16_t dev_id, uint16_t vchan);\n+\n+/**\n+ * @warning\n+ * @b EXPERIMENTAL: this API may change without prior notice.\n+ *\n+ * Dump DMA device info.\n+ *\n+ * @param dev_id\n+ *   The identifier of the device.\n+ * @param f\n+ *   The file to write the output to.\n+ *\n+ * @return\n+ *   0 on success. Otherwise negative value is returned.\n+ */\n+__rte_experimental\n+int rte_dma_dump(int16_t dev_id, FILE *f);\n+\n #ifdef __cplusplus\n }\n #endif\ndiff --git a/lib/dmadev/rte_dmadev_pmd.h b/lib/dmadev/rte_dmadev_pmd.h\nindex bb09382dce..5fcf0f60b8 100644\n--- a/lib/dmadev/rte_dmadev_pmd.h\n+++ b/lib/dmadev/rte_dmadev_pmd.h\n@@ -20,6 +20,62 @@\n extern \"C\" {\n #endif\n \n+struct rte_dma_dev;\n+\n+/** @internal Used to get device information of a device. */\n+typedef int (*rte_dma_info_get_t)(const struct rte_dma_dev *dev,\n+\t\t\t\t  struct rte_dma_info *dev_info,\n+\t\t\t\t  uint32_t info_sz);\n+\n+/** @internal Used to configure a device. */\n+typedef int (*rte_dma_configure_t)(struct rte_dma_dev *dev,\n+\t\t\t\t   const struct rte_dma_conf *dev_conf,\n+\t\t\t\t   uint32_t conf_sz);\n+\n+/** @internal Used to start a configured device. */\n+typedef int (*rte_dma_start_t)(struct rte_dma_dev *dev);\n+\n+/** @internal Used to stop a configured device. */\n+typedef int (*rte_dma_stop_t)(struct rte_dma_dev *dev);\n+\n+/** @internal Used to close a configured device. */\n+typedef int (*rte_dma_close_t)(struct rte_dma_dev *dev);\n+\n+/** @internal Used to allocate and set up a virtual DMA channel. */\n+typedef int (*rte_dma_vchan_setup_t)(struct rte_dma_dev *dev, uint16_t vchan,\n+\t\t\t\tconst struct rte_dma_vchan_conf *conf,\n+\t\t\t\tuint32_t conf_sz);\n+\n+/** @internal Used to retrieve basic statistics. */\n+typedef int (*rte_dma_stats_get_t)(const struct rte_dma_dev *dev,\n+\t\t\tuint16_t vchan, struct rte_dma_stats *stats,\n+\t\t\tuint32_t stats_sz);\n+\n+/** @internal Used to reset basic statistics. */\n+typedef int (*rte_dma_stats_reset_t)(struct rte_dma_dev *dev, uint16_t vchan);\n+\n+/** @internal Used to dump internal information. */\n+typedef int (*rte_dma_dump_t)(const struct rte_dma_dev *dev, FILE *f);\n+\n+/**\n+ * DMA device operations function pointer table.\n+ *\n+ * @see struct rte_dma_dev:dev_ops\n+ */\n+struct rte_dma_dev_ops {\n+\trte_dma_info_get_t         dev_info_get;\n+\trte_dma_configure_t        dev_configure;\n+\trte_dma_start_t            dev_start;\n+\trte_dma_stop_t             dev_stop;\n+\trte_dma_close_t            dev_close;\n+\n+\trte_dma_vchan_setup_t      vchan_setup;\n+\n+\trte_dma_stats_get_t        stats_get;\n+\trte_dma_stats_reset_t      stats_reset;\n+\n+\trte_dma_dump_t             dev_dump;\n+};\n /**\n  * Possible states of a DMA device.\n  *\n@@ -44,7 +100,12 @@ struct rte_dma_dev {\n \tvoid *dev_private; /**< PMD-specific private data. */\n \t/** Device info which supplied during device initialization. */\n \tstruct rte_device *device;\n+\t/** Functions implemented by PMD. */\n+\tconst struct rte_dma_dev_ops *dev_ops;\n+\tstruct rte_dma_conf dev_conf; /**< DMA device configuration. */\n \tenum rte_dma_dev_state state; /**< Flag indicating the device state. */\n+\t__extension__\n+\tuint8_t dev_started : 1; /**< Device state: STARTED(1)/STOPPED(0). */\n \tuint64_t reserved[2]; /**< Reserved for future fields. */\n } __rte_cache_aligned;\n \ndiff --git a/lib/dmadev/version.map b/lib/dmadev/version.map\nindex f8a0076468..e925dfcd6d 100644\n--- a/lib/dmadev/version.map\n+++ b/lib/dmadev/version.map\n@@ -1,10 +1,19 @@\n EXPERIMENTAL {\n \tglobal:\n \n+\trte_dma_close;\n+\trte_dma_configure;\n \trte_dma_count_avail;\n \trte_dma_dev_max;\n+\trte_dma_dump;\n \trte_dma_get_dev_id_by_name;\n+\trte_dma_info_get;\n \trte_dma_is_valid;\n+\trte_dma_start;\n+\trte_dma_stats_get;\n+\trte_dma_stats_reset;\n+\trte_dma_stop;\n+\trte_dma_vchan_setup;\n \n \tlocal: *;\n };\n",
    "prefixes": [
        "v24",
        "2/6"
    ]
}