From: "Michael S. Tsirkin" <mst@redhat.com>
To: Marcel Apfelbaum <marcel.a@redhat.com>
Cc: pbonzini@redhat.com, aliguori@us.ibm.com, qemu-devel@nongnu.org,
afaerber@suse.de
Subject: Re: [Qemu-devel] [PATCH v4 2/3] qemu-help: Sort devices by logical functionality
Date: Mon, 29 Jul 2013 21:11:25 +0300 [thread overview]
Message-ID: <20130729181125.GC10704@redhat.com> (raw)
In-Reply-To: <1375107465-25767-3-git-send-email-marcel.a@redhat.com>
On Mon, Jul 29, 2013 at 05:17:44PM +0300, Marcel Apfelbaum wrote:
> Categorize devices that appear as output to "-device ?" command
> by logical functionality. Sort the devices by logical categories
> before showing them to user.
>
> The sort is done by functionality rather than alphabetical.
>
> Signed-off-by: Marcel Apfelbaum <marcel.a@redhat.com>
> ---
> Changes from v3:
> - fixed a memory leak introduced by v3
> Addressed Michael S. Tsirkin's review
> - removed dead code
> - qdev_print_class_devinfo can print info
> on abstract classes
> Addressed Paolo Bonzini's review
> - Renamed "Assembly" category to "Controller/Bridge/Hub"
>
> Changes from v2:
> Addressed Michael S. Tsirkin's review:
> - Explicit connection between the categories
> and their names
> - Refactoring of unsafe code
> Addressed Paolo Bonzini's review
> - Replaced Management category by USB
>
> Changes from v1:
> Addressed Michael S. Tsirkin's review:
> - Used bitmap operations on categories
> - Moved category names into the header file
>
> include/hw/qdev-core.h | 29 +++++++++++++++++++++++++++++
> qdev-monitor.c | 48 +++++++++++++++++++++++++++++++++++++++---------
> 2 files changed, 68 insertions(+), 9 deletions(-)
>
> diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
> index e8b89b1..46972f4 100644
> --- a/include/hw/qdev-core.h
> +++ b/include/hw/qdev-core.h
> @@ -18,6 +18,34 @@ enum {
> #define DEVICE_CLASS(klass) OBJECT_CLASS_CHECK(DeviceClass, (klass), TYPE_DEVICE)
> #define DEVICE_GET_CLASS(obj) OBJECT_GET_CLASS(DeviceClass, (obj), TYPE_DEVICE)
>
> +typedef enum DeviceCategory {
> + DEVICE_CATEGORY_BRIDGE,
> + DEVICE_CATEGORY_USB,
> + DEVICE_CATEGORY_STORAGE,
> + DEVICE_CATEGORY_NETWORK,
> + DEVICE_CATEGORY_INPUT,
> + DEVICE_CATEGORY_DISPLAY,
> + DEVICE_CATEGORY_SOUND,
> + DEVICE_CATEGORY_MISC,
> + DEVICE_CATEGORY_MAX
> +} DeviceCategory;
> +
> +static inline const char *qdev_category_get_name(DeviceCategory category)
> +{
> + static const char *category_names[DEVICE_CATEGORY_MAX] = {
> + [DEVICE_CATEGORY_BRIDGE] = "Controller/Bridge/Hub",
> + [DEVICE_CATEGORY_USB] = "USB",
> + [DEVICE_CATEGORY_STORAGE] = "Storage",
> + [DEVICE_CATEGORY_NETWORK] = "Network",
> + [DEVICE_CATEGORY_INPUT] = "Input",
> + [DEVICE_CATEGORY_DISPLAY] = "Display",
> + [DEVICE_CATEGORY_SOUND] = "Sound",
> + [DEVICE_CATEGORY_MISC] = "Misc",
> + };
> +
> + return category_names[category];
> +};
> +
> typedef int (*qdev_initfn)(DeviceState *dev);
> typedef int (*qdev_event)(DeviceState *dev);
> typedef void (*qdev_resetfn)(DeviceState *dev);
> @@ -81,6 +109,7 @@ typedef struct DeviceClass {
> ObjectClass parent_class;
> /*< public >*/
>
> + DECLARE_BITMAP(categories, DEVICE_CATEGORY_MAX);
> const char *fw_name;
> const char *desc;
> Property *props;
> diff --git a/qdev-monitor.c b/qdev-monitor.c
> index e54dbc2..230a8df 100644
> --- a/qdev-monitor.c
> +++ b/qdev-monitor.c
> @@ -75,24 +75,27 @@ static bool qdev_class_has_alias(DeviceClass *dc)
> return (qdev_class_get_alias(dc) != NULL);
> }
>
> -static void qdev_print_devinfo(ObjectClass *klass, void *opaque)
> +static void qdev_print_class_devinfo(DeviceClass *dc)
> {
> - DeviceClass *dc;
> - bool *show_no_user = opaque;
> -
> - dc = (DeviceClass *)object_class_dynamic_cast(klass, TYPE_DEVICE);
> + DeviceCategory category;
>
> - if (!dc || (show_no_user && !*show_no_user && dc->no_user)) {
> + if (!dc) {
> return;
> }
>
> - error_printf("name \"%s\"", object_class_get_name(klass));
> + error_printf("name \"%s\"", object_class_get_name(OBJECT_CLASS(dc)));
> if (dc->bus_type) {
> error_printf(", bus %s", dc->bus_type);
> }
> if (qdev_class_has_alias(dc)) {
> error_printf(", alias \"%s\"", qdev_class_get_alias(dc));
> }
> + error_printf(", categories");
> + for (category = 0; category < DEVICE_CATEGORY_MAX; ++category) {
> + if (test_bit(category, dc->categories)) {
> + error_printf(" \"%s\"", qdev_category_get_name(category));
> + }
> + }
> if (dc->desc) {
> error_printf(", desc \"%s\"", dc->desc);
> }
> @@ -102,6 +105,15 @@ static void qdev_print_devinfo(ObjectClass *klass, void *opaque)
> error_printf("\n");
> }
>
> +static void qdev_print_devinfo(ObjectClass *klass, void *opaque)
> +{
> + DeviceClass *dc;
> +
> + dc = (DeviceClass *)object_class_dynamic_cast(klass, TYPE_DEVICE);
> +
> + qdev_print_class_devinfo(dc);
> +}
> +
> static int set_property(const char *name, const char *value, void *opaque)
> {
> DeviceState *dev = opaque;
> @@ -139,6 +151,21 @@ static const char *find_typename_by_alias(const char *alias)
> return NULL;
> }
>
> +static void qdev_print_category_devices(DeviceCategory category)
> +{
> + DeviceClass *dc;
> + GSList *list, *curr;
> +
> + list = object_class_get_list(TYPE_DEVICE, false);
It's probably a bit cleaner to pass in the list, so we don't
end up building up/destroying it repeatedly for
each category.
> + for (curr = list; curr; curr = g_slist_next(curr)) {
> + dc = (DeviceClass *)object_class_dynamic_cast(curr->data, TYPE_DEVICE);
> + if (!dc->no_user && test_bit(category, dc->categories)) {
> + qdev_print_class_devinfo(dc);
> + }
> + }
> + g_slist_free(list);
> +}
> +
> int qdev_device_help(QemuOpts *opts)
> {
> const char *driver;
> @@ -147,8 +174,11 @@ int qdev_device_help(QemuOpts *opts)
>
> driver = qemu_opt_get(opts, "driver");
> if (driver && is_help_option(driver)) {
> - bool show_no_user = false;
> - object_class_foreach(qdev_print_devinfo, TYPE_DEVICE, false, &show_no_user);
> + DeviceCategory category;
> + for (category = 0; category < DEVICE_CATEGORY_MAX; ++category) {
> + qdev_print_category_devices(category);
> + }
> +
> return 1;
> }
>
> --
> 1.8.3.1
next prev parent reply other threads:[~2013-07-29 18:10 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-07-29 14:17 [Qemu-devel] [PATCH v4 0/3] qemu-help: improve -device command line help Marcel Apfelbaum
2013-07-29 14:17 ` [Qemu-devel] [PATCH v4 1/3] hw: import bitmap operations in qdev-core header Marcel Apfelbaum
2013-07-29 14:17 ` [Qemu-devel] [PATCH v4 2/3] qemu-help: Sort devices by logical functionality Marcel Apfelbaum
2013-07-29 18:11 ` Michael S. Tsirkin [this message]
2013-07-29 14:17 ` [Qemu-devel] [PATCH v4 3/3] devices: Associate devices to their logical category Marcel Apfelbaum
2013-07-29 18:11 ` [Qemu-devel] [PATCH v4 0/3] qemu-help: improve -device command line help Michael S. Tsirkin
2013-07-29 20:23 ` Anthony Liguori
2013-08-13 9:57 ` Markus Armbruster
2013-08-13 10:36 ` Michael S. Tsirkin
2013-08-13 12:06 ` Eric Blake
2013-08-21 7:47 ` Marcel Apfelbaum
2013-08-21 9:23 ` Markus Armbruster
2013-08-21 10:42 ` Marcel Apfelbaum
2013-08-21 12:38 ` Michael S. Tsirkin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20130729181125.GC10704@redhat.com \
--to=mst@redhat.com \
--cc=afaerber@suse.de \
--cc=aliguori@us.ibm.com \
--cc=marcel.a@redhat.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.