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