get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 2373,
    "url": "https://patches.dpdk.org/api/patches/2373/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/1421664027-17971-9-git-send-email-mukawa@igel.co.jp/",
    "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": "<1421664027-17971-9-git-send-email-mukawa@igel.co.jp>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1421664027-17971-9-git-send-email-mukawa@igel.co.jp",
    "date": "2015-01-19T10:40:24",
    "name": "[dpdk-dev,v4,08/11] eal/pci: Cleanup pci driver initialization code",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "938a2945bd4d4e2b32887c5e7ff1b8745c39eb25",
    "submitter": {
        "id": 64,
        "url": "https://patches.dpdk.org/api/people/64/?format=api",
        "name": "Tetsuya Mukawa",
        "email": "mukawa@igel.co.jp"
    },
    "delegate": null,
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/1421664027-17971-9-git-send-email-mukawa@igel.co.jp/mbox/",
    "series": [],
    "comments": "https://patches.dpdk.org/api/patches/2373/comments/",
    "check": "pending",
    "checks": "https://patches.dpdk.org/api/patches/2373/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 3E1805A9D;\n\tMon, 19 Jan 2015 11:41:44 +0100 (CET)",
            "from mail-pa0-f45.google.com (mail-pa0-f45.google.com\n\t[209.85.220.45]) by dpdk.org (Postfix) with ESMTP id AC9425AB1\n\tfor <dev@dpdk.org>; Mon, 19 Jan 2015 11:41:22 +0100 (CET)",
            "by mail-pa0-f45.google.com with SMTP id lf10so38147516pab.4\n\tfor <dev@dpdk.org>; Mon, 19 Jan 2015 02:41:22 -0800 (PST)",
            "from localhost.localdomain (napt.igel.co.jp. [219.106.231.132])\n\tby mx.google.com with ESMTPSA id\n\ta13sm11337588pdm.44.2015.01.19.02.41.20\n\t(version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128);\n\tMon, 19 Jan 2015 02:41:21 -0800 (PST)"
        ],
        "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=9cUcTFwrOvn9CJx0YW2PlP5c2T+imo/ag8mTnM13drw=;\n\tb=EaJGDigwuHpIpFWppdlh0g6LkoUz58ApYJ87/ZVkSoHr/L1ca1ljBpXUcJjqu20Wfs\n\tZHIrA5LS9/Lddag3KosF6fxSNLl67ZssX5vCTopmi+WUpvxLJwxfv31MvtPc0+qosIuA\n\toqUja/+TIEFblXsnOfpNwjSk7P+iA6X18bosyCVNsIe5Q9I866SVaAwrf0JgDEf6NiD8\n\tbHElIyvD8CqpRpWLgKv5/VwOw3m2KQ4l5Sp0nBOEJ7f0PB4q+QxJjjNDG9guehbiQeuZ\n\tAAXGQBifIdkJ1/RtZkYVxxscXf9lkSsoLLXiV+j4o/w8nF/micSQhMwZsRbwDozMGEAB\n\tM0WQ==",
        "X-Gm-Message-State": "ALoCoQlMp4UzF9Yjtk1F0LcUE5lNdcsaxxWoFQONsrxDIyhVIwkHjEZd4u5ucaHXUUT2oDYysUFB",
        "X-Received": "by 10.66.141.7 with SMTP id rk7mr21683546pab.15.1421664082071;\n\tMon, 19 Jan 2015 02:41:22 -0800 (PST)",
        "From": "Tetsuya Mukawa <mukawa@igel.co.jp>",
        "To": "dev@dpdk.org",
        "Date": "Mon, 19 Jan 2015 19:40:24 +0900",
        "Message-Id": "<1421664027-17971-9-git-send-email-mukawa@igel.co.jp>",
        "X-Mailer": "git-send-email 1.9.1",
        "In-Reply-To": "<1421664027-17971-1-git-send-email-mukawa@igel.co.jp>",
        "References": "<1418106629-22227-2-git-send-email-mukawa@igel.co.j>\n\t<1421664027-17971-1-git-send-email-mukawa@igel.co.jp>",
        "Subject": "[dpdk-dev] [PATCH v4 08/11] eal/pci: Cleanup pci driver\n\tinitialization code",
        "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": "- Add rte_eal_pci_close_one_dirver()\n  The function is used for closing the specified driver and device.\n- Add pci_invoke_all_drivers()\n  The function is based on pci_probe_all_drivers. But it can not only\n  probe but also close drivers.\n- Add pci_close_all_drivers()\n  The function tries to find a driver for the specified device, and\n  then close the driver.\n- Add rte_eal_pci_probe_one() and rte_eal_pci_close_one()\n  The functions are used for probe and close a device.\n  First the function tries to find a device that has the specfied\n  PCI address. Then, probe or close the device.\n\nv4:\n- Fix paramerter checking.\n- Fix indent of 'if' statement.\n\nSigned-off-by: Tetsuya Mukawa <mukawa@igel.co.jp>\n---\n lib/librte_eal/common/eal_common_pci.c  | 90 +++++++++++++++++++++++++++++----\n lib/librte_eal/common/eal_private.h     | 25 +++++++++\n lib/librte_eal/common/include/rte_pci.h | 33 ++++++++++++\n lib/librte_eal/linuxapp/eal/eal_pci.c   | 69 +++++++++++++++++++++++++\n 4 files changed, 207 insertions(+), 10 deletions(-)",
    "diff": "diff --git a/lib/librte_eal/common/eal_common_pci.c b/lib/librte_eal/common/eal_common_pci.c\nindex a89f5c3..7c9b8c5 100644\n--- a/lib/librte_eal/common/eal_common_pci.c\n+++ b/lib/librte_eal/common/eal_common_pci.c\n@@ -99,19 +99,27 @@ static struct rte_devargs *pci_devargs_lookup(struct rte_pci_device *dev)\n \treturn NULL;\n }\n \n-/*\n- * If vendor/device ID match, call the devinit() function of all\n- * registered driver for the given device. Return -1 if initialization\n- * failed, return 1 if no driver is found for this device.\n- */\n static int\n-pci_probe_all_drivers(struct rte_pci_device *dev)\n+pci_invoke_all_drivers(struct rte_pci_device *dev,\n+\t\tenum rte_eal_invoke_type type)\n {\n \tstruct rte_pci_driver *dr = NULL;\n-\tint rc;\n+\tint rc = 0;\n+\n+\tif ((dev == NULL) || (type >= RTE_EAL_INVOKE_TYPE_MAX))\n+\t\treturn -1;\n \n \tTAILQ_FOREACH(dr, &pci_driver_list, next) {\n-\t\trc = rte_eal_pci_probe_one_driver(dr, dev);\n+\t\tswitch (type) {\n+\t\tcase RTE_EAL_INVOKE_TYPE_PROBE:\n+\t\t\trc = rte_eal_pci_probe_one_driver(dr, dev);\n+\t\t\tbreak;\n+\t\tcase RTE_EAL_INVOKE_TYPE_CLOSE:\n+\t\t\trc = rte_eal_pci_close_one_driver(dr, dev);\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\treturn -1;\n+\t\t}\n \t\tif (rc < 0)\n \t\t\t/* negative value is an error */\n \t\t\treturn -1;\n@@ -123,6 +131,66 @@ pci_probe_all_drivers(struct rte_pci_device *dev)\n \treturn 1;\n }\n \n+#ifdef ENABLE_HOTPLUG\n+static int\n+rte_eal_pci_invoke_one(struct rte_pci_addr *addr,\n+\t\tenum rte_eal_invoke_type type)\n+{\n+\tstruct rte_pci_device *dev = NULL;\n+\tint ret = 0;\n+\n+\tif ((addr == NULL) || (type >= RTE_EAL_INVOKE_TYPE_MAX))\n+\t\treturn -1;\n+\n+\tTAILQ_FOREACH(dev, &pci_device_list, next) {\n+\t\tif (eal_compare_pci_addr(&dev->addr, addr))\n+\t\t\tcontinue;\n+\n+\t\tret = pci_invoke_all_drivers(dev, type);\n+\t\tif (ret < 0)\n+\t\t\tgoto invoke_err_return;\n+\n+\t\tif (type == RTE_EAL_INVOKE_TYPE_CLOSE)\n+\t\t\tgoto remove_dev;\n+\n+\t\treturn 0;\n+\t}\n+\n+\treturn -1;\n+\n+invoke_err_return:\n+\tRTE_LOG(WARNING, EAL, \"Requested device \" PCI_PRI_FMT\n+\t\t\t\" cannot be used\\n\", dev->addr.domain, dev->addr.bus,\n+\t\t\tdev->addr.devid, dev->addr.function);\n+\treturn -1;\n+\n+remove_dev:\n+\tTAILQ_REMOVE(&pci_device_list, dev, next);\n+\treturn 0;\n+}\n+\n+\n+/*\n+ * Find the pci device specified by pci address, then invoke probe function of\n+ * the driver of the devive.\n+ */\n+int\n+rte_eal_pci_probe_one(struct rte_pci_addr *addr)\n+{\n+\treturn rte_eal_pci_invoke_one(addr, RTE_EAL_INVOKE_TYPE_PROBE);\n+}\n+\n+/*\n+ * Find the pci device specified by pci address, then invoke close function of\n+ * the driver of the devive.\n+ */\n+int\n+rte_eal_pci_close_one(struct rte_pci_addr *addr)\n+{\n+\treturn rte_eal_pci_invoke_one(addr, RTE_EAL_INVOKE_TYPE_CLOSE);\n+}\n+#endif /* ENABLE_HOTPLUG */\n+\n /*\n  * Scan the content of the PCI bus, and call the devinit() function for\n  * all registered drivers that have a matching entry in its id_table\n@@ -148,10 +216,12 @@ rte_eal_pci_probe(void)\n \n \t\t/* probe all or only whitelisted devices */\n \t\tif (probe_all)\n-\t\t\tret = pci_probe_all_drivers(dev);\n+\t\t\tret = pci_invoke_all_drivers(dev,\n+\t\t\t\t\tRTE_EAL_INVOKE_TYPE_PROBE);\n \t\telse if (devargs != NULL &&\n \t\t\tdevargs->type == RTE_DEVTYPE_WHITELISTED_PCI)\n-\t\t\tret = pci_probe_all_drivers(dev);\n+\t\t\tret = pci_invoke_all_drivers(dev,\n+\t\t\t\t\tRTE_EAL_INVOKE_TYPE_PROBE);\n \t\tif (ret < 0)\n \t\t\trte_exit(EXIT_FAILURE, \"Requested device \" PCI_PRI_FMT\n \t\t\t\t \" cannot be used\\n\", dev->addr.domain, dev->addr.bus,\ndiff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h\nindex 159cd66..a97c5d8 100644\n--- a/lib/librte_eal/common/eal_private.h\n+++ b/lib/librte_eal/common/eal_private.h\n@@ -154,6 +154,16 @@ struct rte_pci_driver;\n struct rte_pci_device;\n \n /**\n+ * The invoke type.\n+ */\n+enum rte_eal_invoke_type {\n+\tRTE_EAL_INVOKE_TYPE_UNKNOWN,/**< unknown */\n+\tRTE_EAL_INVOKE_TYPE_PROBE,  /**< invoke probe function */\n+\tRTE_EAL_INVOKE_TYPE_CLOSE,  /**< invoke close function */\n+\tRTE_EAL_INVOKE_TYPE_MAX     /**< max value of this enum */\n+};\n+\n+/**\n  * Mmap memory for single PCI device\n  *\n  * This function is private to EAL.\n@@ -165,6 +175,21 @@ int rte_eal_pci_probe_one_driver(struct rte_pci_driver *dr,\n \t\tstruct rte_pci_device *dev);\n \n /**\n+ * Munmap memory for single PCI device\n+ *\n+ * This function is private to EAL.\n+ *\n+ * @param\tdr\n+ *  The pointer to the pci driver structure\n+ * @param\tdev\n+ *  The pointer to the pci device structure\n+ * @return\n+ *   0 on success, negative on error\n+ */\n+int rte_eal_pci_close_one_driver(struct rte_pci_driver *dr,\n+\t\tstruct rte_pci_device *dev);\n+\n+/**\n  * Init tail queues for non-EAL library structures. This is to allow\n  * the rings, mempools, etc. lists to be shared among multiple processes\n  *\ndiff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h\nindex fe57cb6..28462f5 100644\n--- a/lib/librte_eal/common/include/rte_pci.h\n+++ b/lib/librte_eal/common/include/rte_pci.h\n@@ -82,6 +82,7 @@ extern \"C\" {\n #include <inttypes.h>\n \n #include <rte_interrupts.h>\n+#include <rte_dev_hotplug.h>\n \n TAILQ_HEAD(pci_device_list, rte_pci_device); /**< PCI devices in D-linked Q. */\n TAILQ_HEAD(pci_driver_list, rte_pci_driver); /**< PCI drivers in D-linked Q. */\n@@ -315,6 +316,38 @@ eal_compare_pci_addr(struct rte_pci_addr *addr, struct rte_pci_addr *addr2)\n  */\n int rte_eal_pci_probe(void);\n \n+#ifdef ENABLE_HOTPLUG\n+/**\n+ * Probe the single PCI device.\n+ *\n+ * Scan the content of the PCI bus, and find the pci device specified by pci\n+ * address, then call the probe() function for registered driver that has a\n+ * matching entry in its id_table for discovered device.\n+ *\n+ * @param addr\n+ *\tThe PCI Bus-Device-Function address to probe or close.\n+ * @return\n+ *   - 0 on success.\n+ *   - Negative on error.\n+ */\n+int rte_eal_pci_probe_one(struct rte_pci_addr *addr);\n+\n+/**\n+ * Close the single PCI device.\n+ *\n+ * Scan the content of the PCI bus, and find the pci device specified by pci\n+ * address, then call the close() function for registered driver that has a\n+ * matching entry in its id_table for discovered device.\n+ *\n+ * @param addr\n+ *\tThe PCI Bus-Device-Function address to probe or close.\n+ * @return\n+ *   - 0 on success.\n+ *   - Negative on error.\n+ */\n+int rte_eal_pci_close_one(struct rte_pci_addr *addr);\n+#endif /* ENABLE_HOTPLUG */\n+\n /**\n  * Dump the content of the PCI bus.\n  *\ndiff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c\nindex 52c464c..a23cc59 100644\n--- a/lib/librte_eal/linuxapp/eal/eal_pci.c\n+++ b/lib/librte_eal/linuxapp/eal/eal_pci.c\n@@ -619,6 +619,75 @@ rte_eal_pci_probe_one_driver(struct rte_pci_driver *dr, struct rte_pci_device *d\n \treturn 1;\n }\n \n+#ifdef ENABLE_HOTPLUG\n+/*\n+ * If vendor/device ID match, call the devuninit() function of the\n+ * driver.\n+ */\n+int\n+rte_eal_pci_close_one_driver(struct rte_pci_driver *dr,\n+\t\tstruct rte_pci_device *dev)\n+{\n+\tstruct rte_pci_id *id_table;\n+\n+\tif ((dr == NULL) || (dev == NULL))\n+\t\treturn -EINVAL;\n+\n+\tfor (id_table = dr->id_table ; id_table->vendor_id != 0; id_table++) {\n+\n+\t\t/* check if device's identifiers match the driver's ones */\n+\t\tif (id_table->vendor_id != dev->id.vendor_id &&\n+\t\t    id_table->vendor_id != PCI_ANY_ID)\n+\t\t\tcontinue;\n+\t\tif (id_table->device_id != dev->id.device_id &&\n+\t\t    id_table->device_id != PCI_ANY_ID)\n+\t\t\tcontinue;\n+\t\tif (id_table->subsystem_vendor_id !=\n+\t\t    dev->id.subsystem_vendor_id &&\n+\t\t    id_table->subsystem_vendor_id != PCI_ANY_ID)\n+\t\t\tcontinue;\n+\t\tif (id_table->subsystem_device_id !=\n+\t\t    dev->id.subsystem_device_id &&\n+\t\t    id_table->subsystem_device_id != PCI_ANY_ID)\n+\t\t\tcontinue;\n+\n+\t\tstruct rte_pci_addr *loc = &dev->addr;\n+\n+\t\tRTE_LOG(DEBUG, EAL,\n+\t\t\t\t\"PCI device \"PCI_PRI_FMT\" on NUMA socket %i\\n\",\n+\t\t\t\tloc->domain, loc->bus, loc->devid,\n+\t\t\t\tloc->function, dev->numa_node);\n+\n+\t\tRTE_LOG(DEBUG, EAL, \"  remove driver: %x:%x %s\\n\",\n+\t\t\t\tdev->id.vendor_id, dev->id.device_id,\n+\t\t\t\tdr->name);\n+\n+\t\t/* call the driver devuninit() function */\n+\t\tif (dr->devuninit && (dr->devuninit(dr, dev) < 0))\n+\t\t\treturn -1;\t/* negative value is an error */\n+\n+\t\t/* clear driver structure */\n+\t\tdev->driver = NULL;\n+\n+\t\tif (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING)\n+\t\t\t/* unmap resources for devices that use igb_uio */\n+\t\t\tpci_unmap_device(dev);\n+\n+\t\treturn 0;\n+\t}\n+\t/* return positive value if driver is not found */\n+\treturn 1;\n+}\n+#else /* ENABLE_HOTPLUG */\n+int\n+rte_eal_pci_close_one_driver(struct rte_pci_driver *dr __rte_unused,\n+\t\tstruct rte_pci_device *dev __rte_unused)\n+{\n+\tRTE_LOG(ERR, EAL, \"Hotplug support isn't enabled\\n\");\n+\treturn -1;\n+}\n+#endif /* ENABLE_HOTPLUG */\n+\n /* Init the PCI EAL subsystem */\n int\n rte_eal_pci_init(void)\n",
    "prefixes": [
        "dpdk-dev",
        "v4",
        "08/11"
    ]
}