mirror of
https://github.com/xemu-project/xemu.git
synced 2025-02-17 18:48:36 +00:00
usb: Suppress bogus error when automatic usb-hub creation fails
USBDevice's realize method usb_qdev_realize() automatically creates a usb-hub when only one port is left. Creating devices in realize methods is questionable, but works. If usb-hub creation fails, an error is reported to stderr, but the failure is otherwise ignored. We then create the actual device using the last port, which may well succeed. Example: $ qemu -nodefaults -S -display none -machine usb=on -monitor stdio QEMU 2.2.50 monitor - type 'help' for more information (qemu) device_add usb-mouse [Repeat 36 times] (qemu) info usb Device 0.0, Port 1, Speed 12 Mb/s, Product QEMU USB Mouse Device 0.0, Port 2, Speed 12 Mb/s, Product QEMU USB Hub Device 0.0, Port 2.1, Speed 12 Mb/s, Product QEMU USB Mouse [More mice and hubs omitted...] Device 0.0, Port 2.8.8.8.8.7, Speed 12 Mb/s, Product QEMU USB Mouse (qemu) device_add usb-mouse usb hub chain too deep Failed to initialize USB device 'usb-hub' (qemu) info usb [...] Device 0.0, Port 2.8.8.8.8.7, Speed 12 Mb/s, Product QEMU USB Mouse Device 0.0, Port 2.8.8.8.8.8, Speed 12 Mb/s, Product QEMU USB Mouse Despite the "Failed" message, the command actually succeeded. In QMP, it's worse. When adding the 37th mouse via QMP, the command fails with {"error": {"class": "GenericError", "desc": "usb hub chain too deep"}} Additionally, "Failed to initialize USB device 'usb-hub'" is reported on stderr. Despite the command failure, the device was created. This is wrong. Fix by avoiding qdev_init() for usb-hub creation, so we can ignore errors cleanly. Signed-off-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
parent
06f22eb78f
commit
bd8b92d5c8
35
hw/usb/bus.c
35
hw/usb/bus.c
@ -315,15 +315,36 @@ USBDevice *usb_create(USBBus *bus, const char *name)
|
||||
return USB_DEVICE(dev);
|
||||
}
|
||||
|
||||
static USBDevice *usb_try_create_simple(USBBus *bus, const char *name,
|
||||
Error **errp)
|
||||
{
|
||||
Error *err = NULL;
|
||||
USBDevice *dev;
|
||||
|
||||
dev = USB_DEVICE(qdev_try_create(&bus->qbus, name));
|
||||
if (!dev) {
|
||||
error_setg(errp, "Failed to create USB device '%s'", name);
|
||||
return NULL;
|
||||
}
|
||||
object_property_set_bool(OBJECT(dev), true, "realized", &err);
|
||||
if (err) {
|
||||
error_setg(errp, "Failed to initialize USB device '%s': %s",
|
||||
name, error_get_pretty(err));
|
||||
error_free(err);
|
||||
object_unparent(OBJECT(dev));
|
||||
return NULL;
|
||||
}
|
||||
return dev;
|
||||
}
|
||||
|
||||
USBDevice *usb_create_simple(USBBus *bus, const char *name)
|
||||
{
|
||||
USBDevice *dev = usb_create(bus, name);
|
||||
int rc;
|
||||
Error *err = NULL;
|
||||
USBDevice *dev = usb_try_create_simple(bus, name, &err);
|
||||
|
||||
rc = qdev_init(&dev->qdev);
|
||||
if (rc < 0) {
|
||||
error_report("Failed to initialize USB device '%s'", name);
|
||||
return NULL;
|
||||
if (!dev) {
|
||||
error_report("%s", error_get_pretty(err));
|
||||
error_free(err);
|
||||
}
|
||||
return dev;
|
||||
}
|
||||
@ -419,7 +440,7 @@ void usb_claim_port(USBDevice *dev, Error **errp)
|
||||
} else {
|
||||
if (bus->nfree == 1 && strcmp(object_get_typename(OBJECT(dev)), "usb-hub") != 0) {
|
||||
/* Create a new hub and chain it on */
|
||||
usb_create_simple(bus, "usb-hub");
|
||||
usb_try_create_simple(bus, "usb-hub", NULL);
|
||||
}
|
||||
if (bus->nfree == 0) {
|
||||
error_setg(errp, "tried to attach usb device %s to a bus "
|
||||
|
Loading…
x
Reference in New Issue
Block a user