debuggers.hg

view tools/ioemu/patches/usb-mouse-tablet-status-check @ 0:7d21f7218375

Exact replica of unstable on 051908 + README-this
author Mukesh Rathor
date Mon May 19 15:34:57 2008 -0700 (2008-05-19)
parents
children
line source
1 # HG changeset patch
2 # User kfraser@localhost.localdomain
3 # Node ID 60bbcf799384d779c2a561b9d9ba30f28e31d970
4 # Parent fb3cb6f52a2905be938559529ae43b6ba990c878
5 [HVM] qemu mouse: Adds support for USB mouse/tablet status check and
6 restricts Universal Host Controller interrupt generating when received
7 NAK in interrupt transfer.
9 According to usb spec, USB mouse/tablet device returns NAK to host
10 controller if its status does not alter in interrupt transfer.
11 And UHC should leave a TD active when receiving NAK and execute this
12 incompleted TD in a subseqent frame. UHC only generates an interrupt
13 on complete after the TD with ICO bit is completed.
15 This patch make UHC & USB mouse/tablet behave consistently with spec.
17 Signed-off-by: Xinmei Huang <xinmei.huang@intel.com>
19 Index: ioemu/hw/usb-hid.c
20 ===================================================================
21 --- ioemu.orig/hw/usb-hid.c 2007-05-09 14:11:27.000000000 +0100
22 +++ ioemu/hw/usb-hid.c 2007-05-09 14:12:06.000000000 +0100
23 @@ -39,6 +39,7 @@
24 int x, y;
25 int kind;
26 int mouse_grabbed;
27 + int status_changed;
28 QEMUPutMouseEntry *eh_entry;
29 } USBMouseState;
31 @@ -232,6 +233,7 @@
32 s->dy += dy1;
33 s->dz += dz1;
34 s->buttons_state = buttons_state;
35 + s->status_changed = 1;
36 }
38 static void usb_tablet_event(void *opaque,
39 @@ -243,6 +245,7 @@
40 s->y = y;
41 s->dz += dz;
42 s->buttons_state = buttons_state;
43 + s->status_changed = 1;
44 }
46 static inline int int_clamp(int val, int vmin, int vmax)
47 @@ -485,10 +488,16 @@
48 switch(p->pid) {
49 case USB_TOKEN_IN:
50 if (p->devep == 1) {
51 - if (s->kind == USB_MOUSE)
52 - ret = usb_mouse_poll(s, p->data, p->len);
53 - else if (s->kind == USB_TABLET)
54 - ret = usb_tablet_poll(s, p->data, p->len);
55 + if (s->kind == USB_MOUSE)
56 + ret = usb_mouse_poll(s, p->data, p->len);
57 + else if (s->kind == USB_TABLET)
58 + ret = usb_tablet_poll(s, p->data, p->len);
59 +
60 + if (!s->status_changed)
61 + ret = USB_RET_NAK;
62 + else
63 + s->status_changed = 0;
64 +
65 } else {
66 goto fail;
67 }
68 @@ -570,6 +579,7 @@
69 s->dev.handle_data = usb_mouse_handle_data;
70 s->dev.handle_destroy = usb_mouse_handle_destroy;
71 s->kind = USB_TABLET;
72 + s->status_changed = 0;
74 pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Tablet");
76 @@ -593,6 +603,7 @@
77 s->dev.handle_data = usb_mouse_handle_data;
78 s->dev.handle_destroy = usb_mouse_handle_destroy;
79 s->kind = USB_MOUSE;
80 + s->status_changed = 0;
82 pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Mouse");
84 Index: ioemu/hw/usb-uhci.c
85 ===================================================================
86 --- ioemu.orig/hw/usb-uhci.c 2007-05-09 14:12:05.000000000 +0100
87 +++ ioemu/hw/usb-uhci.c 2007-05-09 14:12:06.000000000 +0100
88 @@ -43,9 +43,15 @@
89 #define TD_CTRL_IOC (1 << 24)
90 #define TD_CTRL_ACTIVE (1 << 23)
91 #define TD_CTRL_STALL (1 << 22)
92 +#define TD_CTRL_BUFFER (1 << 21)
93 #define TD_CTRL_BABBLE (1 << 20)
94 #define TD_CTRL_NAK (1 << 19)
95 #define TD_CTRL_TIMEOUT (1 << 18)
96 +#define TD_CTRL_BITSTUFF \
97 + (1 << 17)
98 +#define TD_CTRL_MASK \
99 + (TD_CTRL_BITSTUFF | TD_CTRL_TIMEOUT | TD_CTRL_NAK \
100 + | TD_CTRL_BABBLE | TD_CTRL_BUFFER | TD_CTRL_STALL)
102 #define UHCI_PORT_RESET (1 << 9)
103 #define UHCI_PORT_LSDA (1 << 8)
104 @@ -431,13 +437,13 @@
105 uint8_t pid;
106 int len, max_len, err, ret;
108 - /* ??? This is wrong for async completion. */
109 - if (td->ctrl & TD_CTRL_IOC) {
110 - *int_mask |= 0x01;
111 + if (!(td->ctrl & TD_CTRL_ACTIVE)) {
112 + ret = 1;
113 + goto out;
114 }
115 -
116 - if (!(td->ctrl & TD_CTRL_ACTIVE))
117 - return 1;
118 +
119 + /* Clear TD's status field explicitly */
120 + td->ctrl = td->ctrl & (~TD_CTRL_MASK);
122 /* TD is active */
123 max_len = ((td->token >> 21) + 1) & 0x7ff;
124 @@ -493,11 +499,13 @@
125 /* invalid pid : frame interrupted */
126 s->status |= UHCI_STS_HCPERR;
127 uhci_update_irq(s);
128 - return -1;
129 + ret = -1;
130 + goto out;
131 }
132 }
133 if (ret == USB_RET_ASYNC) {
134 - return 2;
135 + ret = 2;
136 + goto out;
137 }
138 if (td->ctrl & TD_CTRL_IOS)
139 td->ctrl &= ~TD_CTRL_ACTIVE;
140 @@ -509,10 +517,12 @@
141 len < max_len) {
142 *int_mask |= 0x02;
143 /* short packet: do not update QH */
144 - return 1;
145 + ret = 1;
146 + goto out;
147 } else {
148 /* success */
149 - return 0;
150 + ret = 0;
151 + goto out;
152 }
153 } else {
154 switch(ret) {
155 @@ -531,23 +541,34 @@
156 }
157 td->ctrl = (td->ctrl & ~(3 << TD_CTRL_ERROR_SHIFT)) |
158 (err << TD_CTRL_ERROR_SHIFT);
159 - return 1;
160 + ret = 1;
161 + goto out;
162 case USB_RET_NAK:
163 td->ctrl |= TD_CTRL_NAK;
164 if (pid == USB_TOKEN_SETUP)
165 goto do_timeout;
166 - return 1;
167 + ret = 1;
168 + goto out;
169 case USB_RET_STALL:
170 td->ctrl |= TD_CTRL_STALL;
171 td->ctrl &= ~TD_CTRL_ACTIVE;
172 - return 1;
173 + ret = 1;
174 + goto out;
175 case USB_RET_BABBLE:
176 td->ctrl |= TD_CTRL_BABBLE | TD_CTRL_STALL;
177 td->ctrl &= ~TD_CTRL_ACTIVE;
178 /* frame interrupted */
179 - return -1;
180 + ret = -1;
181 + goto out;
182 }
183 }
184 +
185 +out:
186 + /* If TD is inactive and IOC bit set to 1 then update int_mask */
187 + if ((td->ctrl & TD_CTRL_IOC) && (!(td->ctrl & TD_CTRL_ACTIVE))) {
188 + *int_mask |= 0x01;
189 + }
190 + return ret;
191 }
193 static void uhci_async_complete_packet(USBPacket * packet, void *opaque)