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