Staging: hv: hv_mouse: rename hv_mouse_drv.c
[pandora-kernel.git] / drivers / staging / hv / hv_mouse.c
1 /*
2  *  Copyright 2009 Citrix Systems, Inc.
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License along
15  *  with this program; if not, write to the Free Software Foundation, Inc.,
16  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  *
18  *  For clarity, the licensor of this program does not intend that a
19  *  "derivative work" include code which compiles header information from
20  *  this program.
21  *
22  *  This code has been modified from its original by
23  *  Hank Janssen <hjanssen@microsoft.com>
24  *
25  */
26 #include <linux/init.h>
27 #include <linux/module.h>
28 #include <linux/device.h>
29 #include <linux/workqueue.h>
30 #include <linux/sched.h>
31 #include <linux/wait.h>
32 #include <linux/input.h>
33 #include <linux/hid.h>
34 #include <linux/hiddev.h>
35 #include <linux/pci.h>
36 #include <linux/dmi.h>
37
38 #include "hv_api.h"
39 #include "logging.h"
40 #include "version_info.h"
41 #include "vmbus.h"
42 #include "vmbus_api.h"
43 #include "mousevsc_api.h"
44 #include "channel.h"
45 #include "vmbus_packet_format.h"
46 #include "vmbus_hid_protocol.h"
47
48 #define NBITS(x) (((x)/BITS_PER_LONG)+1)
49
50 enum pipe_prot_msg_type {
51         PipeMessageInvalid = 0,
52         PipeMessageData,
53         PipeMessageMaximum
54 };
55
56
57 struct pipe_prt_msg {
58         enum pipe_prot_msg_type PacketType;
59         u32                DataSize;
60         char               Data[1];
61 };
62
63 /*
64  * Data types
65  */
66 struct  mousevsc_prt_msg {
67         enum pipe_prot_msg_type   PacketType;
68         u32                  DataSize;
69         union {
70                 SYNTHHID_PROTOCOL_REQUEST       Request;
71                 SYNTHHID_PROTOCOL_RESPONSE      Response;
72                 SYNTHHID_DEVICE_INFO_ACK        Ack;
73         } u;
74 };
75
76 /*
77  * Represents an mousevsc device
78  */
79 struct mousevsc_dev {
80         struct hv_device        *Device;
81         /* 0 indicates the device is being destroyed */
82         atomic_t                RefCount;
83         int                     NumOutstandingRequests;
84         unsigned char           bInitializeComplete;
85         struct mousevsc_prt_msg ProtocolReq;
86         struct mousevsc_prt_msg ProtocolResp;
87         /* Synchronize the request/response if needed */
88         wait_queue_head_t       ProtocolWaitEvent;
89         wait_queue_head_t       DeviceInfoWaitEvent;
90         int                     protocol_wait_condition;
91         int                     device_wait_condition;
92         int                     DeviceInfoStatus;
93
94         struct hid_descriptor   *HidDesc;
95         unsigned char           *ReportDesc;
96         u32                     ReportDescSize;
97         struct input_dev_info   DeviceAttr;
98 };
99
100
101 /*
102  * Globals
103  */
104 static const char *gDriverName = "mousevsc";
105
106 /* {CFA8B69E-5B4A-4cc0-B98B-8BA1A1F3F95A} */
107 static const struct hv_guid gMousevscDeviceType = {
108         .data = {0x9E, 0xB6, 0xA8, 0xCF, 0x4A, 0x5B, 0xc0, 0x4c,
109                  0xB9, 0x8B, 0x8B, 0xA1, 0xA1, 0xF3, 0xF9, 0x5A}
110 };
111
112 /*
113  * Internal routines
114  */
115 static int MousevscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo);
116
117 static int MousevscOnDeviceRemove(struct hv_device *Device);
118
119 static void MousevscOnCleanup(struct hv_driver *Device);
120
121 static void MousevscOnChannelCallback(void *Context);
122
123 static int MousevscConnectToVsp(struct hv_device *Device);
124
125 static void MousevscOnReceive(struct hv_device *Device,
126                               struct vmpacket_descriptor *Packet);
127
128 static inline struct mousevsc_dev *AllocInputDevice(struct hv_device *Device)
129 {
130         struct mousevsc_dev *inputDevice;
131
132         inputDevice = kzalloc(sizeof(struct mousevsc_dev), GFP_KERNEL);
133
134         if (!inputDevice)
135                 return NULL;
136
137         /*
138          * Set to 2 to allow both inbound and outbound traffics
139          * (ie GetInputDevice() and MustGetInputDevice()) to proceed.
140          */
141         atomic_cmpxchg(&inputDevice->RefCount, 0, 2);
142
143         inputDevice->Device = Device;
144         Device->ext = inputDevice;
145
146         return inputDevice;
147 }
148
149 static inline void FreeInputDevice(struct mousevsc_dev *Device)
150 {
151         WARN_ON(atomic_read(&Device->RefCount) == 0);
152         kfree(Device);
153 }
154
155 /*
156  * Get the inputdevice object if exists and its refcount > 1
157  */
158 static inline struct mousevsc_dev *GetInputDevice(struct hv_device *Device)
159 {
160         struct mousevsc_dev *inputDevice;
161
162         inputDevice = (struct mousevsc_dev *)Device->ext;
163
164 /*
165  *      FIXME
166  *      This sure isn't a valid thing to print for debugging, no matter
167  *      what the intention is...
168  *
169  *      printk(KERN_ERR "-------------------------> REFCOUNT = %d",
170  *             inputDevice->RefCount);
171  */
172
173         if (inputDevice && atomic_read(&inputDevice->RefCount) > 1)
174                 atomic_inc(&inputDevice->RefCount);
175         else
176                 inputDevice = NULL;
177
178         return inputDevice;
179 }
180
181 /*
182  * Get the inputdevice object iff exists and its refcount > 0
183  */
184 static inline struct mousevsc_dev *MustGetInputDevice(struct hv_device *Device)
185 {
186         struct mousevsc_dev *inputDevice;
187
188         inputDevice = (struct mousevsc_dev *)Device->ext;
189
190         if (inputDevice && atomic_read(&inputDevice->RefCount))
191                 atomic_inc(&inputDevice->RefCount);
192         else
193                 inputDevice = NULL;
194
195         return inputDevice;
196 }
197
198 static inline void PutInputDevice(struct hv_device *Device)
199 {
200         struct mousevsc_dev *inputDevice;
201
202         inputDevice = (struct mousevsc_dev *)Device->ext;
203
204         atomic_dec(&inputDevice->RefCount);
205 }
206
207 /*
208  * Drop ref count to 1 to effectively disable GetInputDevice()
209  */
210 static inline struct mousevsc_dev *ReleaseInputDevice(struct hv_device *Device)
211 {
212         struct mousevsc_dev *inputDevice;
213
214         inputDevice = (struct mousevsc_dev *)Device->ext;
215
216         /* Busy wait until the ref drop to 2, then set it to 1  */
217         while (atomic_cmpxchg(&inputDevice->RefCount, 2, 1) != 2)
218                 udelay(100);
219
220         return inputDevice;
221 }
222
223 /*
224  * Drop ref count to 0. No one can use InputDevice object.
225  */
226 static inline struct mousevsc_dev *FinalReleaseInputDevice(struct hv_device *Device)
227 {
228         struct mousevsc_dev *inputDevice;
229
230         inputDevice = (struct mousevsc_dev *)Device->ext;
231
232         /* Busy wait until the ref drop to 1, then set it to 0  */
233         while (atomic_cmpxchg(&inputDevice->RefCount, 1, 0) != 1)
234                 udelay(100);
235
236         Device->ext = NULL;
237         return inputDevice;
238 }
239
240 /*
241  *
242  * Name:
243  *      MousevscInitialize()
244  *
245  * Description:
246  *      Main entry point
247  *
248  */
249 int mouse_vsc_initialize(struct hv_driver *Driver)
250 {
251         struct mousevsc_drv_obj *inputDriver =
252                 (struct mousevsc_drv_obj *)Driver;
253         int ret = 0;
254
255         Driver->name = gDriverName;
256         memcpy(&Driver->dev_type, &gMousevscDeviceType,
257                sizeof(struct hv_guid));
258
259         /* Setup the dispatch table */
260         inputDriver->Base.dev_add               = MousevscOnDeviceAdd;
261         inputDriver->Base.dev_rm = MousevscOnDeviceRemove;
262         inputDriver->Base.cleanup               = MousevscOnCleanup;
263
264         inputDriver->OnOpen                     = NULL;
265         inputDriver->OnClose                    = NULL;
266
267         return ret;
268 }
269
270 /*
271  *
272  * Name:
273  *      MousevscOnDeviceAdd()
274  *
275  * Description:
276  *      Callback when the device belonging to this driver is added
277  *
278  */
279 int
280 MousevscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo)
281 {
282         int ret = 0;
283         struct mousevsc_dev *inputDevice;
284         struct mousevsc_drv_obj *inputDriver;
285         struct input_dev_info deviceInfo;
286
287         inputDevice = AllocInputDevice(Device);
288
289         if (!inputDevice) {
290                 ret = -1;
291                 goto Cleanup;
292         }
293
294         inputDevice->bInitializeComplete = false;
295
296         /* Open the channel */
297         ret = vmbus_open(Device->channel,
298                 INPUTVSC_SEND_RING_BUFFER_SIZE,
299                 INPUTVSC_RECV_RING_BUFFER_SIZE,
300                 NULL,
301                 0,
302                 MousevscOnChannelCallback,
303                 Device
304                 );
305
306         if (ret != 0) {
307                 pr_err("unable to open channel: %d", ret);
308                 return -1;
309         }
310
311         pr_info("InputVsc channel open: %d", ret);
312
313         ret = MousevscConnectToVsp(Device);
314
315         if (ret != 0) {
316                 pr_err("unable to connect channel: %d", ret);
317
318                 vmbus_close(Device->channel);
319                 return ret;
320         }
321
322         inputDriver = (struct mousevsc_drv_obj *)inputDevice->Device->drv;
323
324         deviceInfo.VendorID = inputDevice->DeviceAttr.VendorID;
325         deviceInfo.ProductID = inputDevice->DeviceAttr.ProductID;
326         deviceInfo.VersionNumber = inputDevice->DeviceAttr.VersionNumber;
327         strcpy(deviceInfo.Name, "Microsoft Vmbus HID-compliant Mouse");
328
329         /* Send the device info back up */
330         inputDriver->OnDeviceInfo(Device, &deviceInfo);
331
332         /* Send the report desc back up */
333         /* workaround SA-167 */
334         if (inputDevice->ReportDesc[14] == 0x25)
335                 inputDevice->ReportDesc[14] = 0x29;
336
337         inputDriver->OnReportDescriptor(Device, inputDevice->ReportDesc, inputDevice->ReportDescSize);
338
339         inputDevice->bInitializeComplete = true;
340
341 Cleanup:
342         return ret;
343 }
344
345 int
346 MousevscConnectToVsp(struct hv_device *Device)
347 {
348         int ret = 0;
349         struct mousevsc_dev *inputDevice;
350         struct mousevsc_prt_msg *request;
351         struct mousevsc_prt_msg *response;
352
353         inputDevice = GetInputDevice(Device);
354
355         if (!inputDevice) {
356                 pr_err("unable to get input device...device being destroyed?");
357                 return -1;
358         }
359
360         init_waitqueue_head(&inputDevice->ProtocolWaitEvent);
361         init_waitqueue_head(&inputDevice->DeviceInfoWaitEvent);
362
363         request = &inputDevice->ProtocolReq;
364
365         /*
366          * Now, initiate the vsc/vsp initialization protocol on the open channel
367          */
368         memset(request, sizeof(struct mousevsc_prt_msg), 0);
369
370         request->PacketType = PipeMessageData;
371         request->DataSize = sizeof(SYNTHHID_PROTOCOL_REQUEST);
372
373         request->u.Request.Header.Type = SynthHidProtocolRequest;
374         request->u.Request.Header.Size = sizeof(unsigned long);
375         request->u.Request.VersionRequested.AsDWord =
376                 SYNTHHID_INPUT_VERSION_DWORD;
377
378         pr_info("SYNTHHID_PROTOCOL_REQUEST...");
379
380         ret = vmbus_sendpacket(Device->channel, request,
381                                         sizeof(struct pipe_prt_msg) -
382                                         sizeof(unsigned char) +
383                                         sizeof(SYNTHHID_PROTOCOL_REQUEST),
384                                         (unsigned long)request,
385                                         VM_PKT_DATA_INBAND,
386                                         VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
387         if (ret != 0) {
388                 pr_err("unable to send SYNTHHID_PROTOCOL_REQUEST");
389                 goto Cleanup;
390         }
391
392         inputDevice->protocol_wait_condition = 0;
393         wait_event_timeout(inputDevice->ProtocolWaitEvent, inputDevice->protocol_wait_condition, msecs_to_jiffies(1000));
394         if (inputDevice->protocol_wait_condition == 0) {
395                 ret = -ETIMEDOUT;
396                 goto Cleanup;
397         }
398
399         response = &inputDevice->ProtocolResp;
400
401         if (!response->u.Response.Approved) {
402                 pr_err("SYNTHHID_PROTOCOL_REQUEST failed (version %d)",
403                        SYNTHHID_INPUT_VERSION_DWORD);
404                 ret = -1;
405                 goto Cleanup;
406         }
407
408         inputDevice->device_wait_condition = 0;
409         wait_event_timeout(inputDevice->DeviceInfoWaitEvent, inputDevice->device_wait_condition, msecs_to_jiffies(1000));
410         if (inputDevice->device_wait_condition == 0) {
411                 ret = -ETIMEDOUT;
412                 goto Cleanup;
413         }
414
415         /*
416          * We should have gotten the device attr, hid desc and report
417          * desc at this point
418          */
419         if (!inputDevice->DeviceInfoStatus)
420                 pr_info("**** input channel up and running!! ****");
421         else
422                 ret = -1;
423
424 Cleanup:
425         PutInputDevice(Device);
426
427         return ret;
428 }
429
430
431 /*
432  *
433  * Name:
434  *      MousevscOnDeviceRemove()
435  *
436  * Description:
437  *      Callback when the our device is being removed
438  *
439  */
440 int
441 MousevscOnDeviceRemove(struct hv_device *Device)
442 {
443         struct mousevsc_dev *inputDevice;
444         int ret = 0;
445
446         pr_info("disabling input device (%p)...",
447                     Device->ext);
448
449         inputDevice = ReleaseInputDevice(Device);
450
451
452         /*
453          * At this point, all outbound traffic should be disable. We only
454          * allow inbound traffic (responses) to proceed
455          *
456          * so that outstanding requests can be completed.
457          */
458         while (inputDevice->NumOutstandingRequests) {
459                 pr_info("waiting for %d requests to complete...", inputDevice->NumOutstandingRequests);
460
461                 udelay(100);
462         }
463
464         pr_info("removing input device (%p)...", Device->ext);
465
466         inputDevice = FinalReleaseInputDevice(Device);
467
468         pr_info("input device (%p) safe to remove", inputDevice);
469
470         /* Close the channel */
471         vmbus_close(Device->channel);
472
473         FreeInputDevice(inputDevice);
474
475         return ret;
476 }
477
478
479 /*
480  *
481  * Name:
482  *      MousevscOnCleanup()
483  *
484  * Description:
485  *      Perform any cleanup when the driver is removed
486  */
487 static void MousevscOnCleanup(struct hv_driver *drv)
488 {
489 }
490
491
492 static void
493 MousevscOnSendCompletion(struct hv_device *Device,
494                          struct vmpacket_descriptor *Packet)
495 {
496         struct mousevsc_dev *inputDevice;
497         void *request;
498
499         inputDevice = MustGetInputDevice(Device);
500         if (!inputDevice) {
501                 pr_err("unable to get input device...device being destroyed?");
502                 return;
503         }
504
505         request = (void *)(unsigned long *)Packet->trans_id;
506
507         if (request == &inputDevice->ProtocolReq) {
508                 /* FIXME */
509                 /* Shouldn't we be doing something here? */
510         }
511
512         PutInputDevice(Device);
513 }
514
515 void
516 MousevscOnReceiveDeviceInfo(
517         struct mousevsc_dev *InputDevice,
518         SYNTHHID_DEVICE_INFO *DeviceInfo)
519 {
520         int ret = 0;
521         struct hid_descriptor *desc;
522         struct mousevsc_prt_msg ack;
523
524         /* Assume success for now */
525         InputDevice->DeviceInfoStatus = 0;
526
527         /* Save the device attr */
528         memcpy(&InputDevice->DeviceAttr, &DeviceInfo->HidDeviceAttributes, sizeof(struct input_dev_info));
529
530         /* Save the hid desc */
531         desc = (struct hid_descriptor *)DeviceInfo->HidDescriptorInformation;
532         WARN_ON(desc->bLength > 0);
533
534         InputDevice->HidDesc = kzalloc(desc->bLength, GFP_KERNEL);
535
536         if (!InputDevice->HidDesc) {
537                 pr_err("unable to allocate hid descriptor - size %d", desc->bLength);
538                 goto Cleanup;
539         }
540
541         memcpy(InputDevice->HidDesc, desc, desc->bLength);
542
543         /* Save the report desc */
544         InputDevice->ReportDescSize = desc->desc[0].wDescriptorLength;
545         InputDevice->ReportDesc = kzalloc(InputDevice->ReportDescSize,
546                                           GFP_KERNEL);
547
548         if (!InputDevice->ReportDesc) {
549                 pr_err("unable to allocate report descriptor - size %d",
550                            InputDevice->ReportDescSize);
551                 goto Cleanup;
552         }
553
554         memcpy(InputDevice->ReportDesc,
555                ((unsigned char *)desc) + desc->bLength,
556                desc->desc[0].wDescriptorLength);
557
558         /* Send the ack */
559         memset(&ack, sizeof(struct mousevsc_prt_msg), 0);
560
561         ack.PacketType = PipeMessageData;
562         ack.DataSize = sizeof(SYNTHHID_DEVICE_INFO_ACK);
563
564         ack.u.Ack.Header.Type = SynthHidInitialDeviceInfoAck;
565         ack.u.Ack.Header.Size = 1;
566         ack.u.Ack.Reserved = 0;
567
568         ret = vmbus_sendpacket(InputDevice->Device->channel,
569                         &ack,
570                         sizeof(struct pipe_prt_msg) - sizeof(unsigned char) + sizeof(SYNTHHID_DEVICE_INFO_ACK),
571                         (unsigned long)&ack,
572                         VM_PKT_DATA_INBAND,
573                         VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
574         if (ret != 0) {
575                 pr_err("unable to send SYNTHHID_DEVICE_INFO_ACK - ret %d",
576                            ret);
577                 goto Cleanup;
578         }
579
580         InputDevice->device_wait_condition = 1;
581         wake_up(&InputDevice->DeviceInfoWaitEvent);
582
583         return;
584
585 Cleanup:
586         if (InputDevice->HidDesc) {
587                 kfree(InputDevice->HidDesc);
588                 InputDevice->HidDesc = NULL;
589         }
590
591         if (InputDevice->ReportDesc) {
592                 kfree(InputDevice->ReportDesc);
593                 InputDevice->ReportDesc = NULL;
594         }
595
596         InputDevice->DeviceInfoStatus = -1;
597         InputDevice->device_wait_condition = 1;
598         wake_up(&InputDevice->DeviceInfoWaitEvent);
599 }
600
601
602 void
603 MousevscOnReceiveInputReport(
604         struct mousevsc_dev *InputDevice,
605         SYNTHHID_INPUT_REPORT *InputReport)
606 {
607         struct mousevsc_drv_obj *inputDriver;
608
609         if (!InputDevice->bInitializeComplete) {
610                 pr_info("Initialization incomplete...ignoring InputReport msg");
611                 return;
612         }
613
614         inputDriver = (struct mousevsc_drv_obj *)InputDevice->Device->drv;
615
616         inputDriver->OnInputReport(InputDevice->Device,
617                                    InputReport->ReportBuffer,
618                                    InputReport->Header.Size);
619 }
620
621 void
622 MousevscOnReceive(struct hv_device *Device, struct vmpacket_descriptor *Packet)
623 {
624         struct pipe_prt_msg *pipeMsg;
625         SYNTHHID_MESSAGE *hidMsg;
626         struct mousevsc_dev *inputDevice;
627
628         inputDevice = MustGetInputDevice(Device);
629         if (!inputDevice) {
630                 pr_err("unable to get input device...device being destroyed?");
631                 return;
632         }
633
634         pipeMsg = (struct pipe_prt_msg *)((unsigned long)Packet + (Packet->offset8 << 3));
635
636         if (pipeMsg->PacketType != PipeMessageData) {
637                 pr_err("unknown pipe msg type - type %d len %d",
638                            pipeMsg->PacketType, pipeMsg->DataSize);
639                 PutInputDevice(Device);
640                 return ;
641         }
642
643         hidMsg = (SYNTHHID_MESSAGE *)&pipeMsg->Data[0];
644
645         switch (hidMsg->Header.Type) {
646         case SynthHidProtocolResponse:
647                 memcpy(&inputDevice->ProtocolResp, pipeMsg, pipeMsg->DataSize+sizeof(struct pipe_prt_msg) - sizeof(unsigned char));
648                 inputDevice->protocol_wait_condition = 1;
649                 wake_up(&inputDevice->ProtocolWaitEvent);
650                 break;
651
652         case SynthHidInitialDeviceInfo:
653                 WARN_ON(pipeMsg->DataSize >= sizeof(struct input_dev_info));
654
655                 /*
656                  * Parse out the device info into device attr,
657                  * hid desc and report desc
658                  */
659                 MousevscOnReceiveDeviceInfo(inputDevice,
660                                             (SYNTHHID_DEVICE_INFO *)&pipeMsg->Data[0]);
661                 break;
662         case SynthHidInputReport:
663                 MousevscOnReceiveInputReport(inputDevice,
664                                              (SYNTHHID_INPUT_REPORT *)&pipeMsg->Data[0]);
665
666                 break;
667         default:
668                 pr_err("unsupported hid msg type - type %d len %d",
669                        hidMsg->Header.Type, hidMsg->Header.Size);
670                 break;
671         }
672
673         PutInputDevice(Device);
674 }
675
676 void MousevscOnChannelCallback(void *Context)
677 {
678         const int packetSize = 0x100;
679         int ret = 0;
680         struct hv_device *device = (struct hv_device *)Context;
681         struct mousevsc_dev *inputDevice;
682
683         u32 bytesRecvd;
684         u64 requestId;
685         unsigned char packet[packetSize];
686         struct vmpacket_descriptor *desc;
687         unsigned char   *buffer = packet;
688         int     bufferlen = packetSize;
689
690         inputDevice = MustGetInputDevice(device);
691
692         if (!inputDevice) {
693                 pr_err("unable to get input device...device being destroyed?");
694                 return;
695         }
696
697         do {
698                 ret = vmbus_recvpacket_raw(device->channel, buffer, bufferlen, &bytesRecvd, &requestId);
699
700                 if (ret == 0) {
701                         if (bytesRecvd > 0) {
702                                 desc = (struct vmpacket_descriptor *)buffer;
703
704                                 switch (desc->type) {
705                                         case VM_PKT_COMP:
706                                                 MousevscOnSendCompletion(device,
707                                                                          desc);
708                                                 break;
709
710                                         case VM_PKT_DATA_INBAND:
711                                                 MousevscOnReceive(device, desc);
712                                                 break;
713
714                                         default:
715                                                 pr_err("unhandled packet type %d, tid %llx len %d\n",
716                                                            desc->type,
717                                                            requestId,
718                                                            bytesRecvd);
719                                                 break;
720                                 }
721
722                                 /* reset */
723                                 if (bufferlen > packetSize) {
724                                         kfree(buffer);
725
726                                         buffer = packet;
727                                         bufferlen = packetSize;
728                                 }
729                         } else {
730                                 /*
731                                  * pr_debug("nothing else to read...");
732                                  * reset
733                                  */
734                                 if (bufferlen > packetSize) {
735                                         kfree(buffer);
736
737                                         buffer = packet;
738                                         bufferlen = packetSize;
739                                 }
740                                 break;
741                         }
742                 } else if (ret == -2) {
743                         /* Handle large packet */
744                         bufferlen = bytesRecvd;
745                         buffer = kzalloc(bytesRecvd, GFP_KERNEL);
746
747                         if (buffer == NULL) {
748                                 buffer = packet;
749                                 bufferlen = packetSize;
750
751                                 /* Try again next time around */
752                                 pr_err("unable to allocate buffer of size %d!",
753                                        bytesRecvd);
754                                 break;
755                         }
756                 }
757         } while (1);
758
759         PutInputDevice(device);
760
761         return;
762 }
763
764 /*
765  * Data types
766  */
767 struct input_device_context {
768         struct vm_device        *device_ctx;
769         struct hid_device       *hid_device;
770         struct input_dev_info   device_info;
771         int                     connected;
772 };
773
774 struct mousevsc_driver_context {
775         struct driver_context   drv_ctx;
776         struct mousevsc_drv_obj drv_obj;
777 };
778
779 static struct mousevsc_driver_context g_mousevsc_drv;
780
781 void mousevsc_deviceinfo_callback(struct hv_device *dev,
782                                   struct input_dev_info *info)
783 {
784         struct vm_device *device_ctx = to_vm_device(dev);
785         struct input_device_context *input_device_ctx =
786                 dev_get_drvdata(&device_ctx->device);
787
788         memcpy(&input_device_ctx->device_info, info,
789                sizeof(struct input_dev_info));
790
791         DPRINT_INFO(INPUTVSC_DRV, "mousevsc_deviceinfo_callback()");
792 }
793
794 void mousevsc_inputreport_callback(struct hv_device *dev, void *packet, u32 len)
795 {
796         int ret = 0;
797
798         struct vm_device *device_ctx = to_vm_device(dev);
799         struct input_device_context *input_dev_ctx =
800                 dev_get_drvdata(&device_ctx->device);
801
802         ret = hid_input_report(input_dev_ctx->hid_device,
803                               HID_INPUT_REPORT, packet, len, 1);
804
805         DPRINT_DBG(INPUTVSC_DRV, "hid_input_report (ret %d)", ret);
806 }
807
808 int mousevsc_hid_open(struct hid_device *hid)
809 {
810         return 0;
811 }
812
813 void mousevsc_hid_close(struct hid_device *hid)
814 {
815 }
816
817 int mousevsc_probe(struct device *device)
818 {
819         int ret = 0;
820
821         struct driver_context *driver_ctx =
822                 driver_to_driver_context(device->driver);
823         struct mousevsc_driver_context *mousevsc_drv_ctx =
824                 (struct mousevsc_driver_context *)driver_ctx;
825         struct mousevsc_drv_obj *mousevsc_drv_obj = &mousevsc_drv_ctx->drv_obj;
826
827         struct vm_device *device_ctx = device_to_vm_device(device);
828         struct hv_device *device_obj = &device_ctx->device_obj;
829         struct input_device_context *input_dev_ctx;
830
831         input_dev_ctx = kmalloc(sizeof(struct input_device_context),
832                                 GFP_KERNEL);
833
834         dev_set_drvdata(device, input_dev_ctx);
835
836         /* Call to the vsc driver to add the device */
837         ret = mousevsc_drv_obj->Base.dev_add(device_obj, NULL);
838
839         if (ret != 0) {
840                 DPRINT_ERR(INPUTVSC_DRV, "unable to add input vsc device");
841
842                 return -1;
843         }
844
845         return 0;
846 }
847
848
849 int mousevsc_remove(struct device *device)
850 {
851         int ret = 0;
852
853         struct driver_context *driver_ctx =
854                 driver_to_driver_context(device->driver);
855         struct mousevsc_driver_context *mousevsc_drv_ctx =
856                 (struct mousevsc_driver_context *)driver_ctx;
857         struct mousevsc_drv_obj *mousevsc_drv_obj = &mousevsc_drv_ctx->drv_obj;
858
859         struct vm_device *device_ctx = device_to_vm_device(device);
860         struct hv_device *device_obj = &device_ctx->device_obj;
861         struct input_device_context *input_dev_ctx;
862
863         input_dev_ctx = kmalloc(sizeof(struct input_device_context),
864                                 GFP_KERNEL);
865
866         dev_set_drvdata(device, input_dev_ctx);
867
868         if (input_dev_ctx->connected) {
869                 hidinput_disconnect(input_dev_ctx->hid_device);
870                 input_dev_ctx->connected = 0;
871         }
872
873         if (!mousevsc_drv_obj->Base.dev_rm)
874                 return -1;
875
876         /*
877          * Call to the vsc driver to let it know that the device
878          * is being removed
879          */
880         ret = mousevsc_drv_obj->Base.dev_rm(device_obj);
881
882         if (ret != 0) {
883                 DPRINT_ERR(INPUTVSC_DRV,
884                            "unable to remove vsc device (ret %d)", ret);
885         }
886
887         kfree(input_dev_ctx);
888
889         return ret;
890 }
891
892 void mousevsc_reportdesc_callback(struct hv_device *dev, void *packet, u32 len)
893 {
894         struct vm_device *device_ctx = to_vm_device(dev);
895         struct input_device_context *input_device_ctx =
896                 dev_get_drvdata(&device_ctx->device);
897         struct hid_device *hid_dev;
898
899         /* hid_debug = -1; */
900         hid_dev = kmalloc(sizeof(struct hid_device), GFP_KERNEL);
901
902         if (hid_parse_report(hid_dev, packet, len)) {
903                 DPRINT_INFO(INPUTVSC_DRV, "Unable to call hd_parse_report");
904                 return;
905         }
906
907         if (hid_dev) {
908                 DPRINT_INFO(INPUTVSC_DRV, "hid_device created");
909
910                 hid_dev->ll_driver->open  = mousevsc_hid_open;
911                 hid_dev->ll_driver->close = mousevsc_hid_close;
912
913                 hid_dev->bus =  0x06;  /* BUS_VIRTUAL */
914                 hid_dev->vendor = input_device_ctx->device_info.VendorID;
915                 hid_dev->product = input_device_ctx->device_info.ProductID;
916                 hid_dev->version = input_device_ctx->device_info.VersionNumber;
917                 hid_dev->dev = device_ctx->device;
918
919                 sprintf(hid_dev->name, "%s",
920                         input_device_ctx->device_info.Name);
921
922                 /*
923                  * HJ Do we want to call it with a 0
924                  */
925                 if (!hidinput_connect(hid_dev, 0)) {
926                         hid_dev->claimed |= HID_CLAIMED_INPUT;
927
928                         input_device_ctx->connected = 1;
929
930                         DPRINT_INFO(INPUTVSC_DRV,
931                                      "HID device claimed by input\n");
932                 }
933
934                 if (!hid_dev->claimed) {
935                         DPRINT_ERR(INPUTVSC_DRV,
936                                     "HID device not claimed by "
937                                     "input or hiddev\n");
938                 }
939
940                 input_device_ctx->hid_device = hid_dev;
941         }
942
943         kfree(hid_dev);
944 }
945
946 /*
947  *
948  * Name:        mousevsc_drv_init()
949  *
950  * Desc:        Driver initialization.
951  */
952 int mousevsc_drv_init(int (*pfn_drv_init)(struct hv_driver *pfn_drv_init))
953 {
954         int ret = 0;
955         struct mousevsc_drv_obj *input_drv_obj = &g_mousevsc_drv.drv_obj;
956         struct driver_context *drv_ctx = &g_mousevsc_drv.drv_ctx;
957
958         input_drv_obj->OnDeviceInfo = mousevsc_deviceinfo_callback;
959         input_drv_obj->OnInputReport = mousevsc_inputreport_callback;
960         input_drv_obj->OnReportDescriptor = mousevsc_reportdesc_callback;
961
962         /* Callback to client driver to complete the initialization */
963         pfn_drv_init(&input_drv_obj->Base);
964
965         drv_ctx->driver.name = input_drv_obj->Base.name;
966         memcpy(&drv_ctx->class_id, &input_drv_obj->Base.dev_type,
967                sizeof(struct hv_guid));
968
969         drv_ctx->probe = mousevsc_probe;
970         drv_ctx->remove = mousevsc_remove;
971
972         /* The driver belongs to vmbus */
973         vmbus_child_driver_register(drv_ctx);
974
975         return ret;
976 }
977
978
979 int mousevsc_drv_exit_cb(struct device *dev, void *data)
980 {
981         struct device **curr = (struct device **)data;
982         *curr = dev;
983
984         return 1;
985 }
986
987 void mousevsc_drv_exit(void)
988 {
989         struct mousevsc_drv_obj *mousevsc_drv_obj = &g_mousevsc_drv.drv_obj;
990         struct driver_context *drv_ctx = &g_mousevsc_drv.drv_ctx;
991         int ret;
992
993         struct device *current_dev = NULL;
994
995         while (1) {
996                 current_dev = NULL;
997
998                 /* Get the device */
999                 ret = driver_for_each_device(&drv_ctx->driver, NULL,
1000                                              (void *)&current_dev,
1001                                              mousevsc_drv_exit_cb);
1002                 if (ret)
1003                         printk(KERN_ERR "Can't find mouse device!\n");
1004
1005                 if (current_dev == NULL)
1006                         break;
1007
1008                 /* Initiate removal from the top-down */
1009                 device_unregister(current_dev);
1010         }
1011
1012         if (mousevsc_drv_obj->Base.cleanup)
1013                 mousevsc_drv_obj->Base.cleanup(&mousevsc_drv_obj->Base);
1014
1015         vmbus_child_driver_unregister(drv_ctx);
1016
1017         return;
1018 }
1019
1020 static int __init mousevsc_init(void)
1021 {
1022         int ret;
1023
1024         DPRINT_INFO(INPUTVSC_DRV, "Hyper-V Mouse driver initializing.");
1025
1026         ret = mousevsc_drv_init(mouse_vsc_initialize);
1027
1028         return ret;
1029 }
1030
1031 static void __exit mousevsc_exit(void)
1032 {
1033         mousevsc_drv_exit();
1034 }
1035
1036 /*
1037  * We don't want to automatically load this driver just yet, it's quite
1038  * broken.  It's safe if you want to load it yourself manually, but
1039  * don't inflict it on unsuspecting users, that's just mean.
1040  */
1041 #if 0
1042
1043 /*
1044  * We use a PCI table to determine if we should autoload this driver  This is
1045  * needed by distro tools to determine if the hyperv drivers should be
1046  * installed and/or configured.  We don't do anything else with the table, but
1047  * it needs to be present.
1048  */
1049 const static struct pci_device_id microsoft_hv_pci_table[] = {
1050         { PCI_DEVICE(0x1414, 0x5353) }, /* VGA compatible controller */
1051         { 0 }
1052 };
1053 MODULE_DEVICE_TABLE(pci, microsoft_hv_pci_table);
1054 #endif
1055
1056 MODULE_LICENSE("GPL");
1057 MODULE_VERSION(HV_DRV_VERSION);
1058 module_init(mousevsc_init);
1059 module_exit(mousevsc_exit);
1060