Staging: hv: delete vmbus_hid_protocol.h
[zen-stable.git] / drivers / staging / hv / hv_mouse.c
blobb62409d22ce52f76b26d427b67998f9c36e7be00
1 /*
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
13 * more details.
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>
27 #include "hv_api.h"
28 #include "logging.h"
29 #include "version_info.h"
30 #include "vmbus.h"
31 #include "vmbus_api.h"
32 #include "mousevsc_api.h"
33 #include "channel.h"
34 #include "vmbus_packet_format.h"
37 /* The maximum size of a synthetic input message. */
38 #define SYNTHHID_MAX_INPUT_REPORT_SIZE 16
41 * Current version
43 * History:
44 * Beta, RC < 2008/1/22 1,0
45 * RC > 2008/1/22 2,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))
53 #pragma pack(push,1)
55 * Message types in the synthetic input protocol
57 enum synthhid_msg_type {
58 SynthHidProtocolRequest,
59 SynthHidProtocolResponse,
60 SynthHidInitialDeviceInfo,
61 SynthHidInitialDeviceInfoAck,
62 SynthHidInputReport,
63 SynthHidMax
67 * Basic message structures.
69 typedef struct {
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;
76 typedef struct {
77 SYNTHHID_MESSAGE_HEADER Header;
78 char Data[1]; /* Enclosed message */
79 } SYNTHHID_MESSAGE, *PSYNTHHID_MESSAGE;
81 typedef union {
82 struct {
83 u16 Minor;
84 u16 Major;
87 u32 AsDWord;
88 } SYNTHHID_VERSION, *PSYNTHHID_VERSION;
91 * Protocol messages
93 typedef struct {
94 SYNTHHID_MESSAGE_HEADER Header;
95 SYNTHHID_VERSION VersionRequested;
96 } SYNTHHID_PROTOCOL_REQUEST, *PSYNTHHID_PROTOCOL_REQUEST;
98 typedef struct {
99 SYNTHHID_MESSAGE_HEADER Header;
100 SYNTHHID_VERSION VersionRequested;
101 unsigned char Approved;
102 } SYNTHHID_PROTOCOL_RESPONSE, *PSYNTHHID_PROTOCOL_RESPONSE;
104 typedef struct {
105 SYNTHHID_MESSAGE_HEADER Header;
106 struct input_dev_info HidDeviceAttributes;
107 unsigned char HidDescriptorInformation[1];
108 } SYNTHHID_DEVICE_INFO, *PSYNTHHID_DEVICE_INFO;
110 typedef struct {
111 SYNTHHID_MESSAGE_HEADER Header;
112 unsigned char Reserved;
113 } SYNTHHID_DEVICE_INFO_ACK, *PSYNTHHID_DEVICE_INFO_ACK;
115 typedef struct {
116 SYNTHHID_MESSAGE_HEADER Header;
117 char ReportBuffer[1];
118 } SYNTHHID_INPUT_REPORT, *PSYNTHHID_INPUT_REPORT;
120 #pragma pack(pop)
123 #define NBITS(x) (((x)/BITS_PER_LONG)+1)
125 enum pipe_prot_msg_type {
126 PipeMessageInvalid = 0,
127 PipeMessageData,
128 PipeMessageMaximum
132 struct pipe_prt_msg {
133 enum pipe_prot_msg_type PacketType;
134 u32 DataSize;
135 char Data[1];
139 * Data types
141 struct mousevsc_prt_msg {
142 enum pipe_prot_msg_type PacketType;
143 u32 DataSize;
144 union {
145 SYNTHHID_PROTOCOL_REQUEST Request;
146 SYNTHHID_PROTOCOL_RESPONSE Response;
147 SYNTHHID_DEVICE_INFO_ACK Ack;
148 } u;
152 * Represents an mousevsc device
154 struct mousevsc_dev {
155 struct hv_device *Device;
156 /* 0 indicates the device is being destroyed */
157 atomic_t RefCount;
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;
171 u32 ReportDescSize;
172 struct input_dev_info DeviceAttr;
177 * Globals
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}
188 * Internal routines
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);
209 if (!inputDevice)
210 return NULL;
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;
221 return inputDevice;
224 static inline void FreeInputDevice(struct mousevsc_dev *Device)
226 WARN_ON(atomic_read(&Device->RefCount) == 0);
227 kfree(Device);
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;
240 * FIXME
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);
250 else
251 inputDevice = NULL;
253 return inputDevice;
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);
267 else
268 inputDevice = NULL;
270 return inputDevice;
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)
293 udelay(100);
295 return inputDevice;
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)
309 udelay(100);
311 Device->ext = NULL;
312 return inputDevice;
317 * Name:
318 * MousevscInitialize()
320 * Description:
321 * Main entry point
324 int mouse_vsc_initialize(struct hv_driver *Driver)
326 struct mousevsc_drv_obj *inputDriver =
327 (struct mousevsc_drv_obj *)Driver;
328 int ret = 0;
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;
342 return ret;
347 * Name:
348 * MousevscOnDeviceAdd()
350 * Description:
351 * Callback when the device belonging to this driver is added
355 MousevscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo)
357 int ret = 0;
358 struct mousevsc_dev *inputDevice;
359 struct mousevsc_drv_obj *inputDriver;
360 struct input_dev_info deviceInfo;
362 inputDevice = AllocInputDevice(Device);
364 if (!inputDevice) {
365 ret = -1;
366 goto Cleanup;
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,
375 NULL,
377 MousevscOnChannelCallback,
378 Device
381 if (ret != 0) {
382 pr_err("unable to open channel: %d", ret);
383 return -1;
386 pr_info("InputVsc channel open: %d", ret);
388 ret = MousevscConnectToVsp(Device);
390 if (ret != 0) {
391 pr_err("unable to connect channel: %d", ret);
393 vmbus_close(Device->channel);
394 return ret;
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;
416 Cleanup:
417 return ret;
421 MousevscConnectToVsp(struct hv_device *Device)
423 int ret = 0;
424 struct mousevsc_dev *inputDevice;
425 struct mousevsc_prt_msg *request;
426 struct mousevsc_prt_msg *response;
428 inputDevice = GetInputDevice(Device);
430 if (!inputDevice) {
431 pr_err("unable to get input device...device being destroyed?");
432 return -1;
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,
460 VM_PKT_DATA_INBAND,
461 VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
462 if (ret != 0) {
463 pr_err("unable to send SYNTHHID_PROTOCOL_REQUEST");
464 goto Cleanup;
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) {
470 ret = -ETIMEDOUT;
471 goto Cleanup;
474 response = &inputDevice->ProtocolResp;
476 if (!response->u.Response.Approved) {
477 pr_err("SYNTHHID_PROTOCOL_REQUEST failed (version %d)",
478 SYNTHHID_INPUT_VERSION_DWORD);
479 ret = -1;
480 goto Cleanup;
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) {
486 ret = -ETIMEDOUT;
487 goto Cleanup;
491 * We should have gotten the device attr, hid desc and report
492 * desc at this point
494 if (!inputDevice->DeviceInfoStatus)
495 pr_info("**** input channel up and running!! ****");
496 else
497 ret = -1;
499 Cleanup:
500 PutInputDevice(Device);
502 return ret;
508 * Name:
509 * MousevscOnDeviceRemove()
511 * Description:
512 * Callback when the our device is being removed
516 MousevscOnDeviceRemove(struct hv_device *Device)
518 struct mousevsc_dev *inputDevice;
519 int ret = 0;
521 pr_info("disabling input device (%p)...",
522 Device->ext);
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);
536 udelay(100);
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);
550 return ret;
556 * Name:
557 * MousevscOnCleanup()
559 * Description:
560 * Perform any cleanup when the driver is removed
562 static void MousevscOnCleanup(struct hv_driver *drv)
567 static void
568 MousevscOnSendCompletion(struct hv_device *Device,
569 struct vmpacket_descriptor *Packet)
571 struct mousevsc_dev *inputDevice;
572 void *request;
574 inputDevice = MustGetInputDevice(Device);
575 if (!inputDevice) {
576 pr_err("unable to get input device...device being destroyed?");
577 return;
580 request = (void *)(unsigned long *)Packet->trans_id;
582 if (request == &inputDevice->ProtocolReq) {
583 /* FIXME */
584 /* Shouldn't we be doing something here? */
587 PutInputDevice(Device);
590 void
591 MousevscOnReceiveDeviceInfo(
592 struct mousevsc_dev *InputDevice,
593 SYNTHHID_DEVICE_INFO *DeviceInfo)
595 int ret = 0;
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);
613 goto Cleanup;
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,
621 GFP_KERNEL);
623 if (!InputDevice->ReportDesc) {
624 pr_err("unable to allocate report descriptor - size %d",
625 InputDevice->ReportDescSize);
626 goto Cleanup;
629 memcpy(InputDevice->ReportDesc,
630 ((unsigned char *)desc) + desc->bLength,
631 desc->desc[0].wDescriptorLength);
633 /* Send the ack */
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,
644 &ack,
645 sizeof(struct pipe_prt_msg) - sizeof(unsigned char) + sizeof(SYNTHHID_DEVICE_INFO_ACK),
646 (unsigned long)&ack,
647 VM_PKT_DATA_INBAND,
648 VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
649 if (ret != 0) {
650 pr_err("unable to send SYNTHHID_DEVICE_INFO_ACK - ret %d",
651 ret);
652 goto Cleanup;
655 InputDevice->device_wait_condition = 1;
656 wake_up(&InputDevice->DeviceInfoWaitEvent);
658 return;
660 Cleanup:
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);
677 void
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");
686 return;
689 inputDriver = (struct mousevsc_drv_obj *)InputDevice->Device->drv;
691 inputDriver->OnInputReport(InputDevice->Device,
692 InputReport->ReportBuffer,
693 InputReport->Header.Size);
696 void
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);
704 if (!inputDevice) {
705 pr_err("unable to get input device...device being destroyed?");
706 return;
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);
715 return ;
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);
725 break;
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]);
736 break;
737 case SynthHidInputReport:
738 MousevscOnReceiveInputReport(inputDevice,
739 (SYNTHHID_INPUT_REPORT *)&pipeMsg->Data[0]);
741 break;
742 default:
743 pr_err("unsupported hid msg type - type %d len %d",
744 hidMsg->Header.Type, hidMsg->Header.Size);
745 break;
748 PutInputDevice(Device);
751 void MousevscOnChannelCallback(void *Context)
753 const int packetSize = 0x100;
754 int ret = 0;
755 struct hv_device *device = (struct hv_device *)Context;
756 struct mousevsc_dev *inputDevice;
758 u32 bytesRecvd;
759 u64 requestId;
760 unsigned char packet[packetSize];
761 struct vmpacket_descriptor *desc;
762 unsigned char *buffer = packet;
763 int bufferlen = packetSize;
765 inputDevice = MustGetInputDevice(device);
767 if (!inputDevice) {
768 pr_err("unable to get input device...device being destroyed?");
769 return;
772 do {
773 ret = vmbus_recvpacket_raw(device->channel, buffer, bufferlen, &bytesRecvd, &requestId);
775 if (ret == 0) {
776 if (bytesRecvd > 0) {
777 desc = (struct vmpacket_descriptor *)buffer;
779 switch (desc->type) {
780 case VM_PKT_COMP:
781 MousevscOnSendCompletion(device,
782 desc);
783 break;
785 case VM_PKT_DATA_INBAND:
786 MousevscOnReceive(device, desc);
787 break;
789 default:
790 pr_err("unhandled packet type %d, tid %llx len %d\n",
791 desc->type,
792 requestId,
793 bytesRecvd);
794 break;
797 /* reset */
798 if (bufferlen > packetSize) {
799 kfree(buffer);
801 buffer = packet;
802 bufferlen = packetSize;
804 } else {
806 * pr_debug("nothing else to read...");
807 * reset
809 if (bufferlen > packetSize) {
810 kfree(buffer);
812 buffer = packet;
813 bufferlen = packetSize;
815 break;
817 } else if (ret == -2) {
818 /* Handle large packet */
819 bufferlen = bytesRecvd;
820 buffer = kzalloc(bytesRecvd, GFP_KERNEL);
822 if (buffer == NULL) {
823 buffer = packet;
824 bufferlen = packetSize;
826 /* Try again next time around */
827 pr_err("unable to allocate buffer of size %d!",
828 bytesRecvd);
829 break;
832 } while (1);
834 PutInputDevice(device);
836 return;
840 * Data types
842 struct input_device_context {
843 struct vm_device *device_ctx;
844 struct hid_device *hid_device;
845 struct input_dev_info device_info;
846 int connected;
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)
871 int ret = 0;
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)
885 return 0;
888 void mousevsc_hid_close(struct hid_device *hid)
892 int mousevsc_probe(struct device *device)
894 int ret = 0;
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),
907 GFP_KERNEL);
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);
914 if (ret != 0) {
915 DPRINT_ERR(INPUTVSC_DRV, "unable to add input vsc device");
917 return -1;
920 return 0;
924 int mousevsc_remove(struct device *device)
926 int ret = 0;
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),
939 GFP_KERNEL);
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)
949 return -1;
952 * Call to the vsc driver to let it know that the device
953 * is being removed
955 ret = mousevsc_drv_obj->Base.dev_rm(device_obj);
957 if (ret != 0) {
958 DPRINT_ERR(INPUTVSC_DRV,
959 "unable to remove vsc device (ret %d)", ret);
962 kfree(input_dev_ctx);
964 return ret;
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");
979 return;
982 if (hid_dev) {
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;
1018 kfree(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))
1029 int ret = 0;
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);
1050 return ret;
1054 int mousevsc_drv_exit_cb(struct device *dev, void *data)
1056 struct device **curr = (struct device **)data;
1057 *curr = dev;
1059 return 1;
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;
1066 int ret;
1068 struct device *current_dev = NULL;
1070 while (1) {
1071 current_dev = NULL;
1073 /* Get the device */
1074 ret = driver_for_each_device(&drv_ctx->driver, NULL,
1075 (void *)&current_dev,
1076 mousevsc_drv_exit_cb);
1077 if (ret)
1078 printk(KERN_ERR "Can't find mouse device!\n");
1080 if (current_dev == NULL)
1081 break;
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);
1092 return;
1095 static int __init mousevsc_init(void)
1097 int ret;
1099 DPRINT_INFO(INPUTVSC_DRV, "Hyper-V Mouse driver initializing.");
1101 ret = mousevsc_drv_init(mouse_vsc_initialize);
1103 return ret;
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.
1116 #if 0
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 */
1126 { 0 }
1128 MODULE_DEVICE_TABLE(pci, microsoft_hv_pci_table);
1129 #endif
1131 MODULE_LICENSE("GPL");
1132 MODULE_VERSION(HV_DRV_VERSION);
1133 module_init(mousevsc_init);
1134 module_exit(mousevsc_exit);