dev-hid.c 29 KB

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