* [Qemu-devel] [PATCH v2 0/3] qemu-help: improve -device command line help
@ 2013-07-29 7:07 Marcel Apfelbaum
2013-07-29 7:07 ` [Qemu-devel] [PATCH v2 1/3] hw: import bitmap operations in qdev-core header Marcel Apfelbaum
` (2 more replies)
0 siblings, 3 replies; 12+ messages in thread
From: Marcel Apfelbaum @ 2013-07-29 7:07 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini, aliguori, Marcel Apfelbaum, afaerber, mst
Running qemu with "-device ?" option returns ~145 lines.
It is hard to manage understanding the output.
Theses patches aim to partially solve the problem by dividing the devices
into logical categories like "Network/Display/..." and sorting them by it.
Categories:
Assembly - hosts/hubs/...
Management - controllers
...
(All others are self explanatory)
Changes from v1:
Addressed Michael Tsirkin review:
Used bitmap operations on categories
Moved category names into the header file
Changes from RFC patch:
Made category a bitmap to support multifunction PCI devices.
Assigned all devices to their category.
Marcel Apfelbaum (3):
hw: import bitmap operations in qdev-core header
qemu-help: Sort devices by logical functionality
devices: Associate devices to their logical category
hw/9pfs/virtio-9p-device.c | 1 +
hw/audio/ac97.c | 1 +
hw/audio/adlib.c | 1 +
hw/audio/cs4231a.c | 1 +
hw/audio/es1370.c | 1 +
hw/audio/gus.c | 1 +
hw/audio/hda-codec.c | 3 +++
hw/audio/intel-hda.c | 3 +++
hw/audio/pcspk.c | 1 +
hw/audio/pl041.c | 1 +
hw/audio/sb16.c | 1 +
hw/block/fdc.c | 3 +++
hw/block/nvme.c | 1 +
hw/block/pc_sysfw.c | 1 +
hw/block/pflash_cfi01.c | 1 +
hw/block/virtio-blk.c | 1 +
hw/char/debugcon.c | 1 +
hw/char/imx_serial.c | 1 +
hw/char/ipack.c | 1 +
hw/char/ipoctal232.c | 1 +
hw/char/parallel.c | 1 +
hw/char/serial-isa.c | 1 +
hw/char/serial-pci.c | 3 +++
hw/char/tpci200.c | 1 +
hw/char/virtio-serial-bus.c | 2 ++
hw/core/qdev-properties.c | 4 +--
hw/cpu/icc_bus.c | 8 ++++++
hw/display/cirrus_vga.c | 2 ++
hw/display/g364fb.c | 1 +
hw/display/pl110.c | 3 +++
hw/display/qxl.c | 2 ++
hw/display/vga-isa.c | 1 +
hw/display/vga-pci.c | 1 +
hw/display/vmware_vga.c | 1 +
hw/i2c/bitbang_i2c.c | 1 +
hw/i2c/core.c | 1 +
hw/i386/kvm/pci-assign.c | 1 +
hw/ide/ahci.c | 1 +
hw/ide/ich.c | 1 +
hw/ide/isa.c | 1 +
hw/ide/piix.c | 3 +++
hw/ide/qdev.c | 1 +
hw/ide/via.c | 1 +
hw/isa/i82378.c | 1 +
hw/isa/lpc_ich9.c | 1 +
hw/isa/vt82c686.c | 3 +++
hw/misc/applesmc.c | 1 +
hw/misc/debugexit.c | 1 +
hw/misc/ivshmem.c | 1 +
hw/misc/pc-testdev.c | 1 +
hw/misc/pci-testdev.c | 1 +
hw/misc/sga.c | 1 +
hw/misc/vfio.c | 1 +
hw/net/e1000.c | 1 +
hw/net/eepro100.c | 2 +-
hw/net/lance.c | 1 +
hw/net/mipsnet.c | 1 +
hw/net/ne2000-isa.c | 1 +
hw/net/ne2000.c | 1 +
hw/net/opencores_eth.c | 1 +
hw/net/pcnet-pci.c | 1 +
hw/net/rtl8139.c | 1 +
hw/net/virtio-net.c | 1 +
hw/net/vmxnet3.c | 1 +
hw/pci-bridge/i82801b11.c | 2 ++
hw/pci-bridge/ioh3420.c | 1 +
hw/pci-bridge/pci_bridge_dev.c | 1 +
hw/pci-bridge/xio3130_downstream.c | 1 +
hw/pci-bridge/xio3130_upstream.c | 1 +
hw/pci-host/apb.c | 2 ++
hw/pci-host/ppce500.c | 1 +
hw/pci-host/prep.c | 1 +
hw/pci-host/q35.c | 2 ++
hw/scsi/esp-pci.c | 2 ++
hw/scsi/esp.c | 1 +
hw/scsi/lsi53c895a.c | 1 +
hw/scsi/megasas.c | 1 +
hw/scsi/scsi-bus.c | 1 +
hw/scsi/vhost-scsi.c | 1 +
hw/scsi/virtio-scsi.c | 3 +++
hw/scsi/vmw_pvscsi.c | 1 +
hw/usb/ccid-card-emulated.c | 1 +
hw/usb/ccid-card-passthru.c | 1 +
hw/usb/dev-audio.c | 1 +
hw/usb/dev-bluetooth.c | 1 +
hw/usb/dev-hid.c | 3 +++
hw/usb/dev-hub.c | 1 +
hw/usb/dev-network.c | 1 +
hw/usb/dev-serial.c | 2 ++
hw/usb/dev-smartcard-reader.c | 1 +
hw/usb/dev-storage.c | 1 +
hw/usb/dev-uas.c | 1 +
hw/usb/dev-wacom.c | 1 +
hw/usb/hcd-ehci-pci.c | 2 ++
hw/usb/hcd-ehci-sysbus.c | 9 +++++++
hw/usb/hcd-ohci.c | 2 ++
hw/usb/hcd-uhci.c | 1 +
hw/usb/hcd-xhci.c | 1 +
hw/usb/host-libusb.c | 1 +
hw/usb/host-linux.c | 1 +
hw/usb/redirect.c | 1 +
hw/virtio/virtio-balloon.c | 1 +
hw/virtio/virtio-mmio.c | 1 +
hw/virtio/virtio-pci.c | 8 ++++++
hw/virtio/virtio-rng.c | 1 +
hw/watchdog/wdt_i6300esb.c | 1 +
hw/watchdog/wdt_ib700.c | 1 +
hw/xen/xen_platform.c | 1 +
hw/xen/xen_pt.c | 1 +
include/hw/qdev-core.h | 34 ++++++++++++++++++++++++++
qdev-monitor.c | 50 +++++++++++++++++++++++++++++++++++---
111 files changed, 240 insertions(+), 7 deletions(-)
--
1.8.3.1
^ permalink raw reply [flat|nested] 12+ messages in thread
* [Qemu-devel] [PATCH v2 1/3] hw: import bitmap operations in qdev-core header
2013-07-29 7:07 [Qemu-devel] [PATCH v2 0/3] qemu-help: improve -device command line help Marcel Apfelbaum
@ 2013-07-29 7:07 ` Marcel Apfelbaum
2013-07-29 7:42 ` Michael S. Tsirkin
2013-07-29 7:07 ` [Qemu-devel] [PATCH v2 2/3] qemu-help: Sort devices by logical functionality Marcel Apfelbaum
2013-07-29 7:07 ` [Qemu-devel] [PATCH v2 3/3] devices: Associate devices to their logical category Marcel Apfelbaum
2 siblings, 1 reply; 12+ messages in thread
From: Marcel Apfelbaum @ 2013-07-29 7:07 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini, aliguori, Marcel Apfelbaum, afaerber, mst
Made small tweaks in code to prevent compilation issues
when importing qemu/bitmap.h in qdev-core
Signed-off-by: Marcel Apfelbaum <marcel.a@redhat.com>
---
hw/core/qdev-properties.c | 4 ++--
hw/net/eepro100.c | 1 -
include/hw/qdev-core.h | 1 +
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 3a324fb..01b27eb 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -91,7 +91,7 @@ static void get_bit(Object *obj, Visitor *v, void *opaque,
visit_type_bool(v, &value, name, errp);
}
-static void set_bit(Object *obj, Visitor *v, void *opaque,
+static void prop_set_bit(Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp)
{
DeviceState *dev = DEVICE(obj);
@@ -117,7 +117,7 @@ PropertyInfo qdev_prop_bit = {
.legacy_name = "on/off",
.print = print_bit,
.get = get_bit,
- .set = set_bit,
+ .set = prop_set_bit,
};
/* --- bool --- */
diff --git a/hw/net/eepro100.c b/hw/net/eepro100.c
index e0befb2..3dc4937 100644
--- a/hw/net/eepro100.c
+++ b/hw/net/eepro100.c
@@ -105,7 +105,6 @@
#define PCI_IO_SIZE 64
#define PCI_FLASH_SIZE (128 * KiB)
-#define BIT(n) (1 << (n))
#define BITS(n, m) (((0xffffffffU << (31 - n)) >> (31 - n + m)) << m)
/* The SCB accepts the following controls for the Tx and Rx units: */
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index 7fbffcb..e8b89b1 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -4,6 +4,7 @@
#include "qemu/queue.h"
#include "qemu/option.h"
#include "qemu/typedefs.h"
+#include "qemu/bitmap.h"
#include "qom/object.h"
#include "hw/irq.h"
#include "qapi/error.h"
--
1.8.3.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [Qemu-devel] [PATCH v2 2/3] qemu-help: Sort devices by logical functionality
2013-07-29 7:07 [Qemu-devel] [PATCH v2 0/3] qemu-help: improve -device command line help Marcel Apfelbaum
2013-07-29 7:07 ` [Qemu-devel] [PATCH v2 1/3] hw: import bitmap operations in qdev-core header Marcel Apfelbaum
@ 2013-07-29 7:07 ` Marcel Apfelbaum
2013-07-29 8:04 ` Michael S. Tsirkin
2013-07-29 7:07 ` [Qemu-devel] [PATCH v2 3/3] devices: Associate devices to their logical category Marcel Apfelbaum
2 siblings, 1 reply; 12+ messages in thread
From: Marcel Apfelbaum @ 2013-07-29 7:07 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini, aliguori, Marcel Apfelbaum, afaerber, mst
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 v1:
Addressed Michael Tsirkin review:
Used bitmap operations on categories
Moved category names into the header file
include/hw/qdev-core.h | 33 +++++++++++++++++++++++++++++++++
qdev-monitor.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++----
2 files changed, 79 insertions(+), 4 deletions(-)
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index e8b89b1..80b06ac 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -18,6 +18,38 @@ 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_ASSEMBLY,
+ DEVICE_CATEGORY_MANAGEMENT,
+ 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)
+{
+ /* Category names corresponding to DeviceCategory values
+ * The array elements must be in the same order as they
+ * appear in DeviceCategory enum.
+ */
+ static const char *category_names[] = {
+ "Assembly",
+ "Management",
+ "Storage",
+ "Network",
+ "Input",
+ "Display",
+ "Sound",
+ "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 +113,7 @@ typedef struct DeviceClass {
ObjectClass parent_class;
/*< public >*/
+ DECLARE_BITMAP(categories, 20);
const char *fw_name;
const char *desc;
Property *props;
diff --git a/qdev-monitor.c b/qdev-monitor.c
index e54dbc2..c3a3550 100644
--- a/qdev-monitor.c
+++ b/qdev-monitor.c
@@ -75,14 +75,21 @@ static bool qdev_class_has_alias(DeviceClass *dc)
return (qdev_class_get_alias(dc) != NULL);
}
+typedef struct PrintDevInfoData {
+ bool show_no_user;
+ DeviceCategory category;
+} PrintDevInfoData ;
+
static void qdev_print_devinfo(ObjectClass *klass, void *opaque)
{
DeviceClass *dc;
- bool *show_no_user = opaque;
+ PrintDevInfoData *data = opaque;
+ DeviceCategory category;
+ category = data ? data->category : DEVICE_CATEGORY_MAX;
dc = (DeviceClass *)object_class_dynamic_cast(klass, TYPE_DEVICE);
- if (!dc || (show_no_user && !*show_no_user && dc->no_user)) {
+ if (!dc || (data && !data->show_no_user && dc->no_user)) {
return;
}
@@ -93,6 +100,18 @@ static void qdev_print_devinfo(ObjectClass *klass, void *opaque)
if (qdev_class_has_alias(dc)) {
error_printf(", alias \"%s\"", qdev_class_get_alias(dc));
}
+ if (dc->categories) {
+ if (test_bit(category, dc->categories)) {
+ error_printf(", category \"%s\"", qdev_category_get_name(category));
+ } else {
+ 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);
}
@@ -139,6 +158,23 @@ static const char *find_typename_by_alias(const char *alias)
return NULL;
}
+static GSList *qdev_get_devices_by_category(DeviceCategory category)
+{
+ DeviceClass *dc;
+ GSList *list, *curr, *ret_list = NULL;
+
+ list = object_class_get_list(TYPE_DEVICE, false);
+ for (curr = list; curr; curr = g_slist_next(curr)) {
+ dc = (DeviceClass *)object_class_dynamic_cast(curr->data, TYPE_DEVICE);
+ if (test_bit(category, dc->categories)) {
+ ret_list = g_slist_append(ret_list, dc);
+ }
+ }
+ g_slist_free(list);
+
+ return ret_list;
+}
+
int qdev_device_help(QemuOpts *opts)
{
const char *driver;
@@ -147,8 +183,14 @@ 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) {
+ PrintDevInfoData data = { false, category };
+ GSList *list = qdev_get_devices_by_category(category);
+ g_slist_foreach(list, (GFunc)qdev_print_devinfo, &data);
+ g_slist_free(list);
+ }
+
return 1;
}
--
1.8.3.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [Qemu-devel] [PATCH v2 3/3] devices: Associate devices to their logical category
2013-07-29 7:07 [Qemu-devel] [PATCH v2 0/3] qemu-help: improve -device command line help Marcel Apfelbaum
2013-07-29 7:07 ` [Qemu-devel] [PATCH v2 1/3] hw: import bitmap operations in qdev-core header Marcel Apfelbaum
2013-07-29 7:07 ` [Qemu-devel] [PATCH v2 2/3] qemu-help: Sort devices by logical functionality Marcel Apfelbaum
@ 2013-07-29 7:07 ` Marcel Apfelbaum
2 siblings, 0 replies; 12+ messages in thread
From: Marcel Apfelbaum @ 2013-07-29 7:07 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini, aliguori, Marcel Apfelbaum, afaerber, mst
The category will be used to sort the devices displayed in
the command line help.
Signed-off-by: Marcel Apfelbaum <marcel.a@redhat.com>
---
Changes from v1:
Addressed Michael Tsirkin review:
Categories are now selected using set_bit instead of
manual shifting
hw/9pfs/virtio-9p-device.c | 1 +
hw/audio/ac97.c | 1 +
hw/audio/adlib.c | 1 +
hw/audio/cs4231a.c | 1 +
hw/audio/es1370.c | 1 +
hw/audio/gus.c | 1 +
hw/audio/hda-codec.c | 3 +++
hw/audio/intel-hda.c | 3 +++
hw/audio/pcspk.c | 1 +
hw/audio/pl041.c | 1 +
hw/audio/sb16.c | 1 +
hw/block/fdc.c | 3 +++
hw/block/nvme.c | 1 +
hw/block/pc_sysfw.c | 1 +
hw/block/pflash_cfi01.c | 1 +
hw/block/virtio-blk.c | 1 +
hw/char/debugcon.c | 1 +
hw/char/imx_serial.c | 1 +
hw/char/ipack.c | 1 +
hw/char/ipoctal232.c | 1 +
hw/char/parallel.c | 1 +
hw/char/serial-isa.c | 1 +
hw/char/serial-pci.c | 3 +++
hw/char/tpci200.c | 1 +
hw/char/virtio-serial-bus.c | 2 ++
hw/cpu/icc_bus.c | 8 ++++++++
hw/display/cirrus_vga.c | 2 ++
hw/display/g364fb.c | 1 +
hw/display/pl110.c | 3 +++
hw/display/qxl.c | 2 ++
hw/display/vga-isa.c | 1 +
hw/display/vga-pci.c | 1 +
hw/display/vmware_vga.c | 1 +
hw/i2c/bitbang_i2c.c | 1 +
hw/i2c/core.c | 1 +
hw/i386/kvm/pci-assign.c | 1 +
hw/ide/ahci.c | 1 +
hw/ide/ich.c | 1 +
hw/ide/isa.c | 1 +
hw/ide/piix.c | 3 +++
hw/ide/qdev.c | 1 +
hw/ide/via.c | 1 +
hw/isa/i82378.c | 1 +
hw/isa/lpc_ich9.c | 1 +
hw/isa/vt82c686.c | 3 +++
hw/misc/applesmc.c | 1 +
hw/misc/debugexit.c | 1 +
hw/misc/ivshmem.c | 1 +
hw/misc/pc-testdev.c | 1 +
hw/misc/pci-testdev.c | 1 +
hw/misc/sga.c | 1 +
hw/misc/vfio.c | 1 +
hw/net/e1000.c | 1 +
hw/net/eepro100.c | 1 +
hw/net/lance.c | 1 +
hw/net/mipsnet.c | 1 +
hw/net/ne2000-isa.c | 1 +
hw/net/ne2000.c | 1 +
hw/net/opencores_eth.c | 1 +
hw/net/pcnet-pci.c | 1 +
hw/net/rtl8139.c | 1 +
hw/net/virtio-net.c | 1 +
hw/net/vmxnet3.c | 1 +
hw/pci-bridge/i82801b11.c | 2 ++
hw/pci-bridge/ioh3420.c | 1 +
hw/pci-bridge/pci_bridge_dev.c | 1 +
hw/pci-bridge/xio3130_downstream.c | 1 +
hw/pci-bridge/xio3130_upstream.c | 1 +
hw/pci-host/apb.c | 2 ++
hw/pci-host/ppce500.c | 1 +
hw/pci-host/prep.c | 1 +
hw/pci-host/q35.c | 2 ++
hw/scsi/esp-pci.c | 2 ++
hw/scsi/esp.c | 1 +
hw/scsi/lsi53c895a.c | 1 +
hw/scsi/megasas.c | 1 +
hw/scsi/scsi-bus.c | 1 +
hw/scsi/vhost-scsi.c | 1 +
hw/scsi/virtio-scsi.c | 3 +++
hw/scsi/vmw_pvscsi.c | 1 +
hw/usb/ccid-card-emulated.c | 1 +
hw/usb/ccid-card-passthru.c | 1 +
hw/usb/dev-audio.c | 1 +
hw/usb/dev-bluetooth.c | 1 +
hw/usb/dev-hid.c | 3 +++
hw/usb/dev-hub.c | 1 +
hw/usb/dev-network.c | 1 +
hw/usb/dev-serial.c | 2 ++
hw/usb/dev-smartcard-reader.c | 1 +
hw/usb/dev-storage.c | 1 +
hw/usb/dev-uas.c | 1 +
hw/usb/dev-wacom.c | 1 +
hw/usb/hcd-ehci-pci.c | 2 ++
hw/usb/hcd-ehci-sysbus.c | 9 +++++++++
hw/usb/hcd-ohci.c | 2 ++
hw/usb/hcd-uhci.c | 1 +
hw/usb/hcd-xhci.c | 1 +
hw/usb/host-libusb.c | 1 +
hw/usb/host-linux.c | 1 +
hw/usb/redirect.c | 1 +
hw/virtio/virtio-balloon.c | 1 +
hw/virtio/virtio-mmio.c | 1 +
hw/virtio/virtio-pci.c | 8 ++++++++
hw/virtio/virtio-rng.c | 1 +
hw/watchdog/wdt_i6300esb.c | 1 +
hw/watchdog/wdt_ib700.c | 1 +
hw/xen/xen_platform.c | 1 +
hw/xen/xen_pt.c | 1 +
108 files changed, 158 insertions(+)
diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c
index 35e2af4..de6f0fe 100644
--- a/hw/9pfs/virtio-9p-device.c
+++ b/hw/9pfs/virtio-9p-device.c
@@ -149,6 +149,7 @@ static void virtio_9p_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
dc->props = virtio_9p_properties;
+ set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
vdc->init = virtio_9p_device_init;
vdc->get_features = virtio_9p_get_features;
vdc->get_config = virtio_9p_get_config;
diff --git a/hw/audio/ac97.c b/hw/audio/ac97.c
index 365b2f1..01b4dfb 100644
--- a/hw/audio/ac97.c
+++ b/hw/audio/ac97.c
@@ -1420,6 +1420,7 @@ static void ac97_class_init (ObjectClass *klass, void *data)
k->device_id = PCI_DEVICE_ID_INTEL_82801AA_5;
k->revision = 0x01;
k->class_id = PCI_CLASS_MULTIMEDIA_AUDIO;
+ set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
dc->desc = "Intel 82801AA AC97 Audio";
dc->vmsd = &vmstate_ac97;
dc->props = ac97_properties;
diff --git a/hw/audio/adlib.c b/hw/audio/adlib.c
index f72e6ee..0421d47 100644
--- a/hw/audio/adlib.c
+++ b/hw/audio/adlib.c
@@ -364,6 +364,7 @@ static void adlib_class_initfn (ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS (klass);
dc->realize = adlib_realizefn;
+ set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
dc->desc = ADLIB_DESC;
dc->props = adlib_properties;
}
diff --git a/hw/audio/cs4231a.c b/hw/audio/cs4231a.c
index 7365c3c..666096b 100644
--- a/hw/audio/cs4231a.c
+++ b/hw/audio/cs4231a.c
@@ -685,6 +685,7 @@ static void cs4231a_class_initfn (ObjectClass *klass, void *data)
dc->realize = cs4231a_realizefn;
dc->reset = cs4231a_reset;
+ set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
dc->desc = "Crystal Semiconductor CS4231A";
dc->vmsd = &vmstate_cs4231a;
dc->props = cs4231a_properties;
diff --git a/hw/audio/es1370.c b/hw/audio/es1370.c
index f2c40da..adb66ce 100644
--- a/hw/audio/es1370.c
+++ b/hw/audio/es1370.c
@@ -1069,6 +1069,7 @@ static void es1370_class_init (ObjectClass *klass, void *data)
k->class_id = PCI_CLASS_MULTIMEDIA_AUDIO;
k->subsystem_vendor_id = 0x4942;
k->subsystem_id = 0x4c4c;
+ set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
dc->desc = "ENSONIQ AudioPCI ES1370";
dc->vmsd = &vmstate_es1370;
}
diff --git a/hw/audio/gus.c b/hw/audio/gus.c
index f45ed0b..71be3c6 100644
--- a/hw/audio/gus.c
+++ b/hw/audio/gus.c
@@ -315,6 +315,7 @@ static void gus_class_initfn (ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS (klass);
dc->realize = gus_realizefn;
+ set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
dc->desc = "Gravis Ultrasound GF1";
dc->vmsd = &vmstate_gus;
dc->props = gus_properties;
diff --git a/hw/audio/hda-codec.c b/hw/audio/hda-codec.c
index 362d8c0..9550c97 100644
--- a/hw/audio/hda-codec.c
+++ b/hw/audio/hda-codec.c
@@ -1034,6 +1034,7 @@ static void hda_audio_output_class_init(ObjectClass *klass, void *data)
k->exit = hda_audio_exit;
k->command = hda_audio_command;
k->stream = hda_audio_stream;
+ set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
dc->desc = "HDA Audio Codec, output-only (line-out)";
dc->vmsd = &vmstate_hda_audio;
dc->props = hda_audio_properties;
@@ -1055,6 +1056,7 @@ static void hda_audio_duplex_class_init(ObjectClass *klass, void *data)
k->exit = hda_audio_exit;
k->command = hda_audio_command;
k->stream = hda_audio_stream;
+ set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
dc->desc = "HDA Audio Codec, duplex (line-out, line-in)";
dc->vmsd = &vmstate_hda_audio;
dc->props = hda_audio_properties;
@@ -1076,6 +1078,7 @@ static void hda_audio_micro_class_init(ObjectClass *klass, void *data)
k->exit = hda_audio_exit;
k->command = hda_audio_command;
k->stream = hda_audio_stream;
+ set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
dc->desc = "HDA Audio Codec, duplex (speaker, microphone)";
dc->vmsd = &vmstate_hda_audio;
dc->props = hda_audio_properties;
diff --git a/hw/audio/intel-hda.c b/hw/audio/intel-hda.c
index 58984dc..32e44ad 100644
--- a/hw/audio/intel-hda.c
+++ b/hw/audio/intel-hda.c
@@ -1258,6 +1258,7 @@ static void intel_hda_class_init_ich6(ObjectClass *klass, void *data)
k->device_id = 0x2668;
k->revision = 1;
+ set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
dc->desc = "Intel HD Audio Controller (ich6)";
}
@@ -1268,6 +1269,7 @@ static void intel_hda_class_init_ich9(ObjectClass *klass, void *data)
k->device_id = 0x293e;
k->revision = 3;
+ set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
dc->desc = "Intel HD Audio Controller (ich9)";
}
@@ -1296,6 +1298,7 @@ static void hda_codec_device_class_init(ObjectClass *klass, void *data)
DeviceClass *k = DEVICE_CLASS(klass);
k->init = hda_codec_dev_init;
k->exit = hda_codec_dev_exit;
+ set_bit(DEVICE_CATEGORY_SOUND, k->categories);
k->bus_type = TYPE_HDA_BUS;
k->props = hda_props;
}
diff --git a/hw/audio/pcspk.c b/hw/audio/pcspk.c
index 7ad59a1..9004ce3 100644
--- a/hw/audio/pcspk.c
+++ b/hw/audio/pcspk.c
@@ -191,6 +191,7 @@ static void pcspk_class_initfn(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
dc->realize = pcspk_realizefn;
+ set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
dc->no_user = 1;
dc->props = pcspk_properties;
}
diff --git a/hw/audio/pl041.c b/hw/audio/pl041.c
index 7d331b9..b66d6d2 100644
--- a/hw/audio/pl041.c
+++ b/hw/audio/pl041.c
@@ -626,6 +626,7 @@ static void pl041_device_class_init(ObjectClass *klass, void *data)
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
k->init = pl041_init;
+ set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
dc->no_user = 1;
dc->reset = pl041_device_reset;
dc->vmsd = &vmstate_pl041;
diff --git a/hw/audio/sb16.c b/hw/audio/sb16.c
index e697bc1..3e58688 100644
--- a/hw/audio/sb16.c
+++ b/hw/audio/sb16.c
@@ -1412,6 +1412,7 @@ static void sb16_class_initfn (ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS (klass);
dc->realize = sb16_realizefn;
+ set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
dc->desc = "Creative Sound Blaster 16";
dc->vmsd = &vmstate_sb16;
dc->props = sb16_properties;
diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index d32f6ba..50a350f 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -2249,6 +2249,7 @@ static void isabus_fdc_class_init(ObjectClass *klass, void *data)
dc->reset = fdctrl_external_reset_isa;
dc->vmsd = &vmstate_isa_fdc;
dc->props = isa_fdc_properties;
+ set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
}
static const TypeInfo isa_fdc_info = {
@@ -2282,6 +2283,7 @@ static void sysbus_fdc_class_init(ObjectClass *klass, void *data)
dc->reset = fdctrl_external_reset_sysbus;
dc->vmsd = &vmstate_sysbus_fdc;
dc->props = sysbus_fdc_properties;
+ set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
}
static const TypeInfo sysbus_fdc_info = {
@@ -2305,6 +2307,7 @@ static void sun4m_fdc_class_init(ObjectClass *klass, void *data)
dc->reset = fdctrl_external_reset_sysbus;
dc->vmsd = &vmstate_sysbus_fdc;
dc->props = sun4m_fdc_properties;
+ set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
}
static const TypeInfo sun4m_fdc_info = {
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index f15f04a..0263e5c 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -866,6 +866,7 @@ static void nvme_class_init(ObjectClass *oc, void *data)
pc->revision = 1;
pc->is_express = 1;
+ set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
dc->desc = "Non-Volatile Memory Express";
dc->props = nvme_props;
dc->vmsd = &nvme_vmstate;
diff --git a/hw/block/pc_sysfw.c b/hw/block/pc_sysfw.c
index 0669410..7db68f0 100644
--- a/hw/block/pc_sysfw.c
+++ b/hw/block/pc_sysfw.c
@@ -286,6 +286,7 @@ static void pcsysfw_class_init (ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS (klass);
+ set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
dc->desc = "PC System Firmware";
dc->init = pcsysfw_init;
dc->props = pcsysfw_properties;
diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c
index 2973859..825011d 100644
--- a/hw/block/pflash_cfi01.c
+++ b/hw/block/pflash_cfi01.c
@@ -723,6 +723,7 @@ static void pflash_cfi01_class_init(ObjectClass *klass, void *data)
dc->realize = pflash_cfi01_realize;
dc->props = pflash_cfi01_properties;
dc->vmsd = &vmstate_pflash;
+ set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
}
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index cf12469..a786233 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -704,6 +704,7 @@ static void virtio_blk_class_init(ObjectClass *klass, void *data)
VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
dc->exit = virtio_blk_device_exit;
dc->props = virtio_blk_properties;
+ set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
vdc->init = virtio_blk_device_init;
vdc->get_config = virtio_blk_update_config;
vdc->set_config = virtio_blk_set_config;
diff --git a/hw/char/debugcon.c b/hw/char/debugcon.c
index 03db12f..02d0d57 100644
--- a/hw/char/debugcon.c
+++ b/hw/char/debugcon.c
@@ -122,6 +122,7 @@ static void debugcon_isa_class_initfn(ObjectClass *klass, void *data)
dc->realize = debugcon_isa_realizefn;
dc->props = debugcon_isa_properties;
+ set_bit(DEVICE_CATEGORY_MISC, dc->categories);
}
static const TypeInfo debugcon_isa_info = {
diff --git a/hw/char/imx_serial.c b/hw/char/imx_serial.c
index 69b9ed2..5c17eaa 100644
--- a/hw/char/imx_serial.c
+++ b/hw/char/imx_serial.c
@@ -449,6 +449,7 @@ static void imx_serial_class_init(ObjectClass *klass, void *data)
k->init = imx_serial_init;
dc->vmsd = &vmstate_imx_serial;
dc->reset = imx_serial_reset_at_boot;
+ set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
dc->desc = "i.MX series UART";
dc->props = imx32_serial_properties;
}
diff --git a/hw/char/ipack.c b/hw/char/ipack.c
index e15540d..f890471 100644
--- a/hw/char/ipack.c
+++ b/hw/char/ipack.c
@@ -74,6 +74,7 @@ static Property ipack_device_props[] = {
static void ipack_device_class_init(ObjectClass *klass, void *data)
{
DeviceClass *k = DEVICE_CLASS(klass);
+ set_bit(DEVICE_CATEGORY_INPUT, k->categories);
k->bus_type = TYPE_IPACK_BUS;
k->init = ipack_device_dev_init;
k->exit = ipack_device_dev_exit;
diff --git a/hw/char/ipoctal232.c b/hw/char/ipoctal232.c
index c9698a6..88e2cca 100644
--- a/hw/char/ipoctal232.c
+++ b/hw/char/ipoctal232.c
@@ -585,6 +585,7 @@ static void ipoctal_class_init(ObjectClass *klass, void *data)
ic->mem_read8 = mem_read8;
ic->mem_write8 = mem_write8;
+ set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
dc->desc = "GE IP-Octal 232 8-channel RS-232 IndustryPack";
dc->props = ipoctal_properties;
dc->vmsd = &vmstate_ipoctal;
diff --git a/hw/char/parallel.c b/hw/char/parallel.c
index ad96ea5..7a3b264 100644
--- a/hw/char/parallel.c
+++ b/hw/char/parallel.c
@@ -607,6 +607,7 @@ static void parallel_isa_class_initfn(ObjectClass *klass, void *data)
dc->realize = parallel_isa_realizefn;
dc->props = parallel_isa_properties;
+ set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
}
static const TypeInfo parallel_isa_info = {
diff --git a/hw/char/serial-isa.c b/hw/char/serial-isa.c
index cea8212..5cb77b3 100644
--- a/hw/char/serial-isa.c
+++ b/hw/char/serial-isa.c
@@ -102,6 +102,7 @@ static void serial_isa_class_initfn(ObjectClass *klass, void *data)
dc->realize = serial_isa_realizefn;
dc->vmsd = &vmstate_isa_serial;
dc->props = serial_isa_properties;
+ set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
}
static const TypeInfo serial_isa_info = {
diff --git a/hw/char/serial-pci.c b/hw/char/serial-pci.c
index a17c702..aec6705 100644
--- a/hw/char/serial-pci.c
+++ b/hw/char/serial-pci.c
@@ -205,6 +205,7 @@ static void serial_pci_class_initfn(ObjectClass *klass, void *data)
pc->class_id = PCI_CLASS_COMMUNICATION_SERIAL;
dc->vmsd = &vmstate_pci_serial;
dc->props = serial_pci_properties;
+ set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
}
static void multi_2x_serial_pci_class_initfn(ObjectClass *klass, void *data)
@@ -219,6 +220,7 @@ static void multi_2x_serial_pci_class_initfn(ObjectClass *klass, void *data)
pc->class_id = PCI_CLASS_COMMUNICATION_SERIAL;
dc->vmsd = &vmstate_pci_multi_serial;
dc->props = multi_2x_serial_pci_properties;
+ set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
}
static void multi_4x_serial_pci_class_initfn(ObjectClass *klass, void *data)
@@ -233,6 +235,7 @@ static void multi_4x_serial_pci_class_initfn(ObjectClass *klass, void *data)
pc->class_id = PCI_CLASS_COMMUNICATION_SERIAL;
dc->vmsd = &vmstate_pci_multi_serial;
dc->props = multi_4x_serial_pci_properties;
+ set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
}
static const TypeInfo serial_pci_info = {
diff --git a/hw/char/tpci200.c b/hw/char/tpci200.c
index a199e57..d9e17b2 100644
--- a/hw/char/tpci200.c
+++ b/hw/char/tpci200.c
@@ -652,6 +652,7 @@ static void tpci200_class_init(ObjectClass *klass, void *data)
k->class_id = PCI_CLASS_BRIDGE_OTHER;
k->subsystem_vendor_id = PCI_VENDOR_ID_TEWS;
k->subsystem_id = 0x300A;
+ set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
dc->desc = "TEWS TPCI200 IndustryPack carrier";
dc->vmsd = &vmstate_tpci200;
}
diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
index cc3d1dd..da417c7 100644
--- a/hw/char/virtio-serial-bus.c
+++ b/hw/char/virtio-serial-bus.c
@@ -971,6 +971,7 @@ static void virtio_serial_port_class_init(ObjectClass *klass, void *data)
{
DeviceClass *k = DEVICE_CLASS(klass);
k->init = virtser_port_qdev_init;
+ set_bit(DEVICE_CATEGORY_INPUT, k->categories);
k->bus_type = TYPE_VIRTIO_SERIAL_BUS;
k->exit = virtser_port_qdev_exit;
k->unplug = qdev_simple_unplug_cb;
@@ -1017,6 +1018,7 @@ static void virtio_serial_class_init(ObjectClass *klass, void *data)
VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
dc->exit = virtio_serial_device_exit;
dc->props = virtio_serial_properties;
+ set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
vdc->init = virtio_serial_device_init;
vdc->get_features = get_features;
vdc->get_config = get_config;
diff --git a/hw/cpu/icc_bus.c b/hw/cpu/icc_bus.c
index 8788144..8e8d763 100644
--- a/hw/cpu/icc_bus.c
+++ b/hw/cpu/icc_bus.c
@@ -101,11 +101,19 @@ static void icc_bridge_init(Object *obj)
s->icc_bus.apic_address_space = &s->apic_container;
}
+static void icc_bridge_class_init(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+
+ set_bit(DEVICE_CATEGORY_ASSEMBLY, dc->categories);
+}
+
static const TypeInfo icc_bridge_info = {
.name = TYPE_ICC_BRIDGE,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_init = icc_bridge_init,
.instance_size = sizeof(ICCBridgeState),
+ .class_init = icc_bridge_class_init,
};
diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c
index a440575..dbd1f4a 100644
--- a/hw/display/cirrus_vga.c
+++ b/hw/display/cirrus_vga.c
@@ -2937,6 +2937,7 @@ static void isa_cirrus_vga_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_cirrus_vga;
dc->realize = isa_cirrus_vga_realizefn;
dc->props = isa_cirrus_vga_properties;
+ set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
}
static const TypeInfo isa_cirrus_vga_info = {
@@ -3002,6 +3003,7 @@ static void cirrus_vga_class_init(ObjectClass *klass, void *data)
k->vendor_id = PCI_VENDOR_ID_CIRRUS;
k->device_id = CIRRUS_ID_CLGD5446;
k->class_id = PCI_CLASS_DISPLAY_VGA;
+ set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
dc->desc = "Cirrus CLGD 54xx VGA";
dc->vmsd = &vmstate_pci_cirrus_vga;
dc->props = pci_vga_cirrus_properties;
diff --git a/hw/display/g364fb.c b/hw/display/g364fb.c
index 79a0a50..2d3e912 100644
--- a/hw/display/g364fb.c
+++ b/hw/display/g364fb.c
@@ -528,6 +528,7 @@ static void g364fb_sysbus_class_init(ObjectClass *klass, void *data)
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
k->init = g364fb_sysbus_init;
+ set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
dc->desc = "G364 framebuffer";
dc->reset = g364fb_sysbus_reset;
dc->vmsd = &vmstate_g364fb;
diff --git a/hw/display/pl110.c b/hw/display/pl110.c
index 60afcf3..31993a7 100644
--- a/hw/display/pl110.c
+++ b/hw/display/pl110.c
@@ -481,6 +481,7 @@ static void pl110_class_init(ObjectClass *klass, void *data)
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
k->init = pl110_init;
+ set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
dc->no_user = 1;
dc->vmsd = &vmstate_pl110;
}
@@ -498,6 +499,7 @@ static void pl110_versatile_class_init(ObjectClass *klass, void *data)
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
k->init = pl110_versatile_init;
+ set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
dc->no_user = 1;
dc->vmsd = &vmstate_pl110;
}
@@ -515,6 +517,7 @@ static void pl111_class_init(ObjectClass *klass, void *data)
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
k->init = pl111_init;
+ set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
dc->no_user = 1;
dc->vmsd = &vmstate_pl110;
}
diff --git a/hw/display/qxl.c b/hw/display/qxl.c
index ddefa06..c537057 100644
--- a/hw/display/qxl.c
+++ b/hw/display/qxl.c
@@ -2323,6 +2323,7 @@ static void qxl_primary_class_init(ObjectClass *klass, void *data)
k->vendor_id = REDHAT_PCI_VENDOR_ID;
k->device_id = QXL_DEVICE_ID_STABLE;
k->class_id = PCI_CLASS_DISPLAY_VGA;
+ set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
dc->desc = "Spice QXL GPU (primary, vga compatible)";
dc->reset = qxl_reset_handler;
dc->vmsd = &qxl_vmstate;
@@ -2345,6 +2346,7 @@ static void qxl_secondary_class_init(ObjectClass *klass, void *data)
k->vendor_id = REDHAT_PCI_VENDOR_ID;
k->device_id = QXL_DEVICE_ID_STABLE;
k->class_id = PCI_CLASS_DISPLAY_OTHER;
+ set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
dc->desc = "Spice QXL GPU (secondary)";
dc->reset = qxl_reset_handler;
dc->vmsd = &qxl_vmstate;
diff --git a/hw/display/vga-isa.c b/hw/display/vga-isa.c
index 8d560ec..c2a19ad 100644
--- a/hw/display/vga-isa.c
+++ b/hw/display/vga-isa.c
@@ -87,6 +87,7 @@ static void vga_isa_class_initfn(ObjectClass *klass, void *data)
dc->reset = vga_isa_reset;
dc->vmsd = &vmstate_vga_common;
dc->props = vga_isa_properties;
+ set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
}
static const TypeInfo vga_isa_info = {
diff --git a/hw/display/vga-pci.c b/hw/display/vga-pci.c
index 3e150ab..b3a45c8 100644
--- a/hw/display/vga-pci.c
+++ b/hw/display/vga-pci.c
@@ -198,6 +198,7 @@ static void vga_class_init(ObjectClass *klass, void *data)
k->class_id = PCI_CLASS_DISPLAY_VGA;
dc->vmsd = &vmstate_vga_pci;
dc->props = vga_pci_properties;
+ set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
}
static const TypeInfo vga_info = {
diff --git a/hw/display/vmware_vga.c b/hw/display/vmware_vga.c
index 3536cde..a6a8cdc 100644
--- a/hw/display/vmware_vga.c
+++ b/hw/display/vmware_vga.c
@@ -1306,6 +1306,7 @@ static void vmsvga_class_init(ObjectClass *klass, void *data)
dc->reset = vmsvga_reset;
dc->vmsd = &vmstate_vmware_vga;
dc->props = vga_vmware_properties;
+ set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
}
static const TypeInfo vmsvga_info = {
diff --git a/hw/i2c/bitbang_i2c.c b/hw/i2c/bitbang_i2c.c
index 5f8b972..371f4d5 100644
--- a/hw/i2c/bitbang_i2c.c
+++ b/hw/i2c/bitbang_i2c.c
@@ -227,6 +227,7 @@ static void gpio_i2c_class_init(ObjectClass *klass, void *data)
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
k->init = gpio_i2c_init;
+ set_bit(DEVICE_CATEGORY_ASSEMBLY, dc->categories);
dc->desc = "Virtual GPIO to I2C bridge";
}
diff --git a/hw/i2c/core.c b/hw/i2c/core.c
index 22ef3b9..72bccbf 100644
--- a/hw/i2c/core.c
+++ b/hw/i2c/core.c
@@ -224,6 +224,7 @@ static void i2c_slave_class_init(ObjectClass *klass, void *data)
{
DeviceClass *k = DEVICE_CLASS(klass);
k->init = i2c_slave_qdev_init;
+ set_bit(DEVICE_CATEGORY_ASSEMBLY, k->categories);
k->bus_type = TYPE_I2C_BUS;
k->props = i2c_props;
}
diff --git a/hw/i386/kvm/pci-assign.c b/hw/i386/kvm/pci-assign.c
index ff33dc8..5618173 100644
--- a/hw/i386/kvm/pci-assign.c
+++ b/hw/i386/kvm/pci-assign.c
@@ -1856,6 +1856,7 @@ static void assign_class_init(ObjectClass *klass, void *data)
dc->props = assigned_dev_properties;
dc->vmsd = &vmstate_assigned_device;
dc->reset = reset_assigned_device;
+ set_bit(DEVICE_CATEGORY_MISC, dc->categories);
dc->desc = "KVM-based PCI passthrough";
}
diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index 419adde..ef3f199 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -1338,6 +1338,7 @@ static void sysbus_ahci_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_sysbus_ahci;
dc->props = sysbus_ahci_properties;
dc->reset = sysbus_ahci_reset;
+ set_bit(DEVICE_CATEGORY_MANAGEMENT, dc->categories);
}
static const TypeInfo sysbus_ahci_info = {
diff --git a/hw/ide/ich.c b/hw/ide/ich.c
index 4eb5488..bff952b 100644
--- a/hw/ide/ich.c
+++ b/hw/ide/ich.c
@@ -160,6 +160,7 @@ static void ich_ahci_class_init(ObjectClass *klass, void *data)
k->class_id = PCI_CLASS_STORAGE_SATA;
dc->vmsd = &vmstate_ich9_ahci;
dc->reset = pci_ich9_reset;
+ set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
}
static const TypeInfo ich_ahci_info = {
diff --git a/hw/ide/isa.c b/hw/ide/isa.c
index 7243c82..bbc8c6b 100644
--- a/hw/ide/isa.c
+++ b/hw/ide/isa.c
@@ -118,6 +118,7 @@ static void isa_ide_class_initfn(ObjectClass *klass, void *data)
dc->fw_name = "ide";
dc->reset = isa_ide_reset;
dc->props = isa_ide_properties;
+ set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
}
static const TypeInfo isa_ide_info = {
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index 58532fe..56cf00e 100644
--- a/hw/ide/piix.c
+++ b/hw/ide/piix.c
@@ -248,6 +248,7 @@ static void piix3_ide_class_init(ObjectClass *klass, void *data)
k->vendor_id = PCI_VENDOR_ID_INTEL;
k->device_id = PCI_DEVICE_ID_INTEL_82371SB_1;
k->class_id = PCI_CLASS_STORAGE_IDE;
+ set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
dc->no_user = 1;
}
@@ -267,6 +268,7 @@ static void piix3_ide_xen_class_init(ObjectClass *klass, void *data)
k->vendor_id = PCI_VENDOR_ID_INTEL;
k->device_id = PCI_DEVICE_ID_INTEL_82371SB_1;
k->class_id = PCI_CLASS_STORAGE_IDE;
+ set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
dc->no_user = 1;
dc->unplug = pci_piix3_xen_ide_unplug;
}
@@ -289,6 +291,7 @@ static void piix4_ide_class_init(ObjectClass *klass, void *data)
k->vendor_id = PCI_VENDOR_ID_INTEL;
k->device_id = PCI_DEVICE_ID_INTEL_82371AB;
k->class_id = PCI_CLASS_STORAGE_IDE;
+ set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
dc->no_user = 1;
}
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
index 6a272b0..1d84e15 100644
--- a/hw/ide/qdev.c
+++ b/hw/ide/qdev.c
@@ -282,6 +282,7 @@ static void ide_device_class_init(ObjectClass *klass, void *data)
{
DeviceClass *k = DEVICE_CLASS(klass);
k->init = ide_qdev_init;
+ set_bit(DEVICE_CATEGORY_STORAGE, k->categories);
k->bus_type = TYPE_IDE_BUS;
k->props = ide_props;
}
diff --git a/hw/ide/via.c b/hw/ide/via.c
index 5a83191..d324884 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -223,6 +223,7 @@ static void via_ide_class_init(ObjectClass *klass, void *data)
k->device_id = PCI_DEVICE_ID_VIA_IDE;
k->revision = 0x06;
k->class_id = PCI_CLASS_STORAGE_IDE;
+ set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
dc->no_user = 1;
}
diff --git a/hw/isa/i82378.c b/hw/isa/i82378.c
index b25ed04..21a60db 100644
--- a/hw/isa/i82378.c
+++ b/hw/isa/i82378.c
@@ -261,6 +261,7 @@ static void pci_i82378_class_init(ObjectClass *klass, void *data)
k->subsystem_vendor_id = 0x0;
k->subsystem_id = 0x0;
dc->vmsd = &vmstate_pci_i82378;
+ set_bit(DEVICE_CATEGORY_ASSEMBLY, dc->categories);
dc->props = i82378_properties;
}
diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c
index d1921aa..1ab539e 100644
--- a/hw/isa/lpc_ich9.c
+++ b/hw/isa/lpc_ich9.c
@@ -600,6 +600,7 @@ static void ich9_lpc_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+ set_bit(DEVICE_CATEGORY_ASSEMBLY, dc->categories);
dc->reset = ich9_lpc_reset;
k->init = ich9_lpc_initfn;
dc->vmsd = &vmstate_ich9_lpc;
diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
index 2174eaa..4ed0559 100644
--- a/hw/isa/vt82c686.c
+++ b/hw/isa/vt82c686.c
@@ -281,6 +281,7 @@ static void via_ac97_class_init(ObjectClass *klass, void *data)
k->device_id = PCI_DEVICE_ID_VIA_AC97;
k->revision = 0x50;
k->class_id = PCI_CLASS_MULTIMEDIA_AUDIO;
+ set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
dc->desc = "AC97";
}
@@ -322,6 +323,7 @@ static void via_mc97_class_init(ObjectClass *klass, void *data)
k->device_id = PCI_DEVICE_ID_VIA_MC97;
k->class_id = PCI_CLASS_COMMUNICATION_OTHER;
k->revision = 0x30;
+ set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
dc->desc = "MC97";
}
@@ -401,6 +403,7 @@ static void via_pm_class_init(ObjectClass *klass, void *data)
k->revision = 0x40;
dc->desc = "PM";
dc->vmsd = &vmstate_acpi;
+ set_bit(DEVICE_CATEGORY_ASSEMBLY, dc->categories);
dc->props = via_pm_properties;
}
diff --git a/hw/misc/applesmc.c b/hw/misc/applesmc.c
index bfafa51..fe2f966 100644
--- a/hw/misc/applesmc.c
+++ b/hw/misc/applesmc.c
@@ -263,6 +263,7 @@ static void qdev_applesmc_class_init(ObjectClass *klass, void *data)
dc->realize = applesmc_isa_realize;
dc->reset = qdev_applesmc_isa_reset;
dc->props = applesmc_isa_properties;
+ set_bit(DEVICE_CATEGORY_MANAGEMENT, dc->categories);
}
static const TypeInfo applesmc_isa_info = {
diff --git a/hw/misc/debugexit.c b/hw/misc/debugexit.c
index d754cf1..9db5680 100644
--- a/hw/misc/debugexit.c
+++ b/hw/misc/debugexit.c
@@ -58,6 +58,7 @@ static void debug_exit_class_initfn(ObjectClass *klass, void *data)
dc->realize = debug_exit_realizefn;
dc->props = debug_exit_properties;
+ set_bit(DEVICE_CATEGORY_MISC, dc->categories);
}
static const TypeInfo debug_exit_info = {
diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c
index 4a74856..2838866 100644
--- a/hw/misc/ivshmem.c
+++ b/hw/misc/ivshmem.c
@@ -821,6 +821,7 @@ static void ivshmem_class_init(ObjectClass *klass, void *data)
k->class_id = PCI_CLASS_MEMORY_RAM;
dc->reset = ivshmem_reset;
dc->props = ivshmem_properties;
+ set_bit(DEVICE_CATEGORY_MISC, dc->categories);
}
static const TypeInfo ivshmem_info = {
diff --git a/hw/misc/pc-testdev.c b/hw/misc/pc-testdev.c
index 5867c70..18e94e0 100644
--- a/hw/misc/pc-testdev.c
+++ b/hw/misc/pc-testdev.c
@@ -188,6 +188,7 @@ static void testdev_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
+ set_bit(DEVICE_CATEGORY_MISC, dc->categories);
dc->realize = testdev_realizefn;
}
diff --git a/hw/misc/pci-testdev.c b/hw/misc/pci-testdev.c
index d69ff33..ca53b3f 100644
--- a/hw/misc/pci-testdev.c
+++ b/hw/misc/pci-testdev.c
@@ -315,6 +315,7 @@ static void pci_testdev_class_init(ObjectClass *klass, void *data)
k->revision = 0x00;
k->class_id = PCI_CLASS_OTHERS;
dc->desc = "PCI Test Device";
+ set_bit(DEVICE_CATEGORY_MISC, dc->categories);
dc->reset = qdev_pci_testdev_reset;
}
diff --git a/hw/misc/sga.c b/hw/misc/sga.c
index 08803e7..83d2fd9 100644
--- a/hw/misc/sga.c
+++ b/hw/misc/sga.c
@@ -47,6 +47,7 @@ static void sga_class_initfn(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
+ set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
dc->realize = sga_realizefn;
dc->desc = "Serial Graphics Adapter";
}
diff --git a/hw/misc/vfio.c b/hw/misc/vfio.c
index ad8ce77..017e693 100644
--- a/hw/misc/vfio.c
+++ b/hw/misc/vfio.c
@@ -3299,6 +3299,7 @@ static void vfio_pci_dev_class_init(ObjectClass *klass, void *data)
dc->props = vfio_pci_dev_properties;
dc->vmsd = &vfio_pci_vmstate;
dc->desc = "VFIO-based PCI device assignment";
+ set_bit(DEVICE_CATEGORY_MISC, dc->categories);
pdc->init = vfio_initfn;
pdc->exit = vfio_exitfn;
pdc->config_read = vfio_pci_read_config;
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
index b952d8d..fdb1f89 100644
--- a/hw/net/e1000.c
+++ b/hw/net/e1000.c
@@ -1400,6 +1400,7 @@ static void e1000_class_init(ObjectClass *klass, void *data)
k->device_id = E1000_DEVID;
k->revision = 0x03;
k->class_id = PCI_CLASS_NETWORK_ETHERNET;
+ set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
dc->desc = "Intel Gigabit Ethernet";
dc->reset = qdev_e1000_reset;
dc->vmsd = &vmstate_e1000;
diff --git a/hw/net/eepro100.c b/hw/net/eepro100.c
index 3dc4937..543db29 100644
--- a/hw/net/eepro100.c
+++ b/hw/net/eepro100.c
@@ -2082,6 +2082,7 @@ static void eepro100_class_init(ObjectClass *klass, void *data)
info = eepro100_get_class_by_name(object_class_get_name(klass));
+ set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
dc->props = e100_properties;
dc->desc = info->desc;
k->vendor_id = PCI_VENDOR_ID_INTEL;
diff --git a/hw/net/lance.c b/hw/net/lance.c
index 98bcdfc..1be7b72 100644
--- a/hw/net/lance.c
+++ b/hw/net/lance.c
@@ -150,6 +150,7 @@ static void lance_class_init(ObjectClass *klass, void *data)
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
k->init = lance_init;
+ set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
dc->fw_name = "ethernet";
dc->reset = lance_reset;
dc->vmsd = &vmstate_lance;
diff --git a/hw/net/mipsnet.c b/hw/net/mipsnet.c
index 9080850..61578ed 100644
--- a/hw/net/mipsnet.c
+++ b/hw/net/mipsnet.c
@@ -264,6 +264,7 @@ static void mipsnet_class_init(ObjectClass *klass, void *data)
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
k->init = mipsnet_sysbus_init;
+ set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
dc->desc = "MIPS Simulator network device";
dc->reset = mipsnet_sysbus_reset;
dc->vmsd = &vmstate_mipsnet;
diff --git a/hw/net/ne2000-isa.c b/hw/net/ne2000-isa.c
index e3c8076..26b83ce 100644
--- a/hw/net/ne2000-isa.c
+++ b/hw/net/ne2000-isa.c
@@ -98,6 +98,7 @@ static void isa_ne2000_class_initfn(ObjectClass *klass, void *data)
dc->realize = isa_ne2000_realizefn;
dc->props = ne2000_isa_properties;
+ set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
}
static const TypeInfo ne2000_isa_info = {
diff --git a/hw/net/ne2000.c b/hw/net/ne2000.c
index 8d43fd9..31afd28 100644
--- a/hw/net/ne2000.c
+++ b/hw/net/ne2000.c
@@ -772,6 +772,7 @@ static void ne2000_class_init(ObjectClass *klass, void *data)
k->class_id = PCI_CLASS_NETWORK_ETHERNET;
dc->vmsd = &vmstate_pci_ne2000;
dc->props = ne2000_properties;
+ set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
}
static const TypeInfo ne2000_info = {
diff --git a/hw/net/opencores_eth.c b/hw/net/opencores_eth.c
index 4637557..513f345 100644
--- a/hw/net/opencores_eth.c
+++ b/hw/net/opencores_eth.c
@@ -713,6 +713,7 @@ static void open_eth_class_init(ObjectClass *klass, void *data)
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
k->init = sysbus_open_eth_init;
+ set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
dc->desc = "Opencores 10/100 Mbit Ethernet";
dc->reset = qdev_open_eth_reset;
dc->props = open_eth_properties;
diff --git a/hw/net/pcnet-pci.c b/hw/net/pcnet-pci.c
index 6ef28f7..2c2301c 100644
--- a/hw/net/pcnet-pci.c
+++ b/hw/net/pcnet-pci.c
@@ -366,6 +366,7 @@ static void pcnet_class_init(ObjectClass *klass, void *data)
dc->reset = pci_reset;
dc->vmsd = &vmstate_pci_pcnet;
dc->props = pcnet_properties;
+ set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
}
static const TypeInfo pcnet_info = {
diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
index 6552034..ee3b690 100644
--- a/hw/net/rtl8139.c
+++ b/hw/net/rtl8139.c
@@ -3563,6 +3563,7 @@ static void rtl8139_class_init(ObjectClass *klass, void *data)
dc->reset = rtl8139_reset;
dc->vmsd = &vmstate_rtl8139;
dc->props = rtl8139_properties;
+ set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
}
static const TypeInfo rtl8139_info = {
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 679f50c..aa1880c 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -1638,6 +1638,7 @@ static void virtio_net_class_init(ObjectClass *klass, void *data)
VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
dc->exit = virtio_net_device_exit;
dc->props = virtio_net_properties;
+ set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
vdc->init = virtio_net_device_init;
vdc->get_config = virtio_net_get_config;
vdc->set_config = virtio_net_set_config;
diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c
index b39ff08..fc386fd 100644
--- a/hw/net/vmxnet3.c
+++ b/hw/net/vmxnet3.c
@@ -2453,6 +2453,7 @@ static void vmxnet3_class_init(ObjectClass *class, void *data)
dc->reset = vmxnet3_qdev_reset;
dc->vmsd = &vmstate_vmxnet3;
dc->props = vmxnet3_properties;
+ set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
}
static const TypeInfo vmxnet3_info = {
diff --git a/hw/pci-bridge/i82801b11.c b/hw/pci-bridge/i82801b11.c
index b98bfb0..3059a1c 100644
--- a/hw/pci-bridge/i82801b11.c
+++ b/hw/pci-bridge/i82801b11.c
@@ -81,12 +81,14 @@ err_bridge:
static void i82801b11_bridge_class_init(ObjectClass *klass, void *data)
{
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+ DeviceClass *dc = DEVICE_CLASS(klass);
k->is_bridge = 1;
k->vendor_id = PCI_VENDOR_ID_INTEL;
k->device_id = PCI_DEVICE_ID_INTEL_82801BA_11;
k->revision = ICH9_D2P_A2_REVISION;
k->init = i82801b11_bridge_initfn;
+ set_bit(DEVICE_CATEGORY_ASSEMBLY, dc->categories);
}
static const TypeInfo i82801b11_bridge_info = {
diff --git a/hw/pci-bridge/ioh3420.c b/hw/pci-bridge/ioh3420.c
index bb541eb..974e9b3 100644
--- a/hw/pci-bridge/ioh3420.c
+++ b/hw/pci-bridge/ioh3420.c
@@ -220,6 +220,7 @@ static void ioh3420_class_init(ObjectClass *klass, void *data)
k->vendor_id = PCI_VENDOR_ID_INTEL;
k->device_id = PCI_DEVICE_ID_IOH_EPORT;
k->revision = PCI_DEVICE_ID_IOH_REV;
+ set_bit(DEVICE_CATEGORY_ASSEMBLY, dc->categories);
dc->desc = "Intel IOH device id 3420 PCIE Root Port";
dc->reset = ioh3420_reset;
dc->vmsd = &vmstate_ioh3420;
diff --git a/hw/pci-bridge/pci_bridge_dev.c b/hw/pci-bridge/pci_bridge_dev.c
index 5f11323..b2a47e6 100644
--- a/hw/pci-bridge/pci_bridge_dev.c
+++ b/hw/pci-bridge/pci_bridge_dev.c
@@ -141,6 +141,7 @@ static void pci_bridge_dev_class_init(ObjectClass *klass, void *data)
dc->reset = qdev_pci_bridge_dev_reset;
dc->props = pci_bridge_dev_properties;
dc->vmsd = &pci_bridge_dev_vmstate;
+ set_bit(DEVICE_CATEGORY_ASSEMBLY, dc->categories);
}
static const TypeInfo pci_bridge_dev_info = {
diff --git a/hw/pci-bridge/xio3130_downstream.c b/hw/pci-bridge/xio3130_downstream.c
index 1810dd2..94fa4a1 100644
--- a/hw/pci-bridge/xio3130_downstream.c
+++ b/hw/pci-bridge/xio3130_downstream.c
@@ -187,6 +187,7 @@ static void xio3130_downstream_class_init(ObjectClass *klass, void *data)
k->vendor_id = PCI_VENDOR_ID_TI;
k->device_id = PCI_DEVICE_ID_TI_XIO3130D;
k->revision = XIO3130_REVISION;
+ set_bit(DEVICE_CATEGORY_ASSEMBLY, dc->categories);
dc->desc = "TI X3130 Downstream Port of PCI Express Switch";
dc->reset = xio3130_downstream_reset;
dc->vmsd = &vmstate_xio3130_downstream;
diff --git a/hw/pci-bridge/xio3130_upstream.c b/hw/pci-bridge/xio3130_upstream.c
index 8e0d97a..0d21c7b 100644
--- a/hw/pci-bridge/xio3130_upstream.c
+++ b/hw/pci-bridge/xio3130_upstream.c
@@ -161,6 +161,7 @@ static void xio3130_upstream_class_init(ObjectClass *klass, void *data)
k->vendor_id = PCI_VENDOR_ID_TI;
k->device_id = PCI_DEVICE_ID_TI_XIO3130U;
k->revision = XIO3130_REVISION;
+ set_bit(DEVICE_CATEGORY_ASSEMBLY, dc->categories);
dc->desc = "TI X3130 Upstream Port of PCI Express Switch";
dc->reset = xio3130_upstream_reset;
dc->vmsd = &vmstate_xio3130_upstream;
diff --git a/hw/pci-host/apb.c b/hw/pci-host/apb.c
index 3756ce9..28f03cd 100644
--- a/hw/pci-host/apb.c
+++ b/hw/pci-host/apb.c
@@ -536,6 +536,7 @@ static void pbm_host_class_init(ObjectClass *klass, void *data)
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
k->init = pci_pbm_init_device;
+ set_bit(DEVICE_CATEGORY_ASSEMBLY, dc->categories);
dc->reset = pci_pbm_reset;
}
@@ -558,6 +559,7 @@ static void pbm_pci_bridge_class_init(ObjectClass *klass, void *data)
k->revision = 0x11;
k->config_write = pci_bridge_write_config;
k->is_bridge = 1;
+ set_bit(DEVICE_CATEGORY_ASSEMBLY, dc->categories);
dc->reset = pci_bridge_reset;
dc->vmsd = &vmstate_pci_device;
}
diff --git a/hw/pci-host/ppce500.c b/hw/pci-host/ppce500.c
index 646204e..f13e56c 100644
--- a/hw/pci-host/ppce500.c
+++ b/hw/pci-host/ppce500.c
@@ -407,6 +407,7 @@ static void e500_pcihost_class_init(ObjectClass *klass, void *data)
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
k->init = e500_pcihost_initfn;
+ set_bit(DEVICE_CATEGORY_ASSEMBLY, dc->categories);
dc->props = pcihost_properties;
dc->vmsd = &vmstate_ppce500_pci;
}
diff --git a/hw/pci-host/prep.c b/hw/pci-host/prep.c
index b41d564..4cb9a99 100644
--- a/hw/pci-host/prep.c
+++ b/hw/pci-host/prep.c
@@ -210,6 +210,7 @@ static void raven_pcihost_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
+ set_bit(DEVICE_CATEGORY_ASSEMBLY, dc->categories);
dc->realize = raven_pcihost_realizefn;
dc->fw_name = "pci";
dc->no_user = 1;
diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
index 6b1b3b7..a28befa 100644
--- a/hw/pci-host/q35.c
+++ b/hw/pci-host/q35.c
@@ -78,6 +78,7 @@ static void q35_host_class_init(ObjectClass *klass, void *data)
hc->root_bus_path = q35_host_root_bus_path;
dc->realize = q35_host_realize;
dc->props = mch_props;
+ set_bit(DEVICE_CATEGORY_ASSEMBLY, dc->categories);
dc->fw_name = "pci";
}
@@ -306,6 +307,7 @@ static void mch_class_init(ObjectClass *klass, void *data)
k->init = mch_init;
k->config_write = mch_write_config;
dc->reset = mch_reset;
+ set_bit(DEVICE_CATEGORY_ASSEMBLY, dc->categories);
dc->desc = "Host bridge";
dc->vmsd = &vmstate_mch;
k->vendor_id = PCI_VENDOR_ID_INTEL;
diff --git a/hw/scsi/esp-pci.c b/hw/scsi/esp-pci.c
index 2ac21d4..d7ec173 100644
--- a/hw/scsi/esp-pci.c
+++ b/hw/scsi/esp-pci.c
@@ -392,6 +392,7 @@ static void esp_pci_class_init(ObjectClass *klass, void *data)
k->device_id = PCI_DEVICE_ID_AMD_SCSI;
k->revision = 0x10;
k->class_id = PCI_CLASS_STORAGE_SCSI;
+ set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
dc->desc = "AMD Am53c974 PCscsi-PCI SCSI adapter";
dc->reset = esp_pci_hard_reset;
dc->vmsd = &vmstate_esp_pci_scsi;
@@ -512,6 +513,7 @@ static void dc390_class_init(ObjectClass *klass, void *data)
k->init = dc390_scsi_init;
k->config_read = dc390_read_config;
k->config_write = dc390_write_config;
+ set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
dc->desc = "Tekram DC-390 SCSI adapter";
}
diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 94639b8..101e957 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -720,6 +720,7 @@ static void sysbus_esp_class_init(ObjectClass *klass, void *data)
dc->realize = sysbus_esp_realize;
dc->reset = sysbus_esp_hard_reset;
dc->vmsd = &vmstate_sysbus_esp_scsi;
+ set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
}
static const TypeInfo sysbus_esp_info = {
diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c
index 776e31a..611f2aa 100644
--- a/hw/scsi/lsi53c895a.c
+++ b/hw/scsi/lsi53c895a.c
@@ -2141,6 +2141,7 @@ static void lsi_class_init(ObjectClass *klass, void *data)
k->subsystem_id = 0x1000;
dc->reset = lsi_scsi_reset;
dc->vmsd = &vmstate_lsi_scsi;
+ set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
}
static const TypeInfo lsi_info = {
diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
index eb52164..a6d5285 100644
--- a/hw/scsi/megasas.c
+++ b/hw/scsi/megasas.c
@@ -2213,6 +2213,7 @@ static void megasas_class_init(ObjectClass *oc, void *data)
dc->props = megasas_properties;
dc->reset = megasas_scsi_reset;
dc->vmsd = &vmstate_megasas;
+ set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
dc->desc = "LSI MegaRAID SAS 1078";
}
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index b5a863a..fbf9173 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -1881,6 +1881,7 @@ const VMStateDescription vmstate_scsi_device = {
static void scsi_device_class_init(ObjectClass *klass, void *data)
{
DeviceClass *k = DEVICE_CLASS(klass);
+ set_bit(DEVICE_CATEGORY_STORAGE, k->categories);
k->bus_type = TYPE_SCSI_BUS;
k->init = scsi_qdev_init;
k->unplug = scsi_qdev_unplug;
diff --git a/hw/scsi/vhost-scsi.c b/hw/scsi/vhost-scsi.c
index 785e93f..9e770fb 100644
--- a/hw/scsi/vhost-scsi.c
+++ b/hw/scsi/vhost-scsi.c
@@ -267,6 +267,7 @@ static void vhost_scsi_class_init(ObjectClass *klass, void *data)
VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
dc->exit = vhost_scsi_exit;
dc->props = vhost_scsi_properties;
+ set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
vdc->init = vhost_scsi_init;
vdc->get_features = vhost_scsi_get_features;
vdc->set_config = vhost_scsi_set_config;
diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
index 42cb73b..05da56b 100644
--- a/hw/scsi/virtio-scsi.c
+++ b/hw/scsi/virtio-scsi.c
@@ -669,8 +669,10 @@ static Property virtio_scsi_properties[] = {
static void virtio_scsi_common_class_init(ObjectClass *klass, void *data)
{
VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
+ DeviceClass *dc = DEVICE_CLASS(klass);
vdc->get_config = virtio_scsi_get_config;
+ set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
}
static void virtio_scsi_class_init(ObjectClass *klass, void *data)
@@ -679,6 +681,7 @@ static void virtio_scsi_class_init(ObjectClass *klass, void *data)
VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
dc->exit = virtio_scsi_device_exit;
dc->props = virtio_scsi_properties;
+ set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
vdc->init = virtio_scsi_device_init;
vdc->set_config = virtio_scsi_set_config;
vdc->get_features = virtio_scsi_get_features;
diff --git a/hw/scsi/vmw_pvscsi.c b/hw/scsi/vmw_pvscsi.c
index e1074e1..d42b359 100644
--- a/hw/scsi/vmw_pvscsi.c
+++ b/hw/scsi/vmw_pvscsi.c
@@ -1197,6 +1197,7 @@ static void pvscsi_class_init(ObjectClass *klass, void *data)
dc->reset = pvscsi_reset;
dc->vmsd = &vmstate_pvscsi;
dc->props = pvscsi_properties;
+ set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
k->config_write = pvscsi_write_config;
}
diff --git a/hw/usb/ccid-card-emulated.c b/hw/usb/ccid-card-emulated.c
index deb6d47..aa913df 100644
--- a/hw/usb/ccid-card-emulated.c
+++ b/hw/usb/ccid-card-emulated.c
@@ -592,6 +592,7 @@ static void emulated_class_initfn(ObjectClass *klass, void *data)
cc->exitfn = emulated_exitfn;
cc->get_atr = emulated_get_atr;
cc->apdu_from_guest = emulated_apdu_from_guest;
+ set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
dc->desc = "emulated smartcard";
dc->props = emulated_card_properties;
}
diff --git a/hw/usb/ccid-card-passthru.c b/hw/usb/ccid-card-passthru.c
index 5f01ff1..10f1d30 100644
--- a/hw/usb/ccid-card-passthru.c
+++ b/hw/usb/ccid-card-passthru.c
@@ -392,6 +392,7 @@ static void passthru_class_initfn(ObjectClass *klass, void *data)
cc->exitfn = passthru_exitfn;
cc->get_atr = passthru_get_atr;
cc->apdu_from_guest = passthru_apdu_from_guest;
+ set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
dc->desc = "passthrough smartcard";
dc->vmsd = &passthru_vmstate;
dc->props = passthru_card_properties;
diff --git a/hw/usb/dev-audio.c b/hw/usb/dev-audio.c
index 04933a9..c5420eb 100644
--- a/hw/usb/dev-audio.c
+++ b/hw/usb/dev-audio.c
@@ -673,6 +673,7 @@ static void usb_audio_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_usb_audio;
dc->props = usb_audio_properties;
+ set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
k->product_desc = "QEMU USB Audio Interface";
k->usb_desc = &desc_audio;
k->init = usb_audio_initfn;
diff --git a/hw/usb/dev-bluetooth.c b/hw/usb/dev-bluetooth.c
index 68cc1d4..f2fc2a8 100644
--- a/hw/usb/dev-bluetooth.c
+++ b/hw/usb/dev-bluetooth.c
@@ -553,6 +553,7 @@ static void usb_bt_class_initfn(ObjectClass *klass, void *data)
uc->handle_data = usb_bt_handle_data;
uc->handle_destroy = usb_bt_handle_destroy;
dc->vmsd = &vmstate_usb_bt;
+ set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
}
static const TypeInfo bt_info = {
diff --git a/hw/usb/dev-hid.c b/hw/usb/dev-hid.c
index 31f3cde..66c6331 100644
--- a/hw/usb/dev-hid.c
+++ b/hw/usb/dev-hid.c
@@ -658,6 +658,7 @@ static void usb_tablet_class_initfn(ObjectClass *klass, void *data)
uc->product_desc = "QEMU USB Tablet";
dc->vmsd = &vmstate_usb_ptr;
dc->props = usb_tablet_properties;
+ set_bit(DEVICE_CATEGORY_MISC, dc->categories);
}
static const TypeInfo usb_tablet_info = {
@@ -677,6 +678,7 @@ static void usb_mouse_class_initfn(ObjectClass *klass, void *data)
uc->product_desc = "QEMU USB Mouse";
uc->usb_desc = &desc_mouse;
dc->vmsd = &vmstate_usb_ptr;
+ set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
}
static const TypeInfo usb_mouse_info = {
@@ -696,6 +698,7 @@ static void usb_keyboard_class_initfn(ObjectClass *klass, void *data)
uc->product_desc = "QEMU USB Keyboard";
uc->usb_desc = &desc_keyboard;
dc->vmsd = &vmstate_usb_kbd;
+ set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
}
static const TypeInfo usb_keyboard_info = {
diff --git a/hw/usb/dev-hub.c b/hw/usb/dev-hub.c
index 0b71abd..6bb3d54 100644
--- a/hw/usb/dev-hub.c
+++ b/hw/usb/dev-hub.c
@@ -574,6 +574,7 @@ static void usb_hub_class_initfn(ObjectClass *klass, void *data)
uc->handle_control = usb_hub_handle_control;
uc->handle_data = usb_hub_handle_data;
uc->handle_destroy = usb_hub_handle_destroy;
+ set_bit(DEVICE_CATEGORY_ASSEMBLY, dc->categories);
dc->fw_name = "hub";
dc->vmsd = &vmstate_usb_hub;
}
diff --git a/hw/usb/dev-network.c b/hw/usb/dev-network.c
index 5473ac2..660d774 100644
--- a/hw/usb/dev-network.c
+++ b/hw/usb/dev-network.c
@@ -1429,6 +1429,7 @@ static void usb_net_class_initfn(ObjectClass *klass, void *data)
uc->handle_control = usb_net_handle_control;
uc->handle_data = usb_net_handle_data;
uc->handle_destroy = usb_net_handle_destroy;
+ set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
dc->fw_name = "network";
dc->vmsd = &vmstate_usb_net;
dc->props = net_properties;
diff --git a/hw/usb/dev-serial.c b/hw/usb/dev-serial.c
index 2fc8a3b..0b150d4 100644
--- a/hw/usb/dev-serial.c
+++ b/hw/usb/dev-serial.c
@@ -590,6 +590,7 @@ static void usb_serial_class_initfn(ObjectClass *klass, void *data)
uc->handle_data = usb_serial_handle_data;
dc->vmsd = &vmstate_usb_serial;
dc->props = serial_properties;
+ set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
}
static const TypeInfo serial_info = {
@@ -617,6 +618,7 @@ static void usb_braille_class_initfn(ObjectClass *klass, void *data)
uc->handle_data = usb_serial_handle_data;
dc->vmsd = &vmstate_usb_serial;
dc->props = braille_properties;
+ set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
}
static const TypeInfo braille_info = {
diff --git a/hw/usb/dev-smartcard-reader.c b/hw/usb/dev-smartcard-reader.c
index b33eb25..2233c54 100644
--- a/hw/usb/dev-smartcard-reader.c
+++ b/hw/usb/dev-smartcard-reader.c
@@ -1449,6 +1449,7 @@ static void ccid_class_initfn(ObjectClass *klass, void *data)
dc->desc = "CCID Rev 1.1 smartcard reader";
dc->vmsd = &ccid_vmstate;
dc->props = ccid_properties;
+ set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
}
static const TypeInfo ccid_info = {
diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c
index 1954811..a8dc2fa 100644
--- a/hw/usb/dev-storage.c
+++ b/hw/usb/dev-storage.c
@@ -746,6 +746,7 @@ static void usb_msd_class_initfn_common(ObjectClass *klass)
uc->handle_reset = usb_msd_handle_reset;
uc->handle_control = usb_msd_handle_control;
uc->handle_data = usb_msd_handle_data;
+ set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
dc->fw_name = "storage";
dc->vmsd = &vmstate_usb_msd;
}
diff --git a/hw/usb/dev-uas.c b/hw/usb/dev-uas.c
index 6efab62..63ad12e 100644
--- a/hw/usb/dev-uas.c
+++ b/hw/usb/dev-uas.c
@@ -916,6 +916,7 @@ static void usb_uas_class_initfn(ObjectClass *klass, void *data)
uc->handle_control = usb_uas_handle_control;
uc->handle_data = usb_uas_handle_data;
uc->handle_destroy = usb_uas_handle_destroy;
+ set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
dc->fw_name = "storage";
dc->vmsd = &vmstate_usb_uas;
}
diff --git a/hw/usb/dev-wacom.c b/hw/usb/dev-wacom.c
index 3be5cde..1b09235 100644
--- a/hw/usb/dev-wacom.c
+++ b/hw/usb/dev-wacom.c
@@ -362,6 +362,7 @@ static void usb_wacom_class_init(ObjectClass *klass, void *data)
uc->handle_control = usb_wacom_handle_control;
uc->handle_data = usb_wacom_handle_data;
uc->handle_destroy = usb_wacom_handle_destroy;
+ set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
dc->desc = "QEMU PenPartner Tablet";
dc->vmsd = &vmstate_usb_wacom;
}
diff --git a/hw/usb/hcd-ehci-pci.c b/hw/usb/hcd-ehci-pci.c
index 5d229bc..720dc93 100644
--- a/hw/usb/hcd-ehci-pci.c
+++ b/hw/usb/hcd-ehci-pci.c
@@ -140,11 +140,13 @@ static const TypeInfo ehci_pci_type_info = {
static void ehci_data_class_init(ObjectClass *klass, void *data)
{
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+ DeviceClass *dc = DEVICE_CLASS(klass);
EHCIPCIInfo *i = data;
k->vendor_id = i->vendor_id;
k->device_id = i->device_id;
k->revision = i->revision;
+ set_bit(DEVICE_CATEGORY_MANAGEMENT, dc->categories);
}
static struct EHCIPCIInfo ehci_pci_info[] = {
diff --git a/hw/usb/hcd-ehci-sysbus.c b/hw/usb/hcd-ehci-sysbus.c
index 54147b5..c8f23e4 100644
--- a/hw/usb/hcd-ehci-sysbus.c
+++ b/hw/usb/hcd-ehci-sysbus.c
@@ -70,6 +70,7 @@ static void ehci_sysbus_class_init(ObjectClass *klass, void *data)
dc->realize = usb_ehci_sysbus_realize;
dc->vmsd = &vmstate_ehci_sysbus;
dc->props = ehci_sysbus_properties;
+ set_bit(DEVICE_CATEGORY_MANAGEMENT, dc->categories);
}
static const TypeInfo ehci_type_info = {
@@ -85,7 +86,9 @@ static const TypeInfo ehci_type_info = {
static void ehci_xlnx_class_init(ObjectClass *oc, void *data)
{
SysBusEHCIClass *sec = SYS_BUS_EHCI_CLASS(oc);
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ set_bit(DEVICE_CATEGORY_MANAGEMENT, dc->categories);
sec->capsbase = 0x100;
sec->opregbase = 0x140;
}
@@ -99,9 +102,11 @@ static const TypeInfo ehci_xlnx_type_info = {
static void ehci_exynos4210_class_init(ObjectClass *oc, void *data)
{
SysBusEHCIClass *sec = SYS_BUS_EHCI_CLASS(oc);
+ DeviceClass *dc = DEVICE_CLASS(oc);
sec->capsbase = 0x0;
sec->opregbase = 0x10;
+ set_bit(DEVICE_CATEGORY_MANAGEMENT, dc->categories);
}
static const TypeInfo ehci_exynos4210_type_info = {
@@ -113,9 +118,11 @@ static const TypeInfo ehci_exynos4210_type_info = {
static void ehci_tegra2_class_init(ObjectClass *oc, void *data)
{
SysBusEHCIClass *sec = SYS_BUS_EHCI_CLASS(oc);
+ DeviceClass *dc = DEVICE_CLASS(oc);
sec->capsbase = 0x100;
sec->opregbase = 0x140;
+ set_bit(DEVICE_CATEGORY_MANAGEMENT, dc->categories);
}
static const TypeInfo ehci_tegra2_type_info = {
@@ -183,11 +190,13 @@ static void fusbh200_ehci_init(Object *obj)
static void fusbh200_ehci_class_init(ObjectClass *oc, void *data)
{
SysBusEHCIClass *sec = SYS_BUS_EHCI_CLASS(oc);
+ DeviceClass *dc = DEVICE_CLASS(oc);
sec->capsbase = 0x0;
sec->opregbase = 0x10;
sec->portscbase = 0x20;
sec->portnr = 1;
+ set_bit(DEVICE_CATEGORY_MANAGEMENT, dc->categories);
}
static const TypeInfo ehci_fusbh200_type_info = {
diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c
index 2bab8ff..efabeb1 100644
--- a/hw/usb/hcd-ohci.c
+++ b/hw/usb/hcd-ohci.c
@@ -1917,6 +1917,7 @@ static void ohci_pci_class_init(ObjectClass *klass, void *data)
k->device_id = PCI_DEVICE_ID_APPLE_IPID_USB;
k->class_id = PCI_CLASS_SERIAL_USB;
k->no_hotplug = 1;
+ set_bit(DEVICE_CATEGORY_MANAGEMENT, dc->categories);
dc->desc = "Apple USB Controller";
dc->props = ohci_pci_properties;
}
@@ -1939,6 +1940,7 @@ static void ohci_sysbus_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
dc->realize = ohci_realize_pxa;
+ set_bit(DEVICE_CATEGORY_MANAGEMENT, dc->categories);
dc->desc = "OHCI USB Controller";
dc->props = ohci_sysbus_properties;
}
diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
index 066072e..96bfa8b 100644
--- a/hw/usb/hcd-uhci.c
+++ b/hw/usb/hcd-uhci.c
@@ -1315,6 +1315,7 @@ static void uhci_class_init(ObjectClass *klass, void *data)
k->no_hotplug = 1;
dc->vmsd = &vmstate_uhci;
dc->props = uhci_properties;
+ set_bit(DEVICE_CATEGORY_MANAGEMENT, dc->categories);
u->info = *info;
}
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index 9ba3e3e..90ae95b 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -3591,6 +3591,7 @@ static void xhci_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_xhci;
dc->props = xhci_properties;
dc->reset = xhci_reset;
+ set_bit(DEVICE_CATEGORY_MANAGEMENT, dc->categories);
k->init = usb_xhci_initfn;
k->vendor_id = PCI_VENDOR_ID_NEC;
k->device_id = PCI_DEVICE_ID_NEC_UPD720200;
diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c
index e2f3cc8..d58467e 100644
--- a/hw/usb/host-libusb.c
+++ b/hw/usb/host-libusb.c
@@ -1351,6 +1351,7 @@ static void usb_host_class_initfn(ObjectClass *klass, void *data)
uc->flush_ep_queue = usb_host_flush_ep_queue;
dc->vmsd = &vmstate_usb_host;
dc->props = usb_host_dev_properties;
+ set_bit(DEVICE_CATEGORY_ASSEMBLY, dc->categories);
}
static TypeInfo usb_host_dev_info = {
diff --git a/hw/usb/host-linux.c b/hw/usb/host-linux.c
index ca09a89..8d04b8f 100644
--- a/hw/usb/host-linux.c
+++ b/hw/usb/host-linux.c
@@ -1530,6 +1530,7 @@ static void usb_host_class_initfn(ObjectClass *klass, void *data)
uc->handle_destroy = usb_host_handle_destroy;
dc->vmsd = &vmstate_usb_host;
dc->props = usb_host_dev_properties;
+ set_bit(DEVICE_CATEGORY_ASSEMBLY, dc->categories);
}
static const TypeInfo usb_host_dev_info = {
diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
index a594e95..8b8c010 100644
--- a/hw/usb/redirect.c
+++ b/hw/usb/redirect.c
@@ -2362,6 +2362,7 @@ static void usbredir_class_initfn(ObjectClass *klass, void *data)
uc->ep_stopped = usbredir_ep_stopped;
dc->vmsd = &usbredir_vmstate;
dc->props = usbredir_properties;
+ set_bit(DEVICE_CATEGORY_MISC, dc->categories);
}
static const TypeInfo usbredir_dev_info = {
diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
index 3fa72a9..0c63ce6 100644
--- a/hw/virtio/virtio-balloon.c
+++ b/hw/virtio/virtio-balloon.c
@@ -392,6 +392,7 @@ static void virtio_balloon_class_init(ObjectClass *klass, void *data)
VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
dc->exit = virtio_balloon_device_exit;
dc->props = virtio_balloon_properties;
+ set_bit(DEVICE_CATEGORY_MISC, dc->categories);
vdc->init = virtio_balloon_device_init;
vdc->get_config = virtio_balloon_get_config;
vdc->set_config = virtio_balloon_set_config;
diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c
index 54d6679..88cf994 100644
--- a/hw/virtio/virtio-mmio.c
+++ b/hw/virtio/virtio-mmio.c
@@ -370,6 +370,7 @@ static void virtio_mmio_class_init(ObjectClass *klass, void *data)
dc->realize = virtio_mmio_realizefn;
dc->reset = virtio_mmio_reset;
+ set_bit(DEVICE_CATEGORY_MISC, dc->categories);
}
static const TypeInfo virtio_mmio_info = {
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index c38cfd1..d37037e 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -911,6 +911,7 @@ static void virtio_9p_pci_class_init(ObjectClass *klass, void *data)
pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_9P;
pcidev_k->revision = VIRTIO_PCI_ABI_VERSION;
pcidev_k->class_id = 0x2;
+ set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
dc->props = virtio_9p_pci_properties;
}
@@ -1065,6 +1066,7 @@ static void virtio_blk_pci_class_init(ObjectClass *klass, void *data)
VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
+ set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
dc->props = virtio_blk_pci_properties;
k->init = virtio_blk_pci_init;
pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
@@ -1135,6 +1137,7 @@ static void virtio_scsi_pci_class_init(ObjectClass *klass, void *data)
VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
k->init = virtio_scsi_pci_init_pci;
+ set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
dc->props = virtio_scsi_pci_properties;
pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_SCSI;
@@ -1191,6 +1194,7 @@ static void vhost_scsi_pci_class_init(ObjectClass *klass, void *data)
VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
k->init = vhost_scsi_pci_init_pci;
+ set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
dc->props = vhost_scsi_pci_properties;
pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_SCSI;
@@ -1271,6 +1275,7 @@ static void virtio_balloon_pci_class_init(ObjectClass *klass, void *data)
VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
k->init = virtio_balloon_pci_init;
+ set_bit(DEVICE_CATEGORY_MISC, dc->categories);
dc->props = virtio_balloon_pci_properties;
pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_BALLOON;
@@ -1356,6 +1361,7 @@ static void virtio_serial_pci_class_init(ObjectClass *klass, void *data)
VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
k->init = virtio_serial_pci_init;
+ set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
dc->props = virtio_serial_pci_properties;
pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_CONSOLE;
@@ -1417,6 +1423,7 @@ static void virtio_net_pci_class_init(ObjectClass *klass, void *data)
k->device_id = PCI_DEVICE_ID_VIRTIO_NET;
k->revision = VIRTIO_PCI_ABI_VERSION;
k->class_id = PCI_CLASS_NETWORK_ETHERNET;
+ set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
dc->props = virtio_net_properties;
vpciklass->init = virtio_net_pci_init;
}
@@ -1468,6 +1475,7 @@ static void virtio_rng_pci_class_init(ObjectClass *klass, void *data)
PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
k->init = virtio_rng_pci_init;
+ set_bit(DEVICE_CATEGORY_MISC, dc->categories);
dc->props = virtio_rng_pci_properties;
pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
diff --git a/hw/virtio/virtio-rng.c b/hw/virtio/virtio-rng.c
index cb787c7..bac8421 100644
--- a/hw/virtio/virtio-rng.c
+++ b/hw/virtio/virtio-rng.c
@@ -207,6 +207,7 @@ static void virtio_rng_class_init(ObjectClass *klass, void *data)
VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
dc->exit = virtio_rng_device_exit;
dc->props = virtio_rng_properties;
+ set_bit(DEVICE_CATEGORY_MISC, dc->categories);
vdc->init = virtio_rng_device_init;
vdc->get_features = get_features;
}
diff --git a/hw/watchdog/wdt_i6300esb.c b/hw/watchdog/wdt_i6300esb.c
index 85aebc2..2e064ba 100644
--- a/hw/watchdog/wdt_i6300esb.c
+++ b/hw/watchdog/wdt_i6300esb.c
@@ -451,6 +451,7 @@ static void i6300esb_class_init(ObjectClass *klass, void *data)
k->class_id = PCI_CLASS_SYSTEM_OTHER;
dc->reset = i6300esb_reset;
dc->vmsd = &vmstate_i6300esb;
+ set_bit(DEVICE_CATEGORY_MISC, dc->categories);
}
static const TypeInfo i6300esb_info = {
diff --git a/hw/watchdog/wdt_ib700.c b/hw/watchdog/wdt_ib700.c
index c788554..e97b4c3 100644
--- a/hw/watchdog/wdt_ib700.c
+++ b/hw/watchdog/wdt_ib700.c
@@ -137,6 +137,7 @@ static void wdt_ib700_class_init(ObjectClass *klass, void *data)
dc->realize = wdt_ib700_realize;
dc->reset = wdt_ib700_reset;
dc->vmsd = &vmstate_ib700;
+ set_bit(DEVICE_CATEGORY_MISC, dc->categories);
}
static const TypeInfo wdt_ib700_info = {
diff --git a/hw/xen/xen_platform.c b/hw/xen/xen_platform.c
index 6a8ba7e..79bf0b3 100644
--- a/hw/xen/xen_platform.c
+++ b/hw/xen/xen_platform.c
@@ -428,6 +428,7 @@ static void xen_platform_class_init(ObjectClass *klass, void *data)
k->subsystem_vendor_id = PCI_VENDOR_ID_XEN;
k->subsystem_id = PCI_DEVICE_ID_XEN_PLATFORM;
k->revision = 1;
+ set_bit(DEVICE_CATEGORY_MISC, dc->categories);
dc->desc = "XEN platform pci device";
dc->reset = platform_reset;
dc->vmsd = &vmstate_xen_platform;
diff --git a/hw/xen/xen_pt.c b/hw/xen/xen_pt.c
index d7ee774..57e484d 100644
--- a/hw/xen/xen_pt.c
+++ b/hw/xen/xen_pt.c
@@ -829,6 +829,7 @@ static void xen_pci_passthrough_class_init(ObjectClass *klass, void *data)
k->exit = xen_pt_unregister_device;
k->config_read = xen_pt_pci_read_config;
k->config_write = xen_pt_pci_write_config;
+ set_bit(DEVICE_CATEGORY_MISC, dc->categories);
dc->desc = "Assign an host PCI device with Xen";
dc->props = xen_pci_passthrough_properties;
};
--
1.8.3.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [Qemu-devel] [PATCH v2 1/3] hw: import bitmap operations in qdev-core header
2013-07-29 7:07 ` [Qemu-devel] [PATCH v2 1/3] hw: import bitmap operations in qdev-core header Marcel Apfelbaum
@ 2013-07-29 7:42 ` Michael S. Tsirkin
2013-07-29 8:01 ` Marcel Apfelbaum
0 siblings, 1 reply; 12+ messages in thread
From: Michael S. Tsirkin @ 2013-07-29 7:42 UTC (permalink / raw)
To: Marcel Apfelbaum; +Cc: pbonzini, aliguori, qemu-devel, afaerber
On Mon, Jul 29, 2013 at 10:07:33AM +0300, Marcel Apfelbaum wrote:
> Made small tweaks in code to prevent compilation issues
> when importing qemu/bitmap.h in qdev-core
>
> Signed-off-by: Marcel Apfelbaum <marcel.a@redhat.com>
> ---
> hw/core/qdev-properties.c | 4 ++--
> hw/net/eepro100.c | 1 -
> include/hw/qdev-core.h | 1 +
> 3 files changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
> index 3a324fb..01b27eb 100644
> --- a/hw/core/qdev-properties.c
> +++ b/hw/core/qdev-properties.c
> @@ -91,7 +91,7 @@ static void get_bit(Object *obj, Visitor *v, void *opaque,
> visit_type_bool(v, &value, name, errp);
> }
>
> -static void set_bit(Object *obj, Visitor *v, void *opaque,
> +static void prop_set_bit(Object *obj, Visitor *v, void *opaque,
> const char *name, Error **errp)
> {
> DeviceState *dev = DEVICE(obj);
> @@ -117,7 +117,7 @@ PropertyInfo qdev_prop_bit = {
> .legacy_name = "on/off",
> .print = print_bit,
> .get = get_bit,
> - .set = set_bit,
> + .set = prop_set_bit,
> };
>
> /* --- bool --- */
Other code uses qdev_prop prefix, which makes sense I think.
Let's also update get_bit and print_bit, keep it consistent.
> diff --git a/hw/net/eepro100.c b/hw/net/eepro100.c
> index e0befb2..3dc4937 100644
> --- a/hw/net/eepro100.c
> +++ b/hw/net/eepro100.c
> @@ -105,7 +105,6 @@
> #define PCI_IO_SIZE 64
> #define PCI_FLASH_SIZE (128 * KiB)
>
> -#define BIT(n) (1 << (n))
> #define BITS(n, m) (((0xffffffffU << (31 - n)) >> (31 - n + m)) << m)
>
> /* The SCB accepts the following controls for the Tx and Rx units: */
Please #include "qemu/bitops.h" - don't rely on other headers
pulling it in.
> diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
> index 7fbffcb..e8b89b1 100644
> --- a/include/hw/qdev-core.h
> +++ b/include/hw/qdev-core.h
> @@ -4,6 +4,7 @@
> #include "qemu/queue.h"
> #include "qemu/option.h"
> #include "qemu/typedefs.h"
> +#include "qemu/bitmap.h"
> #include "qom/object.h"
> #include "hw/irq.h"
> #include "qapi/error.h"
> --
> 1.8.3.1
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Qemu-devel] [PATCH v2 1/3] hw: import bitmap operations in qdev-core header
2013-07-29 7:42 ` Michael S. Tsirkin
@ 2013-07-29 8:01 ` Marcel Apfelbaum
0 siblings, 0 replies; 12+ messages in thread
From: Marcel Apfelbaum @ 2013-07-29 8:01 UTC (permalink / raw)
To: Michael S. Tsirkin; +Cc: pbonzini, aliguori, qemu-devel, afaerber
On Mon, 2013-07-29 at 10:42 +0300, Michael S. Tsirkin wrote:
> On Mon, Jul 29, 2013 at 10:07:33AM +0300, Marcel Apfelbaum wrote:
> > Made small tweaks in code to prevent compilation issues
> > when importing qemu/bitmap.h in qdev-core
> >
> > Signed-off-by: Marcel Apfelbaum <marcel.a@redhat.com>
> > ---
> > hw/core/qdev-properties.c | 4 ++--
> > hw/net/eepro100.c | 1 -
> > include/hw/qdev-core.h | 1 +
> > 3 files changed, 3 insertions(+), 3 deletions(-)
> >
> > diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
> > index 3a324fb..01b27eb 100644
> > --- a/hw/core/qdev-properties.c
> > +++ b/hw/core/qdev-properties.c
> > @@ -91,7 +91,7 @@ static void get_bit(Object *obj, Visitor *v, void *opaque,
> > visit_type_bool(v, &value, name, errp);
> > }
> >
> > -static void set_bit(Object *obj, Visitor *v, void *opaque,
> > +static void prop_set_bit(Object *obj, Visitor *v, void *opaque,
> > const char *name, Error **errp)
> > {
> > DeviceState *dev = DEVICE(obj);
> > @@ -117,7 +117,7 @@ PropertyInfo qdev_prop_bit = {
> > .legacy_name = "on/off",
> > .print = print_bit,
> > .get = get_bit,
> > - .set = set_bit,
> > + .set = prop_set_bit,
> > };
> >
> > /* --- bool --- */
>
> Other code uses qdev_prop prefix, which makes sense I think.
> Let's also update get_bit and print_bit, keep it consistent.
Sure
>
> > diff --git a/hw/net/eepro100.c b/hw/net/eepro100.c
> > index e0befb2..3dc4937 100644
> > --- a/hw/net/eepro100.c
> > +++ b/hw/net/eepro100.c
> > @@ -105,7 +105,6 @@
> > #define PCI_IO_SIZE 64
> > #define PCI_FLASH_SIZE (128 * KiB)
> >
> > -#define BIT(n) (1 << (n))
> > #define BITS(n, m) (((0xffffffffU << (31 - n)) >> (31 - n + m)) << m)
> >
> > /* The SCB accepts the following controls for the Tx and Rx units: */
>
> Please #include "qemu/bitops.h" - don't rely on other headers
> pulling it in.
Thanks
Marcel
>
> > diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
> > index 7fbffcb..e8b89b1 100644
> > --- a/include/hw/qdev-core.h
> > +++ b/include/hw/qdev-core.h
> > @@ -4,6 +4,7 @@
> > #include "qemu/queue.h"
> > #include "qemu/option.h"
> > #include "qemu/typedefs.h"
> > +#include "qemu/bitmap.h"
> > #include "qom/object.h"
> > #include "hw/irq.h"
> > #include "qapi/error.h"
> > --
> > 1.8.3.1
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Qemu-devel] [PATCH v2 2/3] qemu-help: Sort devices by logical functionality
2013-07-29 7:07 ` [Qemu-devel] [PATCH v2 2/3] qemu-help: Sort devices by logical functionality Marcel Apfelbaum
@ 2013-07-29 8:04 ` Michael S. Tsirkin
2013-07-29 8:14 ` Marcel Apfelbaum
0 siblings, 1 reply; 12+ messages in thread
From: Michael S. Tsirkin @ 2013-07-29 8:04 UTC (permalink / raw)
To: Marcel Apfelbaum; +Cc: pbonzini, aliguori, qemu-devel, afaerber
On Mon, Jul 29, 2013 at 10:07:34AM +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 v1:
> Addressed Michael Tsirkin review:
> Used bitmap operations on categories
> Moved category names into the header file
>
> include/hw/qdev-core.h | 33 +++++++++++++++++++++++++++++++++
> qdev-monitor.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++----
> 2 files changed, 79 insertions(+), 4 deletions(-)
>
> diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
> index e8b89b1..80b06ac 100644
> --- a/include/hw/qdev-core.h
> +++ b/include/hw/qdev-core.h
> @@ -18,6 +18,38 @@ 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_ASSEMBLY,
> + DEVICE_CATEGORY_MANAGEMENT,
> + 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)
> +{
> + /* Category names corresponding to DeviceCategory values
> + * The array elements must be in the same order as they
> + * appear in DeviceCategory enum.
> + */
I would simply do:
static const char *category_names[DEVICE_CATEGORY_MAX] = {
[DEVICE_CATEGORY_ASSEMBLY] = "Assembly",
[DEVICE_CATEGORY_MANAGEMENT] = "Management",
[DEVICE_CATEGORY_STORAGE] = "Storage",
[DEVICE_CATEGORY_NETWORK] = "Network",
[DEVICE_CATEGORY_INPUT] = "Input",
[DEVICE_CATEGORY_DISPLAY] = "Display",
[DEVICE_CATEGORY_SOUND] = "Sound",
[DEVICE_CATEGORY_MISC] = "Misc",
};
and drop the requirement to use same order.
> + static const char *category_names[] = {
> + "Assembly",
> + "Management",
> + "Storage",
> + "Network",
> + "Input",
> + "Display",
> + "Sound",
> + "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 +113,7 @@ typedef struct DeviceClass {
> ObjectClass parent_class;
> /*< public >*/
>
> + DECLARE_BITMAP(categories, 20);
Why 20? Not DEVICE_CATEGORY_MAX ?
> const char *fw_name;
> const char *desc;
> Property *props;
> diff --git a/qdev-monitor.c b/qdev-monitor.c
> index e54dbc2..c3a3550 100644
> --- a/qdev-monitor.c
> +++ b/qdev-monitor.c
> @@ -75,14 +75,21 @@ static bool qdev_class_has_alias(DeviceClass *dc)
> return (qdev_class_get_alias(dc) != NULL);
> }
>
> +typedef struct PrintDevInfoData {
> + bool show_no_user;
> + DeviceCategory category;
> +} PrintDevInfoData ;
> +
> static void qdev_print_devinfo(ObjectClass *klass, void *opaque)
> {
> DeviceClass *dc;
> - bool *show_no_user = opaque;
> + PrintDevInfoData *data = opaque;
So all callers of qdev_print_devinfo would have to be updated,
but you only updated one caller.
Lack of type checking here is nasty. It's required
by the object_class_foreach but you are not using that
anymore.
So please refactor this function: e.g.
qdev_print_devinfo which gets void *,
and qdev_print_class_devinfo which gets show_no_user and category.
In fact, this way there won't be need for use of void *
at all.
> + DeviceCategory category;
>
> + category = data ? data->category : DEVICE_CATEGORY_MAX;
> dc = (DeviceClass *)object_class_dynamic_cast(klass, TYPE_DEVICE);
>
> - if (!dc || (show_no_user && !*show_no_user && dc->no_user)) {
> + if (!dc || (data && !data->show_no_user && dc->no_user)) {
> return;
> }
>
> @@ -93,6 +100,18 @@ static void qdev_print_devinfo(ObjectClass *klass, void *opaque)
> if (qdev_class_has_alias(dc)) {
> error_printf(", alias \"%s\"", qdev_class_get_alias(dc));
> }
> + if (dc->categories) {
Is this sometimes unset? Some devices don't have a category?
> + if (test_bit(category, dc->categories)) {
> + error_printf(", category \"%s\"", qdev_category_get_name(category));
> + } else {
> + 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));
> + }
> + }
Confused. Why different output format?
Maybe add a comment with explanation.
Also, testing DEVICE_CATEGORY_MAX will cause out of bounds
access on bitmap - you want to special-case it
explicitly.
Also, this overrides category parameter so if one tries to
use it below one gets DEVICE_CATEGORY_MAX.
Better use a different local variable for the loop.
> + }
> + }
> if (dc->desc) {
> error_printf(", desc \"%s\"", dc->desc);
> }
> @@ -139,6 +158,23 @@ static const char *find_typename_by_alias(const char *alias)
> return NULL;
> }
>
> +static GSList *qdev_get_devices_by_category(DeviceCategory category)
> +{
> + DeviceClass *dc;
> + GSList *list, *curr, *ret_list = NULL;
> +
> + list = object_class_get_list(TYPE_DEVICE, false);
> + for (curr = list; curr; curr = g_slist_next(curr)) {
> + dc = (DeviceClass *)object_class_dynamic_cast(curr->data, TYPE_DEVICE);
> + if (test_bit(category, dc->categories)) {
> + ret_list = g_slist_append(ret_list, dc);
So you build list here, then immediately scan it in
the same order and free it.
Wouldn't it be easier to just call qdev_print_devinfo here
directly?
> + }
> + }
> + g_slist_free(list);
> +
> + return ret_list;
> +}
> +
> int qdev_device_help(QemuOpts *opts)
> {
> const char *driver;
> @@ -147,8 +183,14 @@ 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) {
> + PrintDevInfoData data = { false, category };
> + GSList *list = qdev_get_devices_by_category(category);
> + g_slist_foreach(list, (GFunc)qdev_print_devinfo, &data);
This cast should be avoided. If function signatures do not match,
you really don't want to work around it like this.
Refactor code please.
> + g_slist_free(list);
> + }
> +
> return 1;
> }
>
> --
> 1.8.3.1
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Qemu-devel] [PATCH v2 2/3] qemu-help: Sort devices by logical functionality
2013-07-29 8:04 ` Michael S. Tsirkin
@ 2013-07-29 8:14 ` Marcel Apfelbaum
2013-07-29 8:20 ` Michael S. Tsirkin
0 siblings, 1 reply; 12+ messages in thread
From: Marcel Apfelbaum @ 2013-07-29 8:14 UTC (permalink / raw)
To: Michael S. Tsirkin; +Cc: pbonzini, aliguori, qemu-devel, afaerber
On Mon, 2013-07-29 at 11:04 +0300, Michael S. Tsirkin wrote:
> On Mon, Jul 29, 2013 at 10:07:34AM +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 v1:
> > Addressed Michael Tsirkin review:
> > Used bitmap operations on categories
> > Moved category names into the header file
> >
> > include/hw/qdev-core.h | 33 +++++++++++++++++++++++++++++++++
> > qdev-monitor.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++----
> > 2 files changed, 79 insertions(+), 4 deletions(-)
> >
> > diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
> > index e8b89b1..80b06ac 100644
> > --- a/include/hw/qdev-core.h
> > +++ b/include/hw/qdev-core.h
> > @@ -18,6 +18,38 @@ 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_ASSEMBLY,
> > + DEVICE_CATEGORY_MANAGEMENT,
> > + 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)
> > +{
> > + /* Category names corresponding to DeviceCategory values
> > + * The array elements must be in the same order as they
> > + * appear in DeviceCategory enum.
> > + */
>
> I would simply do:
> static const char *category_names[DEVICE_CATEGORY_MAX] = {
> [DEVICE_CATEGORY_ASSEMBLY] = "Assembly",
> [DEVICE_CATEGORY_MANAGEMENT] = "Management",
> [DEVICE_CATEGORY_STORAGE] = "Storage",
> [DEVICE_CATEGORY_NETWORK] = "Network",
> [DEVICE_CATEGORY_INPUT] = "Input",
> [DEVICE_CATEGORY_DISPLAY] = "Display",
> [DEVICE_CATEGORY_SOUND] = "Sound",
> [DEVICE_CATEGORY_MISC] = "Misc",
> };
>
> and drop the requirement to use same order.
OK
>
> > + static const char *category_names[] = {
> > + "Assembly",
> > + "Management",
> > + "Storage",
> > + "Network",
> > + "Input",
> > + "Display",
> > + "Sound",
> > + "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 +113,7 @@ typedef struct DeviceClass {
> > ObjectClass parent_class;
> > /*< public >*/
> >
> > + DECLARE_BITMAP(categories, 20);
>
> Why 20? Not DEVICE_CATEGORY_MAX ?
OK
>
>
> > const char *fw_name;
> > const char *desc;
> > Property *props;
> > diff --git a/qdev-monitor.c b/qdev-monitor.c
> > index e54dbc2..c3a3550 100644
> > --- a/qdev-monitor.c
> > +++ b/qdev-monitor.c
> > @@ -75,14 +75,21 @@ static bool qdev_class_has_alias(DeviceClass *dc)
> > return (qdev_class_get_alias(dc) != NULL);
> > }
> >
> > +typedef struct PrintDevInfoData {
> > + bool show_no_user;
> > + DeviceCategory category;
> > +} PrintDevInfoData ;
> > +
> > static void qdev_print_devinfo(ObjectClass *klass, void *opaque)
> > {
> > DeviceClass *dc;
> > - bool *show_no_user = opaque;
> > + PrintDevInfoData *data = opaque;
>
> So all callers of qdev_print_devinfo would have to be updated,
> but you only updated one caller.
> Lack of type checking here is nasty. It's required
> by the object_class_foreach but you are not using that
> anymore.
>
> So please refactor this function: e.g.
> qdev_print_devinfo which gets void *,
> and qdev_print_class_devinfo which gets show_no_user and category.
> In fact, this way there won't be need for use of void *
> at all.
OK
>
>
> > + DeviceCategory category;
> >
> > + category = data ? data->category : DEVICE_CATEGORY_MAX;
> > dc = (DeviceClass *)object_class_dynamic_cast(klass, TYPE_DEVICE);
> >
> > - if (!dc || (show_no_user && !*show_no_user && dc->no_user)) {
> > + if (!dc || (data && !data->show_no_user && dc->no_user)) {
> > return;
> > }
> >
> > @@ -93,6 +100,18 @@ static void qdev_print_devinfo(ObjectClass *klass, void *opaque)
> > if (qdev_class_has_alias(dc)) {
> > error_printf(", alias \"%s\"", qdev_class_get_alias(dc));
> > }
> > + if (dc->categories) {
>
> Is this sometimes unset? Some devices don't have a category?
All devices shall have a category
>
> > + if (test_bit(category, dc->categories)) {
> > + error_printf(", category \"%s\"", qdev_category_get_name(category));
> > + } else {
> > + 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));
> > + }
> > + }
>
> Confused. Why different output format?
> Maybe add a comment with explanation.
> Also, testing DEVICE_CATEGORY_MAX will cause out of bounds
> access on bitmap - you want to special-case it
> explicitly.
>
In RFC patches was possible to print a device that belonged
to a specific category, or print out all its categories.
In this series it can be done by passing DEVICE_CATEGORY_MAX
> Also, this overrides category parameter so if one tries to
> use it below one gets DEVICE_CATEGORY_MAX.
> Better use a different local variable for the loop.
OK
>
> > + }
> > + }
> > if (dc->desc) {
> > error_printf(", desc \"%s\"", dc->desc);
> > }
> > @@ -139,6 +158,23 @@ static const char *find_typename_by_alias(const char *alias)
> > return NULL;
> > }
> >
> > +static GSList *qdev_get_devices_by_category(DeviceCategory category)
> > +{
> > + DeviceClass *dc;
> > + GSList *list, *curr, *ret_list = NULL;
> > +
> > + list = object_class_get_list(TYPE_DEVICE, false);
> > + for (curr = list; curr; curr = g_slist_next(curr)) {
> > + dc = (DeviceClass *)object_class_dynamic_cast(curr->data, TYPE_DEVICE);
> > + if (test_bit(category, dc->categories)) {
> > + ret_list = g_slist_append(ret_list, dc);
>
> So you build list here, then immediately scan it in
> the same order and free it.
> Wouldn't it be easier to just call qdev_print_devinfo here
> directly?
>
>
> > + }
> > + }
> > + g_slist_free(list);
> > +
> > + return ret_list;
> > +}
> > +
> > int qdev_device_help(QemuOpts *opts)
> > {
> > const char *driver;
> > @@ -147,8 +183,14 @@ 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) {
> > + PrintDevInfoData data = { false, category };
> > + GSList *list = qdev_get_devices_by_category(category);
> > + g_slist_foreach(list, (GFunc)qdev_print_devinfo, &data);
>
> This cast should be avoided. If function signatures do not match,
> you really don't want to work around it like this.
> Refactor code please.
OK
>
>
> > + g_slist_free(list);
> > + }
> > +
> > return 1;
> > }
> >
> > --
> > 1.8.3.1
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Qemu-devel] [PATCH v2 2/3] qemu-help: Sort devices by logical functionality
2013-07-29 8:14 ` Marcel Apfelbaum
@ 2013-07-29 8:20 ` Michael S. Tsirkin
2013-07-29 9:09 ` Marcel Apfelbaum
0 siblings, 1 reply; 12+ messages in thread
From: Michael S. Tsirkin @ 2013-07-29 8:20 UTC (permalink / raw)
To: Marcel Apfelbaum; +Cc: pbonzini, aliguori, qemu-devel, afaerber
On Mon, Jul 29, 2013 at 11:14:11AM +0300, Marcel Apfelbaum wrote:
> On Mon, 2013-07-29 at 11:04 +0300, Michael S. Tsirkin wrote:
> > On Mon, Jul 29, 2013 at 10:07:34AM +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 v1:
> > > Addressed Michael Tsirkin review:
> > > Used bitmap operations on categories
> > > Moved category names into the header file
> > >
> > > include/hw/qdev-core.h | 33 +++++++++++++++++++++++++++++++++
> > > qdev-monitor.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++----
> > > 2 files changed, 79 insertions(+), 4 deletions(-)
> > >
> > > diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
> > > index e8b89b1..80b06ac 100644
> > > --- a/include/hw/qdev-core.h
> > > +++ b/include/hw/qdev-core.h
> > > @@ -18,6 +18,38 @@ 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_ASSEMBLY,
> > > + DEVICE_CATEGORY_MANAGEMENT,
> > > + 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)
> > > +{
> > > + /* Category names corresponding to DeviceCategory values
> > > + * The array elements must be in the same order as they
> > > + * appear in DeviceCategory enum.
> > > + */
> >
> > I would simply do:
> > static const char *category_names[DEVICE_CATEGORY_MAX] = {
> > [DEVICE_CATEGORY_ASSEMBLY] = "Assembly",
> > [DEVICE_CATEGORY_MANAGEMENT] = "Management",
> > [DEVICE_CATEGORY_STORAGE] = "Storage",
> > [DEVICE_CATEGORY_NETWORK] = "Network",
> > [DEVICE_CATEGORY_INPUT] = "Input",
> > [DEVICE_CATEGORY_DISPLAY] = "Display",
> > [DEVICE_CATEGORY_SOUND] = "Sound",
> > [DEVICE_CATEGORY_MISC] = "Misc",
> > };
> >
> > and drop the requirement to use same order.
> OK
> >
> > > + static const char *category_names[] = {
> > > + "Assembly",
> > > + "Management",
> > > + "Storage",
> > > + "Network",
> > > + "Input",
> > > + "Display",
> > > + "Sound",
> > > + "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 +113,7 @@ typedef struct DeviceClass {
> > > ObjectClass parent_class;
> > > /*< public >*/
> > >
> > > + DECLARE_BITMAP(categories, 20);
> >
> > Why 20? Not DEVICE_CATEGORY_MAX ?
> OK
> >
> >
> > > const char *fw_name;
> > > const char *desc;
> > > Property *props;
> > > diff --git a/qdev-monitor.c b/qdev-monitor.c
> > > index e54dbc2..c3a3550 100644
> > > --- a/qdev-monitor.c
> > > +++ b/qdev-monitor.c
> > > @@ -75,14 +75,21 @@ static bool qdev_class_has_alias(DeviceClass *dc)
> > > return (qdev_class_get_alias(dc) != NULL);
> > > }
> > >
> > > +typedef struct PrintDevInfoData {
> > > + bool show_no_user;
> > > + DeviceCategory category;
> > > +} PrintDevInfoData ;
> > > +
> > > static void qdev_print_devinfo(ObjectClass *klass, void *opaque)
> > > {
> > > DeviceClass *dc;
> > > - bool *show_no_user = opaque;
> > > + PrintDevInfoData *data = opaque;
> >
> > So all callers of qdev_print_devinfo would have to be updated,
> > but you only updated one caller.
> > Lack of type checking here is nasty. It's required
> > by the object_class_foreach but you are not using that
> > anymore.
> >
> > So please refactor this function: e.g.
> > qdev_print_devinfo which gets void *,
> > and qdev_print_class_devinfo which gets show_no_user and category.
> > In fact, this way there won't be need for use of void *
> > at all.
> OK
> >
> >
> > > + DeviceCategory category;
> > >
> > > + category = data ? data->category : DEVICE_CATEGORY_MAX;
> > > dc = (DeviceClass *)object_class_dynamic_cast(klass, TYPE_DEVICE);
> > >
> > > - if (!dc || (show_no_user && !*show_no_user && dc->no_user)) {
> > > + if (!dc || (data && !data->show_no_user && dc->no_user)) {
> > > return;
> > > }
> > >
> > > @@ -93,6 +100,18 @@ static void qdev_print_devinfo(ObjectClass *klass, void *opaque)
> > > if (qdev_class_has_alias(dc)) {
> > > error_printf(", alias \"%s\"", qdev_class_get_alias(dc));
> > > }
> > > + if (dc->categories) {
> >
> > Is this sometimes unset? Some devices don't have a category?
> All devices shall have a category
There's no point to the if statement above, apparently.
if (dc->categories) actually tests the array pointer.
Since that's defined statically using DECLARE_BITMAP, it's
never NULL.
> >
> > > + if (test_bit(category, dc->categories)) {
> > > + error_printf(", category \"%s\"", qdev_category_get_name(category));
> > > + } else {
> > > + 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));
> > > + }
> > > + }
> >
> > Confused. Why different output format?
> > Maybe add a comment with explanation.
> > Also, testing DEVICE_CATEGORY_MAX will cause out of bounds
> > access on bitmap - you want to special-case it
> > explicitly.
> >
> In RFC patches was possible to print a device that belonged
> to a specific category, or print out all its categories.
> In this series it can be done by passing DEVICE_CATEGORY_MAX
Yes but when you are printing a specific device, why not
always print all categories?
And assuming you don't want to print all categories,
do if(category == DEVICE_CATEGORY_MAX), test_bit does not
check that it's not a legal value.
> > Also, this overrides category parameter so if one tries to
> > use it below one gets DEVICE_CATEGORY_MAX.
> > Better use a different local variable for the loop.
> OK
> >
> > > + }
> > > + }
> > > if (dc->desc) {
> > > error_printf(", desc \"%s\"", dc->desc);
> > > }
> > > @@ -139,6 +158,23 @@ static const char *find_typename_by_alias(const char *alias)
> > > return NULL;
> > > }
> > >
> > > +static GSList *qdev_get_devices_by_category(DeviceCategory category)
> > > +{
> > > + DeviceClass *dc;
> > > + GSList *list, *curr, *ret_list = NULL;
> > > +
> > > + list = object_class_get_list(TYPE_DEVICE, false);
> > > + for (curr = list; curr; curr = g_slist_next(curr)) {
> > > + dc = (DeviceClass *)object_class_dynamic_cast(curr->data, TYPE_DEVICE);
> > > + if (test_bit(category, dc->categories)) {
> > > + ret_list = g_slist_append(ret_list, dc);
> >
> > So you build list here, then immediately scan it in
> > the same order and free it.
> > Wouldn't it be easier to just call qdev_print_devinfo here
> > directly?
> >
> >
> > > + }
> > > + }
> > > + g_slist_free(list);
> > > +
> > > + return ret_list;
> > > +}
> > > +
> > > int qdev_device_help(QemuOpts *opts)
> > > {
> > > const char *driver;
> > > @@ -147,8 +183,14 @@ 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) {
> > > + PrintDevInfoData data = { false, category };
> > > + GSList *list = qdev_get_devices_by_category(category);
> > > + g_slist_foreach(list, (GFunc)qdev_print_devinfo, &data);
> >
> > This cast should be avoided. If function signatures do not match,
> > you really don't want to work around it like this.
> > Refactor code please.
> OK
> >
> >
> > > + g_slist_free(list);
> > > + }
> > > +
> > > return 1;
> > > }
> > >
> > > --
> > > 1.8.3.1
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Qemu-devel] [PATCH v2 2/3] qemu-help: Sort devices by logical functionality
2013-07-29 8:20 ` Michael S. Tsirkin
@ 2013-07-29 9:09 ` Marcel Apfelbaum
2013-07-29 9:22 ` Michael S. Tsirkin
0 siblings, 1 reply; 12+ messages in thread
From: Marcel Apfelbaum @ 2013-07-29 9:09 UTC (permalink / raw)
To: Michael S. Tsirkin; +Cc: pbonzini, aliguori, qemu-devel, afaerber
On Mon, 2013-07-29 at 11:20 +0300, Michael S. Tsirkin wrote:
> On Mon, Jul 29, 2013 at 11:14:11AM +0300, Marcel Apfelbaum wrote:
> > On Mon, 2013-07-29 at 11:04 +0300, Michael S. Tsirkin wrote:
> > > On Mon, Jul 29, 2013 at 10:07:34AM +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 v1:
> > > > Addressed Michael Tsirkin review:
> > > > Used bitmap operations on categories
> > > > Moved category names into the header file
> > > >
> > > > include/hw/qdev-core.h | 33 +++++++++++++++++++++++++++++++++
> > > > qdev-monitor.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++----
> > > > 2 files changed, 79 insertions(+), 4 deletions(-)
> > > >
> > > > diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
> > > > index e8b89b1..80b06ac 100644
> > > > --- a/include/hw/qdev-core.h
> > > > +++ b/include/hw/qdev-core.h
> > > > @@ -18,6 +18,38 @@ 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_ASSEMBLY,
> > > > + DEVICE_CATEGORY_MANAGEMENT,
> > > > + 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)
> > > > +{
> > > > + /* Category names corresponding to DeviceCategory values
> > > > + * The array elements must be in the same order as they
> > > > + * appear in DeviceCategory enum.
> > > > + */
> > >
> > > I would simply do:
> > > static const char *category_names[DEVICE_CATEGORY_MAX] = {
> > > [DEVICE_CATEGORY_ASSEMBLY] = "Assembly",
> > > [DEVICE_CATEGORY_MANAGEMENT] = "Management",
> > > [DEVICE_CATEGORY_STORAGE] = "Storage",
> > > [DEVICE_CATEGORY_NETWORK] = "Network",
> > > [DEVICE_CATEGORY_INPUT] = "Input",
> > > [DEVICE_CATEGORY_DISPLAY] = "Display",
> > > [DEVICE_CATEGORY_SOUND] = "Sound",
> > > [DEVICE_CATEGORY_MISC] = "Misc",
> > > };
> > >
> > > and drop the requirement to use same order.
> > OK
> > >
> > > > + static const char *category_names[] = {
> > > > + "Assembly",
> > > > + "Management",
> > > > + "Storage",
> > > > + "Network",
> > > > + "Input",
> > > > + "Display",
> > > > + "Sound",
> > > > + "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 +113,7 @@ typedef struct DeviceClass {
> > > > ObjectClass parent_class;
> > > > /*< public >*/
> > > >
> > > > + DECLARE_BITMAP(categories, 20);
> > >
> > > Why 20? Not DEVICE_CATEGORY_MAX ?
> > OK
> > >
> > >
> > > > const char *fw_name;
> > > > const char *desc;
> > > > Property *props;
> > > > diff --git a/qdev-monitor.c b/qdev-monitor.c
> > > > index e54dbc2..c3a3550 100644
> > > > --- a/qdev-monitor.c
> > > > +++ b/qdev-monitor.c
> > > > @@ -75,14 +75,21 @@ static bool qdev_class_has_alias(DeviceClass *dc)
> > > > return (qdev_class_get_alias(dc) != NULL);
> > > > }
> > > >
> > > > +typedef struct PrintDevInfoData {
> > > > + bool show_no_user;
> > > > + DeviceCategory category;
> > > > +} PrintDevInfoData ;
> > > > +
> > > > static void qdev_print_devinfo(ObjectClass *klass, void *opaque)
> > > > {
> > > > DeviceClass *dc;
> > > > - bool *show_no_user = opaque;
> > > > + PrintDevInfoData *data = opaque;
> > >
> > > So all callers of qdev_print_devinfo would have to be updated,
> > > but you only updated one caller.
> > > Lack of type checking here is nasty. It's required
> > > by the object_class_foreach but you are not using that
> > > anymore.
> > >
> > > So please refactor this function: e.g.
> > > qdev_print_devinfo which gets void *,
> > > and qdev_print_class_devinfo which gets show_no_user and category.
> > > In fact, this way there won't be need for use of void *
> > > at all.
> > OK
> > >
> > >
> > > > + DeviceCategory category;
> > > >
> > > > + category = data ? data->category : DEVICE_CATEGORY_MAX;
> > > > dc = (DeviceClass *)object_class_dynamic_cast(klass, TYPE_DEVICE);
> > > >
> > > > - if (!dc || (show_no_user && !*show_no_user && dc->no_user)) {
> > > > + if (!dc || (data && !data->show_no_user && dc->no_user)) {
> > > > return;
> > > > }
> > > >
> > > > @@ -93,6 +100,18 @@ static void qdev_print_devinfo(ObjectClass *klass, void *opaque)
> > > > if (qdev_class_has_alias(dc)) {
> > > > error_printf(", alias \"%s\"", qdev_class_get_alias(dc));
> > > > }
> > > > + if (dc->categories) {
> > >
> > > Is this sometimes unset? Some devices don't have a category?
> > All devices shall have a category
>
> There's no point to the if statement above, apparently.
> if (dc->categories) actually tests the array pointer.
> Since that's defined statically using DECLARE_BITMAP, it's
> never NULL.
Right
>
>
> > >
> > > > + if (test_bit(category, dc->categories)) {
> > > > + error_printf(", category \"%s\"", qdev_category_get_name(category));
> > > > + } else {
> > > > + 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));
> > > > + }
> > > > + }
> > >
> > > Confused. Why different output format?
> > > Maybe add a comment with explanation.
> > > Also, testing DEVICE_CATEGORY_MAX will cause out of bounds
> > > access on bitmap - you want to special-case it
> > > explicitly.
> > >
> > In RFC patches was possible to print a device that belonged
> > to a specific category, or print out all its categories.
> > In this series it can be done by passing DEVICE_CATEGORY_MAX
>
> Yes but when you are printing a specific device, why not
> always print all categories?
Because multifunction devices will appear more than once
in a grep. Also it will not be easy to differentiate devices
belonging to the same category without grep.
> And assuming you don't want to print all categories,
> do if(category == DEVICE_CATEGORY_MAX), test_bit does not
> check that it's not a legal value.
This is exactly what I am going to do.
>
> > > Also, this overrides category parameter so if one tries to
> > > use it below one gets DEVICE_CATEGORY_MAX.
> > > Better use a different local variable for the loop.
> > OK
> > >
> > > > + }
> > > > + }
> > > > if (dc->desc) {
> > > > error_printf(", desc \"%s\"", dc->desc);
> > > > }
> > > > @@ -139,6 +158,23 @@ static const char *find_typename_by_alias(const char *alias)
> > > > return NULL;
> > > > }
> > > >
> > > > +static GSList *qdev_get_devices_by_category(DeviceCategory category)
> > > > +{
> > > > + DeviceClass *dc;
> > > > + GSList *list, *curr, *ret_list = NULL;
> > > > +
> > > > + list = object_class_get_list(TYPE_DEVICE, false);
> > > > + for (curr = list; curr; curr = g_slist_next(curr)) {
> > > > + dc = (DeviceClass *)object_class_dynamic_cast(curr->data, TYPE_DEVICE);
> > > > + if (test_bit(category, dc->categories)) {
> > > > + ret_list = g_slist_append(ret_list, dc);
> > >
> > > So you build list here, then immediately scan it in
> > > the same order and free it.
> > > Wouldn't it be easier to just call qdev_print_devinfo here
> > > directly?
> > >
> > >
> > > > + }
> > > > + }
> > > > + g_slist_free(list);
> > > > +
> > > > + return ret_list;
> > > > +}
> > > > +
> > > > int qdev_device_help(QemuOpts *opts)
> > > > {
> > > > const char *driver;
> > > > @@ -147,8 +183,14 @@ 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) {
> > > > + PrintDevInfoData data = { false, category };
> > > > + GSList *list = qdev_get_devices_by_category(category);
> > > > + g_slist_foreach(list, (GFunc)qdev_print_devinfo, &data);
> > >
> > > This cast should be avoided. If function signatures do not match,
> > > you really don't want to work around it like this.
> > > Refactor code please.
> > OK
> > >
> > >
> > > > + g_slist_free(list);
> > > > + }
> > > > +
> > > > return 1;
> > > > }
> > > >
> > > > --
> > > > 1.8.3.1
> >
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Qemu-devel] [PATCH v2 2/3] qemu-help: Sort devices by logical functionality
2013-07-29 9:09 ` Marcel Apfelbaum
@ 2013-07-29 9:22 ` Michael S. Tsirkin
2013-07-29 9:26 ` Marcel Apfelbaum
0 siblings, 1 reply; 12+ messages in thread
From: Michael S. Tsirkin @ 2013-07-29 9:22 UTC (permalink / raw)
To: Marcel Apfelbaum; +Cc: pbonzini, aliguori, qemu-devel, afaerber
On Mon, Jul 29, 2013 at 12:09:45PM +0300, Marcel Apfelbaum wrote:
> On Mon, 2013-07-29 at 11:20 +0300, Michael S. Tsirkin wrote:
> > On Mon, Jul 29, 2013 at 11:14:11AM +0300, Marcel Apfelbaum wrote:
> > > On Mon, 2013-07-29 at 11:04 +0300, Michael S. Tsirkin wrote:
> > > > On Mon, Jul 29, 2013 at 10:07:34AM +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 v1:
> > > > > Addressed Michael Tsirkin review:
> > > > > Used bitmap operations on categories
> > > > > Moved category names into the header file
> > > > >
> > > > > include/hw/qdev-core.h | 33 +++++++++++++++++++++++++++++++++
> > > > > qdev-monitor.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++----
> > > > > 2 files changed, 79 insertions(+), 4 deletions(-)
> > > > >
> > > > > diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
> > > > > index e8b89b1..80b06ac 100644
> > > > > --- a/include/hw/qdev-core.h
> > > > > +++ b/include/hw/qdev-core.h
> > > > > @@ -18,6 +18,38 @@ 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_ASSEMBLY,
> > > > > + DEVICE_CATEGORY_MANAGEMENT,
> > > > > + 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)
> > > > > +{
> > > > > + /* Category names corresponding to DeviceCategory values
> > > > > + * The array elements must be in the same order as they
> > > > > + * appear in DeviceCategory enum.
> > > > > + */
> > > >
> > > > I would simply do:
> > > > static const char *category_names[DEVICE_CATEGORY_MAX] = {
> > > > [DEVICE_CATEGORY_ASSEMBLY] = "Assembly",
> > > > [DEVICE_CATEGORY_MANAGEMENT] = "Management",
> > > > [DEVICE_CATEGORY_STORAGE] = "Storage",
> > > > [DEVICE_CATEGORY_NETWORK] = "Network",
> > > > [DEVICE_CATEGORY_INPUT] = "Input",
> > > > [DEVICE_CATEGORY_DISPLAY] = "Display",
> > > > [DEVICE_CATEGORY_SOUND] = "Sound",
> > > > [DEVICE_CATEGORY_MISC] = "Misc",
> > > > };
> > > >
> > > > and drop the requirement to use same order.
> > > OK
> > > >
> > > > > + static const char *category_names[] = {
> > > > > + "Assembly",
> > > > > + "Management",
> > > > > + "Storage",
> > > > > + "Network",
> > > > > + "Input",
> > > > > + "Display",
> > > > > + "Sound",
> > > > > + "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 +113,7 @@ typedef struct DeviceClass {
> > > > > ObjectClass parent_class;
> > > > > /*< public >*/
> > > > >
> > > > > + DECLARE_BITMAP(categories, 20);
> > > >
> > > > Why 20? Not DEVICE_CATEGORY_MAX ?
> > > OK
> > > >
> > > >
> > > > > const char *fw_name;
> > > > > const char *desc;
> > > > > Property *props;
> > > > > diff --git a/qdev-monitor.c b/qdev-monitor.c
> > > > > index e54dbc2..c3a3550 100644
> > > > > --- a/qdev-monitor.c
> > > > > +++ b/qdev-monitor.c
> > > > > @@ -75,14 +75,21 @@ static bool qdev_class_has_alias(DeviceClass *dc)
> > > > > return (qdev_class_get_alias(dc) != NULL);
> > > > > }
> > > > >
> > > > > +typedef struct PrintDevInfoData {
> > > > > + bool show_no_user;
> > > > > + DeviceCategory category;
> > > > > +} PrintDevInfoData ;
> > > > > +
> > > > > static void qdev_print_devinfo(ObjectClass *klass, void *opaque)
> > > > > {
> > > > > DeviceClass *dc;
> > > > > - bool *show_no_user = opaque;
> > > > > + PrintDevInfoData *data = opaque;
> > > >
> > > > So all callers of qdev_print_devinfo would have to be updated,
> > > > but you only updated one caller.
> > > > Lack of type checking here is nasty. It's required
> > > > by the object_class_foreach but you are not using that
> > > > anymore.
> > > >
> > > > So please refactor this function: e.g.
> > > > qdev_print_devinfo which gets void *,
> > > > and qdev_print_class_devinfo which gets show_no_user and category.
> > > > In fact, this way there won't be need for use of void *
> > > > at all.
> > > OK
> > > >
> > > >
> > > > > + DeviceCategory category;
> > > > >
> > > > > + category = data ? data->category : DEVICE_CATEGORY_MAX;
> > > > > dc = (DeviceClass *)object_class_dynamic_cast(klass, TYPE_DEVICE);
> > > > >
> > > > > - if (!dc || (show_no_user && !*show_no_user && dc->no_user)) {
> > > > > + if (!dc || (data && !data->show_no_user && dc->no_user)) {
> > > > > return;
> > > > > }
> > > > >
> > > > > @@ -93,6 +100,18 @@ static void qdev_print_devinfo(ObjectClass *klass, void *opaque)
> > > > > if (qdev_class_has_alias(dc)) {
> > > > > error_printf(", alias \"%s\"", qdev_class_get_alias(dc));
> > > > > }
> > > > > + if (dc->categories) {
> > > >
> > > > Is this sometimes unset? Some devices don't have a category?
> > > All devices shall have a category
> >
> > There's no point to the if statement above, apparently.
> > if (dc->categories) actually tests the array pointer.
> > Since that's defined statically using DECLARE_BITMAP, it's
> > never NULL.
> Right
> >
> >
> > > >
> > > > > + if (test_bit(category, dc->categories)) {
> > > > > + error_printf(", category \"%s\"", qdev_category_get_name(category));
> > > > > + } else {
> > > > > + 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));
> > > > > + }
> > > > > + }
> > > >
> > > > Confused. Why different output format?
> > > > Maybe add a comment with explanation.
> > > > Also, testing DEVICE_CATEGORY_MAX will cause out of bounds
> > > > access on bitmap - you want to special-case it
> > > > explicitly.
> > > >
> > > In RFC patches was possible to print a device that belonged
> > > to a specific category, or print out all its categories.
> > > In this series it can be done by passing DEVICE_CATEGORY_MAX
> >
> > Yes but when you are printing a specific device, why not
> > always print all categories?
> Because multifunction devices will appear more than once
> in a grep.
Right. That's fine, isn't it?
> Also it will not be easy to differentiate devices
> belonging to the same category without grep.
Hmm not sure what you mean.
I expect long term we'll add headers like
Network devices:
a
b
c
Storage devices
a
e
f
and it seems more helpful to tell user that a is
both a network and a storage device,
than just rely on user noticing that it appears twice.
> > And assuming you don't want to print all categories,
> > do if(category == DEVICE_CATEGORY_MAX), test_bit does not
> > check that it's not a legal value.
> This is exactly what I am going to do.
> >
> > > > Also, this overrides category parameter so if one tries to
> > > > use it below one gets DEVICE_CATEGORY_MAX.
> > > > Better use a different local variable for the loop.
> > > OK
> > > >
> > > > > + }
> > > > > + }
> > > > > if (dc->desc) {
> > > > > error_printf(", desc \"%s\"", dc->desc);
> > > > > }
> > > > > @@ -139,6 +158,23 @@ static const char *find_typename_by_alias(const char *alias)
> > > > > return NULL;
> > > > > }
> > > > >
> > > > > +static GSList *qdev_get_devices_by_category(DeviceCategory category)
> > > > > +{
> > > > > + DeviceClass *dc;
> > > > > + GSList *list, *curr, *ret_list = NULL;
> > > > > +
> > > > > + list = object_class_get_list(TYPE_DEVICE, false);
> > > > > + for (curr = list; curr; curr = g_slist_next(curr)) {
> > > > > + dc = (DeviceClass *)object_class_dynamic_cast(curr->data, TYPE_DEVICE);
> > > > > + if (test_bit(category, dc->categories)) {
> > > > > + ret_list = g_slist_append(ret_list, dc);
> > > >
> > > > So you build list here, then immediately scan it in
> > > > the same order and free it.
> > > > Wouldn't it be easier to just call qdev_print_devinfo here
> > > > directly?
> > > >
> > > >
> > > > > + }
> > > > > + }
> > > > > + g_slist_free(list);
> > > > > +
> > > > > + return ret_list;
> > > > > +}
> > > > > +
> > > > > int qdev_device_help(QemuOpts *opts)
> > > > > {
> > > > > const char *driver;
> > > > > @@ -147,8 +183,14 @@ 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) {
> > > > > + PrintDevInfoData data = { false, category };
> > > > > + GSList *list = qdev_get_devices_by_category(category);
> > > > > + g_slist_foreach(list, (GFunc)qdev_print_devinfo, &data);
> > > >
> > > > This cast should be avoided. If function signatures do not match,
> > > > you really don't want to work around it like this.
> > > > Refactor code please.
> > > OK
> > > >
> > > >
> > > > > + g_slist_free(list);
> > > > > + }
> > > > > +
> > > > > return 1;
> > > > > }
> > > > >
> > > > > --
> > > > > 1.8.3.1
> > >
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Qemu-devel] [PATCH v2 2/3] qemu-help: Sort devices by logical functionality
2013-07-29 9:22 ` Michael S. Tsirkin
@ 2013-07-29 9:26 ` Marcel Apfelbaum
0 siblings, 0 replies; 12+ messages in thread
From: Marcel Apfelbaum @ 2013-07-29 9:26 UTC (permalink / raw)
To: Michael S. Tsirkin; +Cc: pbonzini, aliguori, qemu-devel, afaerber
On Mon, 2013-07-29 at 12:22 +0300, Michael S. Tsirkin wrote:
> On Mon, Jul 29, 2013 at 12:09:45PM +0300, Marcel Apfelbaum wrote:
> > On Mon, 2013-07-29 at 11:20 +0300, Michael S. Tsirkin wrote:
> > > On Mon, Jul 29, 2013 at 11:14:11AM +0300, Marcel Apfelbaum wrote:
> > > > On Mon, 2013-07-29 at 11:04 +0300, Michael S. Tsirkin wrote:
> > > > > On Mon, Jul 29, 2013 at 10:07:34AM +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 v1:
> > > > > > Addressed Michael Tsirkin review:
> > > > > > Used bitmap operations on categories
> > > > > > Moved category names into the header file
> > > > > >
> > > > > > include/hw/qdev-core.h | 33 +++++++++++++++++++++++++++++++++
> > > > > > qdev-monitor.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++----
> > > > > > 2 files changed, 79 insertions(+), 4 deletions(-)
> > > > > >
> > > > > > diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
> > > > > > index e8b89b1..80b06ac 100644
> > > > > > --- a/include/hw/qdev-core.h
> > > > > > +++ b/include/hw/qdev-core.h
> > > > > > @@ -18,6 +18,38 @@ 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_ASSEMBLY,
> > > > > > + DEVICE_CATEGORY_MANAGEMENT,
> > > > > > + 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)
> > > > > > +{
> > > > > > + /* Category names corresponding to DeviceCategory values
> > > > > > + * The array elements must be in the same order as they
> > > > > > + * appear in DeviceCategory enum.
> > > > > > + */
> > > > >
> > > > > I would simply do:
> > > > > static const char *category_names[DEVICE_CATEGORY_MAX] = {
> > > > > [DEVICE_CATEGORY_ASSEMBLY] = "Assembly",
> > > > > [DEVICE_CATEGORY_MANAGEMENT] = "Management",
> > > > > [DEVICE_CATEGORY_STORAGE] = "Storage",
> > > > > [DEVICE_CATEGORY_NETWORK] = "Network",
> > > > > [DEVICE_CATEGORY_INPUT] = "Input",
> > > > > [DEVICE_CATEGORY_DISPLAY] = "Display",
> > > > > [DEVICE_CATEGORY_SOUND] = "Sound",
> > > > > [DEVICE_CATEGORY_MISC] = "Misc",
> > > > > };
> > > > >
> > > > > and drop the requirement to use same order.
> > > > OK
> > > > >
> > > > > > + static const char *category_names[] = {
> > > > > > + "Assembly",
> > > > > > + "Management",
> > > > > > + "Storage",
> > > > > > + "Network",
> > > > > > + "Input",
> > > > > > + "Display",
> > > > > > + "Sound",
> > > > > > + "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 +113,7 @@ typedef struct DeviceClass {
> > > > > > ObjectClass parent_class;
> > > > > > /*< public >*/
> > > > > >
> > > > > > + DECLARE_BITMAP(categories, 20);
> > > > >
> > > > > Why 20? Not DEVICE_CATEGORY_MAX ?
> > > > OK
> > > > >
> > > > >
> > > > > > const char *fw_name;
> > > > > > const char *desc;
> > > > > > Property *props;
> > > > > > diff --git a/qdev-monitor.c b/qdev-monitor.c
> > > > > > index e54dbc2..c3a3550 100644
> > > > > > --- a/qdev-monitor.c
> > > > > > +++ b/qdev-monitor.c
> > > > > > @@ -75,14 +75,21 @@ static bool qdev_class_has_alias(DeviceClass *dc)
> > > > > > return (qdev_class_get_alias(dc) != NULL);
> > > > > > }
> > > > > >
> > > > > > +typedef struct PrintDevInfoData {
> > > > > > + bool show_no_user;
> > > > > > + DeviceCategory category;
> > > > > > +} PrintDevInfoData ;
> > > > > > +
> > > > > > static void qdev_print_devinfo(ObjectClass *klass, void *opaque)
> > > > > > {
> > > > > > DeviceClass *dc;
> > > > > > - bool *show_no_user = opaque;
> > > > > > + PrintDevInfoData *data = opaque;
> > > > >
> > > > > So all callers of qdev_print_devinfo would have to be updated,
> > > > > but you only updated one caller.
> > > > > Lack of type checking here is nasty. It's required
> > > > > by the object_class_foreach but you are not using that
> > > > > anymore.
> > > > >
> > > > > So please refactor this function: e.g.
> > > > > qdev_print_devinfo which gets void *,
> > > > > and qdev_print_class_devinfo which gets show_no_user and category.
> > > > > In fact, this way there won't be need for use of void *
> > > > > at all.
> > > > OK
> > > > >
> > > > >
> > > > > > + DeviceCategory category;
> > > > > >
> > > > > > + category = data ? data->category : DEVICE_CATEGORY_MAX;
> > > > > > dc = (DeviceClass *)object_class_dynamic_cast(klass, TYPE_DEVICE);
> > > > > >
> > > > > > - if (!dc || (show_no_user && !*show_no_user && dc->no_user)) {
> > > > > > + if (!dc || (data && !data->show_no_user && dc->no_user)) {
> > > > > > return;
> > > > > > }
> > > > > >
> > > > > > @@ -93,6 +100,18 @@ static void qdev_print_devinfo(ObjectClass *klass, void *opaque)
> > > > > > if (qdev_class_has_alias(dc)) {
> > > > > > error_printf(", alias \"%s\"", qdev_class_get_alias(dc));
> > > > > > }
> > > > > > + if (dc->categories) {
> > > > >
> > > > > Is this sometimes unset? Some devices don't have a category?
> > > > All devices shall have a category
> > >
> > > There's no point to the if statement above, apparently.
> > > if (dc->categories) actually tests the array pointer.
> > > Since that's defined statically using DECLARE_BITMAP, it's
> > > never NULL.
> > Right
> > >
> > >
> > > > >
> > > > > > + if (test_bit(category, dc->categories)) {
> > > > > > + error_printf(", category \"%s\"", qdev_category_get_name(category));
> > > > > > + } else {
> > > > > > + 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));
> > > > > > + }
> > > > > > + }
> > > > >
> > > > > Confused. Why different output format?
> > > > > Maybe add a comment with explanation.
> > > > > Also, testing DEVICE_CATEGORY_MAX will cause out of bounds
> > > > > access on bitmap - you want to special-case it
> > > > > explicitly.
> > > > >
> > > > In RFC patches was possible to print a device that belonged
> > > > to a specific category, or print out all its categories.
> > > > In this series it can be done by passing DEVICE_CATEGORY_MAX
> > >
> > > Yes but when you are printing a specific device, why not
> > > always print all categories?
> > Because multifunction devices will appear more than once
> > in a grep.
>
> Right. That's fine, isn't it?
When there are headers I as suggested bellow - yes,
otherwise annoying
>
> > Also it will not be easy to differentiate devices
> > belonging to the same category without grep.
>
> Hmm not sure what you mean.
> I expect long term we'll add headers like
>
> Network devices:
> a
> b
> c
> Storage devices
> a
> e
> f
>
> and it seems more helpful to tell user that a is
> both a network and a storage device,
> than just rely on user noticing that it appears twice.
With the headers - sure
Before them it is not as helpful.
We don't have multifunction yet, but when we will have
such devices, the headers will be very handy
In the meantime we can go with printing all the categories
>
> > > And assuming you don't want to print all categories,
> > > do if(category == DEVICE_CATEGORY_MAX), test_bit does not
> > > check that it's not a legal value.
> > This is exactly what I am going to do.
> > >
> > > > > Also, this overrides category parameter so if one tries to
> > > > > use it below one gets DEVICE_CATEGORY_MAX.
> > > > > Better use a different local variable for the loop.
> > > > OK
> > > > >
> > > > > > + }
> > > > > > + }
> > > > > > if (dc->desc) {
> > > > > > error_printf(", desc \"%s\"", dc->desc);
> > > > > > }
> > > > > > @@ -139,6 +158,23 @@ static const char *find_typename_by_alias(const char *alias)
> > > > > > return NULL;
> > > > > > }
> > > > > >
> > > > > > +static GSList *qdev_get_devices_by_category(DeviceCategory category)
> > > > > > +{
> > > > > > + DeviceClass *dc;
> > > > > > + GSList *list, *curr, *ret_list = NULL;
> > > > > > +
> > > > > > + list = object_class_get_list(TYPE_DEVICE, false);
> > > > > > + for (curr = list; curr; curr = g_slist_next(curr)) {
> > > > > > + dc = (DeviceClass *)object_class_dynamic_cast(curr->data, TYPE_DEVICE);
> > > > > > + if (test_bit(category, dc->categories)) {
> > > > > > + ret_list = g_slist_append(ret_list, dc);
> > > > >
> > > > > So you build list here, then immediately scan it in
> > > > > the same order and free it.
> > > > > Wouldn't it be easier to just call qdev_print_devinfo here
> > > > > directly?
> > > > >
> > > > >
> > > > > > + }
> > > > > > + }
> > > > > > + g_slist_free(list);
> > > > > > +
> > > > > > + return ret_list;
> > > > > > +}
> > > > > > +
> > > > > > int qdev_device_help(QemuOpts *opts)
> > > > > > {
> > > > > > const char *driver;
> > > > > > @@ -147,8 +183,14 @@ 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) {
> > > > > > + PrintDevInfoData data = { false, category };
> > > > > > + GSList *list = qdev_get_devices_by_category(category);
> > > > > > + g_slist_foreach(list, (GFunc)qdev_print_devinfo, &data);
> > > > >
> > > > > This cast should be avoided. If function signatures do not match,
> > > > > you really don't want to work around it like this.
> > > > > Refactor code please.
> > > > OK
> > > > >
> > > > >
> > > > > > + g_slist_free(list);
> > > > > > + }
> > > > > > +
> > > > > > return 1;
> > > > > > }
> > > > > >
> > > > > > --
> > > > > > 1.8.3.1
> > > >
> >
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2013-07-29 9:27 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-07-29 7:07 [Qemu-devel] [PATCH v2 0/3] qemu-help: improve -device command line help Marcel Apfelbaum
2013-07-29 7:07 ` [Qemu-devel] [PATCH v2 1/3] hw: import bitmap operations in qdev-core header Marcel Apfelbaum
2013-07-29 7:42 ` Michael S. Tsirkin
2013-07-29 8:01 ` Marcel Apfelbaum
2013-07-29 7:07 ` [Qemu-devel] [PATCH v2 2/3] qemu-help: Sort devices by logical functionality Marcel Apfelbaum
2013-07-29 8:04 ` Michael S. Tsirkin
2013-07-29 8:14 ` Marcel Apfelbaum
2013-07-29 8:20 ` Michael S. Tsirkin
2013-07-29 9:09 ` Marcel Apfelbaum
2013-07-29 9:22 ` Michael S. Tsirkin
2013-07-29 9:26 ` Marcel Apfelbaum
2013-07-29 7:07 ` [Qemu-devel] [PATCH v2 3/3] devices: Associate devices to their logical category Marcel Apfelbaum
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).