mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-08 10:13:56 -06:00
Merge remote branch 'markus/qerror' into staging
This commit is contained in:
commit
4a39943bd1
45 changed files with 1009 additions and 535 deletions
35
hw/pc.c
35
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 */
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
14
hw/pci.c
14
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)) {
|
||||
|
|
|
@ -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;
|
||||
|
|
240
hw/qdev.c
240
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,26 +77,11 @@ static DeviceInfo *qdev_find_info(BusInfo *bus_info, const char *name)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* 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)
|
||||
static DeviceState *qdev_create_from_info(BusState *bus, DeviceInfo *info)
|
||||
{
|
||||
DeviceInfo *info;
|
||||
DeviceState *dev;
|
||||
|
||||
if (!bus) {
|
||||
if (!main_system_bus) {
|
||||
main_system_bus = qbus_create(&system_bus_info, NULL, "main-system-bus");
|
||||
}
|
||||
bus = main_system_bus;
|
||||
}
|
||||
|
||||
info = qdev_find_info(bus->info, name);
|
||||
if (!info) {
|
||||
hw_error("Unknown device '%s' for bus '%s'\n", name, bus->info->name);
|
||||
}
|
||||
|
||||
assert(bus->info == info->bus_info);
|
||||
dev = qemu_mallocz(info->size);
|
||||
dev->info = info;
|
||||
dev->parent_bus = bus;
|
||||
|
@ -113,27 +97,42 @@ DeviceState *qdev_create(BusState *bus, const char *name)
|
|||
return dev;
|
||||
}
|
||||
|
||||
static int qdev_print_devinfo(DeviceInfo *info, char *dest, int len)
|
||||
/* 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)
|
||||
{
|
||||
int pos = 0;
|
||||
int ret;
|
||||
DeviceInfo *info;
|
||||
|
||||
ret = snprintf(dest+pos, len-pos, "name \"%s\", bus %s",
|
||||
info->name, info->bus_info->name);
|
||||
pos += MIN(len-pos,ret);
|
||||
if (!bus) {
|
||||
if (!main_system_bus) {
|
||||
main_system_bus = qbus_create(&system_bus_info, NULL, "main-system-bus");
|
||||
}
|
||||
bus = main_system_bus;
|
||||
}
|
||||
|
||||
info = qdev_find_info(bus->info, name);
|
||||
if (!info) {
|
||||
hw_error("Unknown device '%s' for bus '%s'\n", name, bus->info->name);
|
||||
}
|
||||
|
||||
return qdev_create_from_info(bus, info);
|
||||
}
|
||||
|
||||
static void qdev_print_devinfo(DeviceInfo *info)
|
||||
{
|
||||
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);
|
||||
|
|
|
@ -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 ***/
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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++;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue