xref: /qemu/hw/usb/dev-hid.c (revision e3a6e0da)
1 /*
2  * QEMU USB HID devices
3  *
4  * Copyright (c) 2005 Fabrice Bellard
5  * Copyright (c) 2007 OpenMoko, Inc.  (andrew@openedhand.com)
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy
8  * of this software and associated documentation files (the "Software"), to deal
9  * in the Software without restriction, including without limitation the rights
10  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11  * copies of the Software, and to permit persons to whom the Software is
12  * furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in
15  * all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23  * THE SOFTWARE.
24  */
25 
26 #include "qemu/osdep.h"
27 #include "ui/console.h"
28 #include "hw/usb.h"
29 #include "migration/vmstate.h"
30 #include "desc.h"
31 #include "qapi/error.h"
32 #include "qemu/module.h"
33 #include "qemu/timer.h"
34 #include "hw/input/hid.h"
35 #include "hw/usb/hid.h"
36 #include "hw/qdev-properties.h"
37 #include "qom/object.h"
38 
39 struct USBHIDState {
40     USBDevice dev;
41     USBEndpoint *intr;
42     HIDState hid;
43     uint32_t usb_version;
44     char *display;
45     uint32_t head;
46 };
47 typedef struct USBHIDState USBHIDState;
48 
49 #define TYPE_USB_HID "usb-hid"
50 DECLARE_INSTANCE_CHECKER(USBHIDState, USB_HID,
51                          TYPE_USB_HID)
52 
53 enum {
54     STR_MANUFACTURER = 1,
55     STR_PRODUCT_MOUSE,
56     STR_PRODUCT_TABLET,
57     STR_PRODUCT_KEYBOARD,
58     STR_SERIAL_COMPAT,
59     STR_CONFIG_MOUSE,
60     STR_CONFIG_TABLET,
61     STR_CONFIG_KEYBOARD,
62     STR_SERIAL_MOUSE,
63     STR_SERIAL_TABLET,
64     STR_SERIAL_KEYBOARD,
65 };
66 
67 static const USBDescStrings desc_strings = {
68     [STR_MANUFACTURER]     = "QEMU",
69     [STR_PRODUCT_MOUSE]    = "QEMU USB Mouse",
70     [STR_PRODUCT_TABLET]   = "QEMU USB Tablet",
71     [STR_PRODUCT_KEYBOARD] = "QEMU USB Keyboard",
72     [STR_SERIAL_COMPAT]    = "42",
73     [STR_CONFIG_MOUSE]     = "HID Mouse",
74     [STR_CONFIG_TABLET]    = "HID Tablet",
75     [STR_CONFIG_KEYBOARD]  = "HID Keyboard",
76     [STR_SERIAL_MOUSE]     = "89126",
77     [STR_SERIAL_TABLET]    = "28754",
78     [STR_SERIAL_KEYBOARD]  = "68284",
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_SERIAL_MOUSE,
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_SERIAL_MOUSE,
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_SERIAL_TABLET,
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_SERIAL_TABLET,
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_SERIAL_KEYBOARD,
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_SERIAL_KEYBOARD,
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 HID_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 HID_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 HID_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 HID_SET_PROTOCOL:
634         if (hs->kind != HID_KEYBOARD && hs->kind != HID_MOUSE) {
635             goto fail;
636         }
637         hs->protocol = value;
638         break;
639     case HID_GET_IDLE:
640         data[0] = hs->idle;
641         p->actual_length = 1;
642         break;
643     case HID_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)
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     usb_desc_create_serial(dev);
722     usb_desc_init(dev);
723     us->intr = usb_ep_get(dev, USB_TOKEN_IN, 1);
724     hid_init(&us->hid, kind, usb_hid_changed);
725     if (us->display && us->hid.s) {
726         qemu_input_handler_bind(us->hid.s, us->display, us->head, NULL);
727     }
728 }
729 
730 static void usb_tablet_realize(USBDevice *dev, Error **errp)
731 {
732 
733     usb_hid_initfn(dev, HID_TABLET, &desc_tablet, &desc_tablet2, errp);
734 }
735 
736 static void usb_mouse_realize(USBDevice *dev, Error **errp)
737 {
738     usb_hid_initfn(dev, HID_MOUSE, &desc_mouse, &desc_mouse2, errp);
739 }
740 
741 static void usb_keyboard_realize(USBDevice *dev, Error **errp)
742 {
743     usb_hid_initfn(dev, HID_KEYBOARD, &desc_keyboard, &desc_keyboard2, errp);
744 }
745 
746 static int usb_ptr_post_load(void *opaque, int version_id)
747 {
748     USBHIDState *s = opaque;
749 
750     if (s->dev.remote_wakeup) {
751         hid_pointer_activate(&s->hid);
752     }
753     return 0;
754 }
755 
756 static const VMStateDescription vmstate_usb_ptr = {
757     .name = "usb-ptr",
758     .version_id = 1,
759     .minimum_version_id = 1,
760     .post_load = usb_ptr_post_load,
761     .fields = (VMStateField[]) {
762         VMSTATE_USB_DEVICE(dev, USBHIDState),
763         VMSTATE_HID_POINTER_DEVICE(hid, USBHIDState),
764         VMSTATE_END_OF_LIST()
765     }
766 };
767 
768 static const VMStateDescription vmstate_usb_kbd = {
769     .name = "usb-kbd",
770     .version_id = 1,
771     .minimum_version_id = 1,
772     .fields = (VMStateField[]) {
773         VMSTATE_USB_DEVICE(dev, USBHIDState),
774         VMSTATE_HID_KEYBOARD_DEVICE(hid, USBHIDState),
775         VMSTATE_END_OF_LIST()
776     }
777 };
778 
779 static void usb_hid_class_initfn(ObjectClass *klass, void *data)
780 {
781     USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
782 
783     uc->handle_reset   = usb_hid_handle_reset;
784     uc->handle_control = usb_hid_handle_control;
785     uc->handle_data    = usb_hid_handle_data;
786     uc->unrealize      = usb_hid_unrealize;
787     uc->handle_attach  = usb_desc_attach;
788 }
789 
790 static const TypeInfo usb_hid_type_info = {
791     .name = TYPE_USB_HID,
792     .parent = TYPE_USB_DEVICE,
793     .instance_size = sizeof(USBHIDState),
794     .abstract = true,
795     .class_init = usb_hid_class_initfn,
796 };
797 
798 static Property usb_tablet_properties[] = {
799         DEFINE_PROP_UINT32("usb_version", USBHIDState, usb_version, 2),
800         DEFINE_PROP_STRING("display", USBHIDState, display),
801         DEFINE_PROP_UINT32("head", USBHIDState, head, 0),
802         DEFINE_PROP_END_OF_LIST(),
803 };
804 
805 static void usb_tablet_class_initfn(ObjectClass *klass, void *data)
806 {
807     DeviceClass *dc = DEVICE_CLASS(klass);
808     USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
809 
810     uc->realize        = usb_tablet_realize;
811     uc->product_desc   = "QEMU USB Tablet";
812     dc->vmsd = &vmstate_usb_ptr;
813     device_class_set_props(dc, usb_tablet_properties);
814     set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
815 }
816 
817 static const TypeInfo usb_tablet_info = {
818     .name          = "usb-tablet",
819     .parent        = TYPE_USB_HID,
820     .class_init    = usb_tablet_class_initfn,
821 };
822 
823 static Property usb_mouse_properties[] = {
824         DEFINE_PROP_UINT32("usb_version", USBHIDState, usb_version, 2),
825         DEFINE_PROP_END_OF_LIST(),
826 };
827 
828 static void usb_mouse_class_initfn(ObjectClass *klass, void *data)
829 {
830     DeviceClass *dc = DEVICE_CLASS(klass);
831     USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
832 
833     uc->realize        = usb_mouse_realize;
834     uc->product_desc   = "QEMU USB Mouse";
835     dc->vmsd = &vmstate_usb_ptr;
836     device_class_set_props(dc, usb_mouse_properties);
837     set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
838 }
839 
840 static const TypeInfo usb_mouse_info = {
841     .name          = "usb-mouse",
842     .parent        = TYPE_USB_HID,
843     .class_init    = usb_mouse_class_initfn,
844 };
845 
846 static Property usb_keyboard_properties[] = {
847         DEFINE_PROP_UINT32("usb_version", USBHIDState, usb_version, 2),
848         DEFINE_PROP_STRING("display", USBHIDState, display),
849         DEFINE_PROP_END_OF_LIST(),
850 };
851 
852 static void usb_keyboard_class_initfn(ObjectClass *klass, void *data)
853 {
854     DeviceClass *dc = DEVICE_CLASS(klass);
855     USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
856 
857     uc->realize        = usb_keyboard_realize;
858     uc->product_desc   = "QEMU USB Keyboard";
859     dc->vmsd = &vmstate_usb_kbd;
860     device_class_set_props(dc, usb_keyboard_properties);
861     set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
862 }
863 
864 static const TypeInfo usb_keyboard_info = {
865     .name          = "usb-kbd",
866     .parent        = TYPE_USB_HID,
867     .class_init    = usb_keyboard_class_initfn,
868 };
869 
870 static void usb_hid_register_types(void)
871 {
872     type_register_static(&usb_hid_type_info);
873     type_register_static(&usb_tablet_info);
874     usb_legacy_register("usb-tablet", "tablet", NULL);
875     type_register_static(&usb_mouse_info);
876     usb_legacy_register("usb-mouse", "mouse", NULL);
877     type_register_static(&usb_keyboard_info);
878     usb_legacy_register("usb-kbd", "keyboard", NULL);
879 }
880 
881 type_init(usb_hid_register_types)
882