summaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorAnthony Liguori <aliguori@us.ibm.com>2010-03-17 09:44:37 -0500
committerAnthony Liguori <aliguori@us.ibm.com>2010-03-17 09:44:37 -0500
commit4a39943bd1fd2ac7e3163f9d9b056394519661f3 (patch)
treeeab01e0258d2344117873952b589bac333bb0ea3 /hw
parent7d834c7450245335db0a7055ccdc783ccab21935 (diff)
parent8bc27249f0f62524887ea355a6604722edd276a9 (diff)
downloadqemu-4a39943bd1fd2ac7e3163f9d9b056394519661f3.tar.gz
Merge remote branch 'markus/qerror' into staging
Diffstat (limited to 'hw')
-rw-r--r--hw/pc.c35
-rw-r--r--hw/pci-hotplug.c14
-rw-r--r--hw/pci.c14
-rw-r--r--hw/qdev-properties.c36
-rw-r--r--hw/qdev.c236
-rw-r--r--hw/qdev.h2
-rw-r--r--hw/scsi-bus.c4
-rw-r--r--hw/scsi-disk.c7
-rw-r--r--hw/scsi-generic.c9
-rw-r--r--hw/usb-bus.c4
-rw-r--r--hw/usb-msd.c4
-rw-r--r--hw/usb-net.c2
-rw-r--r--hw/usb-serial.c9
-rw-r--r--hw/virtio-net.c5
-rw-r--r--hw/virtio-pci.c4
-rw-r--r--hw/virtio-serial-bus.c2
16 files changed, 208 insertions, 179 deletions
diff --git a/hw/pc.c b/hw/pc.c
index e50a48848d..2b3063df8d 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -230,40 +230,40 @@ static int boot_device2nibble(char boot_device)
return 0;
}
-/* copy/pasted from cmos_init, should be made a general function
- and used there as well */
-static int pc_boot_set(void *opaque, const char *boot_device)
+static int set_boot_dev(RTCState *s, const char *boot_device, int fd_bootchk)
{
- Monitor *mon = cur_mon;
#define PC_MAX_BOOT_DEVICES 3
- RTCState *s = (RTCState *)opaque;
int nbds, bds[3] = { 0, };
int i;
nbds = strlen(boot_device);
if (nbds > PC_MAX_BOOT_DEVICES) {
- monitor_printf(mon, "Too many boot devices for PC\n");
+ error_report("Too many boot devices for PC");
return(1);
}
for (i = 0; i < nbds; i++) {
bds[i] = boot_device2nibble(boot_device[i]);
if (bds[i] == 0) {
- monitor_printf(mon, "Invalid boot device for PC: '%c'\n",
- boot_device[i]);
+ error_report("Invalid boot device for PC: '%c'",
+ boot_device[i]);
return(1);
}
}
rtc_set_memory(s, 0x3d, (bds[1] << 4) | bds[0]);
- rtc_set_memory(s, 0x38, (bds[2] << 4));
+ rtc_set_memory(s, 0x38, (bds[2] << 4) | (fd_bootchk ? 0x0 : 0x1));
return(0);
}
+static int pc_boot_set(void *opaque, const char *boot_device)
+{
+ return set_boot_dev(opaque, boot_device, 0);
+}
+
/* hd_table must contain 4 block drivers */
static void cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size,
const char *boot_device, DriveInfo **hd_table)
{
RTCState *s = rtc_state;
- int nbds, bds[3] = { 0, };
int val;
int fd0, fd1, nb;
int i;
@@ -302,22 +302,9 @@ static void cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size,
rtc_set_memory(s, 0x5f, smp_cpus - 1);
/* set boot devices, and disable floppy signature check if requested */
-#define PC_MAX_BOOT_DEVICES 3
- nbds = strlen(boot_device);
- if (nbds > PC_MAX_BOOT_DEVICES) {
- fprintf(stderr, "Too many boot devices for PC\n");
+ if (set_boot_dev(s, boot_device, fd_bootchk)) {
exit(1);
}
- for (i = 0; i < nbds; i++) {
- bds[i] = boot_device2nibble(boot_device[i]);
- if (bds[i] == 0) {
- fprintf(stderr, "Invalid boot device for PC: '%c'\n",
- boot_device[i]);
- exit(1);
- }
- }
- rtc_set_memory(s, 0x3d, (bds[1] << 4) | bds[0]);
- rtc_set_memory(s, 0x38, (bds[2] << 4) | (fd_bootchk ? 0x0 : 0x1));
/* floppy type */
diff --git a/hw/pci-hotplug.c b/hw/pci-hotplug.c
index bd82c6aab7..eb3701bc89 100644
--- a/hw/pci-hotplug.c
+++ b/hw/pci-hotplug.c
@@ -54,7 +54,7 @@ static PCIDevice *qemu_pci_hot_add_nic(Monitor *mon,
return NULL;
}
- opts = qemu_opts_parse(&qemu_net_opts, opts_str ? opts_str : "", NULL);
+ opts = qemu_opts_parse(&qemu_net_opts, opts_str ? opts_str : "", 0);
if (!opts) {
monitor_printf(mon, "parsing network options '%s' failed\n",
opts_str ? opts_str : "");
@@ -73,14 +73,15 @@ static PCIDevice *qemu_pci_hot_add_nic(Monitor *mon,
return pci_nic_init(&nd_table[ret], "rtl8139", devaddr);
}
-static int scsi_hot_add(DeviceState *adapter, DriveInfo *dinfo, int printinfo)
+static int scsi_hot_add(Monitor *mon, DeviceState *adapter,
+ DriveInfo *dinfo, int printinfo)
{
SCSIBus *scsibus;
SCSIDevice *scsidev;
scsibus = DO_UPCAST(SCSIBus, qbus, QLIST_FIRST(&adapter->child_bus));
if (!scsibus || strcmp(scsibus->qbus.info->name, "SCSI") != 0) {
- qemu_error("Device is not a SCSI adapter\n");
+ error_report("Device is not a SCSI adapter");
return -1;
}
@@ -97,7 +98,8 @@ static int scsi_hot_add(DeviceState *adapter, DriveInfo *dinfo, int printinfo)
dinfo->unit = scsidev->id;
if (printinfo)
- qemu_error("OK bus %d, unit %d\n", scsibus->busnr, scsidev->id);
+ monitor_printf(mon, "OK bus %d, unit %d\n",
+ scsibus->busnr, scsidev->id);
return 0;
}
@@ -131,7 +133,7 @@ void drive_hot_add(Monitor *mon, const QDict *qdict)
monitor_printf(mon, "no pci device with address %s\n", pci_addr);
goto err;
}
- if (scsi_hot_add(&dev->qdev, dinfo, 1) != 0) {
+ if (scsi_hot_add(mon, &dev->qdev, dinfo, 1) != 0) {
goto err;
}
break;
@@ -203,7 +205,7 @@ static PCIDevice *qemu_pci_hot_add_storage(Monitor *mon,
if (qdev_init(&dev->qdev) < 0)
dev = NULL;
if (dev && dinfo) {
- if (scsi_hot_add(&dev->qdev, dinfo, 0) != 0) {
+ if (scsi_hot_add(mon, &dev->qdev, dinfo, 0) != 0) {
qdev_unplug(&dev->qdev);
dev = NULL;
}
diff --git a/hw/pci.c b/hw/pci.c
index eb2043e500..0dbca173e3 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -589,12 +589,12 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
if (!bus->devices[devfn])
goto found;
}
- qemu_error("PCI: no devfn available for %s, all in use\n", name);
+ error_report("PCI: no devfn available for %s, all in use", name);
return NULL;
found: ;
} else if (bus->devices[devfn]) {
- qemu_error("PCI: devfn %d not available for %s, in use by %s\n", devfn,
- name, bus->devices[devfn]->name);
+ error_report("PCI: devfn %d not available for %s, in use by %s",
+ devfn, name, bus->devices[devfn]->name);
return NULL;
}
pci_dev->bus = bus;
@@ -1476,8 +1476,8 @@ PCIDevice *pci_nic_init(NICInfo *nd, const char *default_model,
bus = pci_get_bus_devfn(&devfn, devaddr);
if (!bus) {
- qemu_error("Invalid PCI device address %s for device %s\n",
- devaddr, pci_nic_names[i]);
+ error_report("Invalid PCI device address %s for device %s",
+ devaddr, pci_nic_names[i]);
return NULL;
}
@@ -1768,8 +1768,8 @@ static int pci_add_option_rom(PCIDevice *pdev)
size = get_image_size(path);
if (size < 0) {
- qemu_error("%s: failed to find romfile \"%s\"\n", __FUNCTION__,
- pdev->romfile);
+ error_report("%s: failed to find romfile \"%s\"",
+ __FUNCTION__, pdev->romfile);
return -1;
}
if (size & (size - 1)) {
diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index 24671aff9f..92d6793747 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -402,17 +402,11 @@ PropertyInfo qdev_prop_vlan = {
/* --- pointer --- */
-static int print_ptr(DeviceState *dev, Property *prop, char *dest, size_t len)
-{
- void **ptr = qdev_get_prop_ptr(dev, prop);
- return snprintf(dest, len, "<%p>", *ptr);
-}
-
+/* Not a proper property, just for dirty hacks. TODO Remove it! */
PropertyInfo qdev_prop_ptr = {
.name = "ptr",
.type = PROP_TYPE_PTR,
.size = sizeof(void*),
- .print = print_ptr,
};
/* --- mac address --- */
@@ -547,31 +541,31 @@ int qdev_prop_parse(DeviceState *dev, const char *name, const char *value)
int ret;
prop = qdev_prop_find(dev, name);
- if (!prop) {
- fprintf(stderr, "property \"%s.%s\" not found\n",
- dev->info->name, name);
- return -1;
- }
- if (!prop->info->parse) {
- fprintf(stderr, "property \"%s.%s\" has no parser\n",
- dev->info->name, name);
+ /*
+ * TODO Properties without a parse method are just for dirty
+ * hacks. qdev_prop_ptr is the only such PropertyInfo. It's
+ * marked for removal. The test !prop->info->parse should be
+ * removed along with it.
+ */
+ if (!prop || !prop->info->parse) {
+ qerror_report(QERR_PROPERTY_NOT_FOUND, dev->info->name, name);
return -1;
}
ret = prop->info->parse(dev, prop, value);
if (ret < 0) {
switch (ret) {
case -EEXIST:
- fprintf(stderr, "property \"%s.%s\": \"%s\" is already in use\n",
- dev->info->name, name, value);
+ qerror_report(QERR_PROPERTY_VALUE_IN_USE,
+ dev->info->name, name, value);
break;
default:
case -EINVAL:
- fprintf(stderr, "property \"%s.%s\": failed to parse \"%s\"\n",
- dev->info->name, name, value);
+ qerror_report(QERR_PROPERTY_VALUE_BAD,
+ dev->info->name, name, value);
break;
case -ENOENT:
- fprintf(stderr, "property \"%s.%s\": could not find \"%s\"\n",
- dev->info->name, name, value);
+ qerror_report(QERR_PROPERTY_VALUE_NOT_FOUND,
+ dev->info->name, name, value);
break;
}
return -1;
diff --git a/hw/qdev.c b/hw/qdev.c
index b634890068..17a46a7bb3 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -29,7 +29,6 @@
#include "qdev.h"
#include "sysemu.h"
#include "monitor.h"
-#include "qerror.h"
static int qdev_hotplug = 0;
@@ -78,13 +77,32 @@ static DeviceInfo *qdev_find_info(BusInfo *bus_info, const char *name)
return NULL;
}
+static DeviceState *qdev_create_from_info(BusState *bus, DeviceInfo *info)
+{
+ DeviceState *dev;
+
+ assert(bus->info == info->bus_info);
+ dev = qemu_mallocz(info->size);
+ dev->info = info;
+ dev->parent_bus = bus;
+ qdev_prop_set_defaults(dev, dev->info->props);
+ qdev_prop_set_defaults(dev, dev->parent_bus->info->props);
+ qdev_prop_set_globals(dev);
+ QLIST_INSERT_HEAD(&bus->children, dev, sibling);
+ if (qdev_hotplug) {
+ assert(bus->allow_hotplug);
+ dev->hotplugged = 1;
+ }
+ dev->state = DEV_STATE_CREATED;
+ return dev;
+}
+
/* Create a new device. This only initializes the device state structure
and allows properties to be set. qdev_init should be called to
initialize the actual device emulation. */
DeviceState *qdev_create(BusState *bus, const char *name)
{
DeviceInfo *info;
- DeviceState *dev;
if (!bus) {
if (!main_system_bus) {
@@ -98,42 +116,23 @@ DeviceState *qdev_create(BusState *bus, const char *name)
hw_error("Unknown device '%s' for bus '%s'\n", name, bus->info->name);
}
- dev = qemu_mallocz(info->size);
- dev->info = info;
- dev->parent_bus = bus;
- qdev_prop_set_defaults(dev, dev->info->props);
- qdev_prop_set_defaults(dev, dev->parent_bus->info->props);
- qdev_prop_set_globals(dev);
- QLIST_INSERT_HEAD(&bus->children, dev, sibling);
- if (qdev_hotplug) {
- assert(bus->allow_hotplug);
- dev->hotplugged = 1;
- }
- dev->state = DEV_STATE_CREATED;
- return dev;
+ return qdev_create_from_info(bus, info);
}
-static int qdev_print_devinfo(DeviceInfo *info, char *dest, int len)
+static void qdev_print_devinfo(DeviceInfo *info)
{
- int pos = 0;
- int ret;
-
- ret = snprintf(dest+pos, len-pos, "name \"%s\", bus %s",
- info->name, info->bus_info->name);
- pos += MIN(len-pos,ret);
+ error_printf("name \"%s\", bus %s",
+ info->name, info->bus_info->name);
if (info->alias) {
- ret = snprintf(dest+pos, len-pos, ", alias \"%s\"", info->alias);
- pos += MIN(len-pos,ret);
+ error_printf(", alias \"%s\"", info->alias);
}
if (info->desc) {
- ret = snprintf(dest+pos, len-pos, ", desc \"%s\"", info->desc);
- pos += MIN(len-pos,ret);
+ error_printf(", desc \"%s\"", info->desc);
}
if (info->no_user) {
- ret = snprintf(dest+pos, len-pos, ", no-user");
- pos += MIN(len-pos,ret);
+ error_printf(", no-user");
}
- return pos;
+ error_printf("\n");
}
static int set_property(const char *name, const char *value, void *opaque)
@@ -146,8 +145,6 @@ static int set_property(const char *name, const char *value, void *opaque)
return 0;
if (qdev_prop_parse(dev, name, value) == -1) {
- qemu_error("can't set property \"%s\" to \"%s\" for \"%s\"\n",
- name, value, dev->info->name);
return -1;
}
return 0;
@@ -157,14 +154,15 @@ int qdev_device_help(QemuOpts *opts)
{
const char *driver;
DeviceInfo *info;
- char msg[256];
Property *prop;
driver = qemu_opt_get(opts, "driver");
if (driver && !strcmp(driver, "?")) {
for (info = device_info_list; info != NULL; info = info->next) {
- qdev_print_devinfo(info, msg, sizeof(msg));
- qemu_error("%s\n", msg);
+ if (info->no_user) {
+ continue; /* not available, don't show */
+ }
+ qdev_print_devinfo(info);
}
return 1;
}
@@ -179,7 +177,16 @@ int qdev_device_help(QemuOpts *opts)
}
for (prop = info->props; prop && prop->name; prop++) {
- qemu_error("%s.%s=%s\n", info->name, prop->name, prop->info->name);
+ /*
+ * TODO Properties without a parser are just for dirty hacks.
+ * qdev_prop_ptr is the only such PropertyInfo. It's marked
+ * for removal. This conditional should be removed along with
+ * it.
+ */
+ if (!prop->info->parse) {
+ continue; /* no way to set it, don't show */
+ }
+ error_printf("%s.%s=%s\n", info->name, prop->name, prop->info->name);
}
return 1;
}
@@ -193,19 +200,15 @@ DeviceState *qdev_device_add(QemuOpts *opts)
driver = qemu_opt_get(opts, "driver");
if (!driver) {
- qemu_error("-device: no driver specified\n");
+ qerror_report(QERR_MISSING_PARAMETER, "driver");
return NULL;
}
/* find driver */
info = qdev_find_info(NULL, driver);
- if (!info) {
- qemu_error_new(QERR_DEVICE_NOT_FOUND, driver);
- return NULL;
- }
- if (info->no_user) {
- qemu_error("device \"%s\" can't be added via command line\n",
- info->name);
+ if (!info || info->no_user) {
+ qerror_report(QERR_INVALID_PARAMETER, "driver");
+ error_printf_unless_qmp("Try with argument '?' for a list.\n");
return NULL;
}
@@ -213,22 +216,29 @@ DeviceState *qdev_device_add(QemuOpts *opts)
path = qemu_opt_get(opts, "bus");
if (path != NULL) {
bus = qbus_find(path);
+ if (!bus) {
+ return NULL;
+ }
+ if (bus->info != info->bus_info) {
+ qerror_report(QERR_BAD_BUS_FOR_DEVICE,
+ driver, bus->info->name);
+ return NULL;
+ }
} else {
bus = qbus_find_recursive(main_system_bus, NULL, info->bus_info);
- }
- if (!bus) {
- qemu_error("Did not find %s bus for %s\n",
- path ? path : info->bus_info->name, info->name);
- return NULL;
+ if (!bus) {
+ qerror_report(QERR_NO_BUS_FOR_DEVICE,
+ info->name, info->bus_info->name);
+ return NULL;
+ }
}
if (qdev_hotplug && !bus->allow_hotplug) {
- qemu_error("Bus %s does not support hotplugging\n",
- bus->name);
+ qerror_report(QERR_BUS_NO_HOTPLUG, bus->name);
return NULL;
}
/* create device, set properties */
- qdev = qdev_create(bus, driver);
+ qdev = qdev_create_from_info(bus, info);
id = qemu_opts_id(opts);
if (id) {
qdev->id = id;
@@ -238,7 +248,7 @@ DeviceState *qdev_device_add(QemuOpts *opts)
return NULL;
}
if (qdev_init(qdev) < 0) {
- qemu_error("Error initializing device %s\n", driver);
+ qerror_report(QERR_DEVICE_INIT_FAILED, driver);
return NULL;
}
qdev->opts = opts;
@@ -277,8 +287,8 @@ int qdev_init(DeviceState *dev)
int qdev_unplug(DeviceState *dev)
{
if (!dev->parent_bus->allow_hotplug) {
- qemu_error("Bus %s does not support hotplugging\n",
- dev->parent_bus->name);
+ error_report("Bus %s does not support hotplugging",
+ dev->parent_bus->name);
return -1;
}
assert(dev->info->unplug != NULL);
@@ -465,35 +475,33 @@ static DeviceState *qdev_find_recursive(BusState *bus, const char *id)
return NULL;
}
-static void qbus_list_bus(DeviceState *dev, char *dest, int len)
+static void qbus_list_bus(DeviceState *dev)
{
BusState *child;
const char *sep = " ";
- int pos = 0;
- pos += snprintf(dest+pos, len-pos,"child busses at \"%s\":",
- dev->id ? dev->id : dev->info->name);
+ error_printf("child busses at \"%s\":",
+ dev->id ? dev->id : dev->info->name);
QLIST_FOREACH(child, &dev->child_bus, sibling) {
- pos += snprintf(dest+pos, len-pos, "%s\"%s\"", sep, child->name);
+ error_printf("%s\"%s\"", sep, child->name);
sep = ", ";
}
+ error_printf("\n");
}
-static void qbus_list_dev(BusState *bus, char *dest, int len)
+static void qbus_list_dev(BusState *bus)
{
DeviceState *dev;
const char *sep = " ";
- int pos = 0;
- pos += snprintf(dest+pos, len-pos, "devices at \"%s\":",
- bus->name);
+ error_printf("devices at \"%s\":", bus->name);
QLIST_FOREACH(dev, &bus->children, sibling) {
- pos += snprintf(dest+pos, len-pos, "%s\"%s\"",
- sep, dev->info->name);
+ error_printf("%s\"%s\"", sep, dev->info->name);
if (dev->id)
- pos += snprintf(dest+pos, len-pos, "/\"%s\"", dev->id);
+ error_printf("/\"%s\"", dev->id);
sep = ", ";
}
+ error_printf("\n");
}
static BusState *qbus_find_bus(DeviceState *dev, char *elem)
@@ -540,7 +548,7 @@ static BusState *qbus_find(const char *path)
{
DeviceState *dev;
BusState *bus;
- char elem[128], msg[256];
+ char elem[128];
int pos, len;
/* find start element */
@@ -549,62 +557,75 @@ static BusState *qbus_find(const char *path)
pos = 0;
} else {
if (sscanf(path, "%127[^/]%n", elem, &len) != 1) {
- qemu_error("path parse error (\"%s\")\n", path);
- return NULL;
+ assert(!path[0]);
+ elem[0] = len = 0;
}
bus = qbus_find_recursive(main_system_bus, elem, NULL);
if (!bus) {
- qemu_error("bus \"%s\" not found\n", elem);
+ qerror_report(QERR_BUS_NOT_FOUND, elem);
return NULL;
}
pos = len;
}
for (;;) {
+ assert(path[pos] == '/' || !path[pos]);
+ while (path[pos] == '/') {
+ pos++;
+ }
if (path[pos] == '\0') {
- /* we are done */
return bus;
}
/* find device */
- if (sscanf(path+pos, "/%127[^/]%n", elem, &len) != 1) {
- qemu_error("path parse error (\"%s\" pos %d)\n", path, pos);
- return NULL;
+ if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
+ assert(0);
+ elem[0] = len = 0;
}
pos += len;
dev = qbus_find_dev(bus, elem);
if (!dev) {
- qbus_list_dev(bus, msg, sizeof(msg));
- qemu_error("device \"%s\" not found\n%s\n", elem, msg);
+ qerror_report(QERR_DEVICE_NOT_FOUND, elem);
+ if (!monitor_cur_is_qmp()) {
+ qbus_list_dev(bus);
+ }
return NULL;
}
+
+ assert(path[pos] == '/' || !path[pos]);
+ while (path[pos] == '/') {
+ pos++;
+ }
if (path[pos] == '\0') {
/* last specified element is a device. If it has exactly
* one child bus accept it nevertheless */
switch (dev->num_child_bus) {
case 0:
- qemu_error("device has no child bus (%s)\n", path);
+ qerror_report(QERR_DEVICE_NO_BUS, elem);
return NULL;
case 1:
return QLIST_FIRST(&dev->child_bus);
default:
- qbus_list_bus(dev, msg, sizeof(msg));
- qemu_error("device has multiple child busses (%s)\n%s\n",
- path, msg);
+ qerror_report(QERR_DEVICE_MULTIPLE_BUSSES, elem);
+ if (!monitor_cur_is_qmp()) {
+ qbus_list_bus(dev);
+ }
return NULL;
}
}
/* find bus */
- if (sscanf(path+pos, "/%127[^/]%n", elem, &len) != 1) {
- qemu_error("path parse error (\"%s\" pos %d)\n", path, pos);
- return NULL;
+ if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
+ assert(0);
+ elem[0] = len = 0;
}
pos += len;
bus = qbus_find_bus(dev, elem);
if (!bus) {
- qbus_list_bus(dev, msg, sizeof(msg));
- qemu_error("child bus \"%s\" not found\n%s\n", elem, msg);
+ qerror_report(QERR_BUS_NOT_FOUND, elem);
+ if (!monitor_cur_is_qmp()) {
+ qbus_list_bus(dev);
+ }
return NULL;
}
}
@@ -684,6 +705,12 @@ static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
if (!props)
return;
while (props->name) {
+ /*
+ * TODO Properties without a print method are just for dirty
+ * hacks. qdev_prop_ptr is the only such PropertyInfo. It's
+ * marked for removal. The test props->info->print should be
+ * removed along with it.
+ */
if (props->info->print) {
props->info->print(dev, props, buf, sizeof(buf));
qdev_printf("%s-prop: %s = %s\n", prefix, props->name, buf);
@@ -735,25 +762,42 @@ void do_info_qtree(Monitor *mon)
void do_info_qdm(Monitor *mon)
{
DeviceInfo *info;
- char msg[256];
for (info = device_info_list; info != NULL; info = info->next) {
- qdev_print_devinfo(info, msg, sizeof(msg));
- monitor_printf(mon, "%s\n", msg);
+ qdev_print_devinfo(info);
}
}
-void do_device_add(Monitor *mon, const QDict *qdict)
+/**
+ * do_device_add(): Add a device
+ *
+ * Argument qdict contains
+ * - "driver": the name of the new device's driver
+ * - "bus": the device's parent bus (device tree path)
+ * - "id": the device's ID (must be unique)
+ * - device properties
+ *
+ * Example:
+ *
+ * { "driver": "usb-net", "id": "eth1", "netdev": "netdev1" }
+ */
+int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
{
QemuOpts *opts;
- opts = qemu_opts_parse(&qemu_device_opts,
- qdict_get_str(qdict, "config"), "driver");
- if (opts) {
- if (qdev_device_help(opts) || qdev_device_add(opts) == NULL) {
- qemu_opts_del(opts);
- }
+ opts = qemu_opts_from_qdict(&qemu_device_opts, qdict);
+ if (!opts) {
+ return -1;
+ }
+ if (!monitor_cur_is_qmp() && qdev_device_help(opts)) {
+ qemu_opts_del(opts);
+ return 0;
+ }
+ if (!qdev_device_add(opts)) {
+ qemu_opts_del(opts);
+ return -1;
}
+ return 0;
}
void do_device_del(Monitor *mon, const QDict *qdict)
@@ -763,7 +807,7 @@ void do_device_del(Monitor *mon, const QDict *qdict)
dev = qdev_find_recursive(main_system_bus, id);
if (NULL == dev) {
- qemu_error("Device '%s' not found\n", id);
+ error_report("Device '%s' not found", id);
return;
}
qdev_unplug(dev);
diff --git a/hw/qdev.h b/hw/qdev.h
index adfcf795c3..9475705b7b 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -175,7 +175,7 @@ void qbus_free(BusState *bus);
void do_info_qtree(Monitor *mon);
void do_info_qdm(Monitor *mon);
-void do_device_add(Monitor *mon, const QDict *qdict);
+int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data);
void do_device_del(Monitor *mon, const QDict *qdict);
/*** qdev-properties.c ***/
diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index a2f9cc1cc3..383240bc07 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -1,5 +1,5 @@
#include "hw.h"
-#include "sysemu.h"
+#include "qemu-error.h"
#include "scsi.h"
#include "scsi-defs.h"
#include "block.h"
@@ -41,7 +41,7 @@ static int scsi_qdev_init(DeviceState *qdev, DeviceInfo *base)
}
}
if (dev->id >= bus->ndev) {
- qemu_error("bad scsi device id: %d\n", dev->id);
+ error_report("bad scsi device id: %d", dev->id);
goto err;
}
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 8f7ffc143d..da56d2bc1c 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -19,8 +19,6 @@
* the host adapter emulator.
*/
-#include <qemu-common.h>
-#include <sysemu.h>
//#define DEBUG_SCSI
#ifdef DEBUG_SCSI
@@ -34,6 +32,7 @@ do { printf("scsi-disk: " fmt , ## __VA_ARGS__); } while (0)
do { fprintf(stderr, "scsi-disk: " fmt , ## __VA_ARGS__); } while (0)
#include "qemu-common.h"
+#include "qemu-error.h"
#include "block.h"
#include "scsi.h"
#include "scsi-defs.h"
@@ -1026,13 +1025,13 @@ static int scsi_disk_initfn(SCSIDevice *dev)
uint64_t nb_sectors;
if (!s->qdev.conf.dinfo || !s->qdev.conf.dinfo->bdrv) {
- qemu_error("scsi-disk: drive property not set\n");
+ error_report("scsi-disk: drive property not set");
return -1;
}
s->bs = s->qdev.conf.dinfo->bdrv;
if (bdrv_is_sg(s->bs)) {
- qemu_error("scsi-disk: unwanted /dev/sg*\n");
+ error_report("scsi-disk: unwanted /dev/sg*");
return -1;
}
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index de778efa3b..c9aa853cc4 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -12,6 +12,7 @@
*/
#include "qemu-common.h"
+#include "qemu-error.h"
#include "block.h"
#include "scsi.h"
@@ -463,27 +464,27 @@ static int scsi_generic_initfn(SCSIDevice *dev)
struct sg_scsi_id scsiid;
if (!s->qdev.conf.dinfo || !s->qdev.conf.dinfo->bdrv) {
- qemu_error("scsi-generic: drive property not set\n");
+ error_report("scsi-generic: drive property not set");
return -1;
}
s->bs = s->qdev.conf.dinfo->bdrv;
/* check we are really using a /dev/sg* file */
if (!bdrv_is_sg(s->bs)) {
- qemu_error("scsi-generic: not /dev/sg*\n");
+ error_report("scsi-generic: not /dev/sg*");
return -1;
}
/* check we are using a driver managing SG_IO (version 3 and after */
if (bdrv_ioctl(s->bs, SG_GET_VERSION_NUM, &sg_version) < 0 ||
sg_version < 30000) {
- qemu_error("scsi-generic: scsi generic interface too old\n");
+ error_report("scsi-generic: scsi generic interface too old");
return -1;
}
/* get LUN of the /dev/sg? */
if (bdrv_ioctl(s->bs, SG_GET_SCSI_ID, &scsiid)) {
- qemu_error("scsi-generic: SG_GET_SCSI_ID ioctl failed\n");
+ error_report("scsi-generic: SG_GET_SCSI_ID ioctl failed");
return -1;
}
diff --git a/hw/usb-bus.c b/hw/usb-bus.c
index 7c823147ab..e2d87f2d1f 100644
--- a/hw/usb-bus.c
+++ b/hw/usb-bus.c
@@ -291,14 +291,14 @@ USBDevice *usbdevice_create(const char *cmdline)
if (info == NULL) {
#if 0
/* no error because some drivers are not converted (yet) */
- qemu_error("usbdevice %s not found\n", driver);
+ error_report("usbdevice %s not found", driver);
#endif
return NULL;
}
if (!usb->usbdevice_init) {
if (params) {
- qemu_error("usbdevice %s accepts no params\n", driver);
+ error_report("usbdevice %s accepts no params", driver);
return NULL;
}
return usb_create_simple(bus, usb->qdev.name);
diff --git a/hw/usb-msd.c b/hw/usb-msd.c
index 1a11bc557e..e90a47e0e1 100644
--- a/hw/usb-msd.c
+++ b/hw/usb-msd.c
@@ -524,7 +524,7 @@ static int usb_msd_initfn(USBDevice *dev)
MSDState *s = DO_UPCAST(MSDState, dev, dev);
if (!s->conf.dinfo || !s->conf.dinfo->bdrv) {
- qemu_error("usb-msd: drive property not set\n");
+ error_report("usb-msd: drive property not set");
return -1;
}
@@ -535,7 +535,7 @@ static int usb_msd_initfn(USBDevice *dev)
usb_msd_handle_reset(dev);
if (bdrv_key_required(s->conf.dinfo->bdrv)) {
- if (s->dev.qdev.hotplugged) {
+ if (cur_mon) {
monitor_read_bdrv_key_start(cur_mon, s->conf.dinfo->bdrv,
usb_msd_password_cb, s);
s->dev.auto_attach = 0;
diff --git a/hw/usb-net.c b/hw/usb-net.c
index 6875f112fe..4c17435c84 100644
--- a/hw/usb-net.c
+++ b/hw/usb-net.c
@@ -1478,7 +1478,7 @@ static USBDevice *usb_net_init(const char *cmdline)
QemuOpts *opts;
int idx;
- opts = qemu_opts_parse(&qemu_net_opts, cmdline, NULL);
+ opts = qemu_opts_parse(&qemu_net_opts, cmdline, 0);
if (!opts) {
return NULL;
}
diff --git a/hw/usb-serial.c b/hw/usb-serial.c
index 1410b11b2b..69f0e44f11 100644
--- a/hw/usb-serial.c
+++ b/hw/usb-serial.c
@@ -9,6 +9,7 @@
*/
#include "qemu-common.h"
+#include "qemu-error.h"
#include "usb.h"
#include "qemu-char.h"
@@ -564,26 +565,26 @@ static USBDevice *usb_serial_init(const char *filename)
if (strstart(filename, "vendorid=", &p)) {
vendorid = strtol(p, &e, 16);
if (e == p || (*e && *e != ',' && *e != ':')) {
- qemu_error("bogus vendor ID %s\n", p);
+ error_report("bogus vendor ID %s", p);
return NULL;
}
filename = e;
} else if (strstart(filename, "productid=", &p)) {
productid = strtol(p, &e, 16);
if (e == p || (*e && *e != ',' && *e != ':')) {
- qemu_error("bogus product ID %s\n", p);
+ error_report("bogus product ID %s", p);
return NULL;
}
filename = e;
} else {
- qemu_error("unrecognized serial USB option %s\n", filename);
+ error_report("unrecognized serial USB option %s", filename);
return NULL;
}
while(*filename == ',')
filename++;
}
if (!*filename) {
- qemu_error("character device specification needed\n");
+ error_report("character device specification needed");
return NULL;
}
filename++;
diff --git a/hw/virtio-net.c b/hw/virtio-net.c
index 5c0093e879..be33c68bbc 100644
--- a/hw/virtio-net.c
+++ b/hw/virtio-net.c
@@ -15,6 +15,7 @@
#include "net.h"
#include "net/checksum.h"
#include "net/tap.h"
+#include "qemu-error.h"
#include "qemu-timer.h"
#include "virtio-net.h"
@@ -764,7 +765,7 @@ static int virtio_net_load(QEMUFile *f, void *opaque, int version_id)
if (version_id >= 7) {
if (qemu_get_be32(f) && !peer_has_vnet_hdr(n)) {
- qemu_error("virtio-net: saved image requires vnet_hdr=on\n");
+ error_report("virtio-net: saved image requires vnet_hdr=on");
return -1;
}
@@ -793,7 +794,7 @@ static int virtio_net_load(QEMUFile *f, void *opaque, int version_id)
if (version_id >= 11) {
if (qemu_get_byte(f) && !peer_has_ufo(n)) {
- qemu_error("virtio-net: saved image requires TUN_F_UFO support\n");
+ error_report("virtio-net: saved image requires TUN_F_UFO support");
return -1;
}
}
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index 799f664d8e..6eb19cdf8c 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -19,7 +19,7 @@
#include "virtio-blk.h"
#include "virtio-net.h"
#include "pci.h"
-#include "sysemu.h"
+#include "qemu-error.h"
#include "msix.h"
#include "net.h"
#include "block_int.h"
@@ -459,7 +459,7 @@ static int virtio_blk_init_pci(PCIDevice *pci_dev)
proxy->class_code = PCI_CLASS_STORAGE_SCSI;
if (!proxy->block.dinfo) {
- qemu_error("virtio-blk-pci: drive property not set\n");
+ error_report("virtio-blk-pci: drive property not set");
return -1;
}
vdev = virtio_blk_init(&pci_dev->qdev, &proxy->block);
diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index d0e021932c..17c1ec1d06 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -485,7 +485,7 @@ static int virtser_port_qdev_init(DeviceState *qdev, DeviceInfo *base)
plugging_port0 = port->is_console && !find_port_by_id(port->vser, 0);
if (port->vser->config.nr_ports == bus->max_nr_ports && !plugging_port0) {
- qemu_error("virtio-serial-bus: Maximum device limit reached\n");
+ error_report("virtio-serial-bus: Maximum device limit reached");
return -1;
}
dev->info = info;