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