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