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