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