hid-hyperv.c 13 KB

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