get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 72099,
    "url": "http://patches.dpdk.org/api/patches/72099/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20200624082847.21344-10-talshn@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": "<20200624082847.21344-10-talshn@mellanox.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20200624082847.21344-10-talshn@mellanox.com",
    "date": "2020-06-24T08:28:46",
    "name": "[v9,09/10] bus/pci: support Windows with bifurcated drivers",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "62f5c3b049187b647016517217fc9b88bb3ffab6",
    "submitter": {
        "id": 1669,
        "url": "http://patches.dpdk.org/api/people/1669/?format=api",
        "name": "Tal Shnaiderman",
        "email": "talshn@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/20200624082847.21344-10-talshn@mellanox.com/mbox/",
    "series": [
        {
            "id": 10579,
            "url": "http://patches.dpdk.org/api/series/10579/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=10579",
            "date": "2020-06-24T08:28:37",
            "name": "Windows bus/pci support",
            "version": 9,
            "mbox": "http://patches.dpdk.org/series/10579/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/72099/comments/",
    "check": "fail",
    "checks": "http://patches.dpdk.org/api/patches/72099/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 67958A0350;\n\tWed, 24 Jun 2020 10:30:10 +0200 (CEST)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 35FC51D922;\n\tWed, 24 Jun 2020 10:30:10 +0200 (CEST)",
            "from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129])\n by dpdk.org (Postfix) with ESMTP id B24CB1D920\n for <dev@dpdk.org>; Wed, 24 Jun 2020 10:30:08 +0200 (CEST)",
            "from Internal Mail-Server by MTLPINE1 (envelope-from\n talshn@mellanox.com) with SMTP; 24 Jun 2020 11:30:04 +0300",
            "from l-wincomp04-vm.labs.mlnx (l-wincomp04-vm.mtl.labs.mlnx\n [10.237.1.5])\n by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 05O8TGKP012156;\n Wed, 24 Jun 2020 11:29:18 +0300"
        ],
        "From": "talshn@mellanox.com",
        "To": "dev@dpdk.org",
        "Cc": "thomas@monjalon.net, pallavi.kadam@intel.com, dmitry.kozliuk@gmail.com,\n david.marchand@redhat.com, grive@u256.net, ranjit.menon@intel.com,\n navasile@linux.microsoft.com, harini.ramakrishnan@microsoft.com,\n ocardona@microsoft.com, anatoly.burakov@intel.com, fady@mellanox.com,\n bruce.richardson@intel.com, Tal Shnaiderman <talshn@mellanox.com>",
        "Date": "Wed, 24 Jun 2020 11:28:46 +0300",
        "Message-Id": "<20200624082847.21344-10-talshn@mellanox.com>",
        "X-Mailer": "git-send-email 2.16.1.windows.4",
        "In-Reply-To": "<20200624082847.21344-1-talshn@mellanox.com>",
        "References": "<20200622075529.24180-2-talshn@mellanox.com>\n <20200624082847.21344-1-talshn@mellanox.com>",
        "Subject": "[dpdk-dev] [PATCH v9 09/10] bus/pci: support Windows with\n\tbifurcated drivers",
        "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": "From: Tal Shnaiderman <talshn@mellanox.com>\n\nUses SetupAPI.h functions to scan PCI tree.\nUses DEVPKEY_Device_Numa_Node to get the PCI NUMA node.\nUses SPDRP_BUSNUMBER and SPDRP_BUSNUMBER to get the BDF.\nscanning currently supports types RTE_KDRV_NONE.\n\nSigned-off-by: Tal Shnaiderman <talshn@mellanox.com>\n---\n drivers/bus/pci/windows/pci.c                | 263 ++++++++++++++++++++++++++-\n lib/librte_eal/rte_eal_exports.def           |   1 +\n lib/librte_eal/windows/include/rte_windows.h |   1 +\n 3 files changed, 261 insertions(+), 4 deletions(-)",
    "diff": "diff --git a/drivers/bus/pci/windows/pci.c b/drivers/bus/pci/windows/pci.c\nindex b1d34ae11c..489aa7902a 100644\n--- a/drivers/bus/pci/windows/pci.c\n+++ b/drivers/bus/pci/windows/pci.c\n@@ -1,14 +1,27 @@\n /* SPDX-License-Identifier: BSD-3-Clause\n  * Copyright 2020 Mellanox Technologies, Ltd\n  */\n+#include <rte_windows.h>\n #include <rte_errno.h>\n #include <rte_log.h>\n-\n-#include <rte_string_fns.h>\n #include <rte_eal_memconfig.h>\n+#include <rte_eal.h>\n \n #include \"private.h\"\n \n+#include <devpkey.h>\n+\n+#ifdef RTE_TOOLCHAIN_GCC\n+#include <devpropdef.h>\n+DEFINE_DEVPROPKEY(DEVPKEY_Device_Numa_Node, 0x540b947e, 0x8b40, 0x45bc,\n+\t0xa8, 0xa2, 0x6a, 0x0b, 0x89, 0x4c, 0xbd, 0xa2, 3);\n+#endif\n+\n+/*\n+ * This code is used to simulate a PCI probe by parsing information in\n+ * the registry hive for PCI devices.\n+ */\n+\n /* The functions below are not implemented on Windows,\n  * but need to be defined for compilation purposes\n  */\n@@ -146,7 +159,6 @@ rte_pci_ioport_write(struct rte_pci_ioport *p __rte_unused,\n \t */\n }\n \n-\n /* remap the PCI resource of a PCI device in anonymous virtual memory */\n int\n pci_uio_remap_resource(struct rte_pci_device *dev __rte_unused)\n@@ -158,6 +170,210 @@ pci_uio_remap_resource(struct rte_pci_device *dev __rte_unused)\n \t */\n \treturn -1;\n }\n+\n+static int\n+get_device_pci_address(HDEVINFO dev_info,\n+\tPSP_DEVINFO_DATA device_info_data, struct rte_pci_addr *addr)\n+{\n+\tBOOL  res;\n+\tULONG bus_num, dev_and_func;\n+\n+\tres = SetupDiGetDeviceRegistryProperty(dev_info, device_info_data,\n+\t\tSPDRP_BUSNUMBER, NULL, (PBYTE)&bus_num, sizeof(bus_num), NULL);\n+\tif (!res) {\n+\t\tRTE_LOG_WIN32_ERR(\n+\t\t\t\"SetupDiGetDeviceRegistryProperty(SPDRP_BUSNUMBER)\");\n+\t\treturn -1;\n+\t}\n+\n+\tres = SetupDiGetDeviceRegistryProperty(dev_info, device_info_data,\n+\t\tSPDRP_ADDRESS, NULL, (PBYTE)&dev_and_func, sizeof(dev_and_func),\n+\t\tNULL);\n+\tif (!res) {\n+\t\tRTE_LOG_WIN32_ERR(\n+\t\t\t\"SetupDiGetDeviceRegistryProperty(SPDRP_ADDRESS)\");\n+\t\treturn -1;\n+\t}\n+\n+\taddr->domain = 0;\n+\taddr->bus = bus_num;\n+\taddr->devid = dev_and_func >> 16;\n+\taddr->function = dev_and_func & 0xffff;\n+\treturn 0;\n+}\n+\n+static int\n+get_device_resource_info(HDEVINFO dev_info,\n+\tPSP_DEVINFO_DATA dev_info_data, struct rte_pci_device *dev)\n+{\n+\tDEVPROPTYPE property_type;\n+\tDWORD numa_node;\n+\tBOOL  res;\n+\n+\tswitch (dev->kdrv) {\n+\tcase RTE_KDRV_NONE:\n+\t\t/* Get NUMA node using DEVPKEY_Device_Numa_Node */\n+\t\tres = SetupDiGetDevicePropertyW(dev_info, dev_info_data,\n+\t\t\t&DEVPKEY_Device_Numa_Node, &property_type,\n+\t\t\t(BYTE *)&numa_node, sizeof(numa_node), NULL, 0);\n+\t\tif (!res) {\n+\t\t\tRTE_LOG_WIN32_ERR(\n+\t\t\t\t\"SetupDiGetDevicePropertyW\"\n+\t\t\t\t\"(DEVPKEY_Device_Numa_Node)\");\n+\t\t\treturn -1;\n+\t\t}\n+\t\tdev->device.numa_node = numa_node;\n+\t\t/* mem_resource - Unneeded for RTE_KDRV_NONE */\n+\t\tdev->mem_resource[0].phys_addr = 0;\n+\t\tdev->mem_resource[0].len = 0;\n+\t\tdev->mem_resource[0].addr = NULL;\n+\t\tbreak;\n+\tdefault:\n+\t\t/* kernel driver type is unsupported */\n+\t\tRTE_LOG(DEBUG, EAL,\n+\t\t\t\"Kernel driver type for PCI device \" PCI_PRI_FMT \",\"\n+\t\t\t\" is unsupported\",\n+\t\t\tdev->addr.domain, dev->addr.bus,\n+\t\t\tdev->addr.devid, dev->addr.function);\n+\t\treturn -1;\n+\t}\n+\n+\treturn ERROR_SUCCESS;\n+}\n+\n+/*\n+ * get string that contains the list of hardware IDs for a device\n+ */\n+static int\n+get_pci_hardware_id(HDEVINFO dev_info, PSP_DEVINFO_DATA device_info_data,\n+\tchar *pci_device_info, size_t pci_device_info_len)\n+{\n+\tBOOL  res;\n+\n+\t/* Retrieve PCI device IDs */\n+\tres = SetupDiGetDeviceRegistryPropertyA(dev_info, device_info_data,\n+\t\t\tSPDRP_HARDWAREID, NULL, (BYTE *)pci_device_info,\n+\t\t\tpci_device_info_len, NULL);\n+\tif (!res) {\n+\t\tRTE_LOG_WIN32_ERR(\n+\t\t\t\"SetupDiGetDeviceRegistryPropertyA(SPDRP_HARDWAREID)\");\n+\t\treturn -1;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+/*\n+ * parse the SPDRP_HARDWAREID output and assign to rte_pci_id\n+ */\n+static int\n+parse_pci_hardware_id(const char *buf, struct rte_pci_id *pci_id)\n+{\n+\tint ids = 0;\n+\tuint16_t vendor_id, device_id, subvendor_id = 0;\n+\n+\tids = sscanf_s(buf, \"PCI\\\\VEN_%x&DEV_%x&SUBSYS_%x\", &vendor_id,\n+\t\t&device_id, &subvendor_id);\n+\tif (ids != 3)\n+\t\treturn -1;\n+\n+\tpci_id->vendor_id = vendor_id;\n+\tpci_id->device_id = device_id;\n+\tpci_id->subsystem_vendor_id = subvendor_id >> 16;\n+\tpci_id->subsystem_device_id = subvendor_id & 0xffff;\n+\treturn 0;\n+}\n+\n+static void\n+get_kernel_driver_type(struct rte_pci_device *dev)\n+{\n+\t/*\n+\t * If another kernel driver is supported the relevant checking\n+\t * functions should be here\n+\t */\n+\tdev->kdrv = RTE_KDRV_NONE;\n+}\n+\n+static int\n+pci_scan_one(HDEVINFO dev_info, PSP_DEVINFO_DATA device_info_data)\n+{\n+\tstruct rte_pci_device *dev;\n+\tint ret = -1;\n+\tchar  pci_device_info[PATH_MAX];\n+\tstruct rte_pci_addr addr;\n+\tstruct rte_pci_id pci_id;\n+\n+\tdev = malloc(sizeof(*dev));\n+\tif (dev == NULL)\n+\t\tgoto end;\n+\n+\tmemset(dev, 0, sizeof(*dev));\n+\n+\tret = get_pci_hardware_id(dev_info, device_info_data,\n+\t\tpci_device_info, PATH_MAX);\n+\tif (ret != 0)\n+\t\tgoto end;\n+\n+\tret = parse_pci_hardware_id((const char *)&pci_device_info, &pci_id);\n+\tif (ret != 0) {\n+\t\t/*\n+\t\t * We won't add this device, but we want to continue\n+\t\t * looking for supported devices\n+\t\t */\n+\t\tret = ERROR_CONTINUE;\n+\t\tgoto end;\n+\t}\n+\n+\tret = get_device_pci_address(dev_info, device_info_data, &addr);\n+\tif (ret != 0)\n+\t\tgoto end;\n+\n+\tdev->addr = addr;\n+\tdev->id = pci_id;\n+\tdev->max_vfs = 0; /* TODO: get max_vfs */\n+\n+\tpci_name_set(dev);\n+\n+\tget_kernel_driver_type(dev);\n+\n+\t/* get resources */\n+\tif (get_device_resource_info(dev_info, device_info_data, dev)\n+\t\t\t!= ERROR_SUCCESS) {\n+\t\tgoto end;\n+\t}\n+\n+\t/* device is valid, add in list (sorted) */\n+\tif (TAILQ_EMPTY(&rte_pci_bus.device_list)) {\n+\t\trte_pci_add_device(dev);\n+\t} else {\n+\t\tstruct rte_pci_device *dev2 = NULL;\n+\t\tint ret;\n+\n+\t\tTAILQ_FOREACH(dev2, &rte_pci_bus.device_list, next) {\n+\t\t\tret = rte_pci_addr_cmp(&dev->addr, &dev2->addr);\n+\t\t\tif (ret > 0) {\n+\t\t\t\tcontinue;\n+\t\t\t} else if (ret < 0) {\n+\t\t\t\trte_pci_insert_device(dev2, dev);\n+\t\t\t} else { /* already registered */\n+\t\t\t\tdev2->kdrv = dev->kdrv;\n+\t\t\t\tdev2->max_vfs = dev->max_vfs;\n+\t\t\t\tmemmove(dev2->mem_resource, dev->mem_resource,\n+\t\t\t\t\tsizeof(dev->mem_resource));\n+\t\t\t\tfree(dev);\n+\t\t\t}\n+\t\t\treturn 0;\n+\t\t}\n+\t\trte_pci_add_device(dev);\n+\t}\n+\n+\treturn 0;\n+end:\n+\tif (dev)\n+\t\tfree(dev);\n+\treturn ret;\n+}\n+\n /*\n  * Scan the contents of the PCI bus\n  * and add all network class devices into the devices list.\n@@ -165,5 +381,44 @@ pci_uio_remap_resource(struct rte_pci_device *dev __rte_unused)\n int\n rte_pci_scan(void)\n {\n-\treturn 0;\n+\tint   ret = -1;\n+\tDWORD device_index = 0, found_device = 0;\n+\tHDEVINFO dev_info;\n+\tSP_DEVINFO_DATA device_info_data;\n+\n+\t/* for debug purposes, PCI can be disabled */\n+\tif (!rte_eal_has_pci())\n+\t\treturn 0;\n+\n+\tdev_info = SetupDiGetClassDevs(&GUID_DEVCLASS_NET, TEXT(\"PCI\"), NULL,\n+\t\t\t\tDIGCF_PRESENT);\n+\tif (dev_info == INVALID_HANDLE_VALUE) {\n+\t\tRTE_LOG_WIN32_ERR(\"SetupDiGetClassDevs(pci_scan)\");\n+\t\tRTE_LOG(ERR, EAL, \"Unable to enumerate PCI devices.\\n\");\n+\t\tgoto end;\n+\t}\n+\n+\tdevice_info_data.cbSize = sizeof(SP_DEVINFO_DATA);\n+\tdevice_index = 0;\n+\n+\twhile (SetupDiEnumDeviceInfo(dev_info, device_index,\n+\t    &device_info_data)) {\n+\t\tdevice_index++;\n+\t\tret = pci_scan_one(dev_info, &device_info_data);\n+\t\tif (ret == ERROR_SUCCESS)\n+\t\t\tfound_device++;\n+\t\telse if (ret != ERROR_CONTINUE)\n+\t\t\tgoto end;\n+\n+\t\tmemset(&device_info_data, 0, sizeof(SP_DEVINFO_DATA));\n+\t\tdevice_info_data.cbSize = sizeof(SP_DEVINFO_DATA);\n+\t}\n+\n+\tRTE_LOG(DEBUG, EAL, \"PCI scan found %lu devices\\n\", found_device);\n+\tret = 0;\n+end:\n+\tif (dev_info != INVALID_HANDLE_VALUE)\n+\t\tSetupDiDestroyDeviceInfoList(dev_info);\n+\n+\treturn ret;\n }\ndiff --git a/lib/librte_eal/rte_eal_exports.def b/lib/librte_eal/rte_eal_exports.def\nindex 919a92fba9..374e654264 100644\n--- a/lib/librte_eal/rte_eal_exports.def\n+++ b/lib/librte_eal/rte_eal_exports.def\n@@ -9,6 +9,7 @@ EXPORTS\n \trte_devargs_remove\n \trte_eal_get_configuration\n \trte_eal_has_hugepages\n+\trte_eal_has_pci\n \trte_eal_init\n \trte_eal_iova_mode\n \trte_eal_mp_remote_launch\ndiff --git a/lib/librte_eal/windows/include/rte_windows.h b/lib/librte_eal/windows/include/rte_windows.h\nindex 899ed7d874..725ac4f9b2 100644\n--- a/lib/librte_eal/windows/include/rte_windows.h\n+++ b/lib/librte_eal/windows/include/rte_windows.h\n@@ -25,6 +25,7 @@\n #include <psapi.h>\n #include <setupapi.h>\n #include <winioctl.h>\n+#include <devguid.h>\n \n /* Have GUIDs defined. */\n #ifndef INITGUID\n",
    "prefixes": [
        "v9",
        "09/10"
    ]
}