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