get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 12138,
    "url": "http://patches.dpdk.org/api/patches/12138/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1461152657-19969-17-git-send-email-david.marchand@6wind.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": "<1461152657-19969-17-git-send-email-david.marchand@6wind.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1461152657-19969-17-git-send-email-david.marchand@6wind.com",
    "date": "2016-04-20T11:44:16",
    "name": "[dpdk-dev,v2,16/17] ethdev: convert to eal hotplug",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "2b415084dbb48b17577ffb2960be4e17dafeaa65",
    "submitter": {
        "id": 3,
        "url": "http://patches.dpdk.org/api/people/3/?format=api",
        "name": "David Marchand",
        "email": "david.marchand@6wind.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/1461152657-19969-17-git-send-email-david.marchand@6wind.com/mbox/",
    "series": [],
    "comments": "http://patches.dpdk.org/api/patches/12138/comments/",
    "check": "pending",
    "checks": "http://patches.dpdk.org/api/patches/12138/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [IPv6:::1])\n\tby dpdk.org (Postfix) with ESMTP id 5A2DF594E;\n\tWed, 20 Apr 2016 13:44:45 +0200 (CEST)",
            "from mail-wm0-f51.google.com (mail-wm0-f51.google.com\n\t[74.125.82.51]) by dpdk.org (Postfix) with ESMTP id 56715569F\n\tfor <dev@dpdk.org>; Wed, 20 Apr 2016 13:44:39 +0200 (CEST)",
            "by mail-wm0-f51.google.com with SMTP id v188so199771904wme.1\n\tfor <dev@dpdk.org>; Wed, 20 Apr 2016 04:44:39 -0700 (PDT)",
            "from gloops.dev.6wind.com (144.77.126.78.rev.sfr.net.\n\t[78.126.77.144]) by smtp.gmail.com with ESMTPSA id\n\tm6sm5195708wje.21.2016.04.20.04.44.38\n\t(version=TLSv1/SSLv3 cipher=OTHER);\n\tWed, 20 Apr 2016 04:44:38 -0700 (PDT)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=6wind-com.20150623.gappssmtp.com; s=20150623;\n\th=from:to:cc:subject:date:message-id:in-reply-to:references;\n\tbh=MT+J/WBUxWa+r8wSPkqGHOaMn5ErXKzoxsi+CE2fSq8=;\n\tb=DtqnHGvtEs2qIdl9W3AdwYnFy3+P5iReOi+jlNdpd1FO2OjAUvI7Gdjc0noaGPIcwt\n\taOL/PSDhWsiYjJ7lbDrv5NY8RtntzUIdx6MmhZASWZVy9AD9azU03SDO6kbn03TnSVmQ\n\ta6sDqiKvH6MEW6Gg5khfjcPqpFfj/78yvqY/G5swvXzCwdAF/EhfidVaASxeMYcUaRDk\n\tMW2v/7LernND+fHmOPA3WNuENY7PAk8KwyH9XL0MJpQPSlKVCCZKpeGIGESuEjNGSHgU\n\t4waNryRd3wR5iqa5MJrrlOjLTJPul5VgPomHIAFWkEqw9z9gd4KHE6kwSKi38+eQlUpp\n\td6cw==",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20130820;\n\th=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to\n\t:references;\n\tbh=MT+J/WBUxWa+r8wSPkqGHOaMn5ErXKzoxsi+CE2fSq8=;\n\tb=UTfNuHeuHu/OTfP6ggDTAa+BY6dZBNdyK7kUPIU3TuO9DackwQVXx6zpHeakLeL5s0\n\tUUusTQ7C4ZPjrWPWg0RZ6BIwt3BFun9PGhw9paTtIZzl7naNtTE5jc8HH7l1BXbq/uQx\n\tdxMlcvuM97meWvZXBPuM4SBMLRlj/y2Kys9pkvkqe6kYp6iSbgG2TN1wKOhJXE2M4el0\n\tnNjHtP7s1Z5Mumd4fnt4Nqg9cV4w5Z+laE97NkQ+SynFG/w/04TvrM1tooDwL6OvyCfr\n\tH3m5BPuGLI6ARw7+ztE+GUe2SZvEP9ALdxCmq7Po/t3CWPeB2LMaDhWKwXkZVKaJdHOu\n\twTpA==",
        "X-Gm-Message-State": "AOPr4FWY46Oyzr2Rm8JbI2zvhFivphdWObcQnHzCxApsoj1svoeFNm/agMb7HhAmFiOuQ6G+",
        "X-Received": "by 10.194.114.228 with SMTP id jj4mr8334769wjb.121.1461152679159;\n\tWed, 20 Apr 2016 04:44:39 -0700 (PDT)",
        "From": "David Marchand <david.marchand@6wind.com>",
        "To": "dev@dpdk.org",
        "Cc": "thomas.monjalon@6wind.com,\n\tviktorin@rehivetech.com",
        "Date": "Wed, 20 Apr 2016 13:44:16 +0200",
        "Message-Id": "<1461152657-19969-17-git-send-email-david.marchand@6wind.com>",
        "X-Mailer": "git-send-email 1.9.1",
        "In-Reply-To": "<1461152657-19969-1-git-send-email-david.marchand@6wind.com>",
        "References": "<1454076516-21591-1-git-send-email-david.marchand@6wind.com>\n\t<1461152657-19969-1-git-send-email-david.marchand@6wind.com>",
        "Subject": "[dpdk-dev] [PATCH v2 16/17] ethdev: convert to eal hotplug",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "patches and discussions about DPDK <dev.dpdk.org>",
        "List-Unsubscribe": "<http://dpdk.org/ml/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://dpdk.org/ml/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<http://dpdk.org/ml/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "Remove bus logic from ethdev hotplug by using eal for this.\n\nCurrent api is preserved:\n- the last port that has been created is tracked to return it to the\n  application when attaching,\n- the internal device name is reused when detaching.\n\nWe can not get rid of ethdev hotplug yet since we still need some mechanism\nto inform applications of port creation/removal to substitute for ethdev\nhotplug api.\n\ndev_type field in struct rte_eth_dev and rte_eth_dev_allocate are kept as\nis, but this information is not needed anymore and is removed in the following\ncommit.\n\nSigned-off-by: David Marchand <david.marchand@6wind.com>\n---\n lib/librte_ether/rte_ethdev.c | 252 ++++++------------------------------------\n 1 file changed, 33 insertions(+), 219 deletions(-)",
    "diff": "diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c\nindex 6cd6455..1794025 100644\n--- a/lib/librte_ether/rte_ethdev.c\n+++ b/lib/librte_ether/rte_ethdev.c\n@@ -72,6 +72,7 @@\n static const char *MZ_RTE_ETH_DEV_DATA = \"rte_eth_dev_data\";\n struct rte_eth_dev rte_eth_devices[RTE_MAX_ETHPORTS];\n static struct rte_eth_dev_data *rte_eth_dev_data;\n+static uint8_t eth_dev_last_created_port;\n static uint8_t nb_ports;\n \n /* spinlock for eth device callbacks */\n@@ -210,6 +211,7 @@ rte_eth_dev_allocate(const char *name, enum rte_eth_dev_type type)\n \teth_dev->data->port_id = port_id;\n \teth_dev->attached = DEV_ATTACHED;\n \teth_dev->dev_type = type;\n+\teth_dev_last_created_port = port_id;\n \tnb_ports++;\n \treturn eth_dev;\n }\n@@ -342,100 +344,6 @@ rte_eth_dev_count(void)\n \treturn nb_ports;\n }\n \n-static enum rte_eth_dev_type\n-rte_eth_dev_get_device_type(uint8_t port_id)\n-{\n-\tif (!rte_eth_dev_is_valid_port(port_id))\n-\t\treturn RTE_ETH_DEV_UNKNOWN;\n-\treturn rte_eth_devices[port_id].dev_type;\n-}\n-\n-static int\n-rte_eth_dev_get_addr_by_port(uint8_t port_id, struct rte_pci_addr *addr)\n-{\n-\tRTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);\n-\n-\tif (addr == NULL) {\n-\t\tRTE_PMD_DEBUG_TRACE(\"Null pointer is specified\\n\");\n-\t\treturn -EINVAL;\n-\t}\n-\n-\t*addr = rte_eth_devices[port_id].pci_dev->addr;\n-\treturn 0;\n-}\n-\n-static int\n-rte_eth_dev_get_name_by_port(uint8_t port_id, char *name)\n-{\n-\tchar *tmp;\n-\n-\tRTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);\n-\n-\tif (name == NULL) {\n-\t\tRTE_PMD_DEBUG_TRACE(\"Null pointer is specified\\n\");\n-\t\treturn -EINVAL;\n-\t}\n-\n-\t/* shouldn't check 'rte_eth_devices[i].data',\n-\t * because it might be overwritten by VDEV PMD */\n-\ttmp = rte_eth_dev_data[port_id].name;\n-\tstrcpy(name, tmp);\n-\treturn 0;\n-}\n-\n-static int\n-rte_eth_dev_get_port_by_name(const char *name, uint8_t *port_id)\n-{\n-\tint i;\n-\n-\tif (name == NULL) {\n-\t\tRTE_PMD_DEBUG_TRACE(\"Null pointer is specified\\n\");\n-\t\treturn -EINVAL;\n-\t}\n-\n-\t*port_id = RTE_MAX_ETHPORTS;\n-\n-\tfor (i = 0; i < RTE_MAX_ETHPORTS; i++) {\n-\n-\t\tif (!strncmp(name,\n-\t\t\trte_eth_dev_data[i].name, strlen(name))) {\n-\n-\t\t\t*port_id = i;\n-\n-\t\t\treturn 0;\n-\t\t}\n-\t}\n-\treturn -ENODEV;\n-}\n-\n-static int\n-rte_eth_dev_get_port_by_addr(const struct rte_pci_addr *addr, uint8_t *port_id)\n-{\n-\tint i;\n-\tstruct rte_pci_device *pci_dev = NULL;\n-\n-\tif (addr == NULL) {\n-\t\tRTE_PMD_DEBUG_TRACE(\"Null pointer is specified\\n\");\n-\t\treturn -EINVAL;\n-\t}\n-\n-\t*port_id = RTE_MAX_ETHPORTS;\n-\n-\tfor (i = 0; i < RTE_MAX_ETHPORTS; i++) {\n-\n-\t\tpci_dev = rte_eth_devices[i].pci_dev;\n-\n-\t\tif (pci_dev &&\n-\t\t\t!rte_eal_compare_pci_addr(&pci_dev->addr, addr)) {\n-\n-\t\t\t*port_id = i;\n-\n-\t\t\treturn 0;\n-\t\t}\n-\t}\n-\treturn -ENODEV;\n-}\n-\n static int\n rte_eth_dev_is_detachable(uint8_t port_id)\n {\n@@ -464,124 +372,45 @@ rte_eth_dev_is_detachable(uint8_t port_id)\n \t\treturn 1;\n }\n \n-/* attach the new physical device, then store port_id of the device */\n-static int\n-rte_eth_dev_attach_pdev(struct rte_pci_addr *addr, uint8_t *port_id)\n-{\n-\t/* Invoke probe func of the driver can handle the new device. */\n-\tif (rte_eal_pci_probe_one(addr))\n-\t\tgoto err;\n-\n-\tif (rte_eth_dev_get_port_by_addr(addr, port_id))\n-\t\tgoto err;\n-\n-\treturn 0;\n-err:\n-\treturn -1;\n-}\n-\n-/* detach the new physical device, then store pci_addr of the device */\n-static int\n-rte_eth_dev_detach_pdev(uint8_t port_id, struct rte_pci_addr *addr)\n-{\n-\tstruct rte_pci_addr freed_addr;\n-\tstruct rte_pci_addr vp;\n-\n-\t/* get pci address by port id */\n-\tif (rte_eth_dev_get_addr_by_port(port_id, &freed_addr))\n-\t\tgoto err;\n-\n-\t/* Zeroed pci addr means the port comes from virtual device */\n-\tvp.domain = vp.bus = vp.devid = vp.function = 0;\n-\tif (rte_eal_compare_pci_addr(&vp, &freed_addr) == 0)\n-\t\tgoto err;\n-\n-\t/* invoke devuninit func of the pci driver,\n-\t * also remove the device from pci_device_list */\n-\tif (rte_eal_pci_detach(&freed_addr))\n-\t\tgoto err;\n-\n-\t*addr = freed_addr;\n-\treturn 0;\n-err:\n-\treturn -1;\n-}\n-\n-/* attach the new virtual device, then store port_id of the device */\n-static int\n-rte_eth_dev_attach_vdev(const char *vdevargs, uint8_t *port_id)\n-{\n-\tchar *name = NULL, *args = NULL;\n-\tint ret = -1;\n-\n-\t/* parse vdevargs, then retrieve device name and args */\n-\tif (rte_eal_parse_devargs_str(vdevargs, &name, &args))\n-\t\tgoto end;\n-\n-\t/* walk around dev_driver_list to find the driver of the device,\n-\t * then invoke probe function of the driver.\n-\t * rte_eal_vdev_init() updates port_id allocated after\n-\t * initialization.\n-\t */\n-\tif (rte_eal_vdev_init(name, args))\n-\t\tgoto end;\n-\n-\tif (rte_eth_dev_get_port_by_name(name, port_id))\n-\t\tgoto end;\n-\n-\tret = 0;\n-end:\n-\tfree(name);\n-\tfree(args);\n-\n-\treturn ret;\n-}\n-\n-/* detach the new virtual device, then store the name of the device */\n-static int\n-rte_eth_dev_detach_vdev(uint8_t port_id, char *vdevname)\n-{\n-\tchar name[RTE_ETH_NAME_MAX_LEN];\n-\n-\t/* get device name by port id */\n-\tif (rte_eth_dev_get_name_by_port(port_id, name))\n-\t\tgoto err;\n-\t/* walk around dev_driver_list to find the driver of the device,\n-\t * then invoke uninit function of the driver */\n-\tif (rte_eal_vdev_uninit(name))\n-\t\tgoto err;\n-\n-\tstrncpy(vdevname, name, sizeof(name));\n-\treturn 0;\n-err:\n-\treturn -1;\n-}\n-\n /* attach the new device, then store port_id of the device */\n int\n rte_eth_dev_attach(const char *devargs, uint8_t *port_id)\n {\n-\tstruct rte_pci_addr addr;\n \tint ret = -1;\n+\tint current = eth_dev_last_created_port;\n+\tchar *name = NULL;\n+\tchar *args = NULL;\n \n \tif ((devargs == NULL) || (port_id == NULL)) {\n \t\tret = -EINVAL;\n \t\tgoto err;\n \t}\n \n-\tif (eal_parse_pci_DomBDF(devargs, &addr) == 0) {\n-\t\tret = rte_eth_dev_attach_pdev(&addr, port_id);\n-\t\tif (ret < 0)\n-\t\t\tgoto err;\n-\t} else {\n-\t\tret = rte_eth_dev_attach_vdev(devargs, port_id);\n-\t\tif (ret < 0)\n-\t\t\tgoto err;\n+\t/* parse devargs, then retrieve device name and args */\n+\tif (rte_eal_parse_devargs_str(devargs, &name, &args))\n+\t\tgoto err;\n+\n+\tret = rte_eal_dev_attach(name, args);\n+\tif (ret < 0)\n+\t\tgoto err;\n+\n+\t/* no point looking at eth_dev_last_created_port if no port exists */\n+\tif (!nb_ports) {\n+\t\tret = -1;\n+\t\tgoto err;\n \t}\n+\t/* if nothing happened, there is a bug here, since some driver told us\n+\t * it did attach a device, but did not create a port */\n+\tif (current == eth_dev_last_created_port) {\n+\t\tret = -1;\n+\t\tgoto err;\n+\t}\n+\t*port_id = eth_dev_last_created_port;\n+\tret = 0;\n \n-\treturn 0;\n err:\n-\tRTE_LOG(ERR, EAL, \"Driver, cannot attach the device\\n\");\n+\tfree(name);\n+\tfree(args);\n \treturn ret;\n }\n \n@@ -589,7 +418,6 @@ err:\n int\n rte_eth_dev_detach(uint8_t port_id, char *name)\n {\n-\tstruct rte_pci_addr addr;\n \tint ret = -1;\n \n \tif (name == NULL) {\n@@ -597,33 +425,19 @@ rte_eth_dev_detach(uint8_t port_id, char *name)\n \t\tgoto err;\n \t}\n \n-\t/* check whether the driver supports detach feature, or not */\n+\t/* FIXME: move this to eal, once device flags are relocated there */\n \tif (rte_eth_dev_is_detachable(port_id))\n \t\tgoto err;\n \n-\tif (rte_eth_dev_get_device_type(port_id) == RTE_ETH_DEV_PCI) {\n-\t\tret = rte_eth_dev_get_addr_by_port(port_id, &addr);\n-\t\tif (ret < 0)\n-\t\t\tgoto err;\n-\n-\t\tret = rte_eth_dev_detach_pdev(port_id, &addr);\n-\t\tif (ret < 0)\n-\t\t\tgoto err;\n-\n-\t\tsnprintf(name, RTE_ETH_NAME_MAX_LEN,\n-\t\t\t\"%04x:%02x:%02x.%d\",\n-\t\t\taddr.domain, addr.bus,\n-\t\t\taddr.devid, addr.function);\n-\t} else {\n-\t\tret = rte_eth_dev_detach_vdev(port_id, name);\n-\t\tif (ret < 0)\n-\t\t\tgoto err;\n-\t}\n+\tsnprintf(name, sizeof(rte_eth_devices[port_id].data->name),\n+\t\t \"%s\", rte_eth_devices[port_id].data->name);\n+\tret = rte_eal_dev_detach(name);\n+\tif (ret < 0)\n+\t\tgoto err;\n \n \treturn 0;\n \n err:\n-\tRTE_LOG(ERR, EAL, \"Driver, cannot detach the device\\n\");\n \treturn ret;\n }\n \n",
    "prefixes": [
        "dpdk-dev",
        "v2",
        "16/17"
    ]
}