2 * Copyright (c) 2009, Citrix Systems, Inc.
3 * Copyright (c) 2010, Microsoft Corporation.
4 * Copyright (c) 2011, Novell Inc.
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 #include <linux/init.h>
16 #include <linux/module.h>
17 #include <linux/delay.h>
18 #include <linux/device.h>
19 #include <linux/workqueue.h>
20 #include <linux/sched.h>
21 #include <linux/wait.h>
22 #include <linux/input.h>
23 #include <linux/hid.h>
24 #include <linux/hiddev.h>
25 #include <linux/hyperv.h>
28 struct hv_input_dev_info
{
30 unsigned short vendor
;
31 unsigned short product
;
32 unsigned short version
;
33 unsigned short reserved
[11];
36 /* The maximum size of a synthetic input message. */
37 #define SYNTHHID_MAX_INPUT_REPORT_SIZE 16
43 * Beta, RC < 2008/1/22 1,0
46 #define SYNTHHID_INPUT_VERSION_MAJOR 2
47 #define SYNTHHID_INPUT_VERSION_MINOR 0
48 #define SYNTHHID_INPUT_VERSION (SYNTHHID_INPUT_VERSION_MINOR | \
49 (SYNTHHID_INPUT_VERSION_MAJOR << 16))
54 * Message types in the synthetic input protocol
56 enum synthhid_msg_type
{
57 SYNTH_HID_PROTOCOL_REQUEST
,
58 SYNTH_HID_PROTOCOL_RESPONSE
,
59 SYNTH_HID_INITIAL_DEVICE_INFO
,
60 SYNTH_HID_INITIAL_DEVICE_INFO_ACK
,
61 SYNTH_HID_INPUT_REPORT
,
66 * Basic message structures.
68 struct synthhid_msg_hdr
{
69 enum synthhid_msg_type type
;
74 struct synthhid_msg_hdr header
;
75 char data
[1]; /* Enclosed message */
78 union synthhid_version
{
89 struct synthhid_protocol_request
{
90 struct synthhid_msg_hdr header
;
91 union synthhid_version version_requested
;
94 struct synthhid_protocol_response
{
95 struct synthhid_msg_hdr header
;
96 union synthhid_version version_requested
;
97 unsigned char approved
;
100 struct synthhid_device_info
{
101 struct synthhid_msg_hdr header
;
102 struct hv_input_dev_info hid_dev_info
;
103 struct hid_descriptor hid_descriptor
;
106 struct synthhid_device_info_ack
{
107 struct synthhid_msg_hdr header
;
108 unsigned char reserved
;
111 struct synthhid_input_report
{
112 struct synthhid_msg_hdr header
;
118 #define INPUTVSC_SEND_RING_BUFFER_SIZE (10*PAGE_SIZE)
119 #define INPUTVSC_RECV_RING_BUFFER_SIZE (10*PAGE_SIZE)
121 #define NBITS(x) (((x)/BITS_PER_LONG)+1)
123 enum pipe_prot_msg_type
{
124 PIPE_MESSAGE_INVALID
,
130 struct pipe_prt_msg
{
131 enum pipe_prot_msg_type type
;
136 struct mousevsc_prt_msg
{
137 enum pipe_prot_msg_type type
;
140 struct synthhid_protocol_request request
;
141 struct synthhid_protocol_response response
;
142 struct synthhid_device_info_ack ack
;
147 * Represents an mousevsc device
149 struct mousevsc_dev
{
150 struct hv_device
*device
;
151 unsigned char init_complete
;
152 struct mousevsc_prt_msg protocol_req
;
153 struct mousevsc_prt_msg protocol_resp
;
154 /* Synchronize the request/response if needed */
155 struct completion wait_event
;
158 struct hid_descriptor
*hid_desc
;
159 unsigned char *report_desc
;
160 u32 report_desc_size
;
161 struct hv_input_dev_info hid_dev_info
;
163 struct hid_device
*hid_device
;
167 static struct mousevsc_dev
*alloc_input_device(struct hv_device
*device
)
169 struct mousevsc_dev
*input_dev
;
171 input_dev
= kzalloc(sizeof(struct mousevsc_dev
), GFP_KERNEL
);
176 input_dev
->device
= device
;
177 hv_set_drvdata(device
, input_dev
);
178 init_completion(&input_dev
->wait_event
);
183 static void free_input_device(struct mousevsc_dev
*device
)
185 kfree(device
->hid_desc
);
186 kfree(device
->report_desc
);
187 hv_set_drvdata(device
->device
, NULL
);
192 static void mousevsc_on_receive_device_info(struct mousevsc_dev
*input_device
,
193 struct synthhid_device_info
*device_info
)
196 struct hid_descriptor
*desc
;
197 struct mousevsc_prt_msg ack
;
199 /* Assume success for now */
200 input_device
->dev_info_status
= 0;
202 memcpy(&input_device
->hid_dev_info
, &device_info
->hid_dev_info
,
203 sizeof(struct hv_input_dev_info
));
205 desc
= &device_info
->hid_descriptor
;
206 WARN_ON(desc
->bLength
== 0);
208 input_device
->hid_desc
= kzalloc(desc
->bLength
, GFP_ATOMIC
);
210 if (!input_device
->hid_desc
)
213 memcpy(input_device
->hid_desc
, desc
, desc
->bLength
);
215 input_device
->report_desc_size
= desc
->desc
[0].wDescriptorLength
;
216 if (input_device
->report_desc_size
== 0)
218 input_device
->report_desc
= kzalloc(input_device
->report_desc_size
,
221 if (!input_device
->report_desc
)
224 memcpy(input_device
->report_desc
,
225 ((unsigned char *)desc
) + desc
->bLength
,
226 desc
->desc
[0].wDescriptorLength
);
229 memset(&ack
, 0, sizeof(struct mousevsc_prt_msg
));
231 ack
.type
= PIPE_MESSAGE_DATA
;
232 ack
.size
= sizeof(struct synthhid_device_info_ack
);
234 ack
.ack
.header
.type
= SYNTH_HID_INITIAL_DEVICE_INFO_ACK
;
235 ack
.ack
.header
.size
= 1;
236 ack
.ack
.reserved
= 0;
238 ret
= vmbus_sendpacket(input_device
->device
->channel
,
240 sizeof(struct pipe_prt_msg
) - sizeof(unsigned char) +
241 sizeof(struct synthhid_device_info_ack
),
244 VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED
);
248 complete(&input_device
->wait_event
);
253 kfree(input_device
->hid_desc
);
254 input_device
->hid_desc
= NULL
;
256 kfree(input_device
->report_desc
);
257 input_device
->report_desc
= NULL
;
259 input_device
->dev_info_status
= -1;
260 complete(&input_device
->wait_event
);
263 static void mousevsc_on_receive(struct hv_device
*device
,
264 struct vmpacket_descriptor
*packet
)
266 struct pipe_prt_msg
*pipe_msg
;
267 struct synthhid_msg
*hid_msg
;
268 struct mousevsc_dev
*input_dev
= hv_get_drvdata(device
);
269 struct synthhid_input_report
*input_report
;
271 pipe_msg
= (struct pipe_prt_msg
*)((unsigned long)packet
+
272 (packet
->offset8
<< 3));
274 if (pipe_msg
->type
!= PIPE_MESSAGE_DATA
)
277 hid_msg
= (struct synthhid_msg
*)&pipe_msg
->data
[0];
279 switch (hid_msg
->header
.type
) {
280 case SYNTH_HID_PROTOCOL_RESPONSE
:
281 memcpy(&input_dev
->protocol_resp
, pipe_msg
,
282 pipe_msg
->size
+ sizeof(struct pipe_prt_msg
) -
283 sizeof(unsigned char));
284 complete(&input_dev
->wait_event
);
287 case SYNTH_HID_INITIAL_DEVICE_INFO
:
288 WARN_ON(pipe_msg
->size
< sizeof(struct hv_input_dev_info
));
291 * Parse out the device info into device attr,
292 * hid desc and report desc
294 mousevsc_on_receive_device_info(input_dev
,
295 (struct synthhid_device_info
*)&pipe_msg
->data
[0]);
297 case SYNTH_HID_INPUT_REPORT
:
299 (struct synthhid_input_report
*)&pipe_msg
->data
[0];
300 if (!input_dev
->init_complete
)
302 hid_input_report(input_dev
->hid_device
,
303 HID_INPUT_REPORT
, input_report
->buffer
,
304 input_report
->header
.size
, 1);
307 pr_err("unsupported hid msg type - type %d len %d",
308 hid_msg
->header
.type
, hid_msg
->header
.size
);
314 static void mousevsc_on_channel_callback(void *context
)
316 const int packetSize
= 0x100;
318 struct hv_device
*device
= (struct hv_device
*)context
;
322 unsigned char packet
[0x100];
323 struct vmpacket_descriptor
*desc
;
324 unsigned char *buffer
= packet
;
325 int bufferlen
= packetSize
;
329 ret
= vmbus_recvpacket_raw(device
->channel
, buffer
,
330 bufferlen
, &bytes_recvd
, &req_id
);
333 if (bytes_recvd
> 0) {
334 desc
= (struct vmpacket_descriptor
*)buffer
;
336 switch (desc
->type
) {
340 case VM_PKT_DATA_INBAND
:
346 pr_err("unhandled packet type %d, tid %llx len %d\n",
354 if (bufferlen
> packetSize
) {
358 bufferlen
= packetSize
;
361 if (bufferlen
> packetSize
) {
365 bufferlen
= packetSize
;
369 } else if (ret
== -ENOBUFS
) {
370 /* Handle large packet */
371 bufferlen
= bytes_recvd
;
372 buffer
= kzalloc(bytes_recvd
, GFP_ATOMIC
);
374 if (buffer
== NULL
) {
376 bufferlen
= packetSize
;
385 static int mousevsc_connect_to_vsp(struct hv_device
*device
)
389 struct mousevsc_dev
*input_dev
= hv_get_drvdata(device
);
390 struct mousevsc_prt_msg
*request
;
391 struct mousevsc_prt_msg
*response
;
394 request
= &input_dev
->protocol_req
;
396 memset(request
, 0, sizeof(struct mousevsc_prt_msg
));
398 request
->type
= PIPE_MESSAGE_DATA
;
399 request
->size
= sizeof(struct synthhid_protocol_request
);
401 request
->request
.header
.type
= SYNTH_HID_PROTOCOL_REQUEST
;
402 request
->request
.header
.size
= sizeof(unsigned int);
403 request
->request
.version_requested
.version
= SYNTHHID_INPUT_VERSION
;
406 ret
= vmbus_sendpacket(device
->channel
, request
,
407 sizeof(struct pipe_prt_msg
) -
408 sizeof(unsigned char) +
409 sizeof(struct synthhid_protocol_request
),
410 (unsigned long)request
,
412 VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED
);
416 t
= wait_for_completion_timeout(&input_dev
->wait_event
, 5*HZ
);
422 response
= &input_dev
->protocol_resp
;
424 if (!response
->response
.approved
) {
425 pr_err("synthhid protocol request failed (version %d)",
426 SYNTHHID_INPUT_VERSION
);
431 t
= wait_for_completion_timeout(&input_dev
->wait_event
, 5*HZ
);
438 * We should have gotten the device attr, hid desc and report
441 if (input_dev
->dev_info_status
)
449 static int mousevsc_hid_open(struct hid_device
*hid
)
454 static void mousevsc_hid_close(struct hid_device
*hid
)
458 static struct hid_ll_driver mousevsc_ll_driver
= {
459 .open
= mousevsc_hid_open
,
460 .close
= mousevsc_hid_close
,
463 static struct hid_driver mousevsc_hid_driver
;
465 static void reportdesc_callback(struct hv_device
*dev
, void *packet
, u32 len
)
467 struct hid_device
*hid_dev
;
468 struct mousevsc_dev
*input_device
= hv_get_drvdata(dev
);
470 hid_dev
= hid_allocate_device();
474 hid_dev
->ll_driver
= &mousevsc_ll_driver
;
475 hid_dev
->driver
= &mousevsc_hid_driver
;
477 if (hid_parse_report(hid_dev
, packet
, len
))
480 hid_dev
->bus
= BUS_VIRTUAL
;
481 hid_dev
->vendor
= input_device
->hid_dev_info
.vendor
;
482 hid_dev
->product
= input_device
->hid_dev_info
.product
;
483 hid_dev
->version
= input_device
->hid_dev_info
.version
;
485 sprintf(hid_dev
->name
, "%s", "Microsoft Vmbus HID-compliant Mouse");
487 if (!hidinput_connect(hid_dev
, 0)) {
488 hid_dev
->claimed
|= HID_CLAIMED_INPUT
;
490 input_device
->connected
= 1;
494 input_device
->hid_device
= hid_dev
;
497 static int mousevsc_on_device_add(struct hv_device
*device
)
500 struct mousevsc_dev
*input_dev
;
502 input_dev
= alloc_input_device(device
);
507 input_dev
->init_complete
= false;
509 ret
= vmbus_open(device
->channel
,
510 INPUTVSC_SEND_RING_BUFFER_SIZE
,
511 INPUTVSC_RECV_RING_BUFFER_SIZE
,
514 mousevsc_on_channel_callback
,
519 free_input_device(input_dev
);
524 ret
= mousevsc_connect_to_vsp(device
);
527 vmbus_close(device
->channel
);
528 free_input_device(input_dev
);
533 /* workaround SA-167 */
534 if (input_dev
->report_desc
[14] == 0x25)
535 input_dev
->report_desc
[14] = 0x29;
537 reportdesc_callback(device
, input_dev
->report_desc
,
538 input_dev
->report_desc_size
);
540 input_dev
->init_complete
= true;
545 static int mousevsc_probe(struct hv_device
*dev
,
546 const struct hv_vmbus_device_id
*dev_id
)
549 return mousevsc_on_device_add(dev
);
553 static int mousevsc_remove(struct hv_device
*dev
)
555 struct mousevsc_dev
*input_dev
= hv_get_drvdata(dev
);
557 vmbus_close(dev
->channel
);
559 if (input_dev
->connected
) {
560 hidinput_disconnect(input_dev
->hid_device
);
561 input_dev
->connected
= 0;
562 hid_destroy_device(input_dev
->hid_device
);
565 free_input_device(input_dev
);
570 static const struct hv_vmbus_device_id id_table
[] = {
572 { VMBUS_DEVICE(0x9E, 0xB6, 0xA8, 0xCF, 0x4A, 0x5B, 0xc0, 0x4c,
573 0xB9, 0x8B, 0x8B, 0xA1, 0xA1, 0xF3, 0xF9, 0x5A) },
577 MODULE_DEVICE_TABLE(vmbus
, id_table
);
579 static struct hv_driver mousevsc_drv
= {
581 .id_table
= id_table
,
582 .probe
= mousevsc_probe
,
583 .remove
= mousevsc_remove
,
586 static int __init
mousevsc_init(void)
588 return vmbus_driver_register(&mousevsc_drv
);
591 static void __exit
mousevsc_exit(void)
593 vmbus_driver_unregister(&mousevsc_drv
);
596 MODULE_LICENSE("GPL");
597 MODULE_VERSION(HV_DRV_VERSION
);
598 module_init(mousevsc_init
);
599 module_exit(mousevsc_exit
);