xref: /qemu/hw/usb/dev-hid.c (revision 12b35405)
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 
26 #include "qemu/osdep.h"
27 #include "ui/console.h"
28 #include "hw/usb.h"
29 #include "migration/vmstate.h"
30 #include "desc.h"
31 #include "qapi/error.h"
32 #include "qemu/module.h"
33 #include "qemu/timer.h"
34 #include "hw/input/hid.h"
35 #include "hw/qdev-properties.h"
36 
37 /* HID interface requests */
38 #define GET_REPORT   0xa101
39 #define GET_IDLE     0xa102
40 #define GET_PROTOCOL 0xa103
41 #define SET_REPORT   0x2109
42 #define SET_IDLE     0x210a
43 #define SET_PROTOCOL 0x210b
44 
45 /* HID descriptor types */
46 #define USB_DT_HID    0x21
47 #define USB_DT_REPORT 0x22
48 #define USB_DT_PHY    0x23
49 
50 typedef struct USBHIDState {
51     USBDevice dev;
52     USBEndpoint *intr;
53     HIDState hid;
54     uint32_t usb_version;
55     char *display;
56     uint32_t head;
57 } USBHIDState;
58 
59 #define TYPE_USB_HID "usb-hid"
60 #define USB_HID(obj) OBJECT_CHECK(USBHIDState, (obj), TYPE_USB_HID)
61 
62 enum {
63     STR_MANUFACTURER = 1,
64     STR_PRODUCT_MOUSE,
65     STR_PRODUCT_TABLET,
66     STR_PRODUCT_KEYBOARD,
67     STR_SERIAL_COMPAT,
68     STR_CONFIG_MOUSE,
69     STR_CONFIG_TABLET,
70     STR_CONFIG_KEYBOARD,
71     STR_SERIAL_MOUSE,
72     STR_SERIAL_TABLET,
73     STR_SERIAL_KEYBOARD,
74 };
75 
76 static const USBDescStrings desc_strings = {
77     [STR_MANUFACTURER]     = "QEMU",
78     [STR_PRODUCT_MOUSE]    = "QEMU USB Mouse",
79     [STR_PRODUCT_TABLET]   = "QEMU USB Tablet",
80     [STR_PRODUCT_KEYBOARD] = "QEMU USB Keyboard",
81     [STR_SERIAL_COMPAT]    = "42",
82     [STR_CONFIG_MOUSE]     = "HID Mouse",
83     [STR_CONFIG_TABLET]    = "HID Tablet",
84     [STR_CONFIG_KEYBOARD]  = "HID Keyboard",
85     [STR_SERIAL_MOUSE]     = "89126",
86     [STR_SERIAL_TABLET]    = "28754",
87     [STR_SERIAL_KEYBOARD]  = "68284",
88 };
89 
90 static const USBDescIface desc_iface_mouse = {
91     .bInterfaceNumber              = 0,
92     .bNumEndpoints                 = 1,
93     .bInterfaceClass               = USB_CLASS_HID,
94     .bInterfaceSubClass            = 0x01, /* boot */
95     .bInterfaceProtocol            = 0x02,
96     .ndesc                         = 1,
97     .descs = (USBDescOther[]) {
98         {
99             /* HID descriptor */
100             .data = (uint8_t[]) {
101                 0x09,          /*  u8  bLength */
102                 USB_DT_HID,    /*  u8  bDescriptorType */
103                 0x01, 0x00,    /*  u16 HID_class */
104                 0x00,          /*  u8  country_code */
105                 0x01,          /*  u8  num_descriptors */
106                 USB_DT_REPORT, /*  u8  type: Report */
107                 52, 0,         /*  u16 len */
108             },
109         },
110     },
111     .eps = (USBDescEndpoint[]) {
112         {
113             .bEndpointAddress      = USB_DIR_IN | 0x01,
114             .bmAttributes          = USB_ENDPOINT_XFER_INT,
115             .wMaxPacketSize        = 4,
116             .bInterval             = 0x0a,
117         },
118     },
119 };
120 
121 static const USBDescIface desc_iface_mouse2 = {
122     .bInterfaceNumber              = 0,
123     .bNumEndpoints                 = 1,
124     .bInterfaceClass               = USB_CLASS_HID,
125     .bInterfaceSubClass            = 0x01, /* boot */
126     .bInterfaceProtocol            = 0x02,
127     .ndesc                         = 1,
128     .descs = (USBDescOther[]) {
129         {
130             /* HID descriptor */
131             .data = (uint8_t[]) {
132                 0x09,          /*  u8  bLength */
133                 USB_DT_HID,    /*  u8  bDescriptorType */
134                 0x01, 0x00,    /*  u16 HID_class */
135                 0x00,          /*  u8  country_code */
136                 0x01,          /*  u8  num_descriptors */
137                 USB_DT_REPORT, /*  u8  type: Report */
138                 52, 0,         /*  u16 len */
139             },
140         },
141     },
142     .eps = (USBDescEndpoint[]) {
143         {
144             .bEndpointAddress      = USB_DIR_IN | 0x01,
145             .bmAttributes          = USB_ENDPOINT_XFER_INT,
146             .wMaxPacketSize        = 4,
147             .bInterval             = 7, /* 2 ^ (8-1) * 125 usecs = 8 ms */
148         },
149     },
150 };
151 
152 static const USBDescIface desc_iface_tablet = {
153     .bInterfaceNumber              = 0,
154     .bNumEndpoints                 = 1,
155     .bInterfaceClass               = USB_CLASS_HID,
156     .bInterfaceProtocol            = 0x00,
157     .ndesc                         = 1,
158     .descs = (USBDescOther[]) {
159         {
160             /* HID descriptor */
161             .data = (uint8_t[]) {
162                 0x09,          /*  u8  bLength */
163                 USB_DT_HID,    /*  u8  bDescriptorType */
164                 0x01, 0x00,    /*  u16 HID_class */
165                 0x00,          /*  u8  country_code */
166                 0x01,          /*  u8  num_descriptors */
167                 USB_DT_REPORT, /*  u8  type: Report */
168                 74, 0,         /*  u16 len */
169             },
170         },
171     },
172     .eps = (USBDescEndpoint[]) {
173         {
174             .bEndpointAddress      = USB_DIR_IN | 0x01,
175             .bmAttributes          = USB_ENDPOINT_XFER_INT,
176             .wMaxPacketSize        = 8,
177             .bInterval             = 0x0a,
178         },
179     },
180 };
181 
182 static const USBDescIface desc_iface_tablet2 = {
183     .bInterfaceNumber              = 0,
184     .bNumEndpoints                 = 1,
185     .bInterfaceClass               = USB_CLASS_HID,
186     .bInterfaceProtocol            = 0x00,
187     .ndesc                         = 1,
188     .descs = (USBDescOther[]) {
189         {
190             /* HID descriptor */
191             .data = (uint8_t[]) {
192                 0x09,          /*  u8  bLength */
193                 USB_DT_HID,    /*  u8  bDescriptorType */
194                 0x01, 0x00,    /*  u16 HID_class */
195                 0x00,          /*  u8  country_code */
196                 0x01,          /*  u8  num_descriptors */
197                 USB_DT_REPORT, /*  u8  type: Report */
198                 74, 0,         /*  u16 len */
199             },
200         },
201     },
202     .eps = (USBDescEndpoint[]) {
203         {
204             .bEndpointAddress      = USB_DIR_IN | 0x01,
205             .bmAttributes          = USB_ENDPOINT_XFER_INT,
206             .wMaxPacketSize        = 8,
207             .bInterval             = 4, /* 2 ^ (4-1) * 125 usecs = 1 ms */
208         },
209     },
210 };
211 
212 static const USBDescIface desc_iface_keyboard = {
213     .bInterfaceNumber              = 0,
214     .bNumEndpoints                 = 1,
215     .bInterfaceClass               = USB_CLASS_HID,
216     .bInterfaceSubClass            = 0x01, /* boot */
217     .bInterfaceProtocol            = 0x01, /* keyboard */
218     .ndesc                         = 1,
219     .descs = (USBDescOther[]) {
220         {
221             /* HID descriptor */
222             .data = (uint8_t[]) {
223                 0x09,          /*  u8  bLength */
224                 USB_DT_HID,    /*  u8  bDescriptorType */
225                 0x11, 0x01,    /*  u16 HID_class */
226                 0x00,          /*  u8  country_code */
227                 0x01,          /*  u8  num_descriptors */
228                 USB_DT_REPORT, /*  u8  type: Report */
229                 0x3f, 0,       /*  u16 len */
230             },
231         },
232     },
233     .eps = (USBDescEndpoint[]) {
234         {
235             .bEndpointAddress      = USB_DIR_IN | 0x01,
236             .bmAttributes          = USB_ENDPOINT_XFER_INT,
237             .wMaxPacketSize        = 8,
238             .bInterval             = 0x0a,
239         },
240     },
241 };
242 
243 static const USBDescIface desc_iface_keyboard2 = {
244     .bInterfaceNumber              = 0,
245     .bNumEndpoints                 = 1,
246     .bInterfaceClass               = USB_CLASS_HID,
247     .bInterfaceSubClass            = 0x01, /* boot */
248     .bInterfaceProtocol            = 0x01, /* keyboard */
249     .ndesc                         = 1,
250     .descs = (USBDescOther[]) {
251         {
252             /* HID descriptor */
253             .data = (uint8_t[]) {
254                 0x09,          /*  u8  bLength */
255                 USB_DT_HID,    /*  u8  bDescriptorType */
256                 0x11, 0x01,    /*  u16 HID_class */
257                 0x00,          /*  u8  country_code */
258                 0x01,          /*  u8  num_descriptors */
259                 USB_DT_REPORT, /*  u8  type: Report */
260                 0x3f, 0,       /*  u16 len */
261             },
262         },
263     },
264     .eps = (USBDescEndpoint[]) {
265         {
266             .bEndpointAddress      = USB_DIR_IN | 0x01,
267             .bmAttributes          = USB_ENDPOINT_XFER_INT,
268             .wMaxPacketSize        = 8,
269             .bInterval             = 7, /* 2 ^ (8-1) * 125 usecs = 8 ms */
270         },
271     },
272 };
273 
274 static const USBDescDevice desc_device_mouse = {
275     .bcdUSB                        = 0x0100,
276     .bMaxPacketSize0               = 8,
277     .bNumConfigurations            = 1,
278     .confs = (USBDescConfig[]) {
279         {
280             .bNumInterfaces        = 1,
281             .bConfigurationValue   = 1,
282             .iConfiguration        = STR_CONFIG_MOUSE,
283             .bmAttributes          = USB_CFG_ATT_ONE | USB_CFG_ATT_WAKEUP,
284             .bMaxPower             = 50,
285             .nif = 1,
286             .ifs = &desc_iface_mouse,
287         },
288     },
289 };
290 
291 static const USBDescDevice desc_device_mouse2 = {
292     .bcdUSB                        = 0x0200,
293     .bMaxPacketSize0               = 64,
294     .bNumConfigurations            = 1,
295     .confs = (USBDescConfig[]) {
296         {
297             .bNumInterfaces        = 1,
298             .bConfigurationValue   = 1,
299             .iConfiguration        = STR_CONFIG_MOUSE,
300             .bmAttributes          = USB_CFG_ATT_ONE | USB_CFG_ATT_WAKEUP,
301             .bMaxPower             = 50,
302             .nif = 1,
303             .ifs = &desc_iface_mouse2,
304         },
305     },
306 };
307 
308 static const USBDescDevice desc_device_tablet = {
309     .bcdUSB                        = 0x0100,
310     .bMaxPacketSize0               = 8,
311     .bNumConfigurations            = 1,
312     .confs = (USBDescConfig[]) {
313         {
314             .bNumInterfaces        = 1,
315             .bConfigurationValue   = 1,
316             .iConfiguration        = STR_CONFIG_TABLET,
317             .bmAttributes          = USB_CFG_ATT_ONE | USB_CFG_ATT_WAKEUP,
318             .bMaxPower             = 50,
319             .nif = 1,
320             .ifs = &desc_iface_tablet,
321         },
322     },
323 };
324 
325 static const USBDescDevice desc_device_tablet2 = {
326     .bcdUSB                        = 0x0200,
327     .bMaxPacketSize0               = 64,
328     .bNumConfigurations            = 1,
329     .confs = (USBDescConfig[]) {
330         {
331             .bNumInterfaces        = 1,
332             .bConfigurationValue   = 1,
333             .iConfiguration        = STR_CONFIG_TABLET,
334             .bmAttributes          = USB_CFG_ATT_ONE | USB_CFG_ATT_WAKEUP,
335             .bMaxPower             = 50,
336             .nif = 1,
337             .ifs = &desc_iface_tablet2,
338         },
339     },
340 };
341 
342 static const USBDescDevice desc_device_keyboard = {
343     .bcdUSB                        = 0x0100,
344     .bMaxPacketSize0               = 8,
345     .bNumConfigurations            = 1,
346     .confs = (USBDescConfig[]) {
347         {
348             .bNumInterfaces        = 1,
349             .bConfigurationValue   = 1,
350             .iConfiguration        = STR_CONFIG_KEYBOARD,
351             .bmAttributes          = USB_CFG_ATT_ONE | USB_CFG_ATT_WAKEUP,
352             .bMaxPower             = 50,
353             .nif = 1,
354             .ifs = &desc_iface_keyboard,
355         },
356     },
357 };
358 
359 static const USBDescDevice desc_device_keyboard2 = {
360     .bcdUSB                        = 0x0200,
361     .bMaxPacketSize0               = 64,
362     .bNumConfigurations            = 1,
363     .confs = (USBDescConfig[]) {
364         {
365             .bNumInterfaces        = 1,
366             .bConfigurationValue   = 1,
367             .iConfiguration        = STR_CONFIG_KEYBOARD,
368             .bmAttributes          = USB_CFG_ATT_ONE | USB_CFG_ATT_WAKEUP,
369             .bMaxPower             = 50,
370             .nif = 1,
371             .ifs = &desc_iface_keyboard2,
372         },
373     },
374 };
375 
376 static const USBDescMSOS desc_msos_suspend = {
377     .SelectiveSuspendEnabled = true,
378 };
379 
380 static const USBDesc desc_mouse = {
381     .id = {
382         .idVendor          = 0x0627,
383         .idProduct         = 0x0001,
384         .bcdDevice         = 0,
385         .iManufacturer     = STR_MANUFACTURER,
386         .iProduct          = STR_PRODUCT_MOUSE,
387         .iSerialNumber     = STR_SERIAL_MOUSE,
388     },
389     .full = &desc_device_mouse,
390     .str  = desc_strings,
391     .msos = &desc_msos_suspend,
392 };
393 
394 static const USBDesc desc_mouse2 = {
395     .id = {
396         .idVendor          = 0x0627,
397         .idProduct         = 0x0001,
398         .bcdDevice         = 0,
399         .iManufacturer     = STR_MANUFACTURER,
400         .iProduct          = STR_PRODUCT_MOUSE,
401         .iSerialNumber     = STR_SERIAL_MOUSE,
402     },
403     .full = &desc_device_mouse,
404     .high = &desc_device_mouse2,
405     .str  = desc_strings,
406     .msos = &desc_msos_suspend,
407 };
408 
409 static const USBDesc desc_tablet = {
410     .id = {
411         .idVendor          = 0x0627,
412         .idProduct         = 0x0001,
413         .bcdDevice         = 0,
414         .iManufacturer     = STR_MANUFACTURER,
415         .iProduct          = STR_PRODUCT_TABLET,
416         .iSerialNumber     = STR_SERIAL_TABLET,
417     },
418     .full = &desc_device_tablet,
419     .str  = desc_strings,
420     .msos = &desc_msos_suspend,
421 };
422 
423 static const USBDesc desc_tablet2 = {
424     .id = {
425         .idVendor          = 0x0627,
426         .idProduct         = 0x0001,
427         .bcdDevice         = 0,
428         .iManufacturer     = STR_MANUFACTURER,
429         .iProduct          = STR_PRODUCT_TABLET,
430         .iSerialNumber     = STR_SERIAL_TABLET,
431     },
432     .full = &desc_device_tablet,
433     .high = &desc_device_tablet2,
434     .str  = desc_strings,
435     .msos = &desc_msos_suspend,
436 };
437 
438 static const USBDesc desc_keyboard = {
439     .id = {
440         .idVendor          = 0x0627,
441         .idProduct         = 0x0001,
442         .bcdDevice         = 0,
443         .iManufacturer     = STR_MANUFACTURER,
444         .iProduct          = STR_PRODUCT_KEYBOARD,
445         .iSerialNumber     = STR_SERIAL_KEYBOARD,
446     },
447     .full = &desc_device_keyboard,
448     .str  = desc_strings,
449     .msos = &desc_msos_suspend,
450 };
451 
452 static const USBDesc desc_keyboard2 = {
453     .id = {
454         .idVendor          = 0x0627,
455         .idProduct         = 0x0001,
456         .bcdDevice         = 0,
457         .iManufacturer     = STR_MANUFACTURER,
458         .iProduct          = STR_PRODUCT_KEYBOARD,
459         .iSerialNumber     = STR_SERIAL_KEYBOARD,
460     },
461     .full = &desc_device_keyboard,
462     .high = &desc_device_keyboard2,
463     .str  = desc_strings,
464     .msos = &desc_msos_suspend,
465 };
466 
467 static const uint8_t qemu_mouse_hid_report_descriptor[] = {
468     0x05, 0x01,		/* Usage Page (Generic Desktop) */
469     0x09, 0x02,		/* Usage (Mouse) */
470     0xa1, 0x01,		/* Collection (Application) */
471     0x09, 0x01,		/*   Usage (Pointer) */
472     0xa1, 0x00,		/*   Collection (Physical) */
473     0x05, 0x09,		/*     Usage Page (Button) */
474     0x19, 0x01,		/*     Usage Minimum (1) */
475     0x29, 0x03,		/*     Usage Maximum (3) */
476     0x15, 0x00,		/*     Logical Minimum (0) */
477     0x25, 0x01,		/*     Logical Maximum (1) */
478     0x95, 0x03,		/*     Report Count (3) */
479     0x75, 0x01,		/*     Report Size (1) */
480     0x81, 0x02,		/*     Input (Data, Variable, Absolute) */
481     0x95, 0x01,		/*     Report Count (1) */
482     0x75, 0x05,		/*     Report Size (5) */
483     0x81, 0x01,		/*     Input (Constant) */
484     0x05, 0x01,		/*     Usage Page (Generic Desktop) */
485     0x09, 0x30,		/*     Usage (X) */
486     0x09, 0x31,		/*     Usage (Y) */
487     0x09, 0x38,		/*     Usage (Wheel) */
488     0x15, 0x81,		/*     Logical Minimum (-0x7f) */
489     0x25, 0x7f,		/*     Logical Maximum (0x7f) */
490     0x75, 0x08,		/*     Report Size (8) */
491     0x95, 0x03,		/*     Report Count (3) */
492     0x81, 0x06,		/*     Input (Data, Variable, Relative) */
493     0xc0,		/*   End Collection */
494     0xc0,		/* End Collection */
495 };
496 
497 static const uint8_t qemu_tablet_hid_report_descriptor[] = {
498     0x05, 0x01,		/* Usage Page (Generic Desktop) */
499     0x09, 0x02,		/* Usage (Mouse) */
500     0xa1, 0x01,		/* Collection (Application) */
501     0x09, 0x01,		/*   Usage (Pointer) */
502     0xa1, 0x00,		/*   Collection (Physical) */
503     0x05, 0x09,		/*     Usage Page (Button) */
504     0x19, 0x01,		/*     Usage Minimum (1) */
505     0x29, 0x03,		/*     Usage Maximum (3) */
506     0x15, 0x00,		/*     Logical Minimum (0) */
507     0x25, 0x01,		/*     Logical Maximum (1) */
508     0x95, 0x03,		/*     Report Count (3) */
509     0x75, 0x01,		/*     Report Size (1) */
510     0x81, 0x02,		/*     Input (Data, Variable, Absolute) */
511     0x95, 0x01,		/*     Report Count (1) */
512     0x75, 0x05,		/*     Report Size (5) */
513     0x81, 0x01,		/*     Input (Constant) */
514     0x05, 0x01,		/*     Usage Page (Generic Desktop) */
515     0x09, 0x30,		/*     Usage (X) */
516     0x09, 0x31,		/*     Usage (Y) */
517     0x15, 0x00,		/*     Logical Minimum (0) */
518     0x26, 0xff, 0x7f,	/*     Logical Maximum (0x7fff) */
519     0x35, 0x00,		/*     Physical Minimum (0) */
520     0x46, 0xff, 0x7f,	/*     Physical Maximum (0x7fff) */
521     0x75, 0x10,		/*     Report Size (16) */
522     0x95, 0x02,		/*     Report Count (2) */
523     0x81, 0x02,		/*     Input (Data, Variable, Absolute) */
524     0x05, 0x01,		/*     Usage Page (Generic Desktop) */
525     0x09, 0x38,		/*     Usage (Wheel) */
526     0x15, 0x81,		/*     Logical Minimum (-0x7f) */
527     0x25, 0x7f,		/*     Logical Maximum (0x7f) */
528     0x35, 0x00,		/*     Physical Minimum (same as logical) */
529     0x45, 0x00,		/*     Physical Maximum (same as logical) */
530     0x75, 0x08,		/*     Report Size (8) */
531     0x95, 0x01,		/*     Report Count (1) */
532     0x81, 0x06,		/*     Input (Data, Variable, Relative) */
533     0xc0,		/*   End Collection */
534     0xc0,		/* End Collection */
535 };
536 
537 static const uint8_t qemu_keyboard_hid_report_descriptor[] = {
538     0x05, 0x01,		/* Usage Page (Generic Desktop) */
539     0x09, 0x06,		/* Usage (Keyboard) */
540     0xa1, 0x01,		/* Collection (Application) */
541     0x75, 0x01,		/*   Report Size (1) */
542     0x95, 0x08,		/*   Report Count (8) */
543     0x05, 0x07,		/*   Usage Page (Key Codes) */
544     0x19, 0xe0,		/*   Usage Minimum (224) */
545     0x29, 0xe7,		/*   Usage Maximum (231) */
546     0x15, 0x00,		/*   Logical Minimum (0) */
547     0x25, 0x01,		/*   Logical Maximum (1) */
548     0x81, 0x02,		/*   Input (Data, Variable, Absolute) */
549     0x95, 0x01,		/*   Report Count (1) */
550     0x75, 0x08,		/*   Report Size (8) */
551     0x81, 0x01,		/*   Input (Constant) */
552     0x95, 0x05,		/*   Report Count (5) */
553     0x75, 0x01,		/*   Report Size (1) */
554     0x05, 0x08,		/*   Usage Page (LEDs) */
555     0x19, 0x01,		/*   Usage Minimum (1) */
556     0x29, 0x05,		/*   Usage Maximum (5) */
557     0x91, 0x02,		/*   Output (Data, Variable, Absolute) */
558     0x95, 0x01,		/*   Report Count (1) */
559     0x75, 0x03,		/*   Report Size (3) */
560     0x91, 0x01,		/*   Output (Constant) */
561     0x95, 0x06,		/*   Report Count (6) */
562     0x75, 0x08,		/*   Report Size (8) */
563     0x15, 0x00,		/*   Logical Minimum (0) */
564     0x25, 0xff,		/*   Logical Maximum (255) */
565     0x05, 0x07,		/*   Usage Page (Key Codes) */
566     0x19, 0x00,		/*   Usage Minimum (0) */
567     0x29, 0xff,		/*   Usage Maximum (255) */
568     0x81, 0x00,		/*   Input (Data, Array) */
569     0xc0,		/* End Collection */
570 };
571 
572 static void usb_hid_changed(HIDState *hs)
573 {
574     USBHIDState *us = container_of(hs, USBHIDState, hid);
575 
576     usb_wakeup(us->intr, 0);
577 }
578 
579 static void usb_hid_handle_reset(USBDevice *dev)
580 {
581     USBHIDState *us = USB_HID(dev);
582 
583     hid_reset(&us->hid);
584 }
585 
586 static void usb_hid_handle_control(USBDevice *dev, USBPacket *p,
587                int request, int value, int index, int length, uint8_t *data)
588 {
589     USBHIDState *us = USB_HID(dev);
590     HIDState *hs = &us->hid;
591     int ret;
592 
593     ret = usb_desc_handle_control(dev, p, request, value, index, length, data);
594     if (ret >= 0) {
595         return;
596     }
597 
598     switch (request) {
599         /* hid specific requests */
600     case InterfaceRequest | USB_REQ_GET_DESCRIPTOR:
601         switch (value >> 8) {
602         case 0x22:
603             if (hs->kind == HID_MOUSE) {
604                 memcpy(data, qemu_mouse_hid_report_descriptor,
605                        sizeof(qemu_mouse_hid_report_descriptor));
606                 p->actual_length = sizeof(qemu_mouse_hid_report_descriptor);
607             } else if (hs->kind == HID_TABLET) {
608                 memcpy(data, qemu_tablet_hid_report_descriptor,
609                        sizeof(qemu_tablet_hid_report_descriptor));
610                 p->actual_length = sizeof(qemu_tablet_hid_report_descriptor);
611             } else if (hs->kind == HID_KEYBOARD) {
612                 memcpy(data, qemu_keyboard_hid_report_descriptor,
613                        sizeof(qemu_keyboard_hid_report_descriptor));
614                 p->actual_length = sizeof(qemu_keyboard_hid_report_descriptor);
615             }
616             break;
617         default:
618             goto fail;
619         }
620         break;
621     case GET_REPORT:
622         if (hs->kind == HID_MOUSE || hs->kind == HID_TABLET) {
623             p->actual_length = hid_pointer_poll(hs, data, length);
624         } else if (hs->kind == HID_KEYBOARD) {
625             p->actual_length = hid_keyboard_poll(hs, data, length);
626         }
627         break;
628     case SET_REPORT:
629         if (hs->kind == HID_KEYBOARD) {
630             p->actual_length = hid_keyboard_write(hs, data, length);
631         } else {
632             goto fail;
633         }
634         break;
635     case GET_PROTOCOL:
636         if (hs->kind != HID_KEYBOARD && hs->kind != HID_MOUSE) {
637             goto fail;
638         }
639         data[0] = hs->protocol;
640         p->actual_length = 1;
641         break;
642     case SET_PROTOCOL:
643         if (hs->kind != HID_KEYBOARD && hs->kind != HID_MOUSE) {
644             goto fail;
645         }
646         hs->protocol = value;
647         break;
648     case GET_IDLE:
649         data[0] = hs->idle;
650         p->actual_length = 1;
651         break;
652     case SET_IDLE:
653         hs->idle = (uint8_t) (value >> 8);
654         hid_set_next_idle(hs);
655         if (hs->kind == HID_MOUSE || hs->kind == HID_TABLET) {
656             hid_pointer_activate(hs);
657         }
658         break;
659     default:
660     fail:
661         p->status = USB_RET_STALL;
662         break;
663     }
664 }
665 
666 static void usb_hid_handle_data(USBDevice *dev, USBPacket *p)
667 {
668     USBHIDState *us = USB_HID(dev);
669     HIDState *hs = &us->hid;
670     uint8_t buf[p->iov.size];
671     int len = 0;
672 
673     switch (p->pid) {
674     case USB_TOKEN_IN:
675         if (p->ep->nr == 1) {
676             if (hs->kind == HID_MOUSE || hs->kind == HID_TABLET) {
677                 hid_pointer_activate(hs);
678             }
679             if (!hid_has_events(hs)) {
680                 p->status = USB_RET_NAK;
681                 return;
682             }
683             hid_set_next_idle(hs);
684             if (hs->kind == HID_MOUSE || hs->kind == HID_TABLET) {
685                 len = hid_pointer_poll(hs, buf, p->iov.size);
686             } else if (hs->kind == HID_KEYBOARD) {
687                 len = hid_keyboard_poll(hs, buf, p->iov.size);
688             }
689             usb_packet_copy(p, buf, len);
690         } else {
691             goto fail;
692         }
693         break;
694     case USB_TOKEN_OUT:
695     default:
696     fail:
697         p->status = USB_RET_STALL;
698         break;
699     }
700 }
701 
702 static void usb_hid_unrealize(USBDevice *dev)
703 {
704     USBHIDState *us = USB_HID(dev);
705 
706     hid_free(&us->hid);
707 }
708 
709 static void usb_hid_initfn(USBDevice *dev, int kind,
710                            const USBDesc *usb1, const USBDesc *usb2,
711                            Error **errp)
712 {
713     USBHIDState *us = USB_HID(dev);
714     switch (us->usb_version) {
715     case 1:
716         dev->usb_desc = usb1;
717         break;
718     case 2:
719         dev->usb_desc = usb2;
720         break;
721     default:
722         dev->usb_desc = NULL;
723     }
724     if (!dev->usb_desc) {
725         error_setg(errp, "Invalid usb version %d for usb hid device",
726                    us->usb_version);
727         return;
728     }
729 
730     usb_desc_create_serial(dev);
731     usb_desc_init(dev);
732     us->intr = usb_ep_get(dev, USB_TOKEN_IN, 1);
733     hid_init(&us->hid, kind, usb_hid_changed);
734     if (us->display && us->hid.s) {
735         qemu_input_handler_bind(us->hid.s, us->display, us->head, NULL);
736     }
737 }
738 
739 static void usb_tablet_realize(USBDevice *dev, Error **errp)
740 {
741 
742     usb_hid_initfn(dev, HID_TABLET, &desc_tablet, &desc_tablet2, errp);
743 }
744 
745 static void usb_mouse_realize(USBDevice *dev, Error **errp)
746 {
747     usb_hid_initfn(dev, HID_MOUSE, &desc_mouse, &desc_mouse2, errp);
748 }
749 
750 static void usb_keyboard_realize(USBDevice *dev, Error **errp)
751 {
752     usb_hid_initfn(dev, HID_KEYBOARD, &desc_keyboard, &desc_keyboard2, errp);
753 }
754 
755 static int usb_ptr_post_load(void *opaque, int version_id)
756 {
757     USBHIDState *s = opaque;
758 
759     if (s->dev.remote_wakeup) {
760         hid_pointer_activate(&s->hid);
761     }
762     return 0;
763 }
764 
765 static const VMStateDescription vmstate_usb_ptr = {
766     .name = "usb-ptr",
767     .version_id = 1,
768     .minimum_version_id = 1,
769     .post_load = usb_ptr_post_load,
770     .fields = (VMStateField[]) {
771         VMSTATE_USB_DEVICE(dev, USBHIDState),
772         VMSTATE_HID_POINTER_DEVICE(hid, USBHIDState),
773         VMSTATE_END_OF_LIST()
774     }
775 };
776 
777 static const VMStateDescription vmstate_usb_kbd = {
778     .name = "usb-kbd",
779     .version_id = 1,
780     .minimum_version_id = 1,
781     .fields = (VMStateField[]) {
782         VMSTATE_USB_DEVICE(dev, USBHIDState),
783         VMSTATE_HID_KEYBOARD_DEVICE(hid, USBHIDState),
784         VMSTATE_END_OF_LIST()
785     }
786 };
787 
788 static void usb_hid_class_initfn(ObjectClass *klass, void *data)
789 {
790     USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
791 
792     uc->handle_reset   = usb_hid_handle_reset;
793     uc->handle_control = usb_hid_handle_control;
794     uc->handle_data    = usb_hid_handle_data;
795     uc->unrealize      = usb_hid_unrealize;
796     uc->handle_attach  = usb_desc_attach;
797 }
798 
799 static const TypeInfo usb_hid_type_info = {
800     .name = TYPE_USB_HID,
801     .parent = TYPE_USB_DEVICE,
802     .instance_size = sizeof(USBHIDState),
803     .abstract = true,
804     .class_init = usb_hid_class_initfn,
805 };
806 
807 static Property usb_tablet_properties[] = {
808         DEFINE_PROP_UINT32("usb_version", USBHIDState, usb_version, 2),
809         DEFINE_PROP_STRING("display", USBHIDState, display),
810         DEFINE_PROP_UINT32("head", USBHIDState, head, 0),
811         DEFINE_PROP_END_OF_LIST(),
812 };
813 
814 static void usb_tablet_class_initfn(ObjectClass *klass, void *data)
815 {
816     DeviceClass *dc = DEVICE_CLASS(klass);
817     USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
818 
819     uc->realize        = usb_tablet_realize;
820     uc->product_desc   = "QEMU USB Tablet";
821     dc->vmsd = &vmstate_usb_ptr;
822     device_class_set_props(dc, usb_tablet_properties);
823     set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
824 }
825 
826 static const TypeInfo usb_tablet_info = {
827     .name          = "usb-tablet",
828     .parent        = TYPE_USB_HID,
829     .class_init    = usb_tablet_class_initfn,
830 };
831 
832 static Property usb_mouse_properties[] = {
833         DEFINE_PROP_UINT32("usb_version", USBHIDState, usb_version, 2),
834         DEFINE_PROP_END_OF_LIST(),
835 };
836 
837 static void usb_mouse_class_initfn(ObjectClass *klass, void *data)
838 {
839     DeviceClass *dc = DEVICE_CLASS(klass);
840     USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
841 
842     uc->realize        = usb_mouse_realize;
843     uc->product_desc   = "QEMU USB Mouse";
844     dc->vmsd = &vmstate_usb_ptr;
845     device_class_set_props(dc, usb_mouse_properties);
846     set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
847 }
848 
849 static const TypeInfo usb_mouse_info = {
850     .name          = "usb-mouse",
851     .parent        = TYPE_USB_HID,
852     .class_init    = usb_mouse_class_initfn,
853 };
854 
855 static Property usb_keyboard_properties[] = {
856         DEFINE_PROP_UINT32("usb_version", USBHIDState, usb_version, 2),
857         DEFINE_PROP_STRING("display", USBHIDState, display),
858         DEFINE_PROP_END_OF_LIST(),
859 };
860 
861 static void usb_keyboard_class_initfn(ObjectClass *klass, void *data)
862 {
863     DeviceClass *dc = DEVICE_CLASS(klass);
864     USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
865 
866     uc->realize        = usb_keyboard_realize;
867     uc->product_desc   = "QEMU USB Keyboard";
868     dc->vmsd = &vmstate_usb_kbd;
869     device_class_set_props(dc, usb_keyboard_properties);
870     set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
871 }
872 
873 static const TypeInfo usb_keyboard_info = {
874     .name          = "usb-kbd",
875     .parent        = TYPE_USB_HID,
876     .class_init    = usb_keyboard_class_initfn,
877 };
878 
879 static void usb_hid_register_types(void)
880 {
881     type_register_static(&usb_hid_type_info);
882     type_register_static(&usb_tablet_info);
883     usb_legacy_register("usb-tablet", "tablet", NULL);
884     type_register_static(&usb_mouse_info);
885     usb_legacy_register("usb-mouse", "mouse", NULL);
886     type_register_static(&usb_keyboard_info);
887     usb_legacy_register("usb-kbd", "keyboard", NULL);
888 }
889 
890 type_init(usb_hid_register_types)
891