Signed-off-by: Anthony Liguori <aligu...@us.ibm.com>
---
 hw/qdev.c             |    4 ++--
 include/qemu/object.h |    1 +
 qom/object.c          |   18 ++++++++++++++++--
 3 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/hw/qdev.c b/hw/qdev.c
index 636b6b4..a7980c5 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -255,7 +255,7 @@ int qdev_device_help(QemuOpts *opts)
     driver = qemu_opt_get(opts, "driver");
     if (driver && !strcmp(driver, "?")) {
         bool show_no_user = false;
-        object_class_foreach(qdev_print_devinfo, &show_no_user);
+        object_class_foreach(qdev_print_devinfo, TYPE_DEVICE, false, 
&show_no_user);
         return 1;
     }
 
@@ -1077,7 +1077,7 @@ void do_info_qtree(Monitor *mon)
 
 void do_info_qdm(Monitor *mon)
 {
-    object_class_foreach(qdev_print_devinfo, NULL);
+    object_class_foreach(qdev_print_devinfo, TYPE_DEVICE, false, NULL);
 }
 
 int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
diff --git a/include/qemu/object.h b/include/qemu/object.h
index ba37850..adbcfb1 100644
--- a/include/qemu/object.h
+++ b/include/qemu/object.h
@@ -431,6 +431,7 @@ const char *object_class_get_name(ObjectClass *klass);
 ObjectClass *object_class_by_name(const char *typename);
 
 void object_class_foreach(void (*fn)(ObjectClass *klass, void *opaque),
+                          const char *implements_type, bool include_abstract,
                           void *opaque);
 
 #endif
diff --git a/qom/object.c b/qom/object.c
index a12895f..3dabb1a 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -467,6 +467,8 @@ ObjectClass *object_class_by_name(const char *typename)
 typedef struct OCFData
 {
     void (*fn)(ObjectClass *klass, void *opaque);
+    const char *implements_type;
+    bool include_abstract;
     void *opaque;
 } OCFData;
 
@@ -475,16 +477,28 @@ static void object_class_foreach_tramp(gpointer key, 
gpointer value,
 {
     OCFData *data = opaque;
     TypeImpl *type = value;
+    ObjectClass *k;
 
     type_class_init(type);
+    k = type->class;
 
-    data->fn(value, type->class);
+    if (!data->include_abstract && type->abstract) {
+        return;
+    }
+
+    if (data->implements_type && 
+        !object_class_dynamic_cast(k, data->implements_type)) {
+        return;
+    }
+
+    data->fn(k, data->opaque);
 }
 
 void object_class_foreach(void (*fn)(ObjectClass *klass, void *opaque),
+                          const char *implements_type, bool include_abstract,
                           void *opaque)
 {
-    OCFData data = { fn, opaque };
+    OCFData data = { fn, implements_type, include_abstract, opaque };
 
     g_hash_table_foreach(type_table_get(), object_class_foreach_tramp, &data);
 }
-- 
1.7.4.1


Reply via email to