get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 42341,
    "url": "http://patches.dpdk.org/api/patches/42341/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/e21f8a036ed7195324dc5a9d4913d76d65a87c38.1530791217.git.gaetan.rivet@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": "<e21f8a036ed7195324dc5a9d4913d76d65a87c38.1530791217.git.gaetan.rivet@6wind.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/e21f8a036ed7195324dc5a9d4913d76d65a87c38.1530791217.git.gaetan.rivet@6wind.com",
    "date": "2018-07-05T11:48:13",
    "name": "[v10,06/27] eal: introduce device class abstraction",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "dcd315730de818071d6d5e728bf4aa690cf98509",
    "submitter": {
        "id": 269,
        "url": "http://patches.dpdk.org/api/people/269/?format=api",
        "name": "Gaëtan Rivet",
        "email": "gaetan.rivet@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/e21f8a036ed7195324dc5a9d4913d76d65a87c38.1530791217.git.gaetan.rivet@6wind.com/mbox/",
    "series": [
        {
            "id": 419,
            "url": "http://patches.dpdk.org/api/series/419/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=419",
            "date": "2018-07-05T11:48:07",
            "name": "Device querying",
            "version": 10,
            "mbox": "http://patches.dpdk.org/series/419/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/42341/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/42341/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 [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 0ECA31BF06;\n\tThu,  5 Jul 2018 13:49:22 +0200 (CEST)",
            "from mail-wr1-f66.google.com (mail-wr1-f66.google.com\n\t[209.85.221.66]) by dpdk.org (Postfix) with ESMTP id 6AED91BECD\n\tfor <dev@dpdk.org>; Thu,  5 Jul 2018 13:49:05 +0200 (CEST)",
            "by mail-wr1-f66.google.com with SMTP id q10-v6so1016610wrd.4\n\tfor <dev@dpdk.org>; Thu, 05 Jul 2018 04:49:05 -0700 (PDT)",
            "from bidouze.dev.6wind.com. (host.78.145.23.62.rev.coltfrance.com.\n\t[62.23.145.78]) by smtp.gmail.com with ESMTPSA id\n\to42-v6sm15809183wrc.50.2018.07.05.04.49.03\n\t(version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);\n\tThu, 05 Jul 2018 04:49:03 -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\t:mime-version:content-transfer-encoding;\n\tbh=U7kPLkEjGpmnvugg/iDJyH6BaTOGs9Tph70S2j9iOqc=;\n\tb=ObD4wLMqJ/dLxl1RHXvouibAtijZUIagUdRw2alii0bv0oWi1VVuZsGCtwdbu69hwT\n\t3UDuOSqLn56/eNE7E5ts5gJvW8P3eZDXJVUTjdvivryXXLiZudPW9jA5/YRgCdgby7ck\n\tnJbA1kts+7ySEqxGRFfWrqDSgndjr2Ulf9nMcZVd/Src62G6xM8iEPMxc4k7R7M+rEjM\n\tGb7sYzgsw+6I+Ayl0LyAwswl17u0NmVkGIjsZOXXMXA9MWCkjK7f6oK4aLt8zQoi8vGZ\n\tTIoO+3yZD7oHhglCLfB+bZQGA1Pu2nh3TAL+f2d0rCD5wS5fxSfZRYch9MVerQstQvlz\n\twJiA==",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to\n\t:references:mime-version:content-transfer-encoding;\n\tbh=U7kPLkEjGpmnvugg/iDJyH6BaTOGs9Tph70S2j9iOqc=;\n\tb=h6k0r7ZR3wlXwlUprXnMnf/Q01J9PuOxVLTivgaESmfvlIgMd0A/34MvHsmjlHL1ix\n\tm4ufukZy7hr/MDtkbbZImWhtDAZ8BcDVh3HnD/bJpXvcJlvaNlZUxqmYmbVUEQ+R3YxT\n\trYw/WU5P/mzDdY1nsB5nkJYZG/0SVwYrZNg+pQLsJ4ozm4qVP1II35fjNAxVSUGuCNrJ\n\t2J41Ew/3NyKjyJlv+ld54ym81O0BJej4SfudaTjkUaSqk8YdW8FiQbYa8toKeOvSIRCx\n\tL3nv0YOgpGVauLAdpD6trof33w23Qugma7IQxGjRdD+QeZLJnwfXtYXR6Zf39tRTUMlF\n\ts7Aw==",
        "X-Gm-Message-State": "APt69E0PXyDKLORn32zZPerPwgxLJcCXEvFW+ysCoOc5GHRBSbNXBJuk\n\t3Vm3A9+tNnWXMt+b76l0OIT+Q7L6",
        "X-Google-Smtp-Source": "AAOMgpdihGeTGZpmUJXW96SrVRsJp4QVPpOATv96Wv5LCktKlo9vK8AtE9qg5J52gbkXyj7aYtp/5A==",
        "X-Received": "by 2002:adf:80c4:: with SMTP id\n\t62-v6mr4124708wrl.95.1530791344713; \n\tThu, 05 Jul 2018 04:49:04 -0700 (PDT)",
        "From": "Gaetan Rivet <gaetan.rivet@6wind.com>",
        "To": "dev@dpdk.org",
        "Cc": "Gaetan Rivet <gaetan.rivet@6wind.com>",
        "Date": "Thu,  5 Jul 2018 13:48:13 +0200",
        "Message-Id": "<e21f8a036ed7195324dc5a9d4913d76d65a87c38.1530791217.git.gaetan.rivet@6wind.com>",
        "X-Mailer": "git-send-email 2.18.0",
        "In-Reply-To": "<cover.1530791217.git.gaetan.rivet@6wind.com>",
        "References": "<cover.1530791217.git.gaetan.rivet@6wind.com>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain; charset=UTF-8",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[dpdk-dev] [PATCH v10 06/27] eal: introduce device class abstraction",
        "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\t<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\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>\n---\n lib/librte_eal/bsdapp/eal/Makefile         |   1 +\n lib/librte_eal/common/Makefile             |   2 +-\n lib/librte_eal/common/eal_common_class.c   |  62 +++++++++++\n lib/librte_eal/common/include/rte_class.h  | 121 +++++++++++++++++++++\n lib/librte_eal/common/include/rte_common.h |   1 +\n lib/librte_eal/common/meson.build          |   2 +\n lib/librte_eal/linuxapp/eal/Makefile       |   1 +\n lib/librte_eal/rte_eal_version.map         |   2 +\n 8 files changed, 191 insertions(+), 1 deletion(-)\n create mode 100644 lib/librte_eal/common/eal_common_class.c\n create mode 100644 lib/librte_eal/common/include/rte_class.h",
    "diff": "diff --git a/lib/librte_eal/bsdapp/eal/Makefile b/lib/librte_eal/bsdapp/eal/Makefile\nindex 3fd33f1e4..b0a1c880a 100644\n--- a/lib/librte_eal/bsdapp/eal/Makefile\n+++ b/lib/librte_eal/bsdapp/eal/Makefile\n@@ -52,6 +52,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_hypervisor.c\n SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_string_fns.c\n SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_hexdump.c\n SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_devargs.c\n+SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_class.c\n SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_bus.c\n SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_dev.c\n SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_options.c\ndiff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile\nindex 48f870f24..750653093 100644\n--- a/lib/librte_eal/common/Makefile\n+++ b/lib/librte_eal/common/Makefile\n@@ -11,7 +11,7 @@ INC += rte_per_lcore.h rte_random.h\n INC += rte_tailq.h rte_interrupts.h rte_alarm.h\n INC += rte_string_fns.h rte_version.h\n INC += rte_eal_memconfig.h rte_malloc_heap.h\n-INC += rte_hexdump.h rte_devargs.h rte_bus.h rte_dev.h\n+INC += rte_hexdump.h rte_devargs.h rte_bus.h rte_dev.h rte_class.h\n INC += rte_pci_dev_feature_defs.h rte_pci_dev_features.h\n INC += rte_malloc.h rte_keepalive.h rte_time.h\n INC += rte_service.h rte_service_component.h\ndiff --git a/lib/librte_eal/common/eal_common_class.c b/lib/librte_eal/common/eal_common_class.c\nnew file mode 100644\nindex 000000000..aed4dd8fb\n--- /dev/null\n+++ b/lib/librte_eal/common/eal_common_class.c\n@@ -0,0 +1,62 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright 2018 Gaëtan Rivet\n+ */\n+\n+#include <stdio.h>\n+#include <string.h>\n+#include <sys/queue.h>\n+\n+#include <rte_class.h>\n+#include <rte_debug.h>\n+\n+struct rte_class_list rte_class_list =\n+\tTAILQ_HEAD_INITIALIZER(rte_class_list);\n+\n+__rte_experimental void\n+rte_class_register(struct rte_class *class)\n+{\n+\tRTE_VERIFY(class);\n+\tRTE_VERIFY(class->name && strlen(class->name));\n+\n+\tTAILQ_INSERT_TAIL(&rte_class_list, class, next);\n+\tRTE_LOG(DEBUG, EAL, \"Registered [%s] device class.\\n\", class->name);\n+}\n+\n+__rte_experimental void\n+rte_class_unregister(struct rte_class *class)\n+{\n+\tTAILQ_REMOVE(&rte_class_list, class, next);\n+\tRTE_LOG(DEBUG, EAL, \"Unregistered [%s] device class.\\n\", class->name);\n+}\n+\n+struct rte_class *\n+rte_class_find(const struct rte_class *start, rte_class_cmp_t cmp,\n+\t       const void *data)\n+{\n+\tstruct rte_class *cls;\n+\n+\tif (start != NULL)\n+\t\tcls = TAILQ_NEXT(start, next);\n+\telse\n+\t\tcls = TAILQ_FIRST(&rte_class_list);\n+\twhile (cls != NULL) {\n+\t\tif (cmp(cls, data) == 0)\n+\t\t\tbreak;\n+\t\tcls = TAILQ_NEXT(cls, next);\n+\t}\n+\treturn cls;\n+}\n+\n+static int\n+cmp_class_name(const struct rte_class *class, const void *_name)\n+{\n+\tconst char *name = _name;\n+\n+\treturn strcmp(class->name, name);\n+}\n+\n+struct rte_class *\n+rte_class_find_by_name(const char *name)\n+{\n+\treturn rte_class_find(NULL, cmp_class_name, (const void *)name);\n+}\ndiff --git a/lib/librte_eal/common/include/rte_class.h b/lib/librte_eal/common/include/rte_class.h\nnew file mode 100644\nindex 000000000..b5e550a34\n--- /dev/null\n+++ b/lib/librte_eal/common/include/rte_class.h\n@@ -0,0 +1,121 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright 2018 Gaëtan Rivet\n+ */\n+\n+#ifndef _RTE_CLASS_H_\n+#define _RTE_CLASS_H_\n+\n+/**\n+ * @file\n+ *\n+ * DPDK device class interface.\n+ *\n+ * This file exposes API and interfaces of device classes.\n+ */\n+\n+#ifdef __cplusplus\n+extern \"C\" {\n+#endif\n+\n+#include <sys/queue.h>\n+\n+#include <rte_dev.h>\n+\n+/** Double linked list of classes */\n+TAILQ_HEAD(rte_class_list, rte_class);\n+\n+/**\n+ * A structure describing a generic device class.\n+ */\n+struct rte_class {\n+\tTAILQ_ENTRY(rte_class) next; /**< Next device class in linked list */\n+\tconst char *name; /**< Name of the class */\n+};\n+\n+/**\n+ * Class comparison function.\n+ *\n+ * @param cls\n+ *\tClass under test.\n+ *\n+ * @param data\n+ *\tData to compare against.\n+ *\n+ * @return\n+ *\t0 if the class matches the data.\n+ *\t!0 if the class does not match.\n+ *\t<0 if ordering is possible and the class is lower than the data.\n+ *\t>0 if ordering is possible and the class is greater than the data.\n+ */\n+typedef int (*rte_class_cmp_t)(const struct rte_class *cls, const void *data);\n+\n+/**\n+ * Class iterator to find a particular class.\n+ *\n+ * This function compares each registered class to find one that matches\n+ * the data passed as parameter.\n+ *\n+ * If the comparison function returns zero this function will stop iterating\n+ * over any more classes. To continue a search the class of a previous search\n+ * can be passed via the start parameter.\n+ *\n+ * @param start\n+ *\tStarting point for the iteration.\n+ *\n+ * @param cmp\n+ *\tComparison function.\n+ *\n+ * @param data\n+ *\t Data to pass to comparison function.\n+ *\n+ * @return\n+ *\t A pointer to a rte_class structure or NULL in case no class matches\n+ */\n+struct rte_class *\n+rte_class_find(const struct rte_class *start, rte_class_cmp_t cmp,\n+\t       const void *data);\n+\n+/**\n+ * Find the registered class for a given name.\n+ */\n+struct rte_class *\n+rte_class_find_by_name(const char *name);\n+\n+/**\n+ * Register a Class handle.\n+ *\n+ * @param\n+ *   A pointer to a rte_class structure describing the class\n+ *   to be registered.\n+ */\n+__rte_experimental\n+void rte_class_register(struct rte_class *cls);\n+\n+/**\n+ * Unregister a Class handle.\n+ *\n+ * @param class\n+ *   A pointer to a rte_class structure describing the class\n+ *   to be unregistered.\n+ */\n+__rte_experimental\n+void rte_class_unregister(struct rte_class *cls);\n+\n+/**\n+ * Helper for Class registration.\n+ * The constructor has lower priority than Bus constructors.\n+ * The constructor has higher priority than PMD constructors.\n+ */\n+#define RTE_REGISTER_CLASS(nm, cls) \\\n+RTE_INIT_PRIO(classinitfn_ ##nm, CLASS); \\\n+static void classinitfn_ ##nm(void) \\\n+{\\\n+\t(cls).name = RTE_STR(nm);\\\n+\trte_class_register(&cls); \\\n+}\n+\n+#ifdef __cplusplus\n+}\n+#endif\n+\n+#endif /* _RTE_CLASS_H_ */\ndiff --git a/lib/librte_eal/common/include/rte_common.h b/lib/librte_eal/common/include/rte_common.h\nindex 0dd832728..a2e8e6e32 100644\n--- a/lib/librte_eal/common/include/rte_common.h\n+++ b/lib/librte_eal/common/include/rte_common.h\n@@ -83,6 +83,7 @@ typedef uint16_t unaligned_uint16_t;\n \n #define RTE_PRIORITY_LOG 101\n #define RTE_PRIORITY_BUS 110\n+#define RTE_PRIORITY_CLASS 120\n #define RTE_PRIORITY_LAST 65535\n \n #define RTE_PRIO(prio) \\\ndiff --git a/lib/librte_eal/common/meson.build b/lib/librte_eal/common/meson.build\nindex 8a3dcfee0..3009cd0a2 100644\n--- a/lib/librte_eal/common/meson.build\n+++ b/lib/librte_eal/common/meson.build\n@@ -8,6 +8,7 @@ common_objs = []\n common_sources = files(\n \t'eal_common_bus.c',\n \t'eal_common_cpuflags.c',\n+\t'eal_common_class.c',\n \t'eal_common_devargs.c',\n \t'eal_common_dev.c',\n \t'eal_common_errno.c',\n@@ -46,6 +47,7 @@ common_headers = files(\n \t'include/rte_branch_prediction.h',\n \t'include/rte_bus.h',\n \t'include/rte_bitmap.h',\n+\t'include/rte_class.h',\n \t'include/rte_common.h',\n \t'include/rte_debug.h',\n \t'include/rte_devargs.h',\ndiff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile\nindex 3719ec9d7..babc8617a 100644\n--- a/lib/librte_eal/linuxapp/eal/Makefile\n+++ b/lib/librte_eal/linuxapp/eal/Makefile\n@@ -60,6 +60,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_hypervisor.c\n SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_string_fns.c\n SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_hexdump.c\n SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_devargs.c\n+SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_class.c\n SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_bus.c\n SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_dev.c\n SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_options.c\ndiff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map\nindex 1c4db72fa..19d36b4c7 100644\n--- a/lib/librte_eal/rte_eal_version.map\n+++ b/lib/librte_eal/rte_eal_version.map\n@@ -244,6 +244,8 @@ DPDK_18.05 {\n EXPERIMENTAL {\n \tglobal:\n \n+\trte_class_register;\n+\trte_class_unregister;\n \trte_ctrl_thread_create;\n \trte_dev_event_callback_register;\n \trte_dev_event_callback_unregister;\n",
    "prefixes": [
        "v10",
        "06/27"
    ]
}