1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2009, Citrix Systems, Inc.
4 * Copyright (c) 2010, Microsoft Corporation.
5 * Copyright (c) 2011, Novell Inc.
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>
17 struct hv_input_dev_info
{
19 unsigned short vendor
;
20 unsigned short product
;
21 unsigned short version
;
22 unsigned short reserved
[11];
25 /* The maximum size of a synthetic input message. */
26 #define SYNTHHID_MAX_INPUT_REPORT_SIZE 16
32 * Beta, RC < 2008/1/22 1,0
35 #define SYNTHHID_INPUT_VERSION_MAJOR 2
36 #define SYNTHHID_INPUT_VERSION_MINOR 0
37 #define SYNTHHID_INPUT_VERSION (SYNTHHID_INPUT_VERSION_MINOR | \
38 (SYNTHHID_INPUT_VERSION_MAJOR << 16))
43 * Message types in the synthetic input protocol
45 enum synthhid_msg_type
{
46 SYNTH_HID_PROTOCOL_REQUEST
,
47 SYNTH_HID_PROTOCOL_RESPONSE
,
48 SYNTH_HID_INITIAL_DEVICE_INFO
,
49 SYNTH_HID_INITIAL_DEVICE_INFO_ACK
,
50 SYNTH_HID_INPUT_REPORT
,
55 * Basic message structures.
57 struct synthhid_msg_hdr
{
58 enum synthhid_msg_type type
;
63 struct synthhid_msg_hdr header
;
64 char data
[1]; /* Enclosed message */
67 union synthhid_version
{
78 struct synthhid_protocol_request
{
79 struct synthhid_msg_hdr header
;
80 union synthhid_version version_requested
;
83 struct synthhid_protocol_response
{
84 struct synthhid_msg_hdr header
;
85 union synthhid_version version_requested
;
86 unsigned char approved
;
89 struct synthhid_device_info
{
90 struct synthhid_msg_hdr header
;
91 struct hv_input_dev_info hid_dev_info
;
92 struct hid_descriptor hid_descriptor
;
95 struct synthhid_device_info_ack
{
96 struct synthhid_msg_hdr header
;
97 unsigned char reserved
;
100 struct synthhid_input_report
{
101 struct synthhid_msg_hdr header
;
107 #define INPUTVSC_SEND_RING_BUFFER_SIZE (40 * 1024)
108 #define INPUTVSC_RECV_RING_BUFFER_SIZE (40 * 1024)
111 enum pipe_prot_msg_type
{
112 PIPE_MESSAGE_INVALID
,
118 struct pipe_prt_msg
{
119 enum pipe_prot_msg_type type
;
124 struct mousevsc_prt_msg
{
125 enum pipe_prot_msg_type type
;
128 struct synthhid_protocol_request request
;
129 struct synthhid_protocol_response response
;
130 struct synthhid_device_info_ack ack
;
135 * Represents an mousevsc device
137 struct mousevsc_dev
{
138 struct hv_device
*device
;
141 struct mousevsc_prt_msg protocol_req
;
142 struct mousevsc_prt_msg protocol_resp
;
143 /* Synchronize the request/response if needed */
144 struct completion wait_event
;
147 struct hid_descriptor
*hid_desc
;
148 unsigned char *report_desc
;
149 u32 report_desc_size
;
150 struct hv_input_dev_info hid_dev_info
;
151 struct hid_device
*hid_device
;
152 u8 input_buf
[HID_MAX_BUFFER_SIZE
];
156 static struct mousevsc_dev
*mousevsc_alloc_device(struct hv_device
*device
)
158 struct mousevsc_dev
*input_dev
;
160 input_dev
= kzalloc(sizeof(struct mousevsc_dev
), GFP_KERNEL
);
165 input_dev
->device
= device
;
166 hv_set_drvdata(device
, input_dev
);
167 init_completion(&input_dev
->wait_event
);
168 input_dev
->init_complete
= false;
173 static void mousevsc_free_device(struct mousevsc_dev
*device
)
175 kfree(device
->hid_desc
);
176 kfree(device
->report_desc
);
177 hv_set_drvdata(device
->device
, NULL
);
181 static void mousevsc_on_receive_device_info(struct mousevsc_dev
*input_device
,
182 struct synthhid_device_info
*device_info
)
185 struct hid_descriptor
*desc
;
186 struct mousevsc_prt_msg ack
;
188 input_device
->dev_info_status
= -ENOMEM
;
190 input_device
->hid_dev_info
= device_info
->hid_dev_info
;
191 desc
= &device_info
->hid_descriptor
;
192 if (desc
->bLength
== 0)
195 /* The pointer is not NULL when we resume from hibernation */
196 if (input_device
->hid_desc
!= NULL
)
197 kfree(input_device
->hid_desc
);
198 input_device
->hid_desc
= kmemdup(desc
, desc
->bLength
, GFP_ATOMIC
);
200 if (!input_device
->hid_desc
)
203 input_device
->report_desc_size
= desc
->desc
[0].wDescriptorLength
;
204 if (input_device
->report_desc_size
== 0) {
205 input_device
->dev_info_status
= -EINVAL
;
209 /* The pointer is not NULL when we resume from hibernation */
210 if (input_device
->report_desc
!= NULL
)
211 kfree(input_device
->report_desc
);
212 input_device
->report_desc
= kzalloc(input_device
->report_desc_size
,
215 if (!input_device
->report_desc
) {
216 input_device
->dev_info_status
= -ENOMEM
;
220 memcpy(input_device
->report_desc
,
221 ((unsigned char *)desc
) + desc
->bLength
,
222 desc
->desc
[0].wDescriptorLength
);
225 memset(&ack
, 0, sizeof(struct mousevsc_prt_msg
));
227 ack
.type
= PIPE_MESSAGE_DATA
;
228 ack
.size
= sizeof(struct synthhid_device_info_ack
);
230 ack
.ack
.header
.type
= SYNTH_HID_INITIAL_DEVICE_INFO_ACK
;
231 ack
.ack
.header
.size
= 1;
232 ack
.ack
.reserved
= 0;
234 ret
= vmbus_sendpacket(input_device
->device
->channel
,
236 sizeof(struct pipe_prt_msg
) - sizeof(unsigned char) +
237 sizeof(struct synthhid_device_info_ack
),
240 VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED
);
243 input_device
->dev_info_status
= 0;
246 complete(&input_device
->wait_event
);
251 static void mousevsc_on_receive(struct hv_device
*device
,
252 struct vmpacket_descriptor
*packet
)
254 struct pipe_prt_msg
*pipe_msg
;
255 struct synthhid_msg
*hid_msg
;
256 struct mousevsc_dev
*input_dev
= hv_get_drvdata(device
);
257 struct synthhid_input_report
*input_report
;
260 pipe_msg
= (struct pipe_prt_msg
*)((unsigned long)packet
+
261 (packet
->offset8
<< 3));
263 if (pipe_msg
->type
!= PIPE_MESSAGE_DATA
)
266 hid_msg
= (struct synthhid_msg
*)pipe_msg
->data
;
268 switch (hid_msg
->header
.type
) {
269 case SYNTH_HID_PROTOCOL_RESPONSE
:
271 * While it will be impossible for us to protect against
272 * malicious/buggy hypervisor/host, add a check here to
273 * ensure we don't corrupt memory.
275 if ((pipe_msg
->size
+ sizeof(struct pipe_prt_msg
)
276 - sizeof(unsigned char))
277 > sizeof(struct mousevsc_prt_msg
)) {
282 memcpy(&input_dev
->protocol_resp
, pipe_msg
,
283 pipe_msg
->size
+ sizeof(struct pipe_prt_msg
) -
284 sizeof(unsigned char));
285 complete(&input_dev
->wait_event
);
288 case SYNTH_HID_INITIAL_DEVICE_INFO
:
289 WARN_ON(pipe_msg
->size
< sizeof(struct hv_input_dev_info
));
292 * Parse out the device info into device attr,
293 * hid desc and report desc
295 mousevsc_on_receive_device_info(input_dev
,
296 (struct synthhid_device_info
*)pipe_msg
->data
);
298 case SYNTH_HID_INPUT_REPORT
:
300 (struct synthhid_input_report
*)pipe_msg
->data
;
301 if (!input_dev
->init_complete
)
304 len
= min(input_report
->header
.size
,
305 (u32
)sizeof(input_dev
->input_buf
));
306 memcpy(input_dev
->input_buf
, input_report
->buffer
, len
);
307 hid_input_report(input_dev
->hid_device
, HID_INPUT_REPORT
,
308 input_dev
->input_buf
, len
, 1);
310 pm_wakeup_hard_event(&input_dev
->device
->device
);
314 pr_err("unsupported hid msg type - type %d len %d\n",
315 hid_msg
->header
.type
, hid_msg
->header
.size
);
321 static void mousevsc_on_channel_callback(void *context
)
323 struct hv_device
*device
= context
;
324 struct vmpacket_descriptor
*desc
;
326 foreach_vmbus_pkt(desc
, device
->channel
) {
327 switch (desc
->type
) {
331 case VM_PKT_DATA_INBAND
:
332 mousevsc_on_receive(device
, desc
);
336 pr_err("Unhandled packet type %d, tid %llx len %d\n",
337 desc
->type
, desc
->trans_id
, desc
->len8
* 8);
343 static int mousevsc_connect_to_vsp(struct hv_device
*device
)
347 struct mousevsc_dev
*input_dev
= hv_get_drvdata(device
);
348 struct mousevsc_prt_msg
*request
;
349 struct mousevsc_prt_msg
*response
;
351 reinit_completion(&input_dev
->wait_event
);
353 request
= &input_dev
->protocol_req
;
354 memset(request
, 0, sizeof(struct mousevsc_prt_msg
));
356 request
->type
= PIPE_MESSAGE_DATA
;
357 request
->size
= sizeof(struct synthhid_protocol_request
);
358 request
->request
.header
.type
= SYNTH_HID_PROTOCOL_REQUEST
;
359 request
->request
.header
.size
= sizeof(unsigned int);
360 request
->request
.version_requested
.version
= SYNTHHID_INPUT_VERSION
;
362 ret
= vmbus_sendpacket(device
->channel
, request
,
363 sizeof(struct pipe_prt_msg
) -
364 sizeof(unsigned char) +
365 sizeof(struct synthhid_protocol_request
),
366 (unsigned long)request
,
368 VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED
);
372 t
= wait_for_completion_timeout(&input_dev
->wait_event
, 5*HZ
);
378 response
= &input_dev
->protocol_resp
;
380 if (!response
->response
.approved
) {
381 pr_err("synthhid protocol request failed (version %d)\n",
382 SYNTHHID_INPUT_VERSION
);
387 t
= wait_for_completion_timeout(&input_dev
->wait_event
, 5*HZ
);
394 * We should have gotten the device attr, hid desc and report
397 ret
= input_dev
->dev_info_status
;
403 static int mousevsc_hid_parse(struct hid_device
*hid
)
405 struct hv_device
*dev
= hid_get_drvdata(hid
);
406 struct mousevsc_dev
*input_dev
= hv_get_drvdata(dev
);
408 return hid_parse_report(hid
, input_dev
->report_desc
,
409 input_dev
->report_desc_size
);
412 static int mousevsc_hid_open(struct hid_device
*hid
)
417 static int mousevsc_hid_start(struct hid_device
*hid
)
422 static void mousevsc_hid_close(struct hid_device
*hid
)
426 static void mousevsc_hid_stop(struct hid_device
*hid
)
430 static int mousevsc_hid_raw_request(struct hid_device
*hid
,
431 unsigned char report_num
,
432 __u8
*buf
, size_t len
,
439 static struct hid_ll_driver mousevsc_ll_driver
= {
440 .parse
= mousevsc_hid_parse
,
441 .open
= mousevsc_hid_open
,
442 .close
= mousevsc_hid_close
,
443 .start
= mousevsc_hid_start
,
444 .stop
= mousevsc_hid_stop
,
445 .raw_request
= mousevsc_hid_raw_request
,
448 static struct hid_driver mousevsc_hid_driver
;
450 static int mousevsc_probe(struct hv_device
*device
,
451 const struct hv_vmbus_device_id
*dev_id
)
454 struct mousevsc_dev
*input_dev
;
455 struct hid_device
*hid_dev
;
457 input_dev
= mousevsc_alloc_device(device
);
462 ret
= vmbus_open(device
->channel
,
463 INPUTVSC_SEND_RING_BUFFER_SIZE
,
464 INPUTVSC_RECV_RING_BUFFER_SIZE
,
467 mousevsc_on_channel_callback
,
474 ret
= mousevsc_connect_to_vsp(device
);
479 /* workaround SA-167 */
480 if (input_dev
->report_desc
[14] == 0x25)
481 input_dev
->report_desc
[14] = 0x29;
483 hid_dev
= hid_allocate_device();
484 if (IS_ERR(hid_dev
)) {
485 ret
= PTR_ERR(hid_dev
);
489 hid_dev
->ll_driver
= &mousevsc_ll_driver
;
490 hid_dev
->driver
= &mousevsc_hid_driver
;
491 hid_dev
->bus
= BUS_VIRTUAL
;
492 hid_dev
->vendor
= input_dev
->hid_dev_info
.vendor
;
493 hid_dev
->product
= input_dev
->hid_dev_info
.product
;
494 hid_dev
->version
= input_dev
->hid_dev_info
.version
;
495 input_dev
->hid_device
= hid_dev
;
497 sprintf(hid_dev
->name
, "%s", "Microsoft Vmbus HID-compliant Mouse");
499 hid_set_drvdata(hid_dev
, device
);
501 ret
= hid_add_device(hid_dev
);
506 ret
= hid_parse(hid_dev
);
508 hid_err(hid_dev
, "parse failed\n");
512 ret
= hid_hw_start(hid_dev
, HID_CONNECT_HIDINPUT
| HID_CONNECT_HIDDEV
);
515 hid_err(hid_dev
, "hw start failed\n");
519 device_init_wakeup(&device
->device
, true);
521 input_dev
->connected
= true;
522 input_dev
->init_complete
= true;
527 hid_destroy_device(hid_dev
);
530 vmbus_close(device
->channel
);
533 mousevsc_free_device(input_dev
);
539 static int mousevsc_remove(struct hv_device
*dev
)
541 struct mousevsc_dev
*input_dev
= hv_get_drvdata(dev
);
543 device_init_wakeup(&dev
->device
, false);
544 vmbus_close(dev
->channel
);
545 hid_hw_stop(input_dev
->hid_device
);
546 hid_destroy_device(input_dev
->hid_device
);
547 mousevsc_free_device(input_dev
);
552 static int mousevsc_suspend(struct hv_device
*dev
)
554 vmbus_close(dev
->channel
);
559 static int mousevsc_resume(struct hv_device
*dev
)
563 ret
= vmbus_open(dev
->channel
,
564 INPUTVSC_SEND_RING_BUFFER_SIZE
,
565 INPUTVSC_RECV_RING_BUFFER_SIZE
,
567 mousevsc_on_channel_callback
,
572 ret
= mousevsc_connect_to_vsp(dev
);
576 static const struct hv_vmbus_device_id id_table
[] = {
582 MODULE_DEVICE_TABLE(vmbus
, id_table
);
584 static struct hv_driver mousevsc_drv
= {
585 .name
= KBUILD_MODNAME
,
586 .id_table
= id_table
,
587 .probe
= mousevsc_probe
,
588 .remove
= mousevsc_remove
,
589 .suspend
= mousevsc_suspend
,
590 .resume
= mousevsc_resume
,
592 .probe_type
= PROBE_PREFER_ASYNCHRONOUS
,
596 static int __init
mousevsc_init(void)
598 return vmbus_driver_register(&mousevsc_drv
);
601 static void __exit
mousevsc_exit(void)
603 vmbus_driver_unregister(&mousevsc_drv
);
606 MODULE_LICENSE("GPL");
607 MODULE_DESCRIPTION("Microsoft Hyper-V Synthetic HID Driver");
609 module_init(mousevsc_init
);
610 module_exit(mousevsc_exit
);