• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * QEMU USB HID devices
3  *
4  * Copyright (c) 2005 Fabrice Bellard
5  * Copyright (c) 2007 OpenMoko, Inc.  (andrew@openedhand.com)
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy
8  * of this software and associated documentation files (the "Software"), to deal
9  * in the Software without restriction, including without limitation the rights
10  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11  * copies of the Software, and to permit persons to whom the Software is
12  * furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in
15  * all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23  * THE SOFTWARE.
24  */
25 #include "hw.h"
26 #include "console.h"
27 #include "usb.h"
28 
29 /* HID interface requests */
30 #define GET_REPORT   0xa101
31 #define GET_IDLE     0xa102
32 #define GET_PROTOCOL 0xa103
33 #define SET_REPORT   0x2109
34 #define SET_IDLE     0x210a
35 #define SET_PROTOCOL 0x210b
36 
37 /* HID descriptor types */
38 #define USB_DT_HID    0x21
39 #define USB_DT_REPORT 0x22
40 #define USB_DT_PHY    0x23
41 
42 #define USB_MOUSE     1
43 #define USB_TABLET    2
44 #define USB_KEYBOARD  3
45 
46 typedef struct USBMouseState {
47     int dx, dy, dz, buttons_state;
48     int x, y;
49     int mouse_grabbed;
50     QEMUPutMouseEntry *eh_entry;
51 } USBMouseState;
52 
53 typedef struct USBKeyboardState {
54     uint16_t modifiers;
55     uint8_t leds;
56     uint8_t key[16];
57     int keys;
58 } USBKeyboardState;
59 
60 typedef struct USBHIDState {
61     USBDevice dev;
62     union {
63         USBMouseState ptr;
64         USBKeyboardState kbd;
65     };
66     int kind;
67     int protocol;
68     uint8_t idle;
69     int changed;
70     void *datain_opaque;
71     void (*datain)(void *);
72 } USBHIDState;
73 
74 /* mostly the same values as the Bochs USB Mouse device */
75 static const uint8_t qemu_mouse_dev_descriptor[] = {
76 	0x12,       /*  u8 bLength; */
77 	0x01,       /*  u8 bDescriptorType; Device */
78 	0x00, 0x01, /*  u16 bcdUSB; v1.0 */
79 
80 	0x00,	    /*  u8  bDeviceClass; */
81 	0x00,	    /*  u8  bDeviceSubClass; */
82 	0x00,       /*  u8  bDeviceProtocol; [ low/full speeds only ] */
83 	0x08,       /*  u8  bMaxPacketSize0; 8 Bytes */
84 
85 	0x27, 0x06, /*  u16 idVendor; */
86  	0x01, 0x00, /*  u16 idProduct; */
87 	0x00, 0x00, /*  u16 bcdDevice */
88 
89 	0x03,       /*  u8  iManufacturer; */
90 	0x02,       /*  u8  iProduct; */
91 	0x01,       /*  u8  iSerialNumber; */
92 	0x01        /*  u8  bNumConfigurations; */
93 };
94 
95 static const uint8_t qemu_mouse_config_descriptor[] = {
96 	/* one configuration */
97 	0x09,       /*  u8  bLength; */
98 	0x02,       /*  u8  bDescriptorType; Configuration */
99 	0x22, 0x00, /*  u16 wTotalLength; */
100 	0x01,       /*  u8  bNumInterfaces; (1) */
101 	0x01,       /*  u8  bConfigurationValue; */
102 	0x04,       /*  u8  iConfiguration; */
103 	0xa0,       /*  u8  bmAttributes;
104 				 Bit 7: must be set,
105 				     6: Self-powered,
106 				     5: Remote wakeup,
107 				     4..0: resvd */
108 	50,         /*  u8  MaxPower; */
109 
110 	/* USB 1.1:
111 	 * USB 2.0, single TT organization (mandatory):
112 	 *	one interface, protocol 0
113 	 *
114 	 * USB 2.0, multiple TT organization (optional):
115 	 *	two interfaces, protocols 1 (like single TT)
116 	 *	and 2 (multiple TT mode) ... config is
117 	 *	sometimes settable
118 	 *	NOT IMPLEMENTED
119 	 */
120 
121 	/* one interface */
122 	0x09,       /*  u8  if_bLength; */
123 	0x04,       /*  u8  if_bDescriptorType; Interface */
124 	0x00,       /*  u8  if_bInterfaceNumber; */
125 	0x00,       /*  u8  if_bAlternateSetting; */
126 	0x01,       /*  u8  if_bNumEndpoints; */
127 	0x03,       /*  u8  if_bInterfaceClass; */
128 	0x01,       /*  u8  if_bInterfaceSubClass; */
129 	0x02,       /*  u8  if_bInterfaceProtocol; [usb1.1 or single tt] */
130 	0x07,       /*  u8  if_iInterface; */
131 
132         /* HID descriptor */
133         0x09,        /*  u8  bLength; */
134         0x21,        /*  u8 bDescriptorType; */
135         0x01, 0x00,  /*  u16 HID_class */
136         0x00,        /*  u8 country_code */
137         0x01,        /*  u8 num_descriptors */
138         0x22,        /*  u8 type; Report */
139         52, 0,       /*  u16 len */
140 
141 	/* one endpoint (status change endpoint) */
142 	0x07,       /*  u8  ep_bLength; */
143 	0x05,       /*  u8  ep_bDescriptorType; Endpoint */
144 	0x81,       /*  u8  ep_bEndpointAddress; IN Endpoint 1 */
145  	0x03,       /*  u8  ep_bmAttributes; Interrupt */
146  	0x04, 0x00, /*  u16 ep_wMaxPacketSize; */
147 	0x0a,       /*  u8  ep_bInterval; (255ms -- usb 2.0 spec) */
148 };
149 
150 static const uint8_t qemu_tablet_config_descriptor[] = {
151 	/* one configuration */
152 	0x09,       /*  u8  bLength; */
153 	0x02,       /*  u8  bDescriptorType; Configuration */
154 	0x22, 0x00, /*  u16 wTotalLength; */
155 	0x01,       /*  u8  bNumInterfaces; (1) */
156 	0x01,       /*  u8  bConfigurationValue; */
157 	0x05,       /*  u8  iConfiguration; */
158 	0xa0,       /*  u8  bmAttributes;
159 				 Bit 7: must be set,
160 				     6: Self-powered,
161 				     5: Remote wakeup,
162 				     4..0: resvd */
163 	50,         /*  u8  MaxPower; */
164 
165 	/* USB 1.1:
166 	 * USB 2.0, single TT organization (mandatory):
167 	 *	one interface, protocol 0
168 	 *
169 	 * USB 2.0, multiple TT organization (optional):
170 	 *	two interfaces, protocols 1 (like single TT)
171 	 *	and 2 (multiple TT mode) ... config is
172 	 *	sometimes settable
173 	 *	NOT IMPLEMENTED
174 	 */
175 
176 	/* one interface */
177 	0x09,       /*  u8  if_bLength; */
178 	0x04,       /*  u8  if_bDescriptorType; Interface */
179 	0x00,       /*  u8  if_bInterfaceNumber; */
180 	0x00,       /*  u8  if_bAlternateSetting; */
181 	0x01,       /*  u8  if_bNumEndpoints; */
182 	0x03,       /*  u8  if_bInterfaceClass; */
183 	0x01,       /*  u8  if_bInterfaceSubClass; */
184 	0x02,       /*  u8  if_bInterfaceProtocol; [usb1.1 or single tt] */
185 	0x07,       /*  u8  if_iInterface; */
186 
187         /* HID descriptor */
188         0x09,        /*  u8  bLength; */
189         0x21,        /*  u8 bDescriptorType; */
190         0x01, 0x00,  /*  u16 HID_class */
191         0x00,        /*  u8 country_code */
192         0x01,        /*  u8 num_descriptors */
193         0x22,        /*  u8 type; Report */
194         74, 0,       /*  u16 len */
195 
196 	/* one endpoint (status change endpoint) */
197 	0x07,       /*  u8  ep_bLength; */
198 	0x05,       /*  u8  ep_bDescriptorType; Endpoint */
199 	0x81,       /*  u8  ep_bEndpointAddress; IN Endpoint 1 */
200  	0x03,       /*  u8  ep_bmAttributes; Interrupt */
201  	0x08, 0x00, /*  u16 ep_wMaxPacketSize; */
202 	0x0a,       /*  u8  ep_bInterval; (255ms -- usb 2.0 spec) */
203 };
204 
205 static const uint8_t qemu_keyboard_config_descriptor[] = {
206     /* one configuration */
207     0x09,		/*  u8  bLength; */
208     USB_DT_CONFIG,	/*  u8  bDescriptorType; Configuration */
209     0x22, 0x00,		/*  u16 wTotalLength; */
210     0x01,		/*  u8  bNumInterfaces; (1) */
211     0x01,		/*  u8  bConfigurationValue; */
212     0x06,		/*  u8  iConfiguration; */
213     0xa0,		/*  u8  bmAttributes;
214 				Bit 7: must be set,
215 				    6: Self-powered,
216 				    5: Remote wakeup,
217 				    4..0: resvd */
218     0x32,		/*  u8  MaxPower; */
219 
220     /* USB 1.1:
221      * USB 2.0, single TT organization (mandatory):
222      *	one interface, protocol 0
223      *
224      * USB 2.0, multiple TT organization (optional):
225      *	two interfaces, protocols 1 (like single TT)
226      *	and 2 (multiple TT mode) ... config is
227      *	sometimes settable
228      *	NOT IMPLEMENTED
229      */
230 
231     /* one interface */
232     0x09,		/*  u8  if_bLength; */
233     USB_DT_INTERFACE,	/*  u8  if_bDescriptorType; Interface */
234     0x00,		/*  u8  if_bInterfaceNumber; */
235     0x00,		/*  u8  if_bAlternateSetting; */
236     0x01,		/*  u8  if_bNumEndpoints; */
237     0x03,		/*  u8  if_bInterfaceClass; HID */
238     0x01,		/*  u8  if_bInterfaceSubClass; Boot */
239     0x01,		/*  u8  if_bInterfaceProtocol; Keyboard */
240     0x07,		/*  u8  if_iInterface; */
241 
242     /* HID descriptor */
243     0x09,		/*  u8  bLength; */
244     USB_DT_HID,		/*  u8  bDescriptorType; */
245     0x11, 0x01,		/*  u16 HID_class */
246     0x00,		/*  u8  country_code */
247     0x01,		/*  u8  num_descriptors */
248     USB_DT_REPORT,	/*  u8  type; Report */
249     0x3f, 0x00,		/*  u16 len */
250 
251     /* one endpoint (status change endpoint) */
252     0x07,		/*  u8  ep_bLength; */
253     USB_DT_ENDPOINT,	/*  u8  ep_bDescriptorType; Endpoint */
254     USB_DIR_IN | 0x01,	/*  u8  ep_bEndpointAddress; IN Endpoint 1 */
255     0x03,		/*  u8  ep_bmAttributes; Interrupt */
256     0x08, 0x00,		/*  u16 ep_wMaxPacketSize; */
257     0x0a,		/*  u8  ep_bInterval; (255ms -- usb 2.0 spec) */
258 };
259 
260 static const uint8_t qemu_mouse_hid_report_descriptor[] = {
261     0x05, 0x01,		/* Usage Page (Generic Desktop) */
262     0x09, 0x02,		/* Usage (Mouse) */
263     0xa1, 0x01,		/* Collection (Application) */
264     0x09, 0x01,		/*   Usage (Pointer) */
265     0xa1, 0x00,		/*   Collection (Physical) */
266     0x05, 0x09,		/*     Usage Page (Button) */
267     0x19, 0x01,		/*     Usage Minimum (1) */
268     0x29, 0x03,		/*     Usage Maximum (3) */
269     0x15, 0x00,		/*     Logical Minimum (0) */
270     0x25, 0x01,		/*     Logical Maximum (1) */
271     0x95, 0x03,		/*     Report Count (3) */
272     0x75, 0x01,		/*     Report Size (1) */
273     0x81, 0x02,		/*     Input (Data, Variable, Absolute) */
274     0x95, 0x01,		/*     Report Count (1) */
275     0x75, 0x05,		/*     Report Size (5) */
276     0x81, 0x01,		/*     Input (Constant) */
277     0x05, 0x01,		/*     Usage Page (Generic Desktop) */
278     0x09, 0x30,		/*     Usage (X) */
279     0x09, 0x31,		/*     Usage (Y) */
280     0x09, 0x38,		/*     Usage (Wheel) */
281     0x15, 0x81,		/*     Logical Minimum (-0x7f) */
282     0x25, 0x7f,		/*     Logical Maximum (0x7f) */
283     0x75, 0x08,		/*     Report Size (8) */
284     0x95, 0x03,		/*     Report Count (3) */
285     0x81, 0x06,		/*     Input (Data, Variable, Relative) */
286     0xc0,		/*   End Collection */
287     0xc0,		/* End Collection */
288 };
289 
290 static const uint8_t qemu_tablet_hid_report_descriptor[] = {
291     0x05, 0x01,		/* Usage Page (Generic Desktop) */
292     0x09, 0x01,		/* Usage (Pointer) */
293     0xa1, 0x01,		/* Collection (Application) */
294     0x09, 0x01,		/*   Usage (Pointer) */
295     0xa1, 0x00,		/*   Collection (Physical) */
296     0x05, 0x09,		/*     Usage Page (Button) */
297     0x19, 0x01,		/*     Usage Minimum (1) */
298     0x29, 0x03,		/*     Usage Maximum (3) */
299     0x15, 0x00,		/*     Logical Minimum (0) */
300     0x25, 0x01,		/*     Logical Maximum (1) */
301     0x95, 0x03,		/*     Report Count (3) */
302     0x75, 0x01,		/*     Report Size (1) */
303     0x81, 0x02,		/*     Input (Data, Variable, Absolute) */
304     0x95, 0x01,		/*     Report Count (1) */
305     0x75, 0x05,		/*     Report Size (5) */
306     0x81, 0x01,		/*     Input (Constant) */
307     0x05, 0x01,		/*     Usage Page (Generic Desktop) */
308     0x09, 0x30,		/*     Usage (X) */
309     0x09, 0x31,		/*     Usage (Y) */
310     0x15, 0x00,		/*     Logical Minimum (0) */
311     0x26, 0xff, 0x7f,	/*     Logical Maximum (0x7fff) */
312     0x35, 0x00,		/*     Physical Minimum (0) */
313     0x46, 0xff, 0x7f,	/*     Physical Maximum (0x7fff) */
314     0x75, 0x10,		/*     Report Size (16) */
315     0x95, 0x02,		/*     Report Count (2) */
316     0x81, 0x02,		/*     Input (Data, Variable, Absolute) */
317     0x05, 0x01,		/*     Usage Page (Generic Desktop) */
318     0x09, 0x38,		/*     Usage (Wheel) */
319     0x15, 0x81,		/*     Logical Minimum (-0x7f) */
320     0x25, 0x7f,		/*     Logical Maximum (0x7f) */
321     0x35, 0x00,		/*     Physical Minimum (same as logical) */
322     0x45, 0x00,		/*     Physical Maximum (same as logical) */
323     0x75, 0x08,		/*     Report Size (8) */
324     0x95, 0x01,		/*     Report Count (1) */
325     0x81, 0x06,		/*     Input (Data, Variable, Relative) */
326     0xc0,		/*   End Collection */
327     0xc0,		/* End Collection */
328 };
329 
330 static const uint8_t qemu_keyboard_hid_report_descriptor[] = {
331     0x05, 0x01,		/* Usage Page (Generic Desktop) */
332     0x09, 0x06,		/* Usage (Keyboard) */
333     0xa1, 0x01,		/* Collection (Application) */
334     0x75, 0x01,		/*   Report Size (1) */
335     0x95, 0x08,		/*   Report Count (8) */
336     0x05, 0x07,		/*   Usage Page (Key Codes) */
337     0x19, 0xe0,		/*   Usage Minimum (224) */
338     0x29, 0xe7,		/*   Usage Maximum (231) */
339     0x15, 0x00,		/*   Logical Minimum (0) */
340     0x25, 0x01,		/*   Logical Maximum (1) */
341     0x81, 0x02,		/*   Input (Data, Variable, Absolute) */
342     0x95, 0x01,		/*   Report Count (1) */
343     0x75, 0x08,		/*   Report Size (8) */
344     0x81, 0x01,		/*   Input (Constant) */
345     0x95, 0x05,		/*   Report Count (5) */
346     0x75, 0x01,		/*   Report Size (1) */
347     0x05, 0x08,		/*   Usage Page (LEDs) */
348     0x19, 0x01,		/*   Usage Minimum (1) */
349     0x29, 0x05,		/*   Usage Maximum (5) */
350     0x91, 0x02,		/*   Output (Data, Variable, Absolute) */
351     0x95, 0x01,		/*   Report Count (1) */
352     0x75, 0x03,		/*   Report Size (3) */
353     0x91, 0x01,		/*   Output (Constant) */
354     0x95, 0x06,		/*   Report Count (6) */
355     0x75, 0x08,		/*   Report Size (8) */
356     0x15, 0x00,		/*   Logical Minimum (0) */
357     0x25, 0xff,		/*   Logical Maximum (255) */
358     0x05, 0x07,		/*   Usage Page (Key Codes) */
359     0x19, 0x00,		/*   Usage Minimum (0) */
360     0x29, 0xff,		/*   Usage Maximum (255) */
361     0x81, 0x00,		/*   Input (Data, Array) */
362     0xc0,		/* End Collection */
363 };
364 
365 #define USB_HID_USAGE_ERROR_ROLLOVER	0x01
366 #define USB_HID_USAGE_POSTFAIL		0x02
367 #define USB_HID_USAGE_ERROR_UNDEFINED	0x03
368 
369 /* Indices are QEMU keycodes, values are from HID Usage Table.  Indices
370  * above 0x80 are for keys that come after 0xe0 or 0xe1+0x1d or 0xe1+0x9d.  */
371 static const uint8_t usb_hid_usage_keys[0x100] = {
372     0x00, 0x29, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
373     0x24, 0x25, 0x26, 0x27, 0x2d, 0x2e, 0x2a, 0x2b,
374     0x14, 0x1a, 0x08, 0x15, 0x17, 0x1c, 0x18, 0x0c,
375     0x12, 0x13, 0x2f, 0x30, 0x28, 0xe0, 0x04, 0x16,
376     0x07, 0x09, 0x0a, 0x0b, 0x0d, 0x0e, 0x0f, 0x33,
377     0x34, 0x35, 0xe1, 0x31, 0x1d, 0x1b, 0x06, 0x19,
378     0x05, 0x11, 0x10, 0x36, 0x37, 0x38, 0xe5, 0x55,
379     0xe2, 0x2c, 0x32, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
380     0x3f, 0x40, 0x41, 0x42, 0x43, 0x53, 0x47, 0x5f,
381     0x60, 0x61, 0x56, 0x5c, 0x5d, 0x5e, 0x57, 0x59,
382     0x5a, 0x5b, 0x62, 0x63, 0x00, 0x00, 0x00, 0x44,
383     0x45, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
384     0xe8, 0xe9, 0x71, 0x72, 0x73, 0x00, 0x00, 0x00,
385     0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x00,
386     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
387     0x00, 0x00, 0x00, 0x00, 0x00, 0xe3, 0xe7, 0x65,
388 
389     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
390     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
391     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
392     0x00, 0x00, 0x00, 0x00, 0x58, 0xe4, 0x00, 0x00,
393     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
394     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
395     0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x46,
396     0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
397     0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x4a,
398     0x52, 0x4b, 0x00, 0x50, 0x00, 0x4f, 0x00, 0x4d,
399     0x51, 0x4e, 0x49, 0x4c, 0x00, 0x00, 0x00, 0x00,
400     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
401     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
402     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
403     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
404     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
405 };
406 
usb_hid_changed(USBHIDState * hs)407 static void usb_hid_changed(USBHIDState *hs)
408 {
409     hs->changed = 1;
410 
411     if (hs->datain)
412         hs->datain(hs->datain_opaque);
413 }
414 
usb_mouse_event(void * opaque,int dx1,int dy1,int dz1,int buttons_state)415 static void usb_mouse_event(void *opaque,
416                             int dx1, int dy1, int dz1, int buttons_state)
417 {
418     USBHIDState *hs = opaque;
419     USBMouseState *s = &hs->ptr;
420 
421     s->dx += dx1;
422     s->dy += dy1;
423     s->dz += dz1;
424     s->buttons_state = buttons_state;
425 
426     usb_hid_changed(hs);
427 }
428 
usb_tablet_event(void * opaque,int x,int y,int dz,int buttons_state)429 static void usb_tablet_event(void *opaque,
430 			     int x, int y, int dz, int buttons_state)
431 {
432     USBHIDState *hs = opaque;
433     USBMouseState *s = &hs->ptr;
434 
435     s->x = x;
436     s->y = y;
437     s->dz += dz;
438     s->buttons_state = buttons_state;
439 
440     usb_hid_changed(hs);
441 }
442 
usb_keyboard_event(void * opaque,int keycode)443 static void usb_keyboard_event(void *opaque, int keycode)
444 {
445     USBHIDState *hs = opaque;
446     USBKeyboardState *s = &hs->kbd;
447     uint8_t hid_code, key;
448     int i;
449 
450     key = keycode & 0x7f;
451     hid_code = usb_hid_usage_keys[key | ((s->modifiers >> 1) & (1 << 7))];
452     s->modifiers &= ~(1 << 8);
453 
454     switch (hid_code) {
455     case 0x00:
456         return;
457 
458     case 0xe0:
459         if (s->modifiers & (1 << 9)) {
460             s->modifiers ^= 3 << 8;
461             return;
462         }
463     case 0xe1 ... 0xe7:
464         if (keycode & (1 << 7)) {
465             s->modifiers &= ~(1 << (hid_code & 0x0f));
466             return;
467         }
468     case 0xe8 ... 0xef:
469         s->modifiers |= 1 << (hid_code & 0x0f);
470         return;
471     }
472 
473     if (keycode & (1 << 7)) {
474         for (i = s->keys - 1; i >= 0; i --)
475             if (s->key[i] == hid_code) {
476                 s->key[i] = s->key[-- s->keys];
477                 s->key[s->keys] = 0x00;
478                 usb_hid_changed(hs);
479                 break;
480             }
481         if (i < 0)
482             return;
483     } else {
484         for (i = s->keys - 1; i >= 0; i --)
485             if (s->key[i] == hid_code)
486                 break;
487         if (i < 0) {
488             if (s->keys < sizeof(s->key))
489                 s->key[s->keys ++] = hid_code;
490         } else
491             return;
492     }
493 
494     usb_hid_changed(hs);
495 }
496 
int_clamp(int val,int vmin,int vmax)497 static inline int int_clamp(int val, int vmin, int vmax)
498 {
499     if (val < vmin)
500         return vmin;
501     else if (val > vmax)
502         return vmax;
503     else
504         return val;
505 }
506 
usb_mouse_poll(USBHIDState * hs,uint8_t * buf,int len)507 static int usb_mouse_poll(USBHIDState *hs, uint8_t *buf, int len)
508 {
509     int dx, dy, dz, b, l;
510     USBMouseState *s = &hs->ptr;
511 
512     if (!s->mouse_grabbed) {
513 	s->eh_entry = qemu_add_mouse_event_handler(usb_mouse_event, hs,
514                                                   0, "QEMU USB Mouse");
515 	s->mouse_grabbed = 1;
516     }
517 
518     dx = int_clamp(s->dx, -127, 127);
519     dy = int_clamp(s->dy, -127, 127);
520     dz = int_clamp(s->dz, -127, 127);
521 
522     s->dx -= dx;
523     s->dy -= dy;
524     s->dz -= dz;
525 
526     /* Appears we have to invert the wheel direction */
527     dz = 0 - dz;
528 
529     b = 0;
530     if (s->buttons_state & MOUSE_EVENT_LBUTTON)
531         b |= 0x01;
532     if (s->buttons_state & MOUSE_EVENT_RBUTTON)
533         b |= 0x02;
534     if (s->buttons_state & MOUSE_EVENT_MBUTTON)
535         b |= 0x04;
536 
537     l = 0;
538     if (len > l)
539         buf[l ++] = b;
540     if (len > l)
541         buf[l ++] = dx;
542     if (len > l)
543         buf[l ++] = dy;
544     if (len > l)
545         buf[l ++] = dz;
546     return l;
547 }
548 
usb_tablet_poll(USBHIDState * hs,uint8_t * buf,int len)549 static int usb_tablet_poll(USBHIDState *hs, uint8_t *buf, int len)
550 {
551     int dz, b, l;
552     USBMouseState *s = &hs->ptr;
553 
554     if (!s->mouse_grabbed) {
555 	s->eh_entry = qemu_add_mouse_event_handler(usb_tablet_event, hs,
556                                                   1, "QEMU USB Tablet");
557 	s->mouse_grabbed = 1;
558     }
559 
560     dz = int_clamp(s->dz, -127, 127);
561     s->dz -= dz;
562 
563     /* Appears we have to invert the wheel direction */
564     dz = 0 - dz;
565     b = 0;
566     if (s->buttons_state & MOUSE_EVENT_LBUTTON)
567         b |= 0x01;
568     if (s->buttons_state & MOUSE_EVENT_RBUTTON)
569         b |= 0x02;
570     if (s->buttons_state & MOUSE_EVENT_MBUTTON)
571         b |= 0x04;
572 
573     buf[0] = b;
574     buf[1] = s->x & 0xff;
575     buf[2] = s->x >> 8;
576     buf[3] = s->y & 0xff;
577     buf[4] = s->y >> 8;
578     buf[5] = dz;
579     l = 6;
580 
581     return l;
582 }
583 
usb_keyboard_poll(USBKeyboardState * s,uint8_t * buf,int len)584 static int usb_keyboard_poll(USBKeyboardState *s, uint8_t *buf, int len)
585 {
586     if (len < 2)
587         return 0;
588 
589     buf[0] = s->modifiers & 0xff;
590     buf[1] = 0;
591     if (s->keys > 6)
592         memset(buf + 2, USB_HID_USAGE_ERROR_ROLLOVER, MIN(8, len) - 2);
593     else
594         memcpy(buf + 2, s->key, MIN(8, len) - 2);
595 
596     return MIN(8, len);
597 }
598 
usb_keyboard_write(USBKeyboardState * s,uint8_t * buf,int len)599 static int usb_keyboard_write(USBKeyboardState *s, uint8_t *buf, int len)
600 {
601     if (len > 0) {
602         /* 0x01: Num Lock LED
603          * 0x02: Caps Lock LED
604          * 0x04: Scroll Lock LED
605          * 0x08: Compose LED
606          * 0x10: Kana LED */
607         s->leds = buf[0];
608     }
609     return 0;
610 }
611 
usb_mouse_handle_reset(USBDevice * dev)612 static void usb_mouse_handle_reset(USBDevice *dev)
613 {
614     USBHIDState *s = (USBHIDState *)dev;
615 
616     s->ptr.dx = 0;
617     s->ptr.dy = 0;
618     s->ptr.dz = 0;
619     s->ptr.x = 0;
620     s->ptr.y = 0;
621     s->ptr.buttons_state = 0;
622     s->protocol = 1;
623 }
624 
usb_keyboard_handle_reset(USBDevice * dev)625 static void usb_keyboard_handle_reset(USBDevice *dev)
626 {
627     USBHIDState *s = (USBHIDState *)dev;
628 
629     qemu_add_kbd_event_handler(usb_keyboard_event, s);
630     s->protocol = 1;
631 }
632 
usb_hid_handle_control(USBDevice * dev,int request,int value,int index,int length,uint8_t * data)633 static int usb_hid_handle_control(USBDevice *dev, int request, int value,
634                                   int index, int length, uint8_t *data)
635 {
636     USBHIDState *s = (USBHIDState *)dev;
637     int ret = 0;
638 
639     switch(request) {
640     case DeviceRequest | USB_REQ_GET_STATUS:
641         data[0] = (1 << USB_DEVICE_SELF_POWERED) |
642             (dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP);
643         data[1] = 0x00;
644         ret = 2;
645         break;
646     case DeviceOutRequest | USB_REQ_CLEAR_FEATURE:
647         if (value == USB_DEVICE_REMOTE_WAKEUP) {
648             dev->remote_wakeup = 0;
649         } else {
650             goto fail;
651         }
652         ret = 0;
653         break;
654     case DeviceOutRequest | USB_REQ_SET_FEATURE:
655         if (value == USB_DEVICE_REMOTE_WAKEUP) {
656             dev->remote_wakeup = 1;
657         } else {
658             goto fail;
659         }
660         ret = 0;
661         break;
662     case DeviceOutRequest | USB_REQ_SET_ADDRESS:
663         dev->addr = value;
664         ret = 0;
665         break;
666     case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
667         switch(value >> 8) {
668         case USB_DT_DEVICE:
669             memcpy(data, qemu_mouse_dev_descriptor,
670                    sizeof(qemu_mouse_dev_descriptor));
671             ret = sizeof(qemu_mouse_dev_descriptor);
672             break;
673         case USB_DT_CONFIG:
674 	    if (s->kind == USB_MOUSE) {
675 		memcpy(data, qemu_mouse_config_descriptor,
676 		       sizeof(qemu_mouse_config_descriptor));
677 		ret = sizeof(qemu_mouse_config_descriptor);
678 	    } else if (s->kind == USB_TABLET) {
679 		memcpy(data, qemu_tablet_config_descriptor,
680 		       sizeof(qemu_tablet_config_descriptor));
681 		ret = sizeof(qemu_tablet_config_descriptor);
682             } else if (s->kind == USB_KEYBOARD) {
683                 memcpy(data, qemu_keyboard_config_descriptor,
684                        sizeof(qemu_keyboard_config_descriptor));
685                 ret = sizeof(qemu_keyboard_config_descriptor);
686             }
687             break;
688         case USB_DT_STRING:
689             switch(value & 0xff) {
690             case 0:
691                 /* language ids */
692                 data[0] = 4;
693                 data[1] = 3;
694                 data[2] = 0x09;
695                 data[3] = 0x04;
696                 ret = 4;
697                 break;
698             case 1:
699                 /* serial number */
700                 ret = set_usb_string(data, "1");
701                 break;
702             case 2:
703                 /* product description */
704                 ret = set_usb_string(data, s->dev.devname);
705                 break;
706             case 3:
707                 /* vendor description */
708                 ret = set_usb_string(data, "QEMU " QEMU_VERSION);
709                 break;
710             case 4:
711                 ret = set_usb_string(data, "HID Mouse");
712                 break;
713             case 5:
714                 ret = set_usb_string(data, "HID Tablet");
715                 break;
716             case 6:
717                 ret = set_usb_string(data, "HID Keyboard");
718                 break;
719             case 7:
720                 ret = set_usb_string(data, "Endpoint1 Interrupt Pipe");
721                 break;
722             default:
723                 goto fail;
724             }
725             break;
726         default:
727             goto fail;
728         }
729         break;
730     case DeviceRequest | USB_REQ_GET_CONFIGURATION:
731         data[0] = 1;
732         ret = 1;
733         break;
734     case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
735         ret = 0;
736         break;
737     case DeviceRequest | USB_REQ_GET_INTERFACE:
738         data[0] = 0;
739         ret = 1;
740         break;
741     case DeviceOutRequest | USB_REQ_SET_INTERFACE:
742         ret = 0;
743         break;
744         /* hid specific requests */
745     case InterfaceRequest | USB_REQ_GET_DESCRIPTOR:
746         switch(value >> 8) {
747         case 0x22:
748 	    if (s->kind == USB_MOUSE) {
749 		memcpy(data, qemu_mouse_hid_report_descriptor,
750 		       sizeof(qemu_mouse_hid_report_descriptor));
751 		ret = sizeof(qemu_mouse_hid_report_descriptor);
752 	    } else if (s->kind == USB_TABLET) {
753 		memcpy(data, qemu_tablet_hid_report_descriptor,
754 		       sizeof(qemu_tablet_hid_report_descriptor));
755 		ret = sizeof(qemu_tablet_hid_report_descriptor);
756             } else if (s->kind == USB_KEYBOARD) {
757                 memcpy(data, qemu_keyboard_hid_report_descriptor,
758                        sizeof(qemu_keyboard_hid_report_descriptor));
759                 ret = sizeof(qemu_keyboard_hid_report_descriptor);
760             }
761             break;
762         default:
763             goto fail;
764         }
765         break;
766     case GET_REPORT:
767 	if (s->kind == USB_MOUSE)
768             ret = usb_mouse_poll(s, data, length);
769 	else if (s->kind == USB_TABLET)
770             ret = usb_tablet_poll(s, data, length);
771         else if (s->kind == USB_KEYBOARD)
772             ret = usb_keyboard_poll(&s->kbd, data, length);
773         break;
774     case SET_REPORT:
775         if (s->kind == USB_KEYBOARD)
776             ret = usb_keyboard_write(&s->kbd, data, length);
777         else
778             goto fail;
779         break;
780     case GET_PROTOCOL:
781         if (s->kind != USB_KEYBOARD)
782             goto fail;
783         ret = 1;
784         data[0] = s->protocol;
785         break;
786     case SET_PROTOCOL:
787         if (s->kind != USB_KEYBOARD)
788             goto fail;
789         ret = 0;
790         s->protocol = value;
791         break;
792     case GET_IDLE:
793         ret = 1;
794         data[0] = s->idle;
795         break;
796     case SET_IDLE:
797         s->idle = (uint8_t) (value >> 8);
798         ret = 0;
799         break;
800     default:
801     fail:
802         ret = USB_RET_STALL;
803         break;
804     }
805     return ret;
806 }
807 
usb_hid_handle_data(USBDevice * dev,USBPacket * p)808 static int usb_hid_handle_data(USBDevice *dev, USBPacket *p)
809 {
810     USBHIDState *s = (USBHIDState *)dev;
811     int ret = 0;
812 
813     switch(p->pid) {
814     case USB_TOKEN_IN:
815         if (p->devep == 1) {
816             /* TODO: Implement finite idle delays.  */
817             if (!(s->changed || s->idle))
818                 return USB_RET_NAK;
819             s->changed = 0;
820             if (s->kind == USB_MOUSE)
821                 ret = usb_mouse_poll(s, p->data, p->len);
822             else if (s->kind == USB_TABLET)
823                 ret = usb_tablet_poll(s, p->data, p->len);
824             else if (s->kind == USB_KEYBOARD)
825                 ret = usb_keyboard_poll(&s->kbd, p->data, p->len);
826         } else {
827             goto fail;
828         }
829         break;
830     case USB_TOKEN_OUT:
831     default:
832     fail:
833         ret = USB_RET_STALL;
834         break;
835     }
836     return ret;
837 }
838 
usb_hid_handle_destroy(USBDevice * dev)839 static void usb_hid_handle_destroy(USBDevice *dev)
840 {
841     USBHIDState *s = (USBHIDState *)dev;
842 
843     if (s->kind != USB_KEYBOARD)
844         qemu_remove_mouse_event_handler(s->ptr.eh_entry);
845     /* TODO: else */
846     qemu_free(s);
847 }
848 
usb_tablet_init(void)849 USBDevice *usb_tablet_init(void)
850 {
851     USBHIDState *s;
852 
853     s = qemu_mallocz(sizeof(USBHIDState));
854     s->dev.speed = USB_SPEED_FULL;
855     s->dev.handle_packet = usb_generic_handle_packet;
856 
857     s->dev.handle_reset = usb_mouse_handle_reset;
858     s->dev.handle_control = usb_hid_handle_control;
859     s->dev.handle_data = usb_hid_handle_data;
860     s->dev.handle_destroy = usb_hid_handle_destroy;
861     s->kind = USB_TABLET;
862     /* Force poll routine to be run and grab input the first time.  */
863     s->changed = 1;
864 
865     pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Tablet");
866 
867     return (USBDevice *)s;
868 }
869 
usb_mouse_init(void)870 USBDevice *usb_mouse_init(void)
871 {
872     USBHIDState *s;
873 
874     s = qemu_mallocz(sizeof(USBHIDState));
875     s->dev.speed = USB_SPEED_FULL;
876     s->dev.handle_packet = usb_generic_handle_packet;
877 
878     s->dev.handle_reset = usb_mouse_handle_reset;
879     s->dev.handle_control = usb_hid_handle_control;
880     s->dev.handle_data = usb_hid_handle_data;
881     s->dev.handle_destroy = usb_hid_handle_destroy;
882     s->kind = USB_MOUSE;
883     /* Force poll routine to be run and grab input the first time.  */
884     s->changed = 1;
885 
886     pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Mouse");
887 
888     return (USBDevice *)s;
889 }
890 
usb_keyboard_init(void)891 USBDevice *usb_keyboard_init(void)
892 {
893     USBHIDState *s;
894 
895     s = qemu_mallocz(sizeof(USBHIDState));
896     s->dev.speed = USB_SPEED_FULL;
897     s->dev.handle_packet = usb_generic_handle_packet;
898 
899     s->dev.handle_reset = usb_keyboard_handle_reset;
900     s->dev.handle_control = usb_hid_handle_control;
901     s->dev.handle_data = usb_hid_handle_data;
902     s->dev.handle_destroy = usb_hid_handle_destroy;
903     s->kind = USB_KEYBOARD;
904 
905     pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Keyboard");
906 
907     return (USBDevice *) s;
908 }
909 
usb_hid_datain_cb(USBDevice * dev,void * opaque,void (* datain)(void *))910 void usb_hid_datain_cb(USBDevice *dev, void *opaque, void (*datain)(void *))
911 {
912     USBHIDState *s = (USBHIDState *)dev;
913 
914     s->datain_opaque = opaque;
915     s->datain = datain;
916 }
917