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