* [Qemu-devel] [PATCH 0/6] usb: remote wakeup improvements
@ 2013-11-20 14:35 Gerd Hoffmann
2013-11-20 14:35 ` [Qemu-devel] [PATCH v2] curses: fixup SIGWINCH handler mess Gerd Hoffmann
` (6 more replies)
0 siblings, 7 replies; 8+ messages in thread
From: Gerd Hoffmann @ 2013-11-20 14:35 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Hi,
USB patch series from the ReduceWakeupRate department.
Patch #1 implements remote wakeup support to the ehci emulation.
Patch #2 reverts a workaround for lacking ehci remote wakeup
support in the highspeed version of the usb tablet.
Patches #3 + #4 are small preparations for #5.
Patch #5 adds support for microsoft os descriptors.
Patch #6 puts them into use to set registry keys for
the usb tablet.
This series brings windows guests on par with what we have
in Linux for quite a while already: Remote wakeup is used
by default, without manual configuration.
Gerd Hoffmann (6):
ehci: implement port wakeup
Revert "usb-tablet: Don't claim wakeup capability for USB-2 version"
usb: add vendor request defines
usb: move usb_{hi,lo} helpers to header file.
usb: add support for microsoft os descriptors
usb-tablet: add microsoft os descriptor support
hw/usb/Makefile.objs | 2 +-
hw/usb/desc-msos.c | 234 +++++++++++++++++++++++++++++++++++++++++++++++++++
hw/usb/desc.c | 22 ++---
hw/usb/desc.h | 20 +++++
hw/usb/dev-hid.c | 10 ++-
hw/usb/hcd-ehci.c | 18 +++-
include/hw/usb.h | 18 +++-
trace-events | 4 +
8 files changed, 309 insertions(+), 19 deletions(-)
create mode 100644 hw/usb/desc-msos.c
--
1.8.3.1
^ permalink raw reply [flat|nested] 8+ messages in thread
* [Qemu-devel] [PATCH v2] curses: fixup SIGWINCH handler mess
2013-11-20 14:35 [Qemu-devel] [PATCH 0/6] usb: remote wakeup improvements Gerd Hoffmann
@ 2013-11-20 14:35 ` Gerd Hoffmann
2013-11-20 14:35 ` [Qemu-devel] [PATCH 1/6] ehci: implement port wakeup Gerd Hoffmann
` (5 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Gerd Hoffmann @ 2013-11-20 14:35 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann, Anthony Liguori
Don't run code in the signal handler, only set a flag.
Use sigaction(2) to avoid non-portable signal(2) semantics.
Make #ifdefs less messy.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
ui/curses.c | 44 ++++++++++++++++++++++++++++----------------
1 file changed, 28 insertions(+), 16 deletions(-)
diff --git a/ui/curses.c b/ui/curses.c
index 289a955..dbc3d5e 100644
--- a/ui/curses.c
+++ b/ui/curses.c
@@ -106,9 +106,9 @@ static void curses_resize(DisplayChangeListener *dcl,
curses_calc_pad();
}
-#ifndef _WIN32
-#if defined(SIGWINCH) && defined(KEY_RESIZE)
-static void curses_winch_handler(int signum)
+#if !defined(_WIN32) && defined(SIGWINCH) && defined(KEY_RESIZE)
+static volatile sig_atomic_t got_sigwinch;
+static void curses_winch_check(void)
{
struct winsize {
unsigned short ws_row;
@@ -117,18 +117,34 @@ static void curses_winch_handler(int signum)
unsigned short ws_ypixel; /* unused */
} ws;
- /* terminal size changed */
- if (ioctl(1, TIOCGWINSZ, &ws) == -1)
+ if (!got_sigwinch) {
+ return;
+ }
+ got_sigwinch = false;
+
+ if (ioctl(1, TIOCGWINSZ, &ws) == -1) {
return;
+ }
resize_term(ws.ws_row, ws.ws_col);
- curses_calc_pad();
invalidate = 1;
+}
- /* some systems require this */
- signal(SIGWINCH, curses_winch_handler);
+static void curses_winch_handler(int signum)
+{
+ got_sigwinch = true;
}
-#endif
+
+static void curses_winch_init(void)
+{
+ struct sigaction old, winch = {
+ .sa_handler = curses_winch_handler,
+ };
+ sigaction(SIGWINCH, &winch, &old);
+}
+#else
+static void curses_winch_check(void) {}
+static void curses_winch_init(void) {}
#endif
static void curses_cursor_position(DisplayChangeListener *dcl,
@@ -163,6 +179,8 @@ static void curses_refresh(DisplayChangeListener *dcl)
{
int chr, nextchr, keysym, keycode, keycode_alt;
+ curses_winch_check();
+
if (invalidate) {
clear();
refresh();
@@ -349,13 +367,7 @@ void curses_display_init(DisplayState *ds, int full_screen)
curses_keyboard_setup();
atexit(curses_atexit);
-#ifndef _WIN32
-#if defined(SIGWINCH) && defined(KEY_RESIZE)
- /* some curses implementations provide a handler, but we
- * want to be sure this is handled regardless of the library */
- signal(SIGWINCH, curses_winch_handler);
-#endif
-#endif
+ curses_winch_init();
dcl = (DisplayChangeListener *) g_malloc0(sizeof(DisplayChangeListener));
dcl->ops = &dcl_ops;
--
1.8.3.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Qemu-devel] [PATCH 1/6] ehci: implement port wakeup
2013-11-20 14:35 [Qemu-devel] [PATCH 0/6] usb: remote wakeup improvements Gerd Hoffmann
2013-11-20 14:35 ` [Qemu-devel] [PATCH v2] curses: fixup SIGWINCH handler mess Gerd Hoffmann
@ 2013-11-20 14:35 ` Gerd Hoffmann
2013-11-20 14:35 ` [Qemu-devel] [PATCH 2/6] Revert "usb-tablet: Don't claim wakeup capability for USB-2 version" Gerd Hoffmann
` (4 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Gerd Hoffmann @ 2013-11-20 14:35 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Update portsc register and raise irq in case a suspended
port is woken up, so remote wakeup works on our ehci ports.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/usb/hcd-ehci.c | 18 ++++++++++++++++--
trace-events | 3 +++
2 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index 22bdbf4..8765f8f 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -826,9 +826,9 @@ static void ehci_child_detach(USBPort *port, USBDevice *child)
static void ehci_wakeup(USBPort *port)
{
EHCIState *s = port->opaque;
- uint32_t portsc = s->portsc[port->index];
+ uint32_t *portsc = &s->portsc[port->index];
- if (portsc & PORTSC_POWNER) {
+ if (*portsc & PORTSC_POWNER) {
USBPort *companion = s->companion_ports[port->index];
if (companion->ops->wakeup) {
companion->ops->wakeup(companion);
@@ -836,6 +836,12 @@ static void ehci_wakeup(USBPort *port)
return;
}
+ if (*portsc & PORTSC_SUSPEND) {
+ trace_usb_ehci_port_wakeup(port->index);
+ *portsc |= PORTSC_FPRES;
+ ehci_raise_irq(s, USBSTS_PCD);
+ }
+
qemu_bh_schedule(s->async_bh);
}
@@ -1067,6 +1073,14 @@ static void ehci_port_write(void *ptr, hwaddr addr,
}
}
+ if ((val & PORTSC_SUSPEND) && !(*portsc & PORTSC_SUSPEND)) {
+ trace_usb_ehci_port_suspend(port);
+ }
+ if (!(val & PORTSC_FPRES) && (*portsc & PORTSC_FPRES)) {
+ trace_usb_ehci_port_resume(port);
+ val &= ~PORTSC_SUSPEND;
+ }
+
*portsc &= ~PORTSC_RO_MASK;
*portsc |= val;
trace_usb_ehci_portsc_change(addr + s->portscbase, addr >> 2, *portsc, old);
diff --git a/trace-events b/trace-events
index 8695e9e..7322ed8 100644
--- a/trace-events
+++ b/trace-events
@@ -309,6 +309,9 @@ usb_ehci_sitd(uint32_t addr, uint32_t nxt, uint32_t active) "ITD @ %08x: next %0
usb_ehci_port_attach(uint32_t port, const char *owner, const char *device) "attach port #%d, owner %s, device %s"
usb_ehci_port_detach(uint32_t port, const char *owner) "detach port #%d, owner %s"
usb_ehci_port_reset(uint32_t port, int enable) "reset port #%d - %d"
+usb_ehci_port_suspend(uint32_t port) "port #%d"
+usb_ehci_port_wakeup(uint32_t port) "port #%d"
+usb_ehci_port_resume(uint32_t port) "port #%d"
usb_ehci_queue_action(void *q, const char *action) "q %p: %s"
usb_ehci_packet_action(void *q, void *p, const char *action) "q %p p %p: %s"
usb_ehci_irq(uint32_t level, uint32_t frindex, uint32_t sts, uint32_t mask) "level %d, frindex 0x%04x, sts 0x%x, mask 0x%x"
--
1.8.3.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Qemu-devel] [PATCH 2/6] Revert "usb-tablet: Don't claim wakeup capability for USB-2 version"
2013-11-20 14:35 [Qemu-devel] [PATCH 0/6] usb: remote wakeup improvements Gerd Hoffmann
2013-11-20 14:35 ` [Qemu-devel] [PATCH v2] curses: fixup SIGWINCH handler mess Gerd Hoffmann
2013-11-20 14:35 ` [Qemu-devel] [PATCH 1/6] ehci: implement port wakeup Gerd Hoffmann
@ 2013-11-20 14:35 ` Gerd Hoffmann
2013-11-20 14:35 ` [Qemu-devel] [PATCH 3/6] usb: add vendor request defines Gerd Hoffmann
` (3 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Gerd Hoffmann @ 2013-11-20 14:35 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
This reverts commit aa1c9e971e80d25b92908dce3dec7c38b49480ea.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/usb/dev-hid.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/usb/dev-hid.c b/hw/usb/dev-hid.c
index 5956720..5e667f0 100644
--- a/hw/usb/dev-hid.c
+++ b/hw/usb/dev-hid.c
@@ -236,7 +236,7 @@ static const USBDescDevice desc_device_tablet2 = {
.bNumInterfaces = 1,
.bConfigurationValue = 1,
.iConfiguration = STR_CONFIG_TABLET,
- .bmAttributes = 0x80,
+ .bmAttributes = 0xa0,
.bMaxPower = 50,
.nif = 1,
.ifs = &desc_iface_tablet2,
--
1.8.3.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Qemu-devel] [PATCH 3/6] usb: add vendor request defines
2013-11-20 14:35 [Qemu-devel] [PATCH 0/6] usb: remote wakeup improvements Gerd Hoffmann
` (2 preceding siblings ...)
2013-11-20 14:35 ` [Qemu-devel] [PATCH 2/6] Revert "usb-tablet: Don't claim wakeup capability for USB-2 version" Gerd Hoffmann
@ 2013-11-20 14:35 ` Gerd Hoffmann
2013-11-20 14:35 ` [Qemu-devel] [PATCH 4/6] usb: move usb_{hi, lo} helpers to header file Gerd Hoffmann
` (2 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Gerd Hoffmann @ 2013-11-20 14:35 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Add defines for vendor specific usb control requests.
Group defines by Device / Interface / Endpoint while
being at it.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
include/hw/usb.h | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/include/hw/usb.h b/include/hw/usb.h
index 0a6ef4a..2a3ea0c 100644
--- a/include/hw/usb.h
+++ b/include/hw/usb.h
@@ -102,17 +102,26 @@
#define DeviceRequest ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE)<<8)
#define DeviceOutRequest ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_DEVICE)<<8)
-#define InterfaceRequest \
+#define VendorDeviceRequest ((USB_DIR_IN|USB_TYPE_VENDOR|USB_RECIP_DEVICE)<<8)
+#define VendorDeviceOutRequest \
+ ((USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_DEVICE)<<8)
+
+#define InterfaceRequest \
((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8)
#define InterfaceOutRequest \
((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8)
-#define EndpointRequest ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT)<<8)
-#define EndpointOutRequest \
- ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT)<<8)
#define ClassInterfaceRequest \
((USB_DIR_IN|USB_TYPE_CLASS|USB_RECIP_INTERFACE)<<8)
#define ClassInterfaceOutRequest \
((USB_DIR_OUT|USB_TYPE_CLASS|USB_RECIP_INTERFACE)<<8)
+#define VendorInterfaceRequest \
+ ((USB_DIR_IN|USB_TYPE_VENDOR|USB_RECIP_INTERFACE)<<8)
+#define VendorInterfaceOutRequest \
+ ((USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE)<<8)
+
+#define EndpointRequest ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT)<<8)
+#define EndpointOutRequest \
+ ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT)<<8)
#define USB_REQ_GET_STATUS 0x00
#define USB_REQ_CLEAR_FEATURE 0x01
--
1.8.3.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Qemu-devel] [PATCH 4/6] usb: move usb_{hi, lo} helpers to header file.
2013-11-20 14:35 [Qemu-devel] [PATCH 0/6] usb: remote wakeup improvements Gerd Hoffmann
` (3 preceding siblings ...)
2013-11-20 14:35 ` [Qemu-devel] [PATCH 3/6] usb: add vendor request defines Gerd Hoffmann
@ 2013-11-20 14:35 ` Gerd Hoffmann
2013-11-20 14:35 ` [Qemu-devel] [PATCH 5/6] usb: add support for microsoft os descriptors Gerd Hoffmann
2013-11-20 14:35 ` [Qemu-devel] [PATCH 6/6] usb-tablet: add microsoft os descriptor support Gerd Hoffmann
6 siblings, 0 replies; 8+ messages in thread
From: Gerd Hoffmann @ 2013-11-20 14:35 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/usb/desc.c | 10 ----------
hw/usb/desc.h | 11 +++++++++++
2 files changed, 11 insertions(+), 10 deletions(-)
diff --git a/hw/usb/desc.c b/hw/usb/desc.c
index 5dbe754..f18a043 100644
--- a/hw/usb/desc.c
+++ b/hw/usb/desc.c
@@ -6,16 +6,6 @@
/* ------------------------------------------------------------------ */
-static uint8_t usb_lo(uint16_t val)
-{
- return val & 0xff;
-}
-
-static uint8_t usb_hi(uint16_t val)
-{
- return (val >> 8) & 0xff;
-}
-
int usb_desc_device(const USBDescID *id, const USBDescDevice *dev,
uint8_t *dest, size_t len)
{
diff --git a/hw/usb/desc.h b/hw/usb/desc.h
index ddd3e74..81327b0 100644
--- a/hw/usb/desc.h
+++ b/hw/usb/desc.h
@@ -194,6 +194,17 @@ struct USBDesc {
#define USB_DESC_FLAG_SUPER (1 << 1)
+/* little helpers */
+static inline uint8_t usb_lo(uint16_t val)
+{
+ return val & 0xff;
+}
+
+static inline uint8_t usb_hi(uint16_t val)
+{
+ return (val >> 8) & 0xff;
+}
+
/* generate usb packages from structs */
int usb_desc_device(const USBDescID *id, const USBDescDevice *dev,
uint8_t *dest, size_t len);
--
1.8.3.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Qemu-devel] [PATCH 5/6] usb: add support for microsoft os descriptors
2013-11-20 14:35 [Qemu-devel] [PATCH 0/6] usb: remote wakeup improvements Gerd Hoffmann
` (4 preceding siblings ...)
2013-11-20 14:35 ` [Qemu-devel] [PATCH 4/6] usb: move usb_{hi, lo} helpers to header file Gerd Hoffmann
@ 2013-11-20 14:35 ` Gerd Hoffmann
2013-11-20 14:35 ` [Qemu-devel] [PATCH 6/6] usb-tablet: add microsoft os descriptor support Gerd Hoffmann
6 siblings, 0 replies; 8+ messages in thread
From: Gerd Hoffmann @ 2013-11-20 14:35 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
This patch adds support for special usb descriptors used by microsoft
windows. They allow more fine-grained control over driver binding and
adding entries to the registry for configuration.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/usb/Makefile.objs | 2 +-
hw/usb/desc-msos.c | 234 +++++++++++++++++++++++++++++++++++++++++++++++++++
hw/usb/desc.c | 12 +++
hw/usb/desc.h | 9 ++
include/hw/usb.h | 1 +
trace-events | 1 +
6 files changed, 258 insertions(+), 1 deletion(-)
create mode 100644 hw/usb/desc-msos.c
diff --git a/hw/usb/Makefile.objs b/hw/usb/Makefile.objs
index a3eac3e..97b4575 100644
--- a/hw/usb/Makefile.objs
+++ b/hw/usb/Makefile.objs
@@ -1,5 +1,5 @@
# usb subsystem core
-common-obj-y += core.o combined-packet.o bus.o desc.o
+common-obj-y += core.o combined-packet.o bus.o desc.o desc-msos.o
common-obj-y += libhw.o
# usb host adapters
diff --git a/hw/usb/desc-msos.c b/hw/usb/desc-msos.c
new file mode 100644
index 0000000..ed8d62c
--- /dev/null
+++ b/hw/usb/desc-msos.c
@@ -0,0 +1,234 @@
+#include "hw/usb.h"
+#include "hw/usb/desc.h"
+
+/*
+ * Microsoft OS Descriptors
+ *
+ * Windows tries to fetch some special descriptors with informations
+ * specifically for windows. Presence is indicated using a special
+ * string @ index 0xee. There are two kinds of descriptors:
+ *
+ * compatid descriptor
+ * Used to bind drivers, if usb class isn't specific enougth.
+ * Used for PTP/MTP for example (both share the same usb class).
+ *
+ * properties descriptor
+ * Does carry registry entries. They show up in
+ * HLM\SYSTEM\CurrentControlSet\Enum\USB\<devid>\<serial>\Device Parameters
+ *
+ * Note that Windows caches the stuff it got in the registry, so when
+ * playing with this you have to delete registry subtrees to make
+ * windows query the device again:
+ * HLM\SYSTEM\CurrentControlSet\Control\usbflags
+ * HLM\SYSTEM\CurrentControlSet\Enum\USB
+ * Windows will complain it can't delete entries on the second one.
+ * It has deleted everything it had permissions too, which is enouth
+ * as this includes "Device Parameters".
+ *
+ * http://msdn.microsoft.com/en-us/library/windows/hardware/ff537430.aspx
+ *
+ */
+
+/* ------------------------------------------------------------------ */
+
+typedef struct msos_compat_hdr {
+ uint32_t dwLength;
+ uint8_t bcdVersion_lo;
+ uint8_t bcdVersion_hi;
+ uint8_t wIndex_lo;
+ uint8_t wIndex_hi;
+ uint8_t bCount;
+ uint8_t reserved[7];
+} QEMU_PACKED msos_compat_hdr;
+
+typedef struct msos_compat_func {
+ uint8_t bFirstInterfaceNumber;
+ uint8_t reserved_1;
+ uint8_t compatibleId[8];
+ uint8_t subCompatibleId[8];
+ uint8_t reserved_2[6];
+} QEMU_PACKED msos_compat_func;
+
+static int usb_desc_msos_compat(const USBDesc *desc, uint8_t *dest)
+{
+ msos_compat_hdr *hdr = (void *)dest;
+ msos_compat_func *func;
+ int length = sizeof(*hdr);
+ int count = 0;
+
+ func = (void *)(dest + length);
+ func->bFirstInterfaceNumber = 0;
+ func->reserved_1 = 0x01;
+ length += sizeof(*func);
+ count++;
+
+ hdr->dwLength = cpu_to_le32(length);
+ hdr->bcdVersion_lo = 0x00;
+ hdr->bcdVersion_hi = 0x01;
+ hdr->wIndex_lo = 0x04;
+ hdr->wIndex_hi = 0x00;
+ hdr->bCount = count;
+ return length;
+}
+
+/* ------------------------------------------------------------------ */
+
+typedef struct msos_prop_hdr {
+ uint32_t dwLength;
+ uint8_t bcdVersion_lo;
+ uint8_t bcdVersion_hi;
+ uint8_t wIndex_lo;
+ uint8_t wIndex_hi;
+ uint8_t wCount_lo;
+ uint8_t wCount_hi;
+} QEMU_PACKED msos_prop_hdr;
+
+typedef struct msos_prop {
+ uint32_t dwLength;
+ uint32_t dwPropertyDataType;
+ uint8_t dwPropertyNameLength_lo;
+ uint8_t dwPropertyNameLength_hi;
+ uint8_t bPropertyName[];
+} QEMU_PACKED msos_prop;
+
+typedef struct msos_prop_data {
+ uint32_t dwPropertyDataLength;
+ uint8_t bPropertyData[];
+} QEMU_PACKED msos_prop_data;
+
+typedef enum msos_prop_type {
+ MSOS_REG_SZ = 1,
+ MSOS_REG_EXPAND_SZ = 2,
+ MSOS_REG_BINARY = 3,
+ MSOS_REG_DWORD_LE = 4,
+ MSOS_REG_DWORD_BE = 5,
+ MSOS_REG_LINK = 6,
+ MSOS_REG_MULTI_SZ = 7,
+} msos_prop_type;
+
+static int usb_desc_msos_prop_name(struct msos_prop *prop,
+ const wchar_t *name)
+{
+ int length = wcslen(name) + 1;
+ int i;
+
+ prop->dwPropertyNameLength_lo = usb_lo(length*2);
+ prop->dwPropertyNameLength_hi = usb_hi(length*2);
+ for (i = 0; i < length; i++) {
+ prop->bPropertyName[i*2] = usb_lo(name[i]);
+ prop->bPropertyName[i*2+1] = usb_hi(name[i]);
+ }
+ return length*2;
+}
+
+static int usb_desc_msos_prop_str(uint8_t *dest, msos_prop_type type,
+ const wchar_t *name, const wchar_t *value)
+{
+ struct msos_prop *prop = (void *)dest;
+ struct msos_prop_data *data;
+ int length = sizeof(*prop);
+ int i, vlen = wcslen(value) + 1;
+
+ prop->dwPropertyDataType = cpu_to_le32(type);
+ length += usb_desc_msos_prop_name(prop, name);
+ data = (void *)(dest + length);
+
+ data->dwPropertyDataLength = cpu_to_le32(vlen*2);
+ length += sizeof(*prop);
+
+ for (i = 0; i < vlen; i++) {
+ data->bPropertyData[i*2] = usb_lo(value[i]);
+ data->bPropertyData[i*2+1] = usb_hi(value[i]);
+ }
+ length += vlen*2;
+
+ prop->dwLength = cpu_to_le32(length);
+ return length;
+}
+
+static int usb_desc_msos_prop_dword(uint8_t *dest, const wchar_t *name,
+ uint32_t value)
+{
+ struct msos_prop *prop = (void *)dest;
+ struct msos_prop_data *data;
+ int length = sizeof(*prop);
+
+ prop->dwPropertyDataType = cpu_to_le32(MSOS_REG_DWORD_LE);
+ length += usb_desc_msos_prop_name(prop, name);
+ data = (void *)(dest + length);
+
+ data->dwPropertyDataLength = cpu_to_le32(4);
+ data->bPropertyData[0] = (value) & 0xff;
+ data->bPropertyData[1] = (value >> 8) & 0xff;
+ data->bPropertyData[2] = (value >> 16) & 0xff;
+ data->bPropertyData[3] = (value >> 24) & 0xff;
+ length += sizeof(*prop) + 4;
+
+ prop->dwLength = cpu_to_le32(length);
+ return length;
+}
+
+static int usb_desc_msos_prop(const USBDesc *desc, uint8_t *dest)
+{
+ msos_prop_hdr *hdr = (void *)dest;
+ int length = sizeof(*hdr);
+ int count = 0;
+
+ if (desc->msos->Label) {
+ /*
+ * Given as example in the specs. Havn't figured yet where
+ * this label shows up in the windows gui.
+ */
+ length += usb_desc_msos_prop_str(dest+length, MSOS_REG_SZ,
+ L"Label", desc->msos->Label);
+ count++;
+ }
+
+ if (desc->msos->SelectiveSuspendEnabled) {
+ /*
+ * Signaling remote wakeup capability in the standard usb
+ * descriptors isn't enouth to make windows actually use it.
+ * This is the "Yes, we really mean it" registy entry to flip
+ * the switch in the windows drivers.
+ */
+ length += usb_desc_msos_prop_dword(dest+length,
+ L"SelectiveSuspendEnabled", 1);
+ count++;
+ }
+
+ hdr->dwLength = cpu_to_le32(length);
+ hdr->bcdVersion_lo = 0x00;
+ hdr->bcdVersion_hi = 0x01;
+ hdr->wIndex_lo = 0x05;
+ hdr->wIndex_hi = 0x00;
+ hdr->wCount_lo = usb_lo(count);
+ hdr->wCount_hi = usb_hi(count);
+ return length;
+}
+
+/* ------------------------------------------------------------------ */
+
+int usb_desc_msos(const USBDesc *desc, USBPacket *p,
+ int index, uint8_t *dest, size_t len)
+{
+ void *buf = g_malloc0(4096);
+ int length = 0;
+
+ switch (index) {
+ case 0x0004:
+ length = usb_desc_msos_compat(desc, buf);
+ break;
+ case 0x0005:
+ length = usb_desc_msos_prop(desc, buf);
+ break;
+ }
+
+ if (length > len) {
+ length = len;
+ }
+ memcpy(dest, buf, length);
+ free(buf);
+
+ p->actual_length = length;
+ return 0;
+}
diff --git a/hw/usb/desc.c b/hw/usb/desc.c
index f18a043..1539d7c 100644
--- a/hw/usb/desc.c
+++ b/hw/usb/desc.c
@@ -499,6 +499,9 @@ void usb_desc_init(USBDevice *dev)
if (desc->super) {
dev->speedmask |= USB_SPEED_MASK_SUPER;
}
+ if (desc->msos) {
+ usb_desc_set_string(dev, 0xee, "MSFT100Q");
+ }
usb_desc_setdefaults(dev);
}
@@ -782,6 +785,15 @@ int usb_desc_handle_control(USBDevice *dev, USBPacket *p,
trace_usb_set_interface(dev->addr, index, value, ret);
break;
+ case VendorDeviceRequest | 'Q':
+ ret = usb_desc_msos(desc, p, index, data, length);
+ trace_usb_desc_msos(dev->addr, index, length, ret);
+ break;
+ case VendorInterfaceRequest | 'Q':
+ ret = usb_desc_msos(desc, p, index, data, length);
+ trace_usb_desc_msos(dev->addr, index, length, ret);
+ break;
+
}
return ret;
}
diff --git a/hw/usb/desc.h b/hw/usb/desc.h
index 81327b0..64dfc4a 100644
--- a/hw/usb/desc.h
+++ b/hw/usb/desc.h
@@ -2,6 +2,7 @@
#define QEMU_HW_USB_DESC_H
#include <inttypes.h>
+#include <wchar.h>
/* binary representation */
typedef struct USBDescriptor {
@@ -182,6 +183,11 @@ struct USBDescOther {
const uint8_t *data;
};
+struct USBDescMSOS {
+ const wchar_t *Label;
+ bool SelectiveSuspendEnabled;
+};
+
typedef const char *USBDescStrings[256];
struct USBDesc {
@@ -190,6 +196,7 @@ struct USBDesc {
const USBDescDevice *high;
const USBDescDevice *super;
const char* const *str;
+ const USBDescMSOS *msos;
};
#define USB_DESC_FLAG_SUPER (1 << 1)
@@ -219,6 +226,8 @@ int usb_desc_iface(const USBDescIface *iface, int flags,
int usb_desc_endpoint(const USBDescEndpoint *ep, int flags,
uint8_t *dest, size_t len);
int usb_desc_other(const USBDescOther *desc, uint8_t *dest, size_t len);
+int usb_desc_msos(const USBDesc *desc, USBPacket *p,
+ int index, uint8_t *dest, size_t len);
/* control message emulation helpers */
void usb_desc_init(USBDevice *dev);
diff --git a/include/hw/usb.h b/include/hw/usb.h
index 2a3ea0c..d6a3354 100644
--- a/include/hw/usb.h
+++ b/include/hw/usb.h
@@ -182,6 +182,7 @@ typedef struct USBDescIface USBDescIface;
typedef struct USBDescEndpoint USBDescEndpoint;
typedef struct USBDescOther USBDescOther;
typedef struct USBDescString USBDescString;
+typedef struct USBDescMSOS USBDescMSOS;
struct USBDescString {
uint8_t index;
diff --git a/trace-events b/trace-events
index 7322ed8..7070aab 100644
--- a/trace-events
+++ b/trace-events
@@ -400,6 +400,7 @@ usb_desc_config(int addr, int index, int len, int ret) "dev %d query config %d,
usb_desc_other_speed_config(int addr, int index, int len, int ret) "dev %d query config %d, len %d, ret %d"
usb_desc_string(int addr, int index, int len, int ret) "dev %d query string %d, len %d, ret %d"
usb_desc_bos(int addr, int len, int ret) "dev %d bos, len %d, ret %d"
+usb_desc_msos(int addr, int index, int len, int ret) "dev %d msos, index 0x%x, len %d, ret %d"
usb_set_addr(int addr) "dev %d"
usb_set_config(int addr, int config, int ret) "dev %d, config %d, ret %d"
usb_set_interface(int addr, int iface, int alt, int ret) "dev %d, interface %d, altsetting %d, ret %d"
--
1.8.3.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Qemu-devel] [PATCH 6/6] usb-tablet: add microsoft os descriptor support
2013-11-20 14:35 [Qemu-devel] [PATCH 0/6] usb: remote wakeup improvements Gerd Hoffmann
` (5 preceding siblings ...)
2013-11-20 14:35 ` [Qemu-devel] [PATCH 5/6] usb: add support for microsoft os descriptors Gerd Hoffmann
@ 2013-11-20 14:35 ` Gerd Hoffmann
6 siblings, 0 replies; 8+ messages in thread
From: Gerd Hoffmann @ 2013-11-20 14:35 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Set SelectiveSuspendEnabled registy entry to one.
This makes Windows use remote suspend by default,
without manual registry fiddeling.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/usb/dev-hid.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/hw/usb/dev-hid.c b/hw/usb/dev-hid.c
index 5e667f0..dbbb394 100644
--- a/hw/usb/dev-hid.c
+++ b/hw/usb/dev-hid.c
@@ -211,7 +211,7 @@ static const USBDescDevice desc_device_mouse = {
};
static const USBDescDevice desc_device_tablet = {
- .bcdUSB = 0x0100,
+ .bcdUSB = 0x0200,
.bMaxPacketSize0 = 8,
.bNumConfigurations = 1,
.confs = (USBDescConfig[]) {
@@ -261,6 +261,10 @@ static const USBDescDevice desc_device_keyboard = {
},
};
+static const USBDescMSOS desc_msos_suspend = {
+ .SelectiveSuspendEnabled = true,
+};
+
static const USBDesc desc_mouse = {
.id = {
.idVendor = 0x0627,
@@ -285,6 +289,7 @@ static const USBDesc desc_tablet = {
},
.full = &desc_device_tablet,
.str = desc_strings,
+ .msos = &desc_msos_suspend,
};
static const USBDesc desc_tablet2 = {
@@ -299,6 +304,7 @@ static const USBDesc desc_tablet2 = {
.full = &desc_device_tablet,
.high = &desc_device_tablet2,
.str = desc_strings,
+ .msos = &desc_msos_suspend,
};
static const USBDesc desc_keyboard = {
--
1.8.3.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
end of thread, other threads:[~2013-11-20 14:36 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-11-20 14:35 [Qemu-devel] [PATCH 0/6] usb: remote wakeup improvements Gerd Hoffmann
2013-11-20 14:35 ` [Qemu-devel] [PATCH v2] curses: fixup SIGWINCH handler mess Gerd Hoffmann
2013-11-20 14:35 ` [Qemu-devel] [PATCH 1/6] ehci: implement port wakeup Gerd Hoffmann
2013-11-20 14:35 ` [Qemu-devel] [PATCH 2/6] Revert "usb-tablet: Don't claim wakeup capability for USB-2 version" Gerd Hoffmann
2013-11-20 14:35 ` [Qemu-devel] [PATCH 3/6] usb: add vendor request defines Gerd Hoffmann
2013-11-20 14:35 ` [Qemu-devel] [PATCH 4/6] usb: move usb_{hi, lo} helpers to header file Gerd Hoffmann
2013-11-20 14:35 ` [Qemu-devel] [PATCH 5/6] usb: add support for microsoft os descriptors Gerd Hoffmann
2013-11-20 14:35 ` [Qemu-devel] [PATCH 6/6] usb-tablet: add microsoft os descriptor support Gerd Hoffmann
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).