]> Git Repo - qemu.git/blobdiff - qdev-monitor.c
block: Produce zeros when protocols reading beyond end of file
[qemu.git] / qdev-monitor.c
index 9a78ccff6d23376f76410177e0f05a2c7ca0063e..410cdcbe97bc7510a6a4fe75e63f95a89c1100cf 100644 (file)
@@ -18,6 +18,7 @@
  */
 
 #include "hw/qdev.h"
+#include "hw/sysbus.h"
 #include "monitor/monitor.h"
 #include "monitor/qdev.h"
 #include "qmp-commands.h"
@@ -74,24 +75,27 @@ static bool qdev_class_has_alias(DeviceClass *dc)
     return (qdev_class_get_alias(dc) != NULL);
 }
 
-static void qdev_print_devinfo(ObjectClass *klass, void *opaque)
+static void qdev_print_class_devinfo(DeviceClass *dc)
 {
-    DeviceClass *dc;
-    bool *show_no_user = opaque;
-
-    dc = (DeviceClass *)object_class_dynamic_cast(klass, TYPE_DEVICE);
+    DeviceCategory category;
 
-    if (!dc || (show_no_user && !*show_no_user && dc->no_user)) {
+    if (!dc) {
         return;
     }
 
-    error_printf("name \"%s\"", object_class_get_name(klass));
+    error_printf("name \"%s\"", object_class_get_name(OBJECT_CLASS(dc)));
     if (dc->bus_type) {
         error_printf(", bus %s", dc->bus_type);
     }
     if (qdev_class_has_alias(dc)) {
         error_printf(", alias \"%s\"", qdev_class_get_alias(dc));
     }
+    error_printf(", categories");
+    for (category = 0; category < DEVICE_CATEGORY_MAX; ++category) {
+        if (test_bit(category, dc->categories)) {
+            error_printf(" \"%s\"", qdev_category_get_name(category));
+        }
+    }
     if (dc->desc) {
         error_printf(", desc \"%s\"", dc->desc);
     }
@@ -101,16 +105,29 @@ static void qdev_print_devinfo(ObjectClass *klass, void *opaque)
     error_printf("\n");
 }
 
+static void qdev_print_devinfo(ObjectClass *klass, void *opaque)
+{
+    DeviceClass *dc;
+
+    dc = (DeviceClass *)object_class_dynamic_cast(klass, TYPE_DEVICE);
+
+    qdev_print_class_devinfo(dc);
+}
+
 static int set_property(const char *name, const char *value, void *opaque)
 {
     DeviceState *dev = opaque;
+    Error *err = NULL;
 
     if (strcmp(name, "driver") == 0)
         return 0;
     if (strcmp(name, "bus") == 0)
         return 0;
 
-    if (qdev_prop_parse(dev, name, value) == -1) {
+    qdev_prop_parse(dev, name, value, &err);
+    if (err != NULL) {
+        qerror_report_err(err);
+        error_free(err);
         return -1;
     }
     return 0;
@@ -134,6 +151,21 @@ static const char *find_typename_by_alias(const char *alias)
     return NULL;
 }
 
+static void qdev_print_category_devices(DeviceCategory category)
+{
+    DeviceClass *dc;
+    GSList *list, *curr;
+
+    list = object_class_get_list(TYPE_DEVICE, false);
+    for (curr = list; curr; curr = g_slist_next(curr)) {
+        dc = (DeviceClass *)object_class_dynamic_cast(curr->data, TYPE_DEVICE);
+        if (!dc->no_user && test_bit(category, dc->categories)) {
+            qdev_print_class_devinfo(dc);
+        }
+    }
+    g_slist_free(list);
+}
+
 int qdev_device_help(QemuOpts *opts)
 {
     const char *driver;
@@ -142,8 +174,11 @@ int qdev_device_help(QemuOpts *opts)
 
     driver = qemu_opt_get(opts, "driver");
     if (driver && is_help_option(driver)) {
-        bool show_no_user = false;
-        object_class_foreach(qdev_print_devinfo, TYPE_DEVICE, false, &show_no_user);
+        DeviceCategory category;
+        for (category = 0; category < DEVICE_CATEGORY_MAX; ++category) {
+            qdev_print_category_devices(category);
+        }
+
         return 1;
     }
 
@@ -291,11 +326,9 @@ static BusState *qbus_find_recursive(BusState *bus, const char *name,
 
     if (name && (strcmp(bus->name, name) != 0)) {
         match = 0;
-    }
-    if (bus_typename && !object_dynamic_cast(OBJECT(bus), bus_typename)) {
+    } else if (bus_typename && !object_dynamic_cast(OBJECT(bus), bus_typename)) {
         match = 0;
-    }
-    if ((bus_class->max_dev != 0) && (bus_class->max_dev <= bus->max_index)) {
+    } else if ((bus_class->max_dev != 0) && (bus_class->max_dev <= bus->max_index)) {
         if (name != NULL) {
             /* bus was explicitly specified: return an error. */
             qerror_report(ERROR_CLASS_GENERIC_ERROR, "Bus '%s' is full",
@@ -357,7 +390,7 @@ static BusState *qbus_find(const char *path)
 
         /* find device */
         if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
-            assert(0);
+            g_assert_not_reached();
             elem[0] = len = 0;
         }
         pos += len;
@@ -394,7 +427,7 @@ static BusState *qbus_find(const char *path)
 
         /* find bus */
         if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
-            assert(0);
+            g_assert_not_reached();
             elem[0] = len = 0;
         }
         pos += len;
@@ -415,7 +448,7 @@ DeviceState *qdev_device_add(QemuOpts *opts)
     DeviceClass *k;
     const char *driver, *path, *id;
     DeviceState *qdev;
-    BusState *bus;
+    BusState *bus = NULL;
 
     driver = qemu_opt_get(opts, "driver");
     if (!driver) {
@@ -453,7 +486,7 @@ DeviceState *qdev_device_add(QemuOpts *opts)
                           driver, object_get_typename(OBJECT(bus)));
             return NULL;
         }
-    } else {
+    } else if (k->bus_type != NULL) {
         bus = qbus_find_recursive(sysbus_get_default(), NULL, k->bus_type);
         if (!bus) {
             qerror_report(QERR_NO_BUS_FOR_DEVICE,
@@ -461,18 +494,17 @@ DeviceState *qdev_device_add(QemuOpts *opts)
             return NULL;
         }
     }
-    if (qdev_hotplug && !bus->allow_hotplug) {
+    if (qdev_hotplug && bus && !bus->allow_hotplug) {
         qerror_report(QERR_BUS_NO_HOTPLUG, bus->name);
         return NULL;
     }
 
-    if (!bus) {
-        bus = sysbus_get_default();
-    }
-
     /* create device, set properties */
     qdev = DEVICE(object_new(driver));
-    qdev_set_parent_bus(qdev, bus);
+
+    if (bus) {
+        qdev_set_parent_bus(qdev, bus);
+    }
 
     id = qemu_opts_id(opts);
     if (id) {
This page took 0.029023 seconds and 4 git commands to generate.