9ae3a8
From 28b2998fb1285514c2c342d174a36330734cd79c Mon Sep 17 00:00:00 2001
9ae3a8
From: Kevin Wolf <kwolf@redhat.com>
9ae3a8
Date: Wed, 6 Nov 2013 14:41:08 +0100
9ae3a8
Subject: [PATCH 32/81] qemu-help: Sort devices by logical functionality
9ae3a8
9ae3a8
RH-Author: Kevin Wolf <kwolf@redhat.com>
9ae3a8
Message-id: <1383748882-22831-4-git-send-email-kwolf@redhat.com>
9ae3a8
Patchwork-id: 55529
9ae3a8
O-Subject: [RHEL-7.0 qemu-kvm PATCH v2 03/17] qemu-help: Sort devices by logical functionality
9ae3a8
Bugzilla: 1001216
9ae3a8
RH-Acked-by: Marcel Apfelbaum <marcel.a@redhat.com>
9ae3a8
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
9ae3a8
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
9ae3a8
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
9ae3a8
9ae3a8
From: Marcel Apfelbaum <marcel.a@redhat.com>
9ae3a8
9ae3a8
Categorize devices that appear as output to "-device ?" command
9ae3a8
by logical functionality. Sort the devices by logical categories
9ae3a8
before showing them to user.
9ae3a8
9ae3a8
The sort is done by functionality rather than alphabetical.
9ae3a8
9ae3a8
Signed-off-by: Marcel Apfelbaum <marcel.a@redhat.com>
9ae3a8
Message-id: 1375107465-25767-3-git-send-email-marcel.a@redhat.com
9ae3a8
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
9ae3a8
(cherry picked from commit 3d1237fb2ab4edb926c717767bb5e31d6053a7c5)
9ae3a8
Signed-off-by: Markus Armbruster <armbru@redhat.com>
9ae3a8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9ae3a8
---
9ae3a8
 include/hw/qdev-core.h | 29 +++++++++++++++++++++++++++++
9ae3a8
 qdev-monitor.c         | 48 +++++++++++++++++++++++++++++++++++++++---------
9ae3a8
 2 files changed, 68 insertions(+), 9 deletions(-)
9ae3a8
9ae3a8
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
9ae3a8
---
9ae3a8
 include/hw/qdev-core.h |   29 +++++++++++++++++++++++++++++
9ae3a8
 qdev-monitor.c         |   48 +++++++++++++++++++++++++++++++++++++++---------
9ae3a8
 2 files changed, 68 insertions(+), 9 deletions(-)
9ae3a8
9ae3a8
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
9ae3a8
index 9d995bf..18596e9 100644
9ae3a8
--- a/include/hw/qdev-core.h
9ae3a8
+++ b/include/hw/qdev-core.h
9ae3a8
@@ -18,6 +18,34 @@ enum {
9ae3a8
 #define DEVICE_CLASS(klass) OBJECT_CLASS_CHECK(DeviceClass, (klass), TYPE_DEVICE)
9ae3a8
 #define DEVICE_GET_CLASS(obj) OBJECT_GET_CLASS(DeviceClass, (obj), TYPE_DEVICE)
9ae3a8
 
9ae3a8
+typedef enum DeviceCategory {
9ae3a8
+    DEVICE_CATEGORY_BRIDGE,
9ae3a8
+    DEVICE_CATEGORY_USB,
9ae3a8
+    DEVICE_CATEGORY_STORAGE,
9ae3a8
+    DEVICE_CATEGORY_NETWORK,
9ae3a8
+    DEVICE_CATEGORY_INPUT,
9ae3a8
+    DEVICE_CATEGORY_DISPLAY,
9ae3a8
+    DEVICE_CATEGORY_SOUND,
9ae3a8
+    DEVICE_CATEGORY_MISC,
9ae3a8
+    DEVICE_CATEGORY_MAX
9ae3a8
+} DeviceCategory;
9ae3a8
+
9ae3a8
+static inline const char *qdev_category_get_name(DeviceCategory category)
9ae3a8
+{
9ae3a8
+    static const char *category_names[DEVICE_CATEGORY_MAX] = {
9ae3a8
+        [DEVICE_CATEGORY_BRIDGE]  = "Controller/Bridge/Hub",
9ae3a8
+        [DEVICE_CATEGORY_USB]     = "USB",
9ae3a8
+        [DEVICE_CATEGORY_STORAGE] = "Storage",
9ae3a8
+        [DEVICE_CATEGORY_NETWORK] = "Network",
9ae3a8
+        [DEVICE_CATEGORY_INPUT]   = "Input",
9ae3a8
+        [DEVICE_CATEGORY_DISPLAY] = "Display",
9ae3a8
+        [DEVICE_CATEGORY_SOUND]   = "Sound",
9ae3a8
+        [DEVICE_CATEGORY_MISC]    = "Misc",
9ae3a8
+    };
9ae3a8
+
9ae3a8
+    return category_names[category];
9ae3a8
+};
9ae3a8
+
9ae3a8
 typedef int (*qdev_initfn)(DeviceState *dev);
9ae3a8
 typedef int (*qdev_event)(DeviceState *dev);
9ae3a8
 typedef void (*qdev_resetfn)(DeviceState *dev);
9ae3a8
@@ -81,6 +109,7 @@ typedef struct DeviceClass {
9ae3a8
     ObjectClass parent_class;
9ae3a8
     /*< public >*/
9ae3a8
 
9ae3a8
+    DECLARE_BITMAP(categories, DEVICE_CATEGORY_MAX);
9ae3a8
     const char *fw_name;
9ae3a8
     const char *desc;
9ae3a8
     Property *props;
9ae3a8
diff --git a/qdev-monitor.c b/qdev-monitor.c
9ae3a8
index e54dbc2..230a8df 100644
9ae3a8
--- a/qdev-monitor.c
9ae3a8
+++ b/qdev-monitor.c
9ae3a8
@@ -75,24 +75,27 @@ static bool qdev_class_has_alias(DeviceClass *dc)
9ae3a8
     return (qdev_class_get_alias(dc) != NULL);
9ae3a8
 }
9ae3a8
 
9ae3a8
-static void qdev_print_devinfo(ObjectClass *klass, void *opaque)
9ae3a8
+static void qdev_print_class_devinfo(DeviceClass *dc)
9ae3a8
 {
9ae3a8
-    DeviceClass *dc;
9ae3a8
-    bool *show_no_user = opaque;
9ae3a8
-
9ae3a8
-    dc = (DeviceClass *)object_class_dynamic_cast(klass, TYPE_DEVICE);
9ae3a8
+    DeviceCategory category;
9ae3a8
 
9ae3a8
-    if (!dc || (show_no_user && !*show_no_user && dc->no_user)) {
9ae3a8
+    if (!dc) {
9ae3a8
         return;
9ae3a8
     }
9ae3a8
 
9ae3a8
-    error_printf("name \"%s\"", object_class_get_name(klass));
9ae3a8
+    error_printf("name \"%s\"", object_class_get_name(OBJECT_CLASS(dc)));
9ae3a8
     if (dc->bus_type) {
9ae3a8
         error_printf(", bus %s", dc->bus_type);
9ae3a8
     }
9ae3a8
     if (qdev_class_has_alias(dc)) {
9ae3a8
         error_printf(", alias \"%s\"", qdev_class_get_alias(dc));
9ae3a8
     }
9ae3a8
+    error_printf(", categories");
9ae3a8
+    for (category = 0; category < DEVICE_CATEGORY_MAX; ++category) {
9ae3a8
+        if (test_bit(category, dc->categories)) {
9ae3a8
+            error_printf(" \"%s\"", qdev_category_get_name(category));
9ae3a8
+        }
9ae3a8
+    }
9ae3a8
     if (dc->desc) {
9ae3a8
         error_printf(", desc \"%s\"", dc->desc);
9ae3a8
     }
9ae3a8
@@ -102,6 +105,15 @@ static void qdev_print_devinfo(ObjectClass *klass, void *opaque)
9ae3a8
     error_printf("\n");
9ae3a8
 }
9ae3a8
 
9ae3a8
+static void qdev_print_devinfo(ObjectClass *klass, void *opaque)
9ae3a8
+{
9ae3a8
+    DeviceClass *dc;
9ae3a8
+
9ae3a8
+    dc = (DeviceClass *)object_class_dynamic_cast(klass, TYPE_DEVICE);
9ae3a8
+
9ae3a8
+    qdev_print_class_devinfo(dc);
9ae3a8
+}
9ae3a8
+
9ae3a8
 static int set_property(const char *name, const char *value, void *opaque)
9ae3a8
 {
9ae3a8
     DeviceState *dev = opaque;
9ae3a8
@@ -139,6 +151,21 @@ static const char *find_typename_by_alias(const char *alias)
9ae3a8
     return NULL;
9ae3a8
 }
9ae3a8
 
9ae3a8
+static void qdev_print_category_devices(DeviceCategory category)
9ae3a8
+{
9ae3a8
+    DeviceClass *dc;
9ae3a8
+    GSList *list, *curr;
9ae3a8
+
9ae3a8
+    list = object_class_get_list(TYPE_DEVICE, false);
9ae3a8
+    for (curr = list; curr; curr = g_slist_next(curr)) {
9ae3a8
+        dc = (DeviceClass *)object_class_dynamic_cast(curr->data, TYPE_DEVICE);
9ae3a8
+        if (!dc->no_user && test_bit(category, dc->categories)) {
9ae3a8
+            qdev_print_class_devinfo(dc);
9ae3a8
+        }
9ae3a8
+    }
9ae3a8
+    g_slist_free(list);
9ae3a8
+}
9ae3a8
+
9ae3a8
 int qdev_device_help(QemuOpts *opts)
9ae3a8
 {
9ae3a8
     const char *driver;
9ae3a8
@@ -147,8 +174,11 @@ int qdev_device_help(QemuOpts *opts)
9ae3a8
 
9ae3a8
     driver = qemu_opt_get(opts, "driver");
9ae3a8
     if (driver && is_help_option(driver)) {
9ae3a8
-        bool show_no_user = false;
9ae3a8
-        object_class_foreach(qdev_print_devinfo, TYPE_DEVICE, false, &show_no_user);
9ae3a8
+        DeviceCategory category;
9ae3a8
+        for (category = 0; category < DEVICE_CATEGORY_MAX; ++category) {
9ae3a8
+            qdev_print_category_devices(category);
9ae3a8
+        }
9ae3a8
+
9ae3a8
         return 1;
9ae3a8
     }
9ae3a8
 
9ae3a8
-- 
9ae3a8
1.7.1
9ae3a8