52 lines
2.0 KiB
Diff
52 lines
2.0 KiB
Diff
# HG changeset patch
|
|
# User kfraser@localhost.localdomain
|
|
# Date 1169635472 0
|
|
# Node ID b064775fba7d838c99bcf11ca4fec6127e0e8792
|
|
# Parent c9ac0bace498d1c25f07df95b88d8f8e89168514
|
|
[QEMU] Clear TD status field explicitly when it's fetched.
|
|
|
|
In current Qemu-dm, UHC will set some status bits of TD in status
|
|
updating stage, but never process the status bit if relevant condition
|
|
does not occur, leaving it as it is. When a TD is fetched with some
|
|
status bits are set to 1, it will return to Guest OS with these bits
|
|
set to 1 even this TD is executed successfully. Some Windows OS,
|
|
e.g. Windows 2000, will check status bits of TD in UHC interrupt
|
|
routine, treat it as a unsuccessful one if some status bits are set to
|
|
1 and discard the data. Other Windows OS just check USBSTS of UHC,
|
|
ignoring status field of TD unless the value of USBSTS indicates
|
|
occurrence of error.
|
|
|
|
With this patch, USB mouse/tablet in Windows 2000 works correctly.
|
|
|
|
Signed-off-by: Xinmei Huang <xinmei.huang@intel.com>
|
|
|
|
Index: xen-3.0.4-testing/tools/ioemu/hw/usb-uhci.c
|
|
===================================================================
|
|
--- xen-3.0.4-testing.orig/tools/ioemu/hw/usb-uhci.c
|
|
+++ xen-3.0.4-testing/tools/ioemu/hw/usb-uhci.c
|
|
@@ -43,9 +43,15 @@
|
|
#define TD_CTRL_IOC (1 << 24)
|
|
#define TD_CTRL_ACTIVE (1 << 23)
|
|
#define TD_CTRL_STALL (1 << 22)
|
|
+#define TD_CTRL_BUFFER (1 << 21)
|
|
#define TD_CTRL_BABBLE (1 << 20)
|
|
#define TD_CTRL_NAK (1 << 19)
|
|
#define TD_CTRL_TIMEOUT (1 << 18)
|
|
+#define TD_CTRL_BITSTUFF \
|
|
+ (1 << 17)
|
|
+#define TD_CTRL_MASK \
|
|
+ (TD_CTRL_BITSTUFF | TD_CTRL_TIMEOUT | TD_CTRL_NAK \
|
|
+ | TD_CTRL_BABBLE | TD_CTRL_BUFFER | TD_CTRL_STALL)
|
|
|
|
#define UHCI_PORT_RESET (1 << 9)
|
|
#define UHCI_PORT_LSDA (1 << 8)
|
|
@@ -428,6 +434,8 @@ static int uhci_handle_td(UHCIState *s,
|
|
ret = 1;
|
|
goto out;
|
|
}
|
|
+ /* Clear TD's status field explicitly */
|
|
+ td->ctrl = td->ctrl & (~TD_CTRL_MASK);
|
|
|
|
/* TD is active */
|
|
max_len = ((td->token >> 21) + 1) & 0x7ff;
|