hid-hyperv.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2009, Citrix Systems, Inc.
  4. * Copyright (c) 2010, Microsoft Corporation.
  5. * Copyright (c) 2011, Novell Inc.
  6. */
  7. #include <linux/init.h>
  8. #include <linux/module.h>
  9. #include <linux/device.h>
  10. #include <linux/completion.h>
  11. #include <linux/input.h>
  12. #include <linux/hid.h>
  13. #include <linux/hiddev.h>
  14. #include <linux/hyperv.h>
  15. struct hv_input_dev_info {
  16. unsigned int size;
  17. unsigned short vendor;
  18. unsigned short product;
  19. unsigned short version;
  20. unsigned short reserved[11];
  21. };
  22. /*
  23. * Current version
  24. *
  25. * History:
  26. * Beta, RC < 2008/1/22 1,0
  27. * RC > 2008/1/22 2,0
  28. */
  29. #define SYNTHHID_INPUT_VERSION_MAJOR 2
  30. #define SYNTHHID_INPUT_VERSION_MINOR 0
  31. #define SYNTHHID_INPUT_VERSION (SYNTHHID_INPUT_VERSION_MINOR | \
  32. (SYNTHHID_INPUT_VERSION_MAJOR << 16))
  33. #pragma pack(push, 1)
  34. /*
  35. * Message types in the synthetic input protocol
  36. */
  37. enum synthhid_msg_type {
  38. SYNTH_HID_PROTOCOL_REQUEST,
  39. SYNTH_HID_PROTOCOL_RESPONSE,
  40. SYNTH_HID_INITIAL_DEVICE_INFO,
  41. SYNTH_HID_INITIAL_DEVICE_INFO_ACK,
  42. SYNTH_HID_INPUT_REPORT,
  43. SYNTH_HID_MAX
  44. };
  45. /*
  46. * Basic message structures.
  47. */
  48. struct synthhid_msg_hdr {
  49. enum synthhid_msg_type type;
  50. u32 size;
  51. };
  52. union synthhid_version {
  53. struct {
  54. u16 minor_version;
  55. u16 major_version;
  56. };
  57. u32 version;
  58. };
  59. /*
  60. * Protocol messages
  61. */
  62. struct synthhid_protocol_request {
  63. struct synthhid_msg_hdr header;
  64. union synthhid_version version_requested;
  65. };
  66. struct synthhid_protocol_response {
  67. struct synthhid_msg_hdr header;
  68. union synthhid_version version_requested;
  69. unsigned char approved;
  70. };
  71. struct synthhid_device_info {
  72. struct synthhid_msg_hdr header;
  73. struct hv_input_dev_info hid_dev_info;
  74. struct hid_descriptor hid_descriptor;
  75. };
  76. struct synthhid_device_info_ack {
  77. struct synthhid_msg_hdr header;
  78. unsigned char reserved;
  79. };
  80. struct synthhid_input_report {
  81. struct synthhid_msg_hdr header;
  82. char buffer[];
  83. };
  84. #pragma pack(pop)
  85. #define INPUTVSC_SEND_RING_BUFFER_SIZE VMBUS_RING_SIZE(36 * 1024)
  86. #define INPUTVSC_RECV_RING_BUFFER_SIZE VMBUS_RING_SIZE(36 * 1024)
  87. enum pipe_prot_msg_type {
  88. PIPE_MESSAGE_INVALID,
  89. PIPE_MESSAGE_DATA,
  90. PIPE_MESSAGE_MAXIMUM
  91. };
  92. struct pipe_prt_msg {
  93. enum pipe_prot_msg_type type;
  94. u32 size;
  95. char data[];
  96. };
  97. struct mousevsc_prt_msg {
  98. enum pipe_prot_msg_type type;
  99. u32 size;
  100. union {
  101. struct synthhid_protocol_request request;
  102. struct synthhid_protocol_response response;
  103. struct synthhid_device_info_ack ack;
  104. };
  105. };
  106. /*
  107. * Represents an mousevsc device
  108. */
  109. struct mousevsc_dev {
  110. struct hv_device *device;
  111. bool init_complete;
  112. bool connected;
  113. struct mousevsc_prt_msg protocol_req;
  114. struct mousevsc_prt_msg protocol_resp;
  115. /* Synchronize the request/response if needed */
  116. struct completion wait_event;
  117. int dev_info_status;
  118. struct hid_descriptor *hid_desc;
  119. unsigned char *report_desc;
  120. u32 report_desc_size;
  121. struct hv_input_dev_info hid_dev_info;
  122. struct hid_device *hid_device;
  123. u8 input_buf[HID_MAX_BUFFER_SIZE];
  124. };
  125. static struct mousevsc_dev *mousevsc_alloc_device(struct hv_device *device)
  126. {
  127. struct mousevsc_dev *input_dev;
  128. input_dev = kzalloc(sizeof(struct mousevsc_dev), GFP_KERNEL);
  129. if (!input_dev)
  130. return NULL;
  131. input_dev->device = device;
  132. hv_set_drvdata(device, input_dev);
  133. init_completion(&input_dev->wait_event);
  134. input_dev->init_complete = false;
  135. return input_dev;
  136. }
  137. static void mousevsc_free_device(struct mousevsc_dev *device)
  138. {
  139. kfree(device->hid_desc);
  140. kfree(device->report_desc);
  141. hv_set_drvdata(device->device, NULL);
  142. kfree(device);
  143. }
  144. static void mousevsc_on_receive_device_info(struct mousevsc_dev *input_device,
  145. struct synthhid_device_info *device_info)
  146. {
  147. int ret = 0;
  148. struct hid_descriptor *desc;
  149. struct mousevsc_prt_msg ack;
  150. input_device->dev_info_status = -ENOMEM;
  151. input_device->hid_dev_info = device_info->hid_dev_info;
  152. desc = &device_info->hid_descriptor;
  153. if (desc->bLength == 0)
  154. goto cleanup;
  155. /* The pointer is not NULL when we resume from hibernation */
  156. kfree(input_device->hid_desc);
  157. input_device->hid_desc = kmemdup(desc, desc->bLength, GFP_ATOMIC);
  158. if (!input_device->hid_desc)
  159. goto cleanup;
  160. input_device->report_desc_size = le16_to_cpu(
  161. desc->rpt_desc.wDescriptorLength);
  162. if (input_device->report_desc_size == 0) {
  163. input_device->dev_info_status = -EINVAL;
  164. goto cleanup;
  165. }
  166. /* The pointer is not NULL when we resume from hibernation */
  167. kfree(input_device->report_desc);
  168. input_device->report_desc = kzalloc(input_device->report_desc_size,
  169. GFP_ATOMIC);
  170. if (!input_device->report_desc) {
  171. input_device->dev_info_status = -ENOMEM;
  172. goto cleanup;
  173. }
  174. memcpy(input_device->report_desc,
  175. ((unsigned char *)desc) + desc->bLength,
  176. le16_to_cpu(desc->rpt_desc.wDescriptorLength));
  177. /* Send the ack */
  178. memset(&ack, 0, sizeof(struct mousevsc_prt_msg));
  179. ack.type = PIPE_MESSAGE_DATA;
  180. ack.size = sizeof(struct synthhid_device_info_ack);
  181. ack.ack.header.type = SYNTH_HID_INITIAL_DEVICE_INFO_ACK;
  182. ack.ack.header.size = 1;
  183. ack.ack.reserved = 0;
  184. ret = vmbus_sendpacket(input_device->device->channel,
  185. &ack,
  186. sizeof(struct pipe_prt_msg) +
  187. sizeof(struct synthhid_device_info_ack),
  188. (unsigned long)&ack,
  189. VM_PKT_DATA_INBAND,
  190. VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
  191. if (!ret)
  192. input_device->dev_info_status = 0;
  193. cleanup:
  194. complete(&input_device->wait_event);
  195. return;
  196. }
  197. static void mousevsc_on_receive(struct hv_device *device,
  198. struct vmpacket_descriptor *packet)
  199. {
  200. struct pipe_prt_msg *pipe_msg;
  201. struct synthhid_msg_hdr *hid_msg_hdr;
  202. struct mousevsc_dev *input_dev = hv_get_drvdata(device);
  203. struct synthhid_input_report *input_report;
  204. size_t len;
  205. pipe_msg = (struct pipe_prt_msg *)((unsigned long)packet +
  206. (packet->offset8 << 3));
  207. if (pipe_msg->type != PIPE_MESSAGE_DATA)
  208. return;
  209. hid_msg_hdr = (struct synthhid_msg_hdr *)pipe_msg->data;
  210. switch (hid_msg_hdr->type) {
  211. case SYNTH_HID_PROTOCOL_RESPONSE:
  212. len = struct_size(pipe_msg, data, pipe_msg->size);
  213. /*
  214. * While it will be impossible for us to protect against
  215. * malicious/buggy hypervisor/host, add a check here to
  216. * ensure we don't corrupt memory.
  217. */
  218. if (WARN_ON(len > sizeof(struct mousevsc_prt_msg)))
  219. break;
  220. memcpy(&input_dev->protocol_resp, pipe_msg, len);
  221. complete(&input_dev->wait_event);
  222. break;
  223. case SYNTH_HID_INITIAL_DEVICE_INFO:
  224. WARN_ON(pipe_msg->size < sizeof(struct hv_input_dev_info));
  225. /*
  226. * Parse out the device info into device attr,
  227. * hid desc and report desc
  228. */
  229. mousevsc_on_receive_device_info(input_dev,
  230. (struct synthhid_device_info *)pipe_msg->data);
  231. break;
  232. case SYNTH_HID_INPUT_REPORT:
  233. input_report =
  234. (struct synthhid_input_report *)pipe_msg->data;
  235. if (!input_dev->init_complete)
  236. break;
  237. len = min(input_report->header.size,
  238. (u32)sizeof(input_dev->input_buf));
  239. memcpy(input_dev->input_buf, input_report->buffer, len);
  240. hid_input_report(input_dev->hid_device, HID_INPUT_REPORT,
  241. input_dev->input_buf, len, 1);
  242. pm_wakeup_hard_event(&input_dev->device->device);
  243. break;
  244. default:
  245. pr_err("unsupported hid msg type - type %d len %d\n",
  246. hid_msg_hdr->type, hid_msg_hdr->size);
  247. break;
  248. }
  249. }
  250. static void mousevsc_on_channel_callback(void *context)
  251. {
  252. struct hv_device *device = context;
  253. struct vmpacket_descriptor *desc;
  254. foreach_vmbus_pkt(desc, device->channel) {
  255. switch (desc->type) {
  256. case VM_PKT_COMP:
  257. break;
  258. case VM_PKT_DATA_INBAND:
  259. mousevsc_on_receive(device, desc);
  260. break;
  261. default:
  262. pr_err("Unhandled packet type %d, tid %llx len %d\n",
  263. desc->type, desc->trans_id, desc->len8 * 8);
  264. break;
  265. }
  266. }
  267. }
  268. static int mousevsc_connect_to_vsp(struct hv_device *device)
  269. {
  270. int ret = 0;
  271. unsigned long t;
  272. struct mousevsc_dev *input_dev = hv_get_drvdata(device);
  273. struct mousevsc_prt_msg *request;
  274. struct mousevsc_prt_msg *response;
  275. reinit_completion(&input_dev->wait_event);
  276. request = &input_dev->protocol_req;
  277. memset(request, 0, sizeof(struct mousevsc_prt_msg));
  278. request->type = PIPE_MESSAGE_DATA;
  279. request->size = sizeof(struct synthhid_protocol_request);
  280. request->request.header.type = SYNTH_HID_PROTOCOL_REQUEST;
  281. request->request.header.size = sizeof(unsigned int);
  282. request->request.version_requested.version = SYNTHHID_INPUT_VERSION;
  283. ret = vmbus_sendpacket(device->channel, request,
  284. sizeof(struct pipe_prt_msg) +
  285. sizeof(struct synthhid_protocol_request),
  286. (unsigned long)request,
  287. VM_PKT_DATA_INBAND,
  288. VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
  289. if (ret)
  290. goto cleanup;
  291. t = wait_for_completion_timeout(&input_dev->wait_event, 5*HZ);
  292. if (!t) {
  293. ret = -ETIMEDOUT;
  294. goto cleanup;
  295. }
  296. response = &input_dev->protocol_resp;
  297. if (!response->response.approved) {
  298. pr_err("synthhid protocol request failed (version %d)\n",
  299. SYNTHHID_INPUT_VERSION);
  300. ret = -ENODEV;
  301. goto cleanup;
  302. }
  303. t = wait_for_completion_timeout(&input_dev->wait_event, 5*HZ);
  304. if (!t) {
  305. ret = -ETIMEDOUT;
  306. goto cleanup;
  307. }
  308. /*
  309. * We should have gotten the device attr, hid desc and report
  310. * desc at this point
  311. */
  312. ret = input_dev->dev_info_status;
  313. cleanup:
  314. return ret;
  315. }
  316. static int mousevsc_hid_parse(struct hid_device *hid)
  317. {
  318. struct hv_device *dev = hid_get_drvdata(hid);
  319. struct mousevsc_dev *input_dev = hv_get_drvdata(dev);
  320. return hid_parse_report(hid, input_dev->report_desc,
  321. input_dev->report_desc_size);
  322. }
  323. static int mousevsc_hid_open(struct hid_device *hid)
  324. {
  325. return 0;
  326. }
  327. static int mousevsc_hid_start(struct hid_device *hid)
  328. {
  329. return 0;
  330. }
  331. static void mousevsc_hid_close(struct hid_device *hid)
  332. {
  333. }
  334. static void mousevsc_hid_stop(struct hid_device *hid)
  335. {
  336. }
  337. static int mousevsc_hid_raw_request(struct hid_device *hid,
  338. unsigned char report_num,
  339. __u8 *buf, size_t len,
  340. unsigned char rtype,
  341. int reqtype)
  342. {
  343. return 0;
  344. }
  345. static int mousevsc_hid_probe(struct hid_device *hid_dev, const struct hid_device_id *id)
  346. {
  347. int ret;
  348. ret = hid_parse(hid_dev);
  349. if (ret) {
  350. hid_err(hid_dev, "parse failed\n");
  351. return ret;
  352. }
  353. ret = hid_hw_start(hid_dev, HID_CONNECT_HIDINPUT | HID_CONNECT_HIDDEV);
  354. if (ret) {
  355. hid_err(hid_dev, "hw start failed\n");
  356. return ret;
  357. }
  358. return 0;
  359. }
  360. static const struct hid_ll_driver mousevsc_ll_driver = {
  361. .parse = mousevsc_hid_parse,
  362. .open = mousevsc_hid_open,
  363. .close = mousevsc_hid_close,
  364. .start = mousevsc_hid_start,
  365. .stop = mousevsc_hid_stop,
  366. .raw_request = mousevsc_hid_raw_request,
  367. };
  368. static const struct hid_device_id mousevsc_devices[] = {
  369. { HID_DEVICE(BUS_VIRTUAL, HID_GROUP_ANY, 0x045E, 0x0621) },
  370. { }
  371. };
  372. static struct hid_driver mousevsc_hid_driver = {
  373. .name = "hid-hyperv",
  374. .id_table = mousevsc_devices,
  375. .probe = mousevsc_hid_probe,
  376. };
  377. static int mousevsc_probe(struct hv_device *device,
  378. const struct hv_vmbus_device_id *dev_id)
  379. {
  380. int ret;
  381. struct mousevsc_dev *input_dev;
  382. struct hid_device *hid_dev;
  383. input_dev = mousevsc_alloc_device(device);
  384. if (!input_dev)
  385. return -ENOMEM;
  386. ret = vmbus_open(device->channel,
  387. INPUTVSC_SEND_RING_BUFFER_SIZE,
  388. INPUTVSC_RECV_RING_BUFFER_SIZE,
  389. NULL,
  390. 0,
  391. mousevsc_on_channel_callback,
  392. device
  393. );
  394. if (ret)
  395. goto probe_err0;
  396. ret = mousevsc_connect_to_vsp(device);
  397. if (ret)
  398. goto probe_err1;
  399. /* workaround SA-167 */
  400. if (input_dev->report_desc[14] == 0x25)
  401. input_dev->report_desc[14] = 0x29;
  402. hid_dev = hid_allocate_device();
  403. if (IS_ERR(hid_dev)) {
  404. ret = PTR_ERR(hid_dev);
  405. goto probe_err1;
  406. }
  407. hid_dev->ll_driver = &mousevsc_ll_driver;
  408. hid_dev->bus = BUS_VIRTUAL;
  409. hid_dev->vendor = input_dev->hid_dev_info.vendor;
  410. hid_dev->product = input_dev->hid_dev_info.product;
  411. hid_dev->version = input_dev->hid_dev_info.version;
  412. input_dev->hid_device = hid_dev;
  413. sprintf(hid_dev->name, "%s", "Microsoft Vmbus HID-compliant Mouse");
  414. hid_set_drvdata(hid_dev, device);
  415. ret = hid_add_device(hid_dev);
  416. if (ret)
  417. goto probe_err2;
  418. device_init_wakeup(&device->device, true);
  419. input_dev->connected = true;
  420. input_dev->init_complete = true;
  421. return ret;
  422. probe_err2:
  423. hid_destroy_device(hid_dev);
  424. probe_err1:
  425. vmbus_close(device->channel);
  426. probe_err0:
  427. mousevsc_free_device(input_dev);
  428. return ret;
  429. }
  430. static void mousevsc_remove(struct hv_device *dev)
  431. {
  432. struct mousevsc_dev *input_dev = hv_get_drvdata(dev);
  433. device_init_wakeup(&dev->device, false);
  434. vmbus_close(dev->channel);
  435. hid_hw_stop(input_dev->hid_device);
  436. hid_destroy_device(input_dev->hid_device);
  437. mousevsc_free_device(input_dev);
  438. }
  439. static int mousevsc_suspend(struct hv_device *dev)
  440. {
  441. vmbus_close(dev->channel);
  442. return 0;
  443. }
  444. static int mousevsc_resume(struct hv_device *dev)
  445. {
  446. int ret;
  447. ret = vmbus_open(dev->channel,
  448. INPUTVSC_SEND_RING_BUFFER_SIZE,
  449. INPUTVSC_RECV_RING_BUFFER_SIZE,
  450. NULL, 0,
  451. mousevsc_on_channel_callback,
  452. dev);
  453. if (ret)
  454. return ret;
  455. ret = mousevsc_connect_to_vsp(dev);
  456. return ret;
  457. }
  458. static const struct hv_vmbus_device_id id_table[] = {
  459. /* Mouse guid */
  460. { HV_MOUSE_GUID, },
  461. { },
  462. };
  463. MODULE_DEVICE_TABLE(vmbus, id_table);
  464. static struct hv_driver mousevsc_drv = {
  465. .name = KBUILD_MODNAME,
  466. .id_table = id_table,
  467. .probe = mousevsc_probe,
  468. .remove = mousevsc_remove,
  469. .suspend = mousevsc_suspend,
  470. .resume = mousevsc_resume,
  471. .driver = {
  472. .probe_type = PROBE_PREFER_ASYNCHRONOUS,
  473. },
  474. };
  475. static int __init mousevsc_init(void)
  476. {
  477. int ret;
  478. ret = hid_register_driver(&mousevsc_hid_driver);
  479. if (ret)
  480. return ret;
  481. ret = vmbus_driver_register(&mousevsc_drv);
  482. if (ret)
  483. hid_unregister_driver(&mousevsc_hid_driver);
  484. return ret;
  485. }
  486. static void __exit mousevsc_exit(void)
  487. {
  488. vmbus_driver_unregister(&mousevsc_drv);
  489. hid_unregister_driver(&mousevsc_hid_driver);
  490. }
  491. MODULE_LICENSE("GPL");
  492. MODULE_DESCRIPTION("Microsoft Hyper-V Synthetic HID Driver");
  493. module_init(mousevsc_init);
  494. module_exit(mousevsc_exit);