mirror of
https://gitlab.com/qemu-project/qemu.git
synced 2024-12-02 18:42:58 +03:00
usb: bug fix collection, doc update.
-----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQIcBAABAgAGBQJbH6QBAAoJEEy22O7T6HE4ZwMP/RHEknxR+tGKYfUxtVP24+ta tKMVuewqnDuIjUQsYj/tMvtGEvPd827Cy1X+ocqNq1Gk9aJez+DWWoDlrSXlLyiG r4EBMmOasFdmp1D9iQEDUF0pbnbXQv7kqhnM7XbyO+rjNe1rX7HElmRXtcjBcY2I QCIpekUBVGzFO97pVzB66gwYpJvmQu2YS2783NaujeS9VEEUFy6RFCFhfNwxhA4W C264zFVk68oK1fL+71Y3Kq0WKmetBwfW2ozcBAnqLB5z0hGd9bHJocaLwqgaaQWC uaGUJS70Q7iWZ8NwOYvrpK/2ZetjPAeU6ERXeR7tK6yfkjV9UmpPXQ0aqu1OSgEr VjuMPEDK0tL8pgcuhhxkJOD6S/HNyCe8y7WLeHKpd21Mv+R2yB1zs2xsWrdMqreZ 2YXUpgvIaZJBycO8vzmzWwiSNInOGO/3Vu1kpUP4T/rdmFZ1q5f8tGgwMlq/JsU4 Ce/p0BCcCXvcG+2x5uouffIuTur4DUPn93BCUmjy/TuyggtXVNoQHEVGrMDjiyO/ 9RFVUgJl32mTbIqfVaWkweTch/yXm4XVrlbcTW3VhCCVWyA9O0m+MwyjIoNeXn8L yPLF+3ndYgMoTJBFZ20HWEGhZ2+I54fhn/iRW6Nq7qtZ2rOP//K2CqyEp/CuQWis vxb796sHEPPUeTCoCiVY =sxQ0 -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/kraxel/tags/usb-20180612-pull-request' into staging usb: bug fix collection, doc update. # gpg: Signature made Tue 12 Jun 2018 11:44:17 BST # gpg: using RSA key 4CB6D8EED3E87138 # gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>" # gpg: aka "Gerd Hoffmann <gerd@kraxel.org>" # gpg: aka "Gerd Hoffmann (private) <kraxel@gmail.com>" # Primary key fingerprint: A032 8CFF B93A 17A7 9901 FE7D 4CB6 D8EE D3E8 7138 * remotes/kraxel/tags/usb-20180612-pull-request: usb-mtp: Return error on suspicious TYPE_DATA packet from initiator usb-hcd-xhci-test: add a test for ccid hotplug usb-ccid: fix bus leak object: fix OBJ_PROP_LINK_UNREF_ON_RELEASE ambivalence bus: do not unref the added child bus on realize usb/dev-mtp: Fix use of uninitialized values usb: correctly handle Zero Length Packets usb: update docs Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
2ab09bf2f9
@ -1,16 +1,42 @@
|
||||
|
||||
USB 2.0 Quick Start
|
||||
===================
|
||||
USB Quick Start
|
||||
===============
|
||||
|
||||
The QEMU EHCI Adapter can be used with and without companion
|
||||
controllers. See below for the companion controller mode.
|
||||
XHCI controller support
|
||||
-----------------------
|
||||
|
||||
When not running in companion controller mode there are two completely
|
||||
separate USB busses: One USB 1.1 bus driven by the UHCI controller and
|
||||
one USB 2.0 bus driven by the EHCI controller. Devices must be
|
||||
attached to the correct controller manually.
|
||||
QEMU has XHCI host adapter support. The XHCI hardware design is much
|
||||
more virtualization-friendly when compared to EHCI and UHCI, thus XHCI
|
||||
emulation uses less resources (especially cpu). So if your guest
|
||||
supports XHCI (which should be the case for any operating system
|
||||
released around 2010 or later) we recommend using it:
|
||||
|
||||
The '-usb' switch will make qemu create the UHCI controller as part of
|
||||
qemu -device qemu-xhci
|
||||
|
||||
XHCI supports USB 1.1, USB 2.0 and USB 3.0 devices, so this is the
|
||||
only controller you need. With only a single USB controller (and
|
||||
therefore only a single USB bus) present in the system there is no
|
||||
need to use the bus= parameter when adding USB devices.
|
||||
|
||||
|
||||
EHCI controller support
|
||||
-----------------------
|
||||
|
||||
The QEMU EHCI Adapter supports USB 2.0 devices. It can be used either
|
||||
standalone or with companion controllers (UHCI, OHCI) for USB 1.1
|
||||
devices. The companion controller setup is more convenient to use
|
||||
because it provides a single USB bus supporting both USB 2.0 and USB
|
||||
1.1 devices. See next section for details.
|
||||
|
||||
When running EHCI in standalone mode you can add UHCI or OHCI
|
||||
controllers for USB 1.1 devices too. Each controller creates its own
|
||||
bus though, so there are two completely separate USB buses: One USB
|
||||
1.1 bus driven by the UHCI controller and one USB 2.0 bus driven by
|
||||
the EHCI controller. Devices must be attached to the correct
|
||||
controller manually.
|
||||
|
||||
The easiest way to add a UHCI controller to a 'pc' machine is the
|
||||
'-usb' switch. QEMU will create the UHCI controller as function of
|
||||
the PIIX3 chipset. The USB 1.1 bus will carry the name "usb-bus.0".
|
||||
|
||||
You can use the standard -device switch to add a EHCI controller to
|
||||
@ -19,9 +45,8 @@ the controller so the USB 2.0 bus gets a individual name, for example
|
||||
'-device usb-ehci,id=ehci". This will give you a USB 2.0 bus named
|
||||
"ehci.0".
|
||||
|
||||
I strongly recommend to also use -device to attach usb devices because
|
||||
you can specify the bus they should be attached to this way. Here is
|
||||
a complete example:
|
||||
When adding USB devices using the -device switch you can specify the
|
||||
bus they should be attached to. Here is a complete example:
|
||||
|
||||
qemu -M pc ${otheroptions} \
|
||||
-drive if=none,id=usbstick,file=/path/to/image \
|
||||
@ -30,58 +55,44 @@ a complete example:
|
||||
-device usb-tablet,bus=usb-bus.0 \
|
||||
-device usb-storage,bus=ehci.0,drive=usbstick
|
||||
|
||||
This attaches a usb tablet to the UHCI adapter and a usb mass storage
|
||||
This attaches a USB tablet to the UHCI adapter and a USB mass storage
|
||||
device to the EHCI adapter.
|
||||
|
||||
|
||||
Companion controller support
|
||||
----------------------------
|
||||
|
||||
Companion controller support has been added recently. The operational
|
||||
model described above with two completely separate busses still works
|
||||
fine. Additionally the UHCI and OHCI controllers got the ability to
|
||||
attach to a usb bus created by EHCI as companion controllers. This is
|
||||
done by specifying the masterbus and firstport properties. masterbus
|
||||
specifies the bus name the controller should attach to. firstport
|
||||
specifies the first port the controller should attach to, which is
|
||||
needed as usually one ehci controller with six ports has three uhci
|
||||
companion controllers with two ports each.
|
||||
The UHCI and OHCI controllers can attach to a USB bus created by EHCI
|
||||
as companion controllers. This is done by specifying the masterbus
|
||||
and firstport properties. masterbus specifies the bus name the
|
||||
controller should attach to. firstport specifies the first port the
|
||||
controller should attach to, which is needed as usually one EHCI
|
||||
controller with six ports has three UHCI companion controllers with
|
||||
two ports each.
|
||||
|
||||
There is a config file in docs which will do all this for you, just
|
||||
try ...
|
||||
There is a config file in docs which will do all this for
|
||||
you, just try ...
|
||||
|
||||
qemu -readconfig docs/config/ich9-ehci-uhci.cfg
|
||||
|
||||
... then use "bus=ehci.0" to assign your usb devices to that bus.
|
||||
... then use "bus=ehci.0" to assign your USB devices to that bus.
|
||||
|
||||
|
||||
xhci controller support
|
||||
-----------------------
|
||||
|
||||
There is also xhci host controller support available. It got a lot
|
||||
less testing than ehci and there are a bunch of known limitations, so
|
||||
ehci may work better for you. On the other hand the xhci hardware
|
||||
design is much more virtualization-friendly, thus xhci emulation uses
|
||||
less resources (especially cpu). If you want to give xhci a try
|
||||
use this to add the host controller ...
|
||||
|
||||
qemu -device nec-usb-xhci,id=xhci
|
||||
|
||||
... then use "bus=xhci.0" when assigning usb devices.
|
||||
Using the '-usb' switch for 'q35' machines will create a similar
|
||||
USB controller configuration.
|
||||
|
||||
|
||||
More USB tips & tricks
|
||||
======================
|
||||
|
||||
Recently the usb pass through driver (also known as usb-host) and the
|
||||
qemu usb subsystem gained a few capabilities which are available only
|
||||
Recently the USB pass through driver (also known as usb-host) and the
|
||||
QEMU USB subsystem gained a few capabilities which are available only
|
||||
via qdev properties, i,e. when using '-device'.
|
||||
|
||||
|
||||
physical port addressing
|
||||
------------------------
|
||||
|
||||
First you can (for all usb devices) specify the physical port where
|
||||
First you can (for all USB devices) specify the physical port where
|
||||
the device will show up in the guest. This can be done using the
|
||||
"port" property. UHCI has two root ports (1,2). EHCI has four root
|
||||
ports (1-4), the emulated (1.1) USB hub has eight ports.
|
||||
@ -94,7 +105,7 @@ Plugging a hub into UHCI port 2 works like this:
|
||||
|
||||
-device usb-hub,bus=usb-bus.0,port=2
|
||||
|
||||
Plugging a virtual usb stick into port 4 of the hub just plugged works
|
||||
Plugging a virtual USB stick into port 4 of the hub just plugged works
|
||||
this way:
|
||||
|
||||
-device usb-storage,bus=usb-bus.0,port=2.4,drive=...
|
||||
@ -143,7 +154,7 @@ practice only a few combinations are useful:
|
||||
|
||||
Note that USB 1.1 devices are handled by UHCI/OHCI and USB 2.0 by
|
||||
EHCI. That means a device plugged into the very same physical port
|
||||
may show up on different busses depending on the speed. The port I'm
|
||||
may show up on different buses depending on the speed. The port I'm
|
||||
using for testing is bus 1 + port 1 for 2.0 devices and bus 3 + port 1
|
||||
for 1.1 devices. Passing through any device plugged into that port
|
||||
and also assign them to the correct bus can be done this way:
|
||||
|
@ -102,7 +102,6 @@ static void qbus_realize(BusState *bus, DeviceState *parent, const char *name)
|
||||
QLIST_INSERT_HEAD(&bus->parent->child_bus, bus, sibling);
|
||||
bus->parent->num_child_bus++;
|
||||
object_property_add_child(OBJECT(bus->parent), bus->name, OBJECT(bus), NULL);
|
||||
object_unref(OBJECT(bus));
|
||||
} else if (bus != sysbus_get_default()) {
|
||||
/* TODO: once all bus devices are qdevified,
|
||||
only reset handler for main_system_bus should be registered here. */
|
||||
|
@ -1308,7 +1308,7 @@ static void create_link_property(Object *obj, Property *prop, Error **errp)
|
||||
object_property_add_link(obj, prop->name, prop->link_type,
|
||||
child,
|
||||
qdev_prop_allow_set_link_before_realize,
|
||||
OBJ_PROP_LINK_UNREF_ON_RELEASE,
|
||||
OBJ_PROP_LINK_STRONG,
|
||||
errp);
|
||||
}
|
||||
|
||||
|
@ -409,7 +409,7 @@ void qdev_init_gpio_out_named(DeviceState *dev, qemu_irq *pins,
|
||||
object_property_add_link(OBJECT(dev), propname, TYPE_IRQ,
|
||||
(Object **)&pins[i],
|
||||
object_property_allow_set_link,
|
||||
OBJ_PROP_LINK_UNREF_ON_RELEASE,
|
||||
OBJ_PROP_LINK_STRONG,
|
||||
&error_abort);
|
||||
g_free(propname);
|
||||
}
|
||||
|
@ -1223,7 +1223,7 @@ static void xlnx_dp_init(Object *obj)
|
||||
object_property_add_link(obj, "dpdma", TYPE_XLNX_DPDMA,
|
||||
(Object **) &s->dpdma,
|
||||
xlnx_dp_set_dpdma,
|
||||
OBJ_PROP_LINK_UNREF_ON_RELEASE,
|
||||
OBJ_PROP_LINK_STRONG,
|
||||
&error_abort);
|
||||
|
||||
/*
|
||||
|
@ -525,12 +525,12 @@ static void xilinx_axidma_realize(DeviceState *dev, Error **errp)
|
||||
object_property_add_link(OBJECT(ds), "dma", TYPE_XILINX_AXI_DMA,
|
||||
(Object **)&ds->dma,
|
||||
object_property_allow_set_link,
|
||||
OBJ_PROP_LINK_UNREF_ON_RELEASE,
|
||||
OBJ_PROP_LINK_STRONG,
|
||||
&local_err);
|
||||
object_property_add_link(OBJECT(cs), "dma", TYPE_XILINX_AXI_DMA,
|
||||
(Object **)&cs->dma,
|
||||
object_property_allow_set_link,
|
||||
OBJ_PROP_LINK_UNREF_ON_RELEASE,
|
||||
OBJ_PROP_LINK_STRONG,
|
||||
&local_err);
|
||||
if (local_err) {
|
||||
goto xilinx_axidma_realize_fail;
|
||||
|
@ -787,7 +787,7 @@ static void zdma_init(Object *obj)
|
||||
object_property_add_link(obj, "dma", TYPE_MEMORY_REGION,
|
||||
(Object **)&s->dma_mr,
|
||||
qdev_prop_allow_set_link_before_realize,
|
||||
OBJ_PROP_LINK_UNREF_ON_RELEASE,
|
||||
OBJ_PROP_LINK_STRONG,
|
||||
&error_abort);
|
||||
}
|
||||
|
||||
|
@ -483,7 +483,7 @@ void pc_cmos_init(PCMachineState *pcms,
|
||||
TYPE_ISA_DEVICE,
|
||||
(Object **)&pcms->rtc,
|
||||
object_property_allow_set_link,
|
||||
OBJ_PROP_LINK_UNREF_ON_RELEASE, &error_abort);
|
||||
OBJ_PROP_LINK_STRONG, &error_abort);
|
||||
object_property_set_link(OBJECT(pcms), OBJECT(s),
|
||||
"rtc_state", &error_abort);
|
||||
|
||||
|
@ -289,7 +289,7 @@ static void pc_init1(MachineState *machine,
|
||||
TYPE_HOTPLUG_HANDLER,
|
||||
(Object **)&pcms->acpi_dev,
|
||||
object_property_allow_set_link,
|
||||
OBJ_PROP_LINK_UNREF_ON_RELEASE, &error_abort);
|
||||
OBJ_PROP_LINK_STRONG, &error_abort);
|
||||
object_property_set_link(OBJECT(machine), OBJECT(piix4_pm),
|
||||
PC_MACHINE_ACPI_DEVICE_PROP, &error_abort);
|
||||
}
|
||||
|
@ -194,7 +194,7 @@ static void pc_q35_init(MachineState *machine)
|
||||
TYPE_HOTPLUG_HANDLER,
|
||||
(Object **)&pcms->acpi_dev,
|
||||
object_property_allow_set_link,
|
||||
OBJ_PROP_LINK_UNREF_ON_RELEASE, &error_abort);
|
||||
OBJ_PROP_LINK_STRONG, &error_abort);
|
||||
object_property_set_link(OBJECT(machine), OBJECT(lpc),
|
||||
PC_MACHINE_ACPI_DEVICE_PROP, &error_abort);
|
||||
|
||||
|
@ -104,7 +104,7 @@ void ipmi_bmc_find_and_link(Object *obj, Object **bmc)
|
||||
{
|
||||
object_property_add_link(obj, "bmc", TYPE_IPMI_BMC, bmc,
|
||||
isa_ipmi_bmc_check,
|
||||
OBJ_PROP_LINK_UNREF_ON_RELEASE,
|
||||
OBJ_PROP_LINK_STRONG,
|
||||
&error_abort);
|
||||
}
|
||||
|
||||
|
@ -951,12 +951,12 @@ static void xilinx_enet_realize(DeviceState *dev, Error **errp)
|
||||
object_property_add_link(OBJECT(ds), "enet", "xlnx.axi-ethernet",
|
||||
(Object **) &ds->enet,
|
||||
object_property_allow_set_link,
|
||||
OBJ_PROP_LINK_UNREF_ON_RELEASE,
|
||||
OBJ_PROP_LINK_STRONG,
|
||||
&local_err);
|
||||
object_property_add_link(OBJECT(cs), "enet", "xlnx.axi-ethernet",
|
||||
(Object **) &cs->enet,
|
||||
object_property_allow_set_link,
|
||||
OBJ_PROP_LINK_UNREF_ON_RELEASE,
|
||||
OBJ_PROP_LINK_STRONG,
|
||||
&local_err);
|
||||
if (local_err) {
|
||||
goto xilinx_enet_realize_fail;
|
||||
|
@ -1346,7 +1346,7 @@ static void xlnx_zynqmp_qspips_init(Object *obj)
|
||||
object_property_add_link(obj, "stream-connected-dma", TYPE_STREAM_SLAVE,
|
||||
(Object **)&rq->dma,
|
||||
object_property_allow_set_link,
|
||||
OBJ_PROP_LINK_UNREF_ON_RELEASE,
|
||||
OBJ_PROP_LINK_STRONG,
|
||||
NULL);
|
||||
}
|
||||
|
||||
|
@ -1017,12 +1017,16 @@ static MTPData *usb_mtp_get_object(MTPState *s, MTPControl *c,
|
||||
static MTPData *usb_mtp_get_partial_object(MTPState *s, MTPControl *c,
|
||||
MTPObject *o)
|
||||
{
|
||||
MTPData *d = usb_mtp_data_alloc(c);
|
||||
MTPData *d;
|
||||
off_t offset;
|
||||
|
||||
if (c->argc <= 2) {
|
||||
return NULL;
|
||||
}
|
||||
trace_usb_mtp_op_get_partial_object(s->dev.addr, o->handle, o->path,
|
||||
c->argv[1], c->argv[2]);
|
||||
|
||||
d = usb_mtp_data_alloc(c);
|
||||
d->fd = open(o->path, O_RDONLY);
|
||||
if (d->fd == -1) {
|
||||
usb_mtp_data_free(d);
|
||||
@ -1696,6 +1700,11 @@ static void usb_mtp_get_data(MTPState *s, mtp_container *container,
|
||||
uint64_t dlen;
|
||||
uint32_t data_len = p->iov.size;
|
||||
|
||||
if (!d) {
|
||||
usb_mtp_queue_result(s, RES_INVALID_OBJECTINFO, 0,
|
||||
0, 0, 0, 0);
|
||||
return;
|
||||
}
|
||||
if (d->first) {
|
||||
/* Total length of incoming data */
|
||||
d->length = cpu_to_le32(container->length) - sizeof(mtp_container);
|
||||
|
@ -1147,6 +1147,7 @@ static void ccid_unrealize(USBDevice *dev, Error **errp)
|
||||
USBCCIDState *s = USB_CCID_DEV(dev);
|
||||
|
||||
ccid_bulk_in_clear(s);
|
||||
object_unref(OBJECT(&s->bus));
|
||||
}
|
||||
|
||||
static void ccid_flush_pending_answers(USBCCIDState *s)
|
||||
|
@ -795,7 +795,7 @@ static void usbredir_handle_bulk_data(USBRedirDevice *dev, USBPacket *p,
|
||||
usbredirparser_peer_has_cap(dev->parser,
|
||||
usb_redir_cap_32bits_bulk_length));
|
||||
|
||||
if (ep & USB_DIR_IN) {
|
||||
if (ep & USB_DIR_IN || size == 0) {
|
||||
usbredirparser_send_bulk_packet(dev->parser, p->id,
|
||||
&bulk_packet, NULL, 0);
|
||||
} else {
|
||||
|
@ -1103,6 +1103,11 @@ char *object_property_get_str(Object *obj, const char *name,
|
||||
* @errp: returns an error if this function fails
|
||||
*
|
||||
* Writes an object's canonical path to a property.
|
||||
*
|
||||
* If the link property was created with
|
||||
* <code>OBJ_PROP_LINK_STRONG</code> bit, the old target object is
|
||||
* unreferenced, and a reference is added to the new target object.
|
||||
*
|
||||
*/
|
||||
void object_property_set_link(Object *obj, Object *value,
|
||||
const char *name, Error **errp);
|
||||
@ -1394,7 +1399,7 @@ void object_property_add_child(Object *obj, const char *name,
|
||||
|
||||
typedef enum {
|
||||
/* Unref the link pointer when the property is deleted */
|
||||
OBJ_PROP_LINK_UNREF_ON_RELEASE = 0x1,
|
||||
OBJ_PROP_LINK_STRONG = 0x1,
|
||||
} ObjectPropertyLinkFlags;
|
||||
|
||||
/**
|
||||
@ -1432,8 +1437,9 @@ void object_property_allow_set_link(const Object *, const char *,
|
||||
* link property. The reference count for <code>*@child</code> is
|
||||
* managed by the property from after the function returns till the
|
||||
* property is deleted with object_property_del(). If the
|
||||
* <code>@flags</code> <code>OBJ_PROP_LINK_UNREF_ON_RELEASE</code> bit is set,
|
||||
* the reference count is decremented when the property is deleted.
|
||||
* <code>@flags</code> <code>OBJ_PROP_LINK_STRONG</code> bit is set,
|
||||
* the reference count is decremented when the property is deleted or
|
||||
* modified.
|
||||
*/
|
||||
void object_property_add_link(Object *obj, const char *name,
|
||||
const char *type, Object **child,
|
||||
|
@ -77,7 +77,7 @@ static void can_host_instance_init(Object *obj)
|
||||
object_property_add_link(obj, "canbus", TYPE_CAN_BUS,
|
||||
(Object **)&ch->bus,
|
||||
object_property_allow_set_link,
|
||||
OBJ_PROP_LINK_UNREF_ON_RELEASE,
|
||||
OBJ_PROP_LINK_STRONG,
|
||||
&error_abort);
|
||||
}
|
||||
|
||||
|
@ -980,7 +980,7 @@ static void colo_compare_init(Object *obj)
|
||||
object_property_add_link(obj, "iothread", TYPE_IOTHREAD,
|
||||
(Object **)&s->iothread,
|
||||
object_property_allow_set_link,
|
||||
OBJ_PROP_LINK_UNREF_ON_RELEASE, NULL);
|
||||
OBJ_PROP_LINK_STRONG, NULL);
|
||||
|
||||
s->vnet_hdr = false;
|
||||
object_property_add_bool(obj, "vnet_hdr_support", compare_get_vnet_hdr,
|
||||
|
@ -1564,9 +1564,11 @@ static void object_set_link_property(Object *obj, Visitor *v,
|
||||
return;
|
||||
}
|
||||
|
||||
object_ref(new_target);
|
||||
*child = new_target;
|
||||
object_unref(old_target);
|
||||
if (prop->flags == OBJ_PROP_LINK_STRONG) {
|
||||
object_ref(new_target);
|
||||
object_unref(old_target);
|
||||
}
|
||||
}
|
||||
|
||||
static Object *object_resolve_link_property(Object *parent, void *opaque, const gchar *part)
|
||||
@ -1581,7 +1583,7 @@ static void object_release_link_property(Object *obj, const char *name,
|
||||
{
|
||||
LinkProperty *prop = opaque;
|
||||
|
||||
if ((prop->flags & OBJ_PROP_LINK_UNREF_ON_RELEASE) && *prop->child) {
|
||||
if ((prop->flags & OBJ_PROP_LINK_STRONG) && *prop->child) {
|
||||
object_unref(*prop->child);
|
||||
}
|
||||
g_free(prop);
|
||||
|
@ -690,7 +690,7 @@ static void arm_cpu_post_init(Object *obj)
|
||||
TYPE_MEMORY_REGION,
|
||||
(Object **)&cpu->secure_memory,
|
||||
qdev_prop_allow_set_link_before_realize,
|
||||
OBJ_PROP_LINK_UNREF_ON_RELEASE,
|
||||
OBJ_PROP_LINK_STRONG,
|
||||
&error_abort);
|
||||
#endif
|
||||
}
|
||||
@ -718,7 +718,7 @@ static void arm_cpu_post_init(Object *obj)
|
||||
if (arm_feature(&cpu->env, ARM_FEATURE_M_SECURITY)) {
|
||||
object_property_add_link(obj, "idau", TYPE_IDAU_INTERFACE, &cpu->idau,
|
||||
qdev_prop_allow_set_link_before_realize,
|
||||
OBJ_PROP_LINK_UNREF_ON_RELEASE,
|
||||
OBJ_PROP_LINK_STRONG,
|
||||
&error_abort);
|
||||
qdev_property_add_static(DEVICE(obj), &arm_cpu_initsvtor_property,
|
||||
&error_abort);
|
||||
|
@ -35,6 +35,15 @@ static void test_usb_uas_hotplug(void)
|
||||
qtest_qmp_device_del("uas");
|
||||
}
|
||||
|
||||
static void test_usb_ccid_hotplug(void)
|
||||
{
|
||||
qtest_qmp_device_add("usb-ccid", "ccid", NULL);
|
||||
qtest_qmp_device_del("ccid");
|
||||
/* check the device can be added again */
|
||||
qtest_qmp_device_add("usb-ccid", "ccid", NULL);
|
||||
qtest_qmp_device_del("ccid");
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ret;
|
||||
@ -44,6 +53,7 @@ int main(int argc, char **argv)
|
||||
qtest_add_func("/xhci/pci/init", test_xhci_init);
|
||||
qtest_add_func("/xhci/pci/hotplug", test_xhci_hotplug);
|
||||
qtest_add_func("/xhci/pci/hotplug/usb-uas", test_usb_uas_hotplug);
|
||||
qtest_add_func("/xhci/pci/hotplug/usb-ccid", test_usb_ccid_hotplug);
|
||||
|
||||
qtest_start("-device nec-usb-xhci,id=xhci"
|
||||
" -drive id=drive0,if=none,file=null-co://,format=raw");
|
||||
|
@ -1287,7 +1287,7 @@ static QemuConsole *new_console(DisplayState *ds, console_type_t console_type,
|
||||
object_property_add_link(obj, "device", TYPE_DEVICE,
|
||||
(Object **)&s->device,
|
||||
object_property_allow_set_link,
|
||||
OBJ_PROP_LINK_UNREF_ON_RELEASE,
|
||||
OBJ_PROP_LINK_STRONG,
|
||||
&error_abort);
|
||||
object_property_add_uint32_ptr(obj, "head",
|
||||
&s->head, &error_abort);
|
||||
|
Loading…
Reference in New Issue
Block a user