get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 109873,
    "url": "https://patches.dpdk.org/api/patches/109873/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/20220418042915.5765-4-srikanth.k@oneconvergence.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": "<20220418042915.5765-4-srikanth.k@oneconvergence.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20220418042915.5765-4-srikanth.k@oneconvergence.com",
    "date": "2022-04-18T04:29:04",
    "name": "[v4,03/14] bus/vmbus: move OS independent UIO functions",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "b0a3242774f18b454e5a704bd0436b45d96e01aa",
    "submitter": {
        "id": 2368,
        "url": "https://patches.dpdk.org/api/people/2368/?format=api",
        "name": "Srikanth Kaka",
        "email": "srikanth.k@oneconvergence.com"
    },
    "delegate": null,
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/20220418042915.5765-4-srikanth.k@oneconvergence.com/mbox/",
    "series": [
        {
            "id": 22557,
            "url": "https://patches.dpdk.org/api/series/22557/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=22557",
            "date": "2022-04-18T04:29:01",
            "name": "add FreeBSD support to VMBUS & NetVSC PMDs",
            "version": 4,
            "mbox": "https://patches.dpdk.org/series/22557/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/109873/comments/",
    "check": "success",
    "checks": "https://patches.dpdk.org/api/patches/109873/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 47817A00BE;\n\tTue, 19 Apr 2022 11:34:05 +0200 (CEST)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 328CC427F9;\n\tTue, 19 Apr 2022 11:33:42 +0200 (CEST)",
            "from mail-pj1-f68.google.com (mail-pj1-f68.google.com\n [209.85.216.68]) by mails.dpdk.org (Postfix) with ESMTP id 2752B40141\n for <dev@dpdk.org>; Mon, 18 Apr 2022 06:29:40 +0200 (CEST)",
            "by mail-pj1-f68.google.com with SMTP id\n h15-20020a17090a054f00b001cb7cd2b11dso13031482pjf.5\n for <dev@dpdk.org>; Sun, 17 Apr 2022 21:29:40 -0700 (PDT)",
            "from srikanth-ThinkPad-T450.. ([49.37.158.191])\n by smtp.gmail.com with ESMTPSA id\n e14-20020aa78c4e000000b00506475da4cesm10377577pfd.49.2022.04.17.21.29.35\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Sun, 17 Apr 2022 21:29:38 -0700 (PDT)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=oneconvergence.com; s=google;\n h=from:to:cc:subject:date:message-id:in-reply-to:references\n :mime-version:content-transfer-encoding;\n bh=8+RWzaA3MUIkhoYz6xAcNAUxsbBzPp7jA3/JMxvjClk=;\n b=Pw7/e8ffMB4oRkrQ3dflK6ics39hoRwBSpgT02b2wMOhntpoU9maSTvldocI5j6W8K\n LnMrTwy99DBKfIXYhzxuO3NRlLwnXtP7OFI7AWUpRjF2dMC51sZiD8OdUNox9tD+uaox\n EWAEqU9/PUTlTK63+1HYMGF2iOoYYWGDYgxXo=",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20210112;\n h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to\n :references:mime-version:content-transfer-encoding;\n bh=8+RWzaA3MUIkhoYz6xAcNAUxsbBzPp7jA3/JMxvjClk=;\n b=SorM1wDkjGuVHxeEcRs8mH+ArEWO3ICWtcW3+Choe9ei+t12rQZrBI4uS76Xx50NH4\n l8mdoJ+e3GUYNCwQ04KDk5sh8y7qs1Fvfqfd01u1YnlNQ5MHHCHJA6peLplDpo/IV/RJ\n R3NotHC4OPkSxk5jqjGvGoBj47BAefB0ubxOf9gREEpvfkRnULfNpKcQTjKi2xi97+dO\n h27Ckw/eino4EmxXYu53zm5acJIxTV6kXBmqd+SIkDnDmE2LDxithzZ+DQRI1mub1Npr\n MDeHyyJ8EP2clAUweWjlaEVL2IrvwaqdS4U8gmxGfDy6fJt1YjxeSy95vvwLkzDTYniI\n Q+dA==",
        "X-Gm-Message-State": "AOAM53321UYJkajCZCs9fWBnFavgw/QhnF8qTdeybbw7gy1Hwn6v5n3p\n x7Esrb2OO8somXm5hhH6E8aMkA==",
        "X-Google-Smtp-Source": "\n ABdhPJxiPkhkl1KDWTNJNUMgdwACMmAOuyRKMgqWhKBCypxBmHoAdETckGWLknmtEs6tGurPZU5awQ==",
        "X-Received": "by 2002:a17:902:b941:b0:14d:af72:3f23 with SMTP id\n h1-20020a170902b94100b0014daf723f23mr9495513pls.6.1650256179324;\n Sun, 17 Apr 2022 21:29:39 -0700 (PDT)",
        "From": "Srikanth Kaka <srikanth.k@oneconvergence.com>",
        "To": "Stephen Hemminger <sthemmin@microsoft.com>, Long Li <longli@microsoft.com>",
        "Cc": "dev@dpdk.org, Vag Singh <vag.singh@oneconvergence.com>,\n Anand Thulasiram <avelu@juniper.net>,\n Srikanth Kaka <srikanth.k@oneconvergence.com>",
        "Subject": "[PATCH v4 03/14] bus/vmbus: move OS independent UIO functions",
        "Date": "Mon, 18 Apr 2022 09:59:04 +0530",
        "Message-Id": "<20220418042915.5765-4-srikanth.k@oneconvergence.com>",
        "X-Mailer": "git-send-email 2.30.2",
        "In-Reply-To": "<20220418042915.5765-1-srikanth.k@oneconvergence.com>",
        "References": "<20220217160613.70161-16-srikanth.k@oneconvergence.com>\n <20220418042915.5765-1-srikanth.k@oneconvergence.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "X-Mailman-Approved-At": "Tue, 19 Apr 2022 11:33:36 +0200",
        "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": "Moved all Linux independent UIO functions to OSI dir.\nSplit the vmbus_uio_map_subchan() by keeping OS dependent\ncode in vmbus_uio_map_subchan_os() function\n\nSigned-off-by: Srikanth Kaka <srikanth.k@oneconvergence.com>\nSigned-off-by: Vag Singh <vag.singh@oneconvergence.com>\nSigned-off-by: Anand Thulasiram <avelu@juniper.net>\n---\n drivers/bus/vmbus/linux/vmbus_uio.c   | 292 +-----------------------\n drivers/bus/vmbus/meson.build         |   3 +-\n drivers/bus/vmbus/osi/vmbus_osi.h     |  12 +\n drivers/bus/vmbus/osi/vmbus_osi_uio.c | 306 ++++++++++++++++++++++++++\n 4 files changed, 330 insertions(+), 283 deletions(-)\n create mode 100644 drivers/bus/vmbus/osi/vmbus_osi_uio.c",
    "diff": "diff --git a/drivers/bus/vmbus/linux/vmbus_uio.c b/drivers/bus/vmbus/linux/vmbus_uio.c\nindex 5db70f8e0d..ea6df21409 100644\n--- a/drivers/bus/vmbus/linux/vmbus_uio.c\n+++ b/drivers/bus/vmbus/linux/vmbus_uio.c\n@@ -21,233 +21,18 @@\n #include <rte_string_fns.h>\n \n #include \"private.h\"\n+#include \"vmbus_osi.h\"\n \n /** Pathname of VMBUS devices directory. */\n #define SYSFS_VMBUS_DEVICES \"/sys/bus/vmbus/devices\"\n \n-static void *vmbus_map_addr;\n-\n-/* Control interrupts */\n-void vmbus_uio_irq_control(struct rte_vmbus_device *dev, int32_t onoff)\n-{\n-\tif ((rte_intr_fd_get(dev->intr_handle) < 0) ||\n-\t    write(rte_intr_fd_get(dev->intr_handle), &onoff,\n-\t\t  sizeof(onoff)) < 0) {\n-\t\tVMBUS_LOG(ERR, \"cannot write to %d:%s\",\n-\t\t\t  rte_intr_fd_get(dev->intr_handle),\n-\t\t\t  strerror(errno));\n-\t}\n-}\n-\n-int vmbus_uio_irq_read(struct rte_vmbus_device *dev)\n-{\n-\tint32_t count;\n-\tint cc;\n-\n-\tif (rte_intr_fd_get(dev->intr_handle) < 0)\n-\t\treturn -1;\n-\n-\tcc = read(rte_intr_fd_get(dev->intr_handle), &count,\n-\t\t  sizeof(count));\n-\tif (cc < (int)sizeof(count)) {\n-\t\tif (cc < 0) {\n-\t\t\tVMBUS_LOG(ERR, \"IRQ read failed %s\",\n-\t\t\t\t  strerror(errno));\n-\t\t\treturn -errno;\n-\t\t}\n-\t\tVMBUS_LOG(ERR, \"can't read IRQ count\");\n-\t\treturn -EINVAL;\n-\t}\n-\n-\treturn count;\n-}\n-\n-void\n-vmbus_uio_free_resource(struct rte_vmbus_device *dev,\n-\t\tstruct mapped_vmbus_resource *uio_res)\n-{\n-\trte_free(uio_res);\n-\n-\tif (rte_intr_dev_fd_get(dev->intr_handle) >= 0) {\n-\t\tclose(rte_intr_dev_fd_get(dev->intr_handle));\n-\t\trte_intr_dev_fd_set(dev->intr_handle, -1);\n-\t}\n-\n-\tif (rte_intr_fd_get(dev->intr_handle) >= 0) {\n-\t\tclose(rte_intr_fd_get(dev->intr_handle));\n-\t\trte_intr_fd_set(dev->intr_handle, -1);\n-\t\trte_intr_type_set(dev->intr_handle, RTE_INTR_HANDLE_UNKNOWN);\n-\t}\n-}\n-\n-int\n-vmbus_uio_alloc_resource(struct rte_vmbus_device *dev,\n-\t\t\t struct mapped_vmbus_resource **uio_res)\n-{\n-\tchar devname[PATH_MAX]; /* contains the /dev/uioX */\n-\tint fd;\n-\n-\t/* save fd if in primary process */\n-\tsnprintf(devname, sizeof(devname), \"/dev/uio%u\", dev->uio_num);\n-\tfd = open(devname, O_RDWR);\n-\tif (fd < 0) {\n-\t\tVMBUS_LOG(ERR, \"Cannot open %s: %s\",\n-\t\t\tdevname, strerror(errno));\n-\t\tgoto error;\n-\t}\n-\n-\tif (rte_intr_fd_set(dev->intr_handle, fd))\n-\t\tgoto error;\n-\n-\tif (rte_intr_type_set(dev->intr_handle, RTE_INTR_HANDLE_UIO_INTX))\n-\t\tgoto error;\n-\n-\t/* allocate the mapping details for secondary processes*/\n-\t*uio_res = rte_zmalloc(\"UIO_RES\", sizeof(**uio_res), 0);\n-\tif (*uio_res == NULL) {\n-\t\tVMBUS_LOG(ERR, \"cannot store uio mmap details\");\n-\t\tgoto error;\n-\t}\n-\n-\tstrlcpy((*uio_res)->path, devname, PATH_MAX);\n-\trte_uuid_copy((*uio_res)->id, dev->device_id);\n-\n-\treturn 0;\n-\n-error:\n-\tvmbus_uio_free_resource(dev, *uio_res);\n-\treturn -1;\n-}\n-\n-static int\n-find_max_end_va(const struct rte_memseg_list *msl, void *arg)\n-{\n-\tsize_t sz = msl->memseg_arr.len * msl->page_sz;\n-\tvoid *end_va = RTE_PTR_ADD(msl->base_va, sz);\n-\tvoid **max_va = arg;\n-\n-\tif (*max_va < end_va)\n-\t\t*max_va = end_va;\n-\treturn 0;\n-}\n-\n-/*\n- * TODO: this should be part of memseg api.\n- *       code is duplicated from PCI.\n- */\n-static void *\n-vmbus_find_max_end_va(void)\n-{\n-\tvoid *va = NULL;\n-\n-\trte_memseg_list_walk(find_max_end_va, &va);\n-\treturn va;\n-}\n-\n-int\n-vmbus_uio_map_resource_by_index(struct rte_vmbus_device *dev, int idx,\n-\t\t\t\tstruct mapped_vmbus_resource *uio_res,\n-\t\t\t\tint flags)\n-{\n-\tsize_t size = dev->resource[idx].len;\n-\tstruct vmbus_map *maps = uio_res->maps;\n-\tvoid *mapaddr;\n-\toff_t offset;\n-\tint fd;\n-\n-\t/* devname for mmap  */\n-\tfd = open(uio_res->path, O_RDWR);\n-\tif (fd < 0) {\n-\t\tVMBUS_LOG(ERR, \"Cannot open %s: %s\",\n-\t\t\t  uio_res->path, strerror(errno));\n-\t\treturn -1;\n-\t}\n-\n-\t/* try mapping somewhere close to the end of hugepages */\n-\tif (vmbus_map_addr == NULL)\n-\t\tvmbus_map_addr = vmbus_find_max_end_va();\n-\n-\t/* offset is special in uio it indicates which resource */\n-\toffset = idx * rte_mem_page_size();\n-\n-\tmapaddr = vmbus_map_resource(vmbus_map_addr, fd, offset, size, flags);\n-\tclose(fd);\n-\n-\tif (mapaddr == MAP_FAILED)\n-\t\treturn -1;\n-\n-\tdev->resource[idx].addr = mapaddr;\n-\tvmbus_map_addr = RTE_PTR_ADD(mapaddr, size);\n-\n-\t/* Record result of successful mapping for use by secondary */\n-\tmaps[idx].addr = mapaddr;\n-\tmaps[idx].size = size;\n-\n-\treturn 0;\n-}\n-\n-static int vmbus_uio_map_primary(struct vmbus_channel *chan,\n-\t\t\t\t void **ring_buf, uint32_t *ring_size)\n-{\n-\tstruct mapped_vmbus_resource *uio_res;\n-\n-\tuio_res = vmbus_uio_find_resource(chan->device);\n-\tif (!uio_res) {\n-\t\tVMBUS_LOG(ERR, \"can not find resources!\");\n-\t\treturn -ENOMEM;\n-\t}\n-\n-\tif (uio_res->nb_maps < VMBUS_MAX_RESOURCE) {\n-\t\tVMBUS_LOG(ERR, \"VMBUS: only %u resources found!\",\n-\t\t\t  uio_res->nb_maps);\n-\t\treturn -EINVAL;\n-\t}\n-\n-\t*ring_size = uio_res->maps[HV_TXRX_RING_MAP].size / 2;\n-\t*ring_buf  = uio_res->maps[HV_TXRX_RING_MAP].addr;\n-\treturn 0;\n-}\n-\n-static int vmbus_uio_map_subchan(const struct rte_vmbus_device *dev,\n-\t\t\t\t const struct vmbus_channel *chan,\n-\t\t\t\t void **ring_buf, uint32_t *ring_size)\n+int vmbus_uio_map_subchan_os(const struct rte_vmbus_device *dev,\n+\t\t\t     const struct vmbus_channel *chan,\n+\t\t\t     void **mapaddr, size_t *file_size)\n {\n \tchar ring_path[PATH_MAX];\n-\tsize_t file_size;\n \tstruct stat sb;\n-\tvoid *mapaddr;\n \tint fd;\n-\tstruct mapped_vmbus_resource *uio_res;\n-\tint channel_idx;\n-\n-\tuio_res = vmbus_uio_find_resource(dev);\n-\tif (!uio_res) {\n-\t\tVMBUS_LOG(ERR, \"can not find resources for mapping subchan\");\n-\t\treturn -ENOMEM;\n-\t}\n-\n-\tif (rte_eal_process_type() == RTE_PROC_PRIMARY) {\n-\t\tif (uio_res->nb_subchannels >= UIO_MAX_SUBCHANNEL) {\n-\t\t\tVMBUS_LOG(ERR,\n-\t\t\t\t\"exceeding max subchannels UIO_MAX_SUBCHANNEL(%d)\",\n-\t\t\t\tUIO_MAX_SUBCHANNEL);\n-\t\t\tVMBUS_LOG(ERR, \"Change UIO_MAX_SUBCHANNEL and recompile\");\n-\t\t\treturn -ENOMEM;\n-\t\t}\n-\t} else {\n-\t\tfor (channel_idx = 0; channel_idx < uio_res->nb_subchannels;\n-\t\t     channel_idx++)\n-\t\t\tif (uio_res->subchannel_maps[channel_idx].relid ==\n-\t\t\t\t\tchan->relid)\n-\t\t\t\tbreak;\n-\t\tif (channel_idx == uio_res->nb_subchannels) {\n-\t\t\tVMBUS_LOG(ERR,\n-\t\t\t\t\"couldn't find sub channel %d from shared mapping in primary\",\n-\t\t\t\tchan->relid);\n-\t\t\treturn -ENOMEM;\n-\t\t}\n-\t\tvmbus_map_addr = uio_res->subchannel_maps[channel_idx].addr;\n-\t}\n \n \tsnprintf(ring_path, sizeof(ring_path),\n \t\t \"%s/%s/channels/%u/ring\",\n@@ -267,68 +52,23 @@ static int vmbus_uio_map_subchan(const struct rte_vmbus_device *dev,\n \t\tclose(fd);\n \t\treturn -errno;\n \t}\n-\tfile_size = sb.st_size;\n+\t*file_size = sb.st_size;\n \n-\tif (file_size == 0 || (file_size & (rte_mem_page_size() - 1))) {\n+\tif (*file_size == 0 || (*file_size & (rte_mem_page_size() - 1))) {\n \t\tVMBUS_LOG(ERR, \"incorrect size %s: %zu\",\n-\t\t\t  ring_path, file_size);\n+\t\t\t  ring_path, *file_size);\n \n \t\tclose(fd);\n \t\treturn -EINVAL;\n \t}\n \n-\tmapaddr = vmbus_map_resource(vmbus_map_addr, fd,\n-\t\t\t\t     0, file_size, 0);\n+\t*mapaddr = vmbus_map_resource(vmbus_map_addr, fd,\n+\t\t\t\t     0, *file_size, 0);\n \tclose(fd);\n \n-\tif (mapaddr == MAP_FAILED)\n+\tif (*mapaddr == MAP_FAILED)\n \t\treturn -EIO;\n \n-\tif (rte_eal_process_type() == RTE_PROC_PRIMARY) {\n-\n-\t\t/* Add this mapping to uio_res for use by secondary */\n-\t\tuio_res->subchannel_maps[uio_res->nb_subchannels].relid =\n-\t\t\tchan->relid;\n-\t\tuio_res->subchannel_maps[uio_res->nb_subchannels].addr =\n-\t\t\tmapaddr;\n-\t\tuio_res->subchannel_maps[uio_res->nb_subchannels].size =\n-\t\t\tfile_size;\n-\t\tuio_res->nb_subchannels++;\n-\n-\t\tvmbus_map_addr = RTE_PTR_ADD(mapaddr, file_size);\n-\t} else {\n-\t\tif (mapaddr != vmbus_map_addr) {\n-\t\t\tVMBUS_LOG(ERR, \"failed to map channel %d to addr %p\",\n-\t\t\t\t\tchan->relid, mapaddr);\n-\t\t\tvmbus_unmap_resource(mapaddr, file_size);\n-\t\t\treturn -EIO;\n-\t\t}\n-\t}\n-\n-\t*ring_size = file_size / 2;\n-\t*ring_buf = mapaddr;\n-\n-\treturn 0;\n-}\n-\n-int vmbus_uio_map_rings(struct vmbus_channel *chan)\n-{\n-\tconst struct rte_vmbus_device *dev = chan->device;\n-\tuint32_t ring_size;\n-\tvoid *ring_buf;\n-\tint ret;\n-\n-\t/* Primary channel */\n-\tif (chan->subchannel_id == 0)\n-\t\tret = vmbus_uio_map_primary(chan, &ring_buf, &ring_size);\n-\telse\n-\t\tret = vmbus_uio_map_subchan(dev, chan, &ring_buf, &ring_size);\n-\n-\tif (ret)\n-\t\treturn ret;\n-\n-\tvmbus_br_setup(&chan->txbr, ring_buf, ring_size);\n-\tvmbus_br_setup(&chan->rxbr, (char *)ring_buf + ring_size, ring_size);\n \treturn 0;\n }\n \n@@ -377,18 +117,6 @@ bool vmbus_uio_subchannels_supported(const struct rte_vmbus_device *dev,\n \treturn vmbus_uio_ring_present(dev, chan->relid);\n }\n \n-static bool vmbus_isnew_subchannel(struct vmbus_channel *primary,\n-\t\t\t\t   unsigned long id)\n-{\n-\tconst struct vmbus_channel *c;\n-\n-\tSTAILQ_FOREACH(c, &primary->subchannel_list, next) {\n-\t\tif (c->relid == id)\n-\t\t\treturn false;\n-\t}\n-\treturn true;\n-}\n-\n int vmbus_uio_get_subchan(struct vmbus_channel *primary,\n \t\t\t  struct vmbus_channel **subchan)\n {\ndiff --git a/drivers/bus/vmbus/meson.build b/drivers/bus/vmbus/meson.build\nindex cbcba44e16..fe9c72bce1 100644\n--- a/drivers/bus/vmbus/meson.build\n+++ b/drivers/bus/vmbus/meson.build\n@@ -18,7 +18,8 @@ sources = files(\n \n includes += include_directories('osi')\n sources += files(\n-\t'osi/vmbus_osi_bus.c'\n+\t'osi/vmbus_osi_bus.c',\n+\t'osi/vmbus_osi_uio.c'\n )\n \n if is_linux\ndiff --git a/drivers/bus/vmbus/osi/vmbus_osi.h b/drivers/bus/vmbus/osi/vmbus_osi.h\nindex 2db9399181..579c4bb99c 100644\n--- a/drivers/bus/vmbus/osi/vmbus_osi.h\n+++ b/drivers/bus/vmbus/osi/vmbus_osi.h\n@@ -6,6 +6,18 @@\n #ifndef _VMBUS_BUS_OSI_H_\n #define _VMBUS_BUS_OSI_H_\n \n+#include <rte_bus_vmbus.h>\n+\n+#include \"private.h\"\n+\n extern const rte_uuid_t vmbus_nic_uuid;\n+extern void *vmbus_map_addr;\n+\n+int vmbus_uio_map_subchan_os(const struct rte_vmbus_device *dev,\n+\t\t\t     const struct vmbus_channel *chan,\n+\t\t\t     void **mapaddr, size_t *file_size);\n+\n+bool vmbus_isnew_subchannel(struct vmbus_channel *primary,\n+\t\t\t    unsigned long id);\n \n #endif /* _VMBUS_BUS_OSI_H_ */\ndiff --git a/drivers/bus/vmbus/osi/vmbus_osi_uio.c b/drivers/bus/vmbus/osi/vmbus_osi_uio.c\nnew file mode 100644\nindex 0000000000..35106e247e\n--- /dev/null\n+++ b/drivers/bus/vmbus/osi/vmbus_osi_uio.c\n@@ -0,0 +1,306 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright (c) 2018, Microsoft Corporation.\n+ * All Rights Reserved.\n+ */\n+\n+#include <unistd.h>\n+#include <fcntl.h>\n+#include <sys/mman.h>\n+\n+#include <rte_eal.h>\n+#include <rte_log.h>\n+#include <rte_bus.h>\n+#include <rte_memory.h>\n+#include <rte_common.h>\n+#include <rte_malloc.h>\n+#include <rte_bus_vmbus.h>\n+#include <rte_string_fns.h>\n+\n+#include \"private.h\"\n+#include \"vmbus_osi.h\"\n+\n+void *vmbus_map_addr;\n+\n+/* Control interrupts */\n+void vmbus_uio_irq_control(struct rte_vmbus_device *dev, int32_t onoff)\n+{\n+\tif ((rte_intr_fd_get(dev->intr_handle) < 0) ||\n+\t    write(rte_intr_fd_get(dev->intr_handle), &onoff,\n+\t\t  sizeof(onoff)) < 0) {\n+\t\tVMBUS_LOG(ERR, \"cannot write to %d:%s\",\n+\t\t\t  rte_intr_fd_get(dev->intr_handle),\n+\t\t\t  strerror(errno));\n+\t}\n+}\n+\n+int vmbus_uio_irq_read(struct rte_vmbus_device *dev)\n+{\n+\tint32_t count;\n+\tint cc;\n+\n+\tif (rte_intr_fd_get(dev->intr_handle) < 0)\n+\t\treturn -1;\n+\n+\tcc = read(rte_intr_fd_get(dev->intr_handle), &count,\n+\t\t  sizeof(count));\n+\tif (cc < (int)sizeof(count)) {\n+\t\tif (cc < 0) {\n+\t\t\tVMBUS_LOG(ERR, \"IRQ read failed %s\",\n+\t\t\t\t  strerror(errno));\n+\t\t\treturn -errno;\n+\t\t}\n+\t\tVMBUS_LOG(ERR, \"can't read IRQ count\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\treturn count;\n+}\n+\n+void\n+vmbus_uio_free_resource(struct rte_vmbus_device *dev,\n+\t\tstruct mapped_vmbus_resource *uio_res)\n+{\n+\trte_free(uio_res);\n+\n+\tif (rte_intr_dev_fd_get(dev->intr_handle) >= 0) {\n+\t\tclose(rte_intr_dev_fd_get(dev->intr_handle));\n+\t\trte_intr_dev_fd_set(dev->intr_handle, -1);\n+\t}\n+\n+\tif (rte_intr_fd_get(dev->intr_handle) >= 0) {\n+\t\tclose(rte_intr_fd_get(dev->intr_handle));\n+\t\trte_intr_fd_set(dev->intr_handle, -1);\n+\t\trte_intr_type_set(dev->intr_handle, RTE_INTR_HANDLE_UNKNOWN);\n+\t}\n+}\n+\n+int\n+vmbus_uio_alloc_resource(struct rte_vmbus_device *dev,\n+\t\t\t struct mapped_vmbus_resource **uio_res)\n+{\n+\tchar devname[PATH_MAX]; /* contains the /dev/uioX */\n+\tint fd;\n+\n+\t/* save fd if in primary process */\n+\tsnprintf(devname, sizeof(devname), \"/dev/uio%u\", dev->uio_num);\n+\tfd = open(devname, O_RDWR);\n+\tif (fd < 0) {\n+\t\tVMBUS_LOG(ERR, \"Cannot open %s: %s\",\n+\t\t\tdevname, strerror(errno));\n+\t\tgoto error;\n+\t}\n+\n+\tif (rte_intr_fd_set(dev->intr_handle, fd))\n+\t\tgoto error;\n+\n+\tif (rte_intr_type_set(dev->intr_handle, RTE_INTR_HANDLE_UIO_INTX))\n+\t\tgoto error;\n+\n+\t/* allocate the mapping details for secondary processes*/\n+\t*uio_res = rte_zmalloc(\"UIO_RES\", sizeof(**uio_res), 0);\n+\tif (*uio_res == NULL) {\n+\t\tVMBUS_LOG(ERR, \"cannot store uio mmap details\");\n+\t\tgoto error;\n+\t}\n+\n+\tstrlcpy((*uio_res)->path, devname, PATH_MAX);\n+\trte_uuid_copy((*uio_res)->id, dev->device_id);\n+\n+\treturn 0;\n+\n+error:\n+\tvmbus_uio_free_resource(dev, *uio_res);\n+\treturn -1;\n+}\n+\n+static int\n+find_max_end_va(const struct rte_memseg_list *msl, void *arg)\n+{\n+\tsize_t sz = msl->memseg_arr.len * msl->page_sz;\n+\tvoid *end_va = RTE_PTR_ADD(msl->base_va, sz);\n+\tvoid **max_va = arg;\n+\n+\tif (*max_va < end_va)\n+\t\t*max_va = end_va;\n+\treturn 0;\n+}\n+\n+/*\n+ * TODO: this should be part of memseg api.\n+ *       code is duplicated from PCI.\n+ */\n+static void *\n+vmbus_find_max_end_va(void)\n+{\n+\tvoid *va = NULL;\n+\n+\trte_memseg_list_walk(find_max_end_va, &va);\n+\treturn va;\n+}\n+\n+int\n+vmbus_uio_map_resource_by_index(struct rte_vmbus_device *dev, int idx,\n+\t\t\t\tstruct mapped_vmbus_resource *uio_res,\n+\t\t\t\tint flags)\n+{\n+\tsize_t size = dev->resource[idx].len;\n+\tstruct vmbus_map *maps = uio_res->maps;\n+\tvoid *mapaddr;\n+\toff_t offset;\n+\tint fd;\n+\n+\t/* devname for mmap  */\n+\tfd = open(uio_res->path, O_RDWR);\n+\tif (fd < 0) {\n+\t\tVMBUS_LOG(ERR, \"Cannot open %s: %s\",\n+\t\t\t  uio_res->path, strerror(errno));\n+\t\treturn -1;\n+\t}\n+\n+\t/* try mapping somewhere close to the end of hugepages */\n+\tif (vmbus_map_addr == NULL)\n+\t\tvmbus_map_addr = vmbus_find_max_end_va();\n+\n+\t/* offset is special in uio it indicates which resource */\n+\toffset = idx * rte_mem_page_size();\n+\n+\tmapaddr = vmbus_map_resource(vmbus_map_addr, fd, offset, size, flags);\n+\tclose(fd);\n+\n+\tif (mapaddr == MAP_FAILED)\n+\t\treturn -1;\n+\n+\tdev->resource[idx].addr = mapaddr;\n+\tvmbus_map_addr = RTE_PTR_ADD(mapaddr, size);\n+\n+\t/* Record result of successful mapping for use by secondary */\n+\tmaps[idx].addr = mapaddr;\n+\tmaps[idx].size = size;\n+\n+\treturn 0;\n+}\n+\n+static int vmbus_uio_map_primary(struct vmbus_channel *chan,\n+\t\t\t\t void **ring_buf, uint32_t *ring_size)\n+{\n+\tstruct mapped_vmbus_resource *uio_res;\n+\n+\tuio_res = vmbus_uio_find_resource(chan->device);\n+\tif (!uio_res) {\n+\t\tVMBUS_LOG(ERR, \"can not find resources!\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tif (uio_res->nb_maps < VMBUS_MAX_RESOURCE) {\n+\t\tVMBUS_LOG(ERR, \"VMBUS: only %u resources found!\",\n+\t\t\t  uio_res->nb_maps);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t*ring_size = uio_res->maps[HV_TXRX_RING_MAP].size / 2;\n+\t*ring_buf  = uio_res->maps[HV_TXRX_RING_MAP].addr;\n+\treturn 0;\n+}\n+\n+static int vmbus_uio_map_subchan(const struct rte_vmbus_device *dev,\n+\t\t\t\t const struct vmbus_channel *chan,\n+\t\t\t\t void **ring_buf, uint32_t *ring_size)\n+{\n+\tsize_t file_size = 0;\n+\tvoid *mapaddr = NULL;\n+\tstruct mapped_vmbus_resource *uio_res;\n+\tint channel_idx;\n+\tint ret;\n+\n+\tuio_res = vmbus_uio_find_resource(dev);\n+\tif (!uio_res) {\n+\t\tVMBUS_LOG(ERR, \"can not find resources for mapping subchan\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tif (rte_eal_process_type() == RTE_PROC_PRIMARY) {\n+\t\tif (uio_res->nb_subchannels >= UIO_MAX_SUBCHANNEL) {\n+\t\t\tVMBUS_LOG(ERR,\n+\t\t\t\t\"exceeding max subchannels UIO_MAX_SUBCHANNEL(%d)\",\n+\t\t\t\tUIO_MAX_SUBCHANNEL);\n+\t\t\tVMBUS_LOG(ERR, \"Change UIO_MAX_SUBCHANNEL and recompile\");\n+\t\t\treturn -ENOMEM;\n+\t\t}\n+\t} else {\n+\t\tfor (channel_idx = 0; channel_idx < uio_res->nb_subchannels;\n+\t\t     channel_idx++)\n+\t\t\tif (uio_res->subchannel_maps[channel_idx].relid ==\n+\t\t\t\t\tchan->relid)\n+\t\t\t\tbreak;\n+\t\tif (channel_idx == uio_res->nb_subchannels) {\n+\t\t\tVMBUS_LOG(ERR,\n+\t\t\t\t\"couldn't find sub channel %d from shared mapping in primary\",\n+\t\t\t\tchan->relid);\n+\t\t\treturn -ENOMEM;\n+\t\t}\n+\t\tvmbus_map_addr = uio_res->subchannel_maps[channel_idx].addr;\n+\t}\n+\n+\tret = vmbus_uio_map_subchan_os(dev, chan, &mapaddr, &file_size);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tif (rte_eal_process_type() == RTE_PROC_PRIMARY) {\n+\n+\t\t/* Add this mapping to uio_res for use by secondary */\n+\t\tuio_res->subchannel_maps[uio_res->nb_subchannels].relid =\n+\t\t\tchan->relid;\n+\t\tuio_res->subchannel_maps[uio_res->nb_subchannels].addr =\n+\t\t\tmapaddr;\n+\t\tuio_res->subchannel_maps[uio_res->nb_subchannels].size =\n+\t\t\tfile_size;\n+\t\tuio_res->nb_subchannels++;\n+\n+\t\tvmbus_map_addr = RTE_PTR_ADD(mapaddr, file_size);\n+\t} else {\n+\t\tif (mapaddr != vmbus_map_addr) {\n+\t\t\tVMBUS_LOG(ERR, \"failed to map channel %d to addr %p\",\n+\t\t\t\t\tchan->relid, mapaddr);\n+\t\t\tvmbus_unmap_resource(mapaddr, file_size);\n+\t\t\treturn -EIO;\n+\t\t}\n+\t}\n+\n+\t*ring_size = file_size / 2;\n+\t*ring_buf = mapaddr;\n+\n+\treturn 0;\n+}\n+\n+int vmbus_uio_map_rings(struct vmbus_channel *chan)\n+{\n+\tconst struct rte_vmbus_device *dev = chan->device;\n+\tuint32_t ring_size = 0;\n+\tvoid *ring_buf = NULL;\n+\tint ret;\n+\n+\t/* Primary channel */\n+\tif (chan->subchannel_id == 0)\n+\t\tret = vmbus_uio_map_primary(chan, &ring_buf, &ring_size);\n+\telse\n+\t\tret = vmbus_uio_map_subchan(dev, chan, &ring_buf, &ring_size);\n+\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tvmbus_br_setup(&chan->txbr, ring_buf, ring_size);\n+\tvmbus_br_setup(&chan->rxbr, (char *)ring_buf + ring_size, ring_size);\n+\treturn 0;\n+}\n+\n+bool vmbus_isnew_subchannel(struct vmbus_channel *primary,\n+\t\t\t    unsigned long id)\n+{\n+\tconst struct vmbus_channel *c;\n+\n+\tSTAILQ_FOREACH(c, &primary->subchannel_list, next) {\n+\t\tif (c->relid == id)\n+\t\t\treturn false;\n+\t}\n+\treturn true;\n+}\n",
    "prefixes": [
        "v4",
        "03/14"
    ]
}