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