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