dev-hid.c 28 KB

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