qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

dev-hid.c (29043B)


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