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