aboutsummaryrefslogtreecommitdiff
path: root/hw/usb/host-libusb.c
diff options
context:
space:
mode:
authorYuri Benditovich <yuri.benditovich@daynix.com>2020-01-08 11:10:43 +0200
committerGerd Hoffmann <kraxel@redhat.com>2020-01-13 09:17:31 +0100
commit7bacaf5fea5729d400201106359f6803b15621af (patch)
treeaec306ed8f89bebe33f6325a9bbfd3dc97b79f3f /hw/usb/host-libusb.c
parentdc65a5bdc9fa543690a775b50d4ffbeb22c56d6d (diff)
usb-host: remove 'remote wakeup' flag from configuration descriptor
If the redirected device has this capability, Windows guest may place the device into D2 and expect it to wake when the device becomes active, but this will never happen. For example, when internal Bluetooth adapter is redirected, keyboards and mice connected to it do not work. Current commit removes this capability (starting from machine 5.0) Set 'usb-host.suppress-remote-wake' property to 'off' to keep 'remote wake' as is or to 'on' to remove 'remote wake' on 4.2 or earlier. Signed-off-by: Yuri Benditovich <yuri.benditovich@daynix.com> Message-id: 20200108091044.18055-2-yuri.benditovich@daynix.com Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Diffstat (limited to 'hw/usb/host-libusb.c')
-rw-r--r--hw/usb/host-libusb.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c
index fcf48c0193..00e0e36369 100644
--- a/hw/usb/host-libusb.c
+++ b/hw/usb/host-libusb.c
@@ -88,6 +88,7 @@ struct USBHostDevice {
bool needs_autoscan;
bool allow_one_guest_reset;
bool allow_all_guest_resets;
+ bool suppress_remote_wake;
/* state */
QTAILQ_ENTRY(USBHostDevice) next;
@@ -386,6 +387,8 @@ static void LIBUSB_CALL usb_host_req_complete_ctrl(struct libusb_transfer *xfer)
r->p->status = status_map[xfer->status];
r->p->actual_length = xfer->actual_length;
if (r->in && xfer->actual_length) {
+ USBDevice *udev = USB_DEVICE(s);
+ struct libusb_config_descriptor *conf = (void *)r->cbuf;
memcpy(r->cbuf, r->buffer + 8, xfer->actual_length);
/* Fix up USB-3 ep0 maxpacket size to allow superspeed connected devices
@@ -394,6 +397,21 @@ static void LIBUSB_CALL usb_host_req_complete_ctrl(struct libusb_transfer *xfer)
r->cbuf[7] == 9) {
r->cbuf[7] = 64;
}
+ /*
+ *If this is GET_DESCRIPTOR request for configuration descriptor,
+ * remove 'remote wakeup' flag from it to prevent idle power down
+ * in Windows guest
+ */
+ if (s->suppress_remote_wake &&
+ udev->setup_buf[0] == USB_DIR_IN &&
+ udev->setup_buf[1] == USB_REQ_GET_DESCRIPTOR &&
+ udev->setup_buf[3] == USB_DT_CONFIG && udev->setup_buf[2] == 0 &&
+ xfer->actual_length >
+ offsetof(struct libusb_config_descriptor, bmAttributes) &&
+ (conf->bmAttributes & USB_CFG_ATT_WAKEUP)) {
+ trace_usb_host_remote_wakeup_removed(s->bus_num, s->addr);
+ conf->bmAttributes &= ~USB_CFG_ATT_WAKEUP;
+ }
}
trace_usb_host_req_complete(s->bus_num, s->addr, r->p,
r->p->status, r->p->actual_length);
@@ -1596,6 +1614,8 @@ static Property usb_host_dev_properties[] = {
LIBUSB_LOG_LEVEL_WARNING),
DEFINE_PROP_BIT("pipeline", USBHostDevice, options,
USB_HOST_OPT_PIPELINE, true),
+ DEFINE_PROP_BOOL("suppress-remote-wake", USBHostDevice,
+ suppress_remote_wake, true),
DEFINE_PROP_END_OF_LIST(),
};