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/device.h>
18 #include <linux/workqueue.h>
19 #include <linux/sched.h>
20 #include <linux/wait.h>
21 #include <linux/input.h>
22 #include <linux/hid.h>
23 #include <linux/hiddev.h>
24 #include <linux/pci.h>
25 #include <linux/dmi.h>
29 #include "version_info.h"
31 #include "vmbus_api.h"
32 #include "mousevsc_api.h"
34 #include "vmbus_packet_format.h"
37 /* The maximum size of a synthetic input message. */
38 #define SYNTHHID_MAX_INPUT_REPORT_SIZE 16
44 * Beta, RC < 2008/1/22 1,0
47 #define SYNTHHID_INPUT_VERSION_MAJOR 2
48 #define SYNTHHID_INPUT_VERSION_MINOR 0
49 #define SYNTHHID_INPUT_VERSION_DWORD (SYNTHHID_INPUT_VERSION_MINOR | \
50 (SYNTHHID_INPUT_VERSION_MAJOR << 16))
55 * Message types in the synthetic input protocol
57 enum synthhid_msg_type
{
58 SynthHidProtocolRequest
,
59 SynthHidProtocolResponse
,
60 SynthHidInitialDeviceInfo
,
61 SynthHidInitialDeviceInfoAck
,
67 * Basic message structures.
70 enum synthhid_msg_type Type
; /* Type of the enclosed message */
71 u32 Size
; /* Size of the enclosed message
72 * (size of the data payload)
74 } SYNTHHID_MESSAGE_HEADER
, *PSYNTHHID_MESSAGE_HEADER
;
77 SYNTHHID_MESSAGE_HEADER Header
;
78 char Data
[1]; /* Enclosed message */
79 } SYNTHHID_MESSAGE
, *PSYNTHHID_MESSAGE
;
88 } SYNTHHID_VERSION
, *PSYNTHHID_VERSION
;
94 SYNTHHID_MESSAGE_HEADER Header
;
95 SYNTHHID_VERSION VersionRequested
;
96 } SYNTHHID_PROTOCOL_REQUEST
, *PSYNTHHID_PROTOCOL_REQUEST
;
99 SYNTHHID_MESSAGE_HEADER Header
;
100 SYNTHHID_VERSION VersionRequested
;
101 unsigned char Approved
;
102 } SYNTHHID_PROTOCOL_RESPONSE
, *PSYNTHHID_PROTOCOL_RESPONSE
;
105 SYNTHHID_MESSAGE_HEADER Header
;
106 struct input_dev_info HidDeviceAttributes
;
107 unsigned char HidDescriptorInformation
[1];
108 } SYNTHHID_DEVICE_INFO
, *PSYNTHHID_DEVICE_INFO
;
111 SYNTHHID_MESSAGE_HEADER Header
;
112 unsigned char Reserved
;
113 } SYNTHHID_DEVICE_INFO_ACK
, *PSYNTHHID_DEVICE_INFO_ACK
;
116 SYNTHHID_MESSAGE_HEADER Header
;
117 char ReportBuffer
[1];
118 } SYNTHHID_INPUT_REPORT
, *PSYNTHHID_INPUT_REPORT
;
123 #define NBITS(x) (((x)/BITS_PER_LONG)+1)
125 enum pipe_prot_msg_type
{
126 PipeMessageInvalid
= 0,
132 struct pipe_prt_msg
{
133 enum pipe_prot_msg_type PacketType
;
141 struct mousevsc_prt_msg
{
142 enum pipe_prot_msg_type PacketType
;
145 SYNTHHID_PROTOCOL_REQUEST Request
;
146 SYNTHHID_PROTOCOL_RESPONSE Response
;
147 SYNTHHID_DEVICE_INFO_ACK Ack
;
152 * Represents an mousevsc device
154 struct mousevsc_dev
{
155 struct hv_device
*Device
;
156 /* 0 indicates the device is being destroyed */
158 int NumOutstandingRequests
;
159 unsigned char bInitializeComplete
;
160 struct mousevsc_prt_msg ProtocolReq
;
161 struct mousevsc_prt_msg ProtocolResp
;
162 /* Synchronize the request/response if needed */
163 wait_queue_head_t ProtocolWaitEvent
;
164 wait_queue_head_t DeviceInfoWaitEvent
;
165 int protocol_wait_condition
;
166 int device_wait_condition
;
167 int DeviceInfoStatus
;
169 struct hid_descriptor
*HidDesc
;
170 unsigned char *ReportDesc
;
172 struct input_dev_info DeviceAttr
;
179 static const char *gDriverName
= "mousevsc";
181 /* {CFA8B69E-5B4A-4cc0-B98B-8BA1A1F3F95A} */
182 static const struct hv_guid gMousevscDeviceType
= {
183 .data
= {0x9E, 0xB6, 0xA8, 0xCF, 0x4A, 0x5B, 0xc0, 0x4c,
184 0xB9, 0x8B, 0x8B, 0xA1, 0xA1, 0xF3, 0xF9, 0x5A}
190 static int MousevscOnDeviceAdd(struct hv_device
*Device
, void *AdditionalInfo
);
192 static int MousevscOnDeviceRemove(struct hv_device
*Device
);
194 static void MousevscOnCleanup(struct hv_driver
*Device
);
196 static void MousevscOnChannelCallback(void *Context
);
198 static int MousevscConnectToVsp(struct hv_device
*Device
);
200 static void MousevscOnReceive(struct hv_device
*Device
,
201 struct vmpacket_descriptor
*Packet
);
203 static inline struct mousevsc_dev
*AllocInputDevice(struct hv_device
*Device
)
205 struct mousevsc_dev
*inputDevice
;
207 inputDevice
= kzalloc(sizeof(struct mousevsc_dev
), GFP_KERNEL
);
213 * Set to 2 to allow both inbound and outbound traffics
214 * (ie GetInputDevice() and MustGetInputDevice()) to proceed.
216 atomic_cmpxchg(&inputDevice
->RefCount
, 0, 2);
218 inputDevice
->Device
= Device
;
219 Device
->ext
= inputDevice
;
224 static inline void FreeInputDevice(struct mousevsc_dev
*Device
)
226 WARN_ON(atomic_read(&Device
->RefCount
) == 0);
231 * Get the inputdevice object if exists and its refcount > 1
233 static inline struct mousevsc_dev
*GetInputDevice(struct hv_device
*Device
)
235 struct mousevsc_dev
*inputDevice
;
237 inputDevice
= (struct mousevsc_dev
*)Device
->ext
;
241 * This sure isn't a valid thing to print for debugging, no matter
242 * what the intention is...
244 * printk(KERN_ERR "-------------------------> REFCOUNT = %d",
245 * inputDevice->RefCount);
248 if (inputDevice
&& atomic_read(&inputDevice
->RefCount
) > 1)
249 atomic_inc(&inputDevice
->RefCount
);
257 * Get the inputdevice object iff exists and its refcount > 0
259 static inline struct mousevsc_dev
*MustGetInputDevice(struct hv_device
*Device
)
261 struct mousevsc_dev
*inputDevice
;
263 inputDevice
= (struct mousevsc_dev
*)Device
->ext
;
265 if (inputDevice
&& atomic_read(&inputDevice
->RefCount
))
266 atomic_inc(&inputDevice
->RefCount
);
273 static inline void PutInputDevice(struct hv_device
*Device
)
275 struct mousevsc_dev
*inputDevice
;
277 inputDevice
= (struct mousevsc_dev
*)Device
->ext
;
279 atomic_dec(&inputDevice
->RefCount
);
283 * Drop ref count to 1 to effectively disable GetInputDevice()
285 static inline struct mousevsc_dev
*ReleaseInputDevice(struct hv_device
*Device
)
287 struct mousevsc_dev
*inputDevice
;
289 inputDevice
= (struct mousevsc_dev
*)Device
->ext
;
291 /* Busy wait until the ref drop to 2, then set it to 1 */
292 while (atomic_cmpxchg(&inputDevice
->RefCount
, 2, 1) != 2)
299 * Drop ref count to 0. No one can use InputDevice object.
301 static inline struct mousevsc_dev
*FinalReleaseInputDevice(struct hv_device
*Device
)
303 struct mousevsc_dev
*inputDevice
;
305 inputDevice
= (struct mousevsc_dev
*)Device
->ext
;
307 /* Busy wait until the ref drop to 1, then set it to 0 */
308 while (atomic_cmpxchg(&inputDevice
->RefCount
, 1, 0) != 1)
318 * MousevscInitialize()
324 int mouse_vsc_initialize(struct hv_driver
*Driver
)
326 struct mousevsc_drv_obj
*inputDriver
=
327 (struct mousevsc_drv_obj
*)Driver
;
330 Driver
->name
= gDriverName
;
331 memcpy(&Driver
->dev_type
, &gMousevscDeviceType
,
332 sizeof(struct hv_guid
));
334 /* Setup the dispatch table */
335 inputDriver
->Base
.dev_add
= MousevscOnDeviceAdd
;
336 inputDriver
->Base
.dev_rm
= MousevscOnDeviceRemove
;
337 inputDriver
->Base
.cleanup
= MousevscOnCleanup
;
339 inputDriver
->OnOpen
= NULL
;
340 inputDriver
->OnClose
= NULL
;
348 * MousevscOnDeviceAdd()
351 * Callback when the device belonging to this driver is added
355 MousevscOnDeviceAdd(struct hv_device
*Device
, void *AdditionalInfo
)
358 struct mousevsc_dev
*inputDevice
;
359 struct mousevsc_drv_obj
*inputDriver
;
360 struct input_dev_info deviceInfo
;
362 inputDevice
= AllocInputDevice(Device
);
369 inputDevice
->bInitializeComplete
= false;
371 /* Open the channel */
372 ret
= vmbus_open(Device
->channel
,
373 INPUTVSC_SEND_RING_BUFFER_SIZE
,
374 INPUTVSC_RECV_RING_BUFFER_SIZE
,
377 MousevscOnChannelCallback
,
382 pr_err("unable to open channel: %d", ret
);
386 pr_info("InputVsc channel open: %d", ret
);
388 ret
= MousevscConnectToVsp(Device
);
391 pr_err("unable to connect channel: %d", ret
);
393 vmbus_close(Device
->channel
);
397 inputDriver
= (struct mousevsc_drv_obj
*)inputDevice
->Device
->drv
;
399 deviceInfo
.VendorID
= inputDevice
->DeviceAttr
.VendorID
;
400 deviceInfo
.ProductID
= inputDevice
->DeviceAttr
.ProductID
;
401 deviceInfo
.VersionNumber
= inputDevice
->DeviceAttr
.VersionNumber
;
402 strcpy(deviceInfo
.Name
, "Microsoft Vmbus HID-compliant Mouse");
404 /* Send the device info back up */
405 inputDriver
->OnDeviceInfo(Device
, &deviceInfo
);
407 /* Send the report desc back up */
408 /* workaround SA-167 */
409 if (inputDevice
->ReportDesc
[14] == 0x25)
410 inputDevice
->ReportDesc
[14] = 0x29;
412 inputDriver
->OnReportDescriptor(Device
, inputDevice
->ReportDesc
, inputDevice
->ReportDescSize
);
414 inputDevice
->bInitializeComplete
= true;
421 MousevscConnectToVsp(struct hv_device
*Device
)
424 struct mousevsc_dev
*inputDevice
;
425 struct mousevsc_prt_msg
*request
;
426 struct mousevsc_prt_msg
*response
;
428 inputDevice
= GetInputDevice(Device
);
431 pr_err("unable to get input device...device being destroyed?");
435 init_waitqueue_head(&inputDevice
->ProtocolWaitEvent
);
436 init_waitqueue_head(&inputDevice
->DeviceInfoWaitEvent
);
438 request
= &inputDevice
->ProtocolReq
;
441 * Now, initiate the vsc/vsp initialization protocol on the open channel
443 memset(request
, sizeof(struct mousevsc_prt_msg
), 0);
445 request
->PacketType
= PipeMessageData
;
446 request
->DataSize
= sizeof(SYNTHHID_PROTOCOL_REQUEST
);
448 request
->u
.Request
.Header
.Type
= SynthHidProtocolRequest
;
449 request
->u
.Request
.Header
.Size
= sizeof(unsigned long);
450 request
->u
.Request
.VersionRequested
.AsDWord
=
451 SYNTHHID_INPUT_VERSION_DWORD
;
453 pr_info("SYNTHHID_PROTOCOL_REQUEST...");
455 ret
= vmbus_sendpacket(Device
->channel
, request
,
456 sizeof(struct pipe_prt_msg
) -
457 sizeof(unsigned char) +
458 sizeof(SYNTHHID_PROTOCOL_REQUEST
),
459 (unsigned long)request
,
461 VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED
);
463 pr_err("unable to send SYNTHHID_PROTOCOL_REQUEST");
467 inputDevice
->protocol_wait_condition
= 0;
468 wait_event_timeout(inputDevice
->ProtocolWaitEvent
, inputDevice
->protocol_wait_condition
, msecs_to_jiffies(1000));
469 if (inputDevice
->protocol_wait_condition
== 0) {
474 response
= &inputDevice
->ProtocolResp
;
476 if (!response
->u
.Response
.Approved
) {
477 pr_err("SYNTHHID_PROTOCOL_REQUEST failed (version %d)",
478 SYNTHHID_INPUT_VERSION_DWORD
);
483 inputDevice
->device_wait_condition
= 0;
484 wait_event_timeout(inputDevice
->DeviceInfoWaitEvent
, inputDevice
->device_wait_condition
, msecs_to_jiffies(1000));
485 if (inputDevice
->device_wait_condition
== 0) {
491 * We should have gotten the device attr, hid desc and report
494 if (!inputDevice
->DeviceInfoStatus
)
495 pr_info("**** input channel up and running!! ****");
500 PutInputDevice(Device
);
509 * MousevscOnDeviceRemove()
512 * Callback when the our device is being removed
516 MousevscOnDeviceRemove(struct hv_device
*Device
)
518 struct mousevsc_dev
*inputDevice
;
521 pr_info("disabling input device (%p)...",
524 inputDevice
= ReleaseInputDevice(Device
);
528 * At this point, all outbound traffic should be disable. We only
529 * allow inbound traffic (responses) to proceed
531 * so that outstanding requests can be completed.
533 while (inputDevice
->NumOutstandingRequests
) {
534 pr_info("waiting for %d requests to complete...", inputDevice
->NumOutstandingRequests
);
539 pr_info("removing input device (%p)...", Device
->ext
);
541 inputDevice
= FinalReleaseInputDevice(Device
);
543 pr_info("input device (%p) safe to remove", inputDevice
);
545 /* Close the channel */
546 vmbus_close(Device
->channel
);
548 FreeInputDevice(inputDevice
);
557 * MousevscOnCleanup()
560 * Perform any cleanup when the driver is removed
562 static void MousevscOnCleanup(struct hv_driver
*drv
)
568 MousevscOnSendCompletion(struct hv_device
*Device
,
569 struct vmpacket_descriptor
*Packet
)
571 struct mousevsc_dev
*inputDevice
;
574 inputDevice
= MustGetInputDevice(Device
);
576 pr_err("unable to get input device...device being destroyed?");
580 request
= (void *)(unsigned long *)Packet
->trans_id
;
582 if (request
== &inputDevice
->ProtocolReq
) {
584 /* Shouldn't we be doing something here? */
587 PutInputDevice(Device
);
591 MousevscOnReceiveDeviceInfo(
592 struct mousevsc_dev
*InputDevice
,
593 SYNTHHID_DEVICE_INFO
*DeviceInfo
)
596 struct hid_descriptor
*desc
;
597 struct mousevsc_prt_msg ack
;
599 /* Assume success for now */
600 InputDevice
->DeviceInfoStatus
= 0;
602 /* Save the device attr */
603 memcpy(&InputDevice
->DeviceAttr
, &DeviceInfo
->HidDeviceAttributes
, sizeof(struct input_dev_info
));
605 /* Save the hid desc */
606 desc
= (struct hid_descriptor
*)DeviceInfo
->HidDescriptorInformation
;
607 WARN_ON(desc
->bLength
> 0);
609 InputDevice
->HidDesc
= kzalloc(desc
->bLength
, GFP_KERNEL
);
611 if (!InputDevice
->HidDesc
) {
612 pr_err("unable to allocate hid descriptor - size %d", desc
->bLength
);
616 memcpy(InputDevice
->HidDesc
, desc
, desc
->bLength
);
618 /* Save the report desc */
619 InputDevice
->ReportDescSize
= desc
->desc
[0].wDescriptorLength
;
620 InputDevice
->ReportDesc
= kzalloc(InputDevice
->ReportDescSize
,
623 if (!InputDevice
->ReportDesc
) {
624 pr_err("unable to allocate report descriptor - size %d",
625 InputDevice
->ReportDescSize
);
629 memcpy(InputDevice
->ReportDesc
,
630 ((unsigned char *)desc
) + desc
->bLength
,
631 desc
->desc
[0].wDescriptorLength
);
634 memset(&ack
, sizeof(struct mousevsc_prt_msg
), 0);
636 ack
.PacketType
= PipeMessageData
;
637 ack
.DataSize
= sizeof(SYNTHHID_DEVICE_INFO_ACK
);
639 ack
.u
.Ack
.Header
.Type
= SynthHidInitialDeviceInfoAck
;
640 ack
.u
.Ack
.Header
.Size
= 1;
641 ack
.u
.Ack
.Reserved
= 0;
643 ret
= vmbus_sendpacket(InputDevice
->Device
->channel
,
645 sizeof(struct pipe_prt_msg
) - sizeof(unsigned char) + sizeof(SYNTHHID_DEVICE_INFO_ACK
),
648 VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED
);
650 pr_err("unable to send SYNTHHID_DEVICE_INFO_ACK - ret %d",
655 InputDevice
->device_wait_condition
= 1;
656 wake_up(&InputDevice
->DeviceInfoWaitEvent
);
661 if (InputDevice
->HidDesc
) {
662 kfree(InputDevice
->HidDesc
);
663 InputDevice
->HidDesc
= NULL
;
666 if (InputDevice
->ReportDesc
) {
667 kfree(InputDevice
->ReportDesc
);
668 InputDevice
->ReportDesc
= NULL
;
671 InputDevice
->DeviceInfoStatus
= -1;
672 InputDevice
->device_wait_condition
= 1;
673 wake_up(&InputDevice
->DeviceInfoWaitEvent
);
678 MousevscOnReceiveInputReport(
679 struct mousevsc_dev
*InputDevice
,
680 SYNTHHID_INPUT_REPORT
*InputReport
)
682 struct mousevsc_drv_obj
*inputDriver
;
684 if (!InputDevice
->bInitializeComplete
) {
685 pr_info("Initialization incomplete...ignoring InputReport msg");
689 inputDriver
= (struct mousevsc_drv_obj
*)InputDevice
->Device
->drv
;
691 inputDriver
->OnInputReport(InputDevice
->Device
,
692 InputReport
->ReportBuffer
,
693 InputReport
->Header
.Size
);
697 MousevscOnReceive(struct hv_device
*Device
, struct vmpacket_descriptor
*Packet
)
699 struct pipe_prt_msg
*pipeMsg
;
700 SYNTHHID_MESSAGE
*hidMsg
;
701 struct mousevsc_dev
*inputDevice
;
703 inputDevice
= MustGetInputDevice(Device
);
705 pr_err("unable to get input device...device being destroyed?");
709 pipeMsg
= (struct pipe_prt_msg
*)((unsigned long)Packet
+ (Packet
->offset8
<< 3));
711 if (pipeMsg
->PacketType
!= PipeMessageData
) {
712 pr_err("unknown pipe msg type - type %d len %d",
713 pipeMsg
->PacketType
, pipeMsg
->DataSize
);
714 PutInputDevice(Device
);
718 hidMsg
= (SYNTHHID_MESSAGE
*)&pipeMsg
->Data
[0];
720 switch (hidMsg
->Header
.Type
) {
721 case SynthHidProtocolResponse
:
722 memcpy(&inputDevice
->ProtocolResp
, pipeMsg
, pipeMsg
->DataSize
+sizeof(struct pipe_prt_msg
) - sizeof(unsigned char));
723 inputDevice
->protocol_wait_condition
= 1;
724 wake_up(&inputDevice
->ProtocolWaitEvent
);
727 case SynthHidInitialDeviceInfo
:
728 WARN_ON(pipeMsg
->DataSize
>= sizeof(struct input_dev_info
));
731 * Parse out the device info into device attr,
732 * hid desc and report desc
734 MousevscOnReceiveDeviceInfo(inputDevice
,
735 (SYNTHHID_DEVICE_INFO
*)&pipeMsg
->Data
[0]);
737 case SynthHidInputReport
:
738 MousevscOnReceiveInputReport(inputDevice
,
739 (SYNTHHID_INPUT_REPORT
*)&pipeMsg
->Data
[0]);
743 pr_err("unsupported hid msg type - type %d len %d",
744 hidMsg
->Header
.Type
, hidMsg
->Header
.Size
);
748 PutInputDevice(Device
);
751 void MousevscOnChannelCallback(void *Context
)
753 const int packetSize
= 0x100;
755 struct hv_device
*device
= (struct hv_device
*)Context
;
756 struct mousevsc_dev
*inputDevice
;
760 unsigned char packet
[packetSize
];
761 struct vmpacket_descriptor
*desc
;
762 unsigned char *buffer
= packet
;
763 int bufferlen
= packetSize
;
765 inputDevice
= MustGetInputDevice(device
);
768 pr_err("unable to get input device...device being destroyed?");
773 ret
= vmbus_recvpacket_raw(device
->channel
, buffer
, bufferlen
, &bytesRecvd
, &requestId
);
776 if (bytesRecvd
> 0) {
777 desc
= (struct vmpacket_descriptor
*)buffer
;
779 switch (desc
->type
) {
781 MousevscOnSendCompletion(device
,
785 case VM_PKT_DATA_INBAND
:
786 MousevscOnReceive(device
, desc
);
790 pr_err("unhandled packet type %d, tid %llx len %d\n",
798 if (bufferlen
> packetSize
) {
802 bufferlen
= packetSize
;
806 * pr_debug("nothing else to read...");
809 if (bufferlen
> packetSize
) {
813 bufferlen
= packetSize
;
817 } else if (ret
== -2) {
818 /* Handle large packet */
819 bufferlen
= bytesRecvd
;
820 buffer
= kzalloc(bytesRecvd
, GFP_KERNEL
);
822 if (buffer
== NULL
) {
824 bufferlen
= packetSize
;
826 /* Try again next time around */
827 pr_err("unable to allocate buffer of size %d!",
834 PutInputDevice(device
);
842 struct input_device_context
{
843 struct vm_device
*device_ctx
;
844 struct hid_device
*hid_device
;
845 struct input_dev_info device_info
;
849 struct mousevsc_driver_context
{
850 struct driver_context drv_ctx
;
851 struct mousevsc_drv_obj drv_obj
;
854 static struct mousevsc_driver_context g_mousevsc_drv
;
856 void mousevsc_deviceinfo_callback(struct hv_device
*dev
,
857 struct input_dev_info
*info
)
859 struct vm_device
*device_ctx
= to_vm_device(dev
);
860 struct input_device_context
*input_device_ctx
=
861 dev_get_drvdata(&device_ctx
->device
);
863 memcpy(&input_device_ctx
->device_info
, info
,
864 sizeof(struct input_dev_info
));
866 DPRINT_INFO(INPUTVSC_DRV
, "mousevsc_deviceinfo_callback()");
869 void mousevsc_inputreport_callback(struct hv_device
*dev
, void *packet
, u32 len
)
873 struct vm_device
*device_ctx
= to_vm_device(dev
);
874 struct input_device_context
*input_dev_ctx
=
875 dev_get_drvdata(&device_ctx
->device
);
877 ret
= hid_input_report(input_dev_ctx
->hid_device
,
878 HID_INPUT_REPORT
, packet
, len
, 1);
880 DPRINT_DBG(INPUTVSC_DRV
, "hid_input_report (ret %d)", ret
);
883 int mousevsc_hid_open(struct hid_device
*hid
)
888 void mousevsc_hid_close(struct hid_device
*hid
)
892 int mousevsc_probe(struct device
*device
)
896 struct driver_context
*driver_ctx
=
897 driver_to_driver_context(device
->driver
);
898 struct mousevsc_driver_context
*mousevsc_drv_ctx
=
899 (struct mousevsc_driver_context
*)driver_ctx
;
900 struct mousevsc_drv_obj
*mousevsc_drv_obj
= &mousevsc_drv_ctx
->drv_obj
;
902 struct vm_device
*device_ctx
= device_to_vm_device(device
);
903 struct hv_device
*device_obj
= &device_ctx
->device_obj
;
904 struct input_device_context
*input_dev_ctx
;
906 input_dev_ctx
= kmalloc(sizeof(struct input_device_context
),
909 dev_set_drvdata(device
, input_dev_ctx
);
911 /* Call to the vsc driver to add the device */
912 ret
= mousevsc_drv_obj
->Base
.dev_add(device_obj
, NULL
);
915 DPRINT_ERR(INPUTVSC_DRV
, "unable to add input vsc device");
924 int mousevsc_remove(struct device
*device
)
928 struct driver_context
*driver_ctx
=
929 driver_to_driver_context(device
->driver
);
930 struct mousevsc_driver_context
*mousevsc_drv_ctx
=
931 (struct mousevsc_driver_context
*)driver_ctx
;
932 struct mousevsc_drv_obj
*mousevsc_drv_obj
= &mousevsc_drv_ctx
->drv_obj
;
934 struct vm_device
*device_ctx
= device_to_vm_device(device
);
935 struct hv_device
*device_obj
= &device_ctx
->device_obj
;
936 struct input_device_context
*input_dev_ctx
;
938 input_dev_ctx
= kmalloc(sizeof(struct input_device_context
),
941 dev_set_drvdata(device
, input_dev_ctx
);
943 if (input_dev_ctx
->connected
) {
944 hidinput_disconnect(input_dev_ctx
->hid_device
);
945 input_dev_ctx
->connected
= 0;
948 if (!mousevsc_drv_obj
->Base
.dev_rm
)
952 * Call to the vsc driver to let it know that the device
955 ret
= mousevsc_drv_obj
->Base
.dev_rm(device_obj
);
958 DPRINT_ERR(INPUTVSC_DRV
,
959 "unable to remove vsc device (ret %d)", ret
);
962 kfree(input_dev_ctx
);
967 void mousevsc_reportdesc_callback(struct hv_device
*dev
, void *packet
, u32 len
)
969 struct vm_device
*device_ctx
= to_vm_device(dev
);
970 struct input_device_context
*input_device_ctx
=
971 dev_get_drvdata(&device_ctx
->device
);
972 struct hid_device
*hid_dev
;
974 /* hid_debug = -1; */
975 hid_dev
= kmalloc(sizeof(struct hid_device
), GFP_KERNEL
);
977 if (hid_parse_report(hid_dev
, packet
, len
)) {
978 DPRINT_INFO(INPUTVSC_DRV
, "Unable to call hd_parse_report");
983 DPRINT_INFO(INPUTVSC_DRV
, "hid_device created");
985 hid_dev
->ll_driver
->open
= mousevsc_hid_open
;
986 hid_dev
->ll_driver
->close
= mousevsc_hid_close
;
988 hid_dev
->bus
= 0x06; /* BUS_VIRTUAL */
989 hid_dev
->vendor
= input_device_ctx
->device_info
.VendorID
;
990 hid_dev
->product
= input_device_ctx
->device_info
.ProductID
;
991 hid_dev
->version
= input_device_ctx
->device_info
.VersionNumber
;
992 hid_dev
->dev
= device_ctx
->device
;
994 sprintf(hid_dev
->name
, "%s",
995 input_device_ctx
->device_info
.Name
);
998 * HJ Do we want to call it with a 0
1000 if (!hidinput_connect(hid_dev
, 0)) {
1001 hid_dev
->claimed
|= HID_CLAIMED_INPUT
;
1003 input_device_ctx
->connected
= 1;
1005 DPRINT_INFO(INPUTVSC_DRV
,
1006 "HID device claimed by input\n");
1009 if (!hid_dev
->claimed
) {
1010 DPRINT_ERR(INPUTVSC_DRV
,
1011 "HID device not claimed by "
1012 "input or hiddev\n");
1015 input_device_ctx
->hid_device
= hid_dev
;
1023 * Name: mousevsc_drv_init()
1025 * Desc: Driver initialization.
1027 int mousevsc_drv_init(int (*pfn_drv_init
)(struct hv_driver
*pfn_drv_init
))
1030 struct mousevsc_drv_obj
*input_drv_obj
= &g_mousevsc_drv
.drv_obj
;
1031 struct driver_context
*drv_ctx
= &g_mousevsc_drv
.drv_ctx
;
1033 input_drv_obj
->OnDeviceInfo
= mousevsc_deviceinfo_callback
;
1034 input_drv_obj
->OnInputReport
= mousevsc_inputreport_callback
;
1035 input_drv_obj
->OnReportDescriptor
= mousevsc_reportdesc_callback
;
1037 /* Callback to client driver to complete the initialization */
1038 pfn_drv_init(&input_drv_obj
->Base
);
1040 drv_ctx
->driver
.name
= input_drv_obj
->Base
.name
;
1041 memcpy(&drv_ctx
->class_id
, &input_drv_obj
->Base
.dev_type
,
1042 sizeof(struct hv_guid
));
1044 drv_ctx
->probe
= mousevsc_probe
;
1045 drv_ctx
->remove
= mousevsc_remove
;
1047 /* The driver belongs to vmbus */
1048 vmbus_child_driver_register(drv_ctx
);
1054 int mousevsc_drv_exit_cb(struct device
*dev
, void *data
)
1056 struct device
**curr
= (struct device
**)data
;
1062 void mousevsc_drv_exit(void)
1064 struct mousevsc_drv_obj
*mousevsc_drv_obj
= &g_mousevsc_drv
.drv_obj
;
1065 struct driver_context
*drv_ctx
= &g_mousevsc_drv
.drv_ctx
;
1068 struct device
*current_dev
= NULL
;
1073 /* Get the device */
1074 ret
= driver_for_each_device(&drv_ctx
->driver
, NULL
,
1075 (void *)¤t_dev
,
1076 mousevsc_drv_exit_cb
);
1078 printk(KERN_ERR
"Can't find mouse device!\n");
1080 if (current_dev
== NULL
)
1083 /* Initiate removal from the top-down */
1084 device_unregister(current_dev
);
1087 if (mousevsc_drv_obj
->Base
.cleanup
)
1088 mousevsc_drv_obj
->Base
.cleanup(&mousevsc_drv_obj
->Base
);
1090 vmbus_child_driver_unregister(drv_ctx
);
1095 static int __init
mousevsc_init(void)
1099 DPRINT_INFO(INPUTVSC_DRV
, "Hyper-V Mouse driver initializing.");
1101 ret
= mousevsc_drv_init(mouse_vsc_initialize
);
1106 static void __exit
mousevsc_exit(void)
1108 mousevsc_drv_exit();
1112 * We don't want to automatically load this driver just yet, it's quite
1113 * broken. It's safe if you want to load it yourself manually, but
1114 * don't inflict it on unsuspecting users, that's just mean.
1119 * We use a PCI table to determine if we should autoload this driver This is
1120 * needed by distro tools to determine if the hyperv drivers should be
1121 * installed and/or configured. We don't do anything else with the table, but
1122 * it needs to be present.
1124 const static struct pci_device_id microsoft_hv_pci_table
[] = {
1125 { PCI_DEVICE(0x1414, 0x5353) }, /* VGA compatible controller */
1128 MODULE_DEVICE_TABLE(pci
, microsoft_hv_pci_table
);
1131 MODULE_LICENSE("GPL");
1132 MODULE_VERSION(HV_DRV_VERSION
);
1133 module_init(mousevsc_init
);
1134 module_exit(mousevsc_exit
);