]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/staging/hv/hv_mouse.c
Staging: hv: mousevsc: Free allocated memory in free_input_device()
[karo-tx-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/delay.h>
18 #include <linux/device.h>
19 #include <linux/workqueue.h>
20 #include <linux/sched.h>
21 #include <linux/wait.h>
22 #include <linux/input.h>
23 #include <linux/hid.h>
24 #include <linux/hiddev.h>
25
26 #include "hyperv.h"
27
28
29 /*
30  * Data types
31  */
32 struct hv_input_dev_info {
33         unsigned int size;
34         unsigned short vendor;
35         unsigned short product;
36         unsigned short version;
37         unsigned short reserved[11];
38 };
39
40 /* The maximum size of a synthetic input message. */
41 #define SYNTHHID_MAX_INPUT_REPORT_SIZE 16
42
43 /*
44  * Current version
45  *
46  * History:
47  * Beta, RC < 2008/1/22        1,0
48  * RC > 2008/1/22              2,0
49  */
50 #define SYNTHHID_INPUT_VERSION_MAJOR    2
51 #define SYNTHHID_INPUT_VERSION_MINOR    0
52 #define SYNTHHID_INPUT_VERSION          (SYNTHHID_INPUT_VERSION_MINOR | \
53                                          (SYNTHHID_INPUT_VERSION_MAJOR << 16))
54
55
56 #pragma pack(push, 1)
57 /*
58  * Message types in the synthetic input protocol
59  */
60 enum synthhid_msg_type {
61         SynthHidProtocolRequest,
62         SynthHidProtocolResponse,
63         SynthHidInitialDeviceInfo,
64         SynthHidInitialDeviceInfoAck,
65         SynthHidInputReport,
66         SynthHidMax
67 };
68
69 /*
70  * Basic message structures.
71  */
72 struct synthhid_msg_hdr {
73         enum synthhid_msg_type type;
74         u32 size;
75 };
76
77 struct synthhid_msg {
78         struct synthhid_msg_hdr header;
79         char data[1]; /* Enclosed message */
80 };
81
82 union synthhid_version {
83         struct {
84                 u16 minor_version;
85                 u16 major_version;
86         };
87         u32 version;
88 };
89
90 /*
91  * Protocol messages
92  */
93 struct synthhid_protocol_request {
94         struct synthhid_msg_hdr header;
95         union synthhid_version version_requested;
96 };
97
98 struct synthhid_protocol_response {
99         struct synthhid_msg_hdr header;
100         union synthhid_version version_requested;
101         unsigned char approved;
102 };
103
104 struct synthhid_device_info {
105         struct synthhid_msg_hdr header;
106         struct hv_input_dev_info hid_dev_info;
107         struct hid_descriptor hid_descriptor;
108 };
109
110 struct synthhid_device_info_ack {
111         struct synthhid_msg_hdr header;
112         unsigned char reserved;
113 };
114
115 struct synthhid_input_report {
116         struct synthhid_msg_hdr header;
117         char buffer[1];
118 };
119
120 #pragma pack(pop)
121
122 #define INPUTVSC_SEND_RING_BUFFER_SIZE          (10*PAGE_SIZE)
123 #define INPUTVSC_RECV_RING_BUFFER_SIZE          (10*PAGE_SIZE)
124
125 #define NBITS(x) (((x)/BITS_PER_LONG)+1)
126
127 enum pipe_prot_msg_type {
128         PipeMessageInvalid = 0,
129         PipeMessageData,
130         PipeMessageMaximum
131 };
132
133
134 struct pipe_prt_msg {
135         enum pipe_prot_msg_type type;
136         u32 size;
137         char data[1];
138 };
139
140 /*
141  * Data types
142  */
143 struct  mousevsc_prt_msg {
144         enum pipe_prot_msg_type type;
145         u32 size;
146         union {
147                 struct synthhid_protocol_request request;
148                 struct synthhid_protocol_response response;
149                 struct synthhid_device_info_ack ack;
150         };
151 };
152
153 /*
154  * Represents an mousevsc device
155  */
156 struct mousevsc_dev {
157         struct hv_device        *device;
158         /* 0 indicates the device is being destroyed */
159         atomic_t                ref_count;
160         int                     num_outstanding_req;
161         unsigned char           init_complete;
162         struct mousevsc_prt_msg protocol_req;
163         struct mousevsc_prt_msg protocol_resp;
164         /* Synchronize the request/response if needed */
165         struct completion       wait_event;
166         int                     dev_info_status;
167
168         struct hid_descriptor   *hid_desc;
169         unsigned char           *report_desc;
170         u32                     report_desc_size;
171         struct hv_input_dev_info hid_dev_info;
172         int                     connected;
173         struct hid_device       *hid_device;
174 };
175
176
177 static struct mousevsc_dev *alloc_input_device(struct hv_device *device)
178 {
179         struct mousevsc_dev *input_dev;
180
181         input_dev = kzalloc(sizeof(struct mousevsc_dev), GFP_KERNEL);
182
183         if (!input_dev)
184                 return NULL;
185
186         /*
187          * Set to 2 to allow both inbound and outbound traffics
188          * (ie get_input_device() and must_get_input_device()) to proceed.
189          */
190         atomic_cmpxchg(&input_dev->ref_count, 0, 2);
191
192         input_dev->device = device;
193         hv_set_drvdata(device, input_dev);
194         init_completion(&input_dev->wait_event);
195
196         return input_dev;
197 }
198
199 static void free_input_device(struct mousevsc_dev *device)
200 {
201         WARN_ON(atomic_read(&device->ref_count) != 0);
202         kfree(device->hid_desc);
203         kfree(device->report_desc);
204         kfree(device);
205 }
206
207 /*
208  * Get the inputdevice object if exists and its refcount > 1
209  */
210 static struct mousevsc_dev *get_input_device(struct hv_device *device)
211 {
212         struct mousevsc_dev *input_dev;
213
214         input_dev = hv_get_drvdata(device);
215
216 /*
217  *      FIXME
218  *      This sure isn't a valid thing to print for debugging, no matter
219  *      what the intention is...
220  *
221  *      printk(KERN_ERR "-------------------------> REFCOUNT = %d",
222  *             input_dev->ref_count);
223  */
224
225         if (input_dev && atomic_read(&input_dev->ref_count) > 1)
226                 atomic_inc(&input_dev->ref_count);
227         else
228                 input_dev = NULL;
229
230         return input_dev;
231 }
232
233 /*
234  * Get the inputdevice object iff exists and its refcount > 0
235  */
236 static struct mousevsc_dev *must_get_input_device(struct hv_device *device)
237 {
238         struct mousevsc_dev *input_dev;
239
240         input_dev = hv_get_drvdata(device);
241
242         if (input_dev && atomic_read(&input_dev->ref_count))
243                 atomic_inc(&input_dev->ref_count);
244         else
245                 input_dev = NULL;
246
247         return input_dev;
248 }
249
250 static void put_input_device(struct hv_device *device)
251 {
252         struct mousevsc_dev *input_dev;
253
254         input_dev = hv_get_drvdata(device);
255
256         atomic_dec(&input_dev->ref_count);
257 }
258
259 /*
260  * Drop ref count to 1 to effectively disable get_input_device()
261  */
262 static struct mousevsc_dev *release_input_device(struct hv_device *device)
263 {
264         struct mousevsc_dev *input_dev;
265
266         input_dev = hv_get_drvdata(device);
267
268         /* Busy wait until the ref drop to 2, then set it to 1  */
269         while (atomic_cmpxchg(&input_dev->ref_count, 2, 1) != 2)
270                 udelay(100);
271
272         return input_dev;
273 }
274
275 /*
276  * Drop ref count to 0. No one can use input_device object.
277  */
278 static struct mousevsc_dev *final_release_input_device(struct hv_device *device)
279 {
280         struct mousevsc_dev *input_dev;
281
282         input_dev = hv_get_drvdata(device);
283
284         /* Busy wait until the ref drop to 1, then set it to 0  */
285         while (atomic_cmpxchg(&input_dev->ref_count, 1, 0) != 1)
286                 udelay(100);
287
288         hv_set_drvdata(device, NULL);
289         return input_dev;
290 }
291
292 static void mousevsc_on_send_completion(struct hv_device *device,
293                                         struct vmpacket_descriptor *packet)
294 {
295         struct mousevsc_dev *input_dev;
296         void *request;
297
298         input_dev = must_get_input_device(device);
299         if (!input_dev)
300                 return;
301
302         request = (void *)(unsigned long)packet->trans_id;
303
304         if (request == &input_dev->protocol_req) {
305                 /* FIXME */
306                 /* Shouldn't we be doing something here? */
307         }
308
309         put_input_device(device);
310 }
311
312 static void mousevsc_on_receive_device_info(struct mousevsc_dev *input_device,
313                                 struct synthhid_device_info *device_info)
314 {
315         int ret = 0;
316         struct hid_descriptor *desc;
317         struct mousevsc_prt_msg ack;
318
319         /* Assume success for now */
320         input_device->dev_info_status = 0;
321
322         /* Save the device attr */
323         memcpy(&input_device->hid_dev_info, &device_info->hid_dev_info,
324                 sizeof(struct hv_input_dev_info));
325
326         /* Save the hid desc */
327         desc = &device_info->hid_descriptor;
328         WARN_ON(desc->bLength == 0);
329
330         input_device->hid_desc = kzalloc(desc->bLength, GFP_ATOMIC);
331
332         if (!input_device->hid_desc)
333                 goto cleanup;
334
335         memcpy(input_device->hid_desc, desc, desc->bLength);
336
337         /* Save the report desc */
338         input_device->report_desc_size = desc->desc[0].wDescriptorLength;
339         if (input_device->report_desc_size == 0)
340                 goto cleanup;
341         input_device->report_desc = kzalloc(input_device->report_desc_size,
342                                           GFP_ATOMIC);
343
344         if (!input_device->report_desc)
345                 goto cleanup;
346
347         memcpy(input_device->report_desc,
348                ((unsigned char *)desc) + desc->bLength,
349                desc->desc[0].wDescriptorLength);
350
351         /* Send the ack */
352         memset(&ack, 0, sizeof(struct mousevsc_prt_msg));
353
354         ack.type = PipeMessageData;
355         ack.size = sizeof(struct synthhid_device_info_ack);
356
357         ack.ack.header.type = SynthHidInitialDeviceInfoAck;
358         ack.ack.header.size = 1;
359         ack.ack.reserved = 0;
360
361         ret = vmbus_sendpacket(input_device->device->channel,
362                         &ack,
363                         sizeof(struct pipe_prt_msg) - sizeof(unsigned char) +
364                         sizeof(struct synthhid_device_info_ack),
365                         (unsigned long)&ack,
366                         VM_PKT_DATA_INBAND,
367                         VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
368         if (ret != 0)
369                 goto cleanup;
370
371         complete(&input_device->wait_event);
372
373         return;
374
375 cleanup:
376         kfree(input_device->hid_desc);
377         input_device->hid_desc = NULL;
378
379         kfree(input_device->report_desc);
380         input_device->report_desc = NULL;
381
382         input_device->dev_info_status = -1;
383         complete(&input_device->wait_event);
384 }
385
386 static void mousevsc_on_receive_input_report(struct mousevsc_dev *input_device,
387                                 struct synthhid_input_report *input_report)
388 {
389         struct hv_driver *input_drv;
390
391         if (!input_device->init_complete)
392                 return;
393
394         input_drv = drv_to_hv_drv(input_device->device->device.driver);
395
396
397         hid_input_report(input_device->hid_device,
398                               HID_INPUT_REPORT, input_report->buffer, input_report->header.size, 1);
399
400 }
401
402 static void mousevsc_on_receive(struct hv_device *device,
403                                 struct vmpacket_descriptor *packet)
404 {
405         struct pipe_prt_msg *pipe_msg;
406         struct synthhid_msg *hid_msg;
407         struct mousevsc_dev *input_dev;
408
409         input_dev = must_get_input_device(device);
410         if (!input_dev)
411                 return;
412
413         pipe_msg = (struct pipe_prt_msg *)((unsigned long)packet +
414                                                 (packet->offset8 << 3));
415
416         if (pipe_msg->type != PipeMessageData) {
417                 put_input_device(device);
418                 return ;
419         }
420
421         hid_msg = (struct synthhid_msg *)&pipe_msg->data[0];
422
423         switch (hid_msg->header.type) {
424         case SynthHidProtocolResponse:
425                 memcpy(&input_dev->protocol_resp, pipe_msg,
426                        pipe_msg->size + sizeof(struct pipe_prt_msg) -
427                        sizeof(unsigned char));
428                 complete(&input_dev->wait_event);
429                 break;
430
431         case SynthHidInitialDeviceInfo:
432                 WARN_ON(pipe_msg->size < sizeof(struct hv_input_dev_info));
433
434                 /*
435                  * Parse out the device info into device attr,
436                  * hid desc and report desc
437                  */
438                 mousevsc_on_receive_device_info(input_dev,
439                         (struct synthhid_device_info *)&pipe_msg->data[0]);
440                 break;
441         case SynthHidInputReport:
442                 mousevsc_on_receive_input_report(input_dev,
443                         (struct synthhid_input_report *)&pipe_msg->data[0]);
444
445                 break;
446         default:
447                 pr_err("unsupported hid msg type - type %d len %d",
448                        hid_msg->header.type, hid_msg->header.size);
449                 break;
450         }
451
452         put_input_device(device);
453 }
454
455 static void mousevsc_on_channel_callback(void *context)
456 {
457         const int packetSize = 0x100;
458         int ret = 0;
459         struct hv_device *device = (struct hv_device *)context;
460         struct mousevsc_dev *input_dev;
461
462         u32 bytes_recvd;
463         u64 req_id;
464         unsigned char packet[0x100];
465         struct vmpacket_descriptor *desc;
466         unsigned char   *buffer = packet;
467         int     bufferlen = packetSize;
468
469         input_dev = must_get_input_device(device);
470
471         if (!input_dev)
472                 return;
473
474         do {
475                 ret = vmbus_recvpacket_raw(device->channel, buffer,
476                                         bufferlen, &bytes_recvd, &req_id);
477
478                 if (ret == 0) {
479                         if (bytes_recvd > 0) {
480                                 desc = (struct vmpacket_descriptor *)buffer;
481
482                                 switch (desc->type) {
483                                 case VM_PKT_COMP:
484                                         mousevsc_on_send_completion(
485                                                 device, desc);
486                                         break;
487
488                                 case VM_PKT_DATA_INBAND:
489                                         mousevsc_on_receive(
490                                                 device, desc);
491                                         break;
492
493                                 default:
494                                         pr_err("unhandled packet type %d, tid %llx len %d\n",
495                                                    desc->type,
496                                                    req_id,
497                                                    bytes_recvd);
498                                         break;
499                                 }
500
501                                 /* reset */
502                                 if (bufferlen > packetSize) {
503                                         kfree(buffer);
504
505                                         buffer = packet;
506                                         bufferlen = packetSize;
507                                 }
508                         } else {
509                                 /*
510                                  * pr_debug("nothing else to read...");
511                                  * reset
512                                  */
513                                 if (bufferlen > packetSize) {
514                                         kfree(buffer);
515
516                                         buffer = packet;
517                                         bufferlen = packetSize;
518                                 }
519                                 break;
520                         }
521                 } else if (ret == -ENOBUFS) {
522                         /* Handle large packet */
523                         bufferlen = bytes_recvd;
524                         buffer = kzalloc(bytes_recvd, GFP_ATOMIC);
525
526                         if (buffer == NULL) {
527                                 buffer = packet;
528                                 bufferlen = packetSize;
529
530                                 /* Try again next time around */
531                                 break;
532                         }
533                 }
534         } while (1);
535
536         put_input_device(device);
537
538         return;
539 }
540
541 static int mousevsc_connect_to_vsp(struct hv_device *device)
542 {
543         int ret = 0;
544         int t;
545         struct mousevsc_dev *input_dev;
546         struct mousevsc_prt_msg *request;
547         struct mousevsc_prt_msg *response;
548
549         input_dev = get_input_device(device);
550
551         if (!input_dev)
552                 return -ENODEV;
553
554
555         request = &input_dev->protocol_req;
556
557         /*
558          * Now, initiate the vsc/vsp initialization protocol on the open channel
559          */
560         memset(request, 0, sizeof(struct mousevsc_prt_msg));
561
562         request->type = PipeMessageData;
563         request->size = sizeof(struct synthhid_protocol_request);
564
565         request->request.header.type = SynthHidProtocolRequest;
566         request->request.header.size = sizeof(unsigned int);
567         request->request.version_requested.version = SYNTHHID_INPUT_VERSION;
568
569
570         ret = vmbus_sendpacket(device->channel, request,
571                                 sizeof(struct pipe_prt_msg) -
572                                 sizeof(unsigned char) +
573                                 sizeof(struct synthhid_protocol_request),
574                                 (unsigned long)request,
575                                 VM_PKT_DATA_INBAND,
576                                 VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
577         if (ret != 0)
578                 goto cleanup;
579
580         t = wait_for_completion_timeout(&input_dev->wait_event, 5*HZ);
581         if (t == 0) {
582                 ret = -ETIMEDOUT;
583                 goto cleanup;
584         }
585
586         response = &input_dev->protocol_resp;
587
588         if (!response->response.approved) {
589                 pr_err("synthhid protocol request failed (version %d)",
590                        SYNTHHID_INPUT_VERSION);
591                 ret = -ENODEV;
592                 goto cleanup;
593         }
594
595         t = wait_for_completion_timeout(&input_dev->wait_event, 5*HZ);
596         if (t == 0) {
597                 ret = -ETIMEDOUT;
598                 goto cleanup;
599         }
600
601         /*
602          * We should have gotten the device attr, hid desc and report
603          * desc at this point
604          */
605         if (input_dev->dev_info_status)
606                 ret = -ENOMEM;
607
608 cleanup:
609         put_input_device(device);
610
611         return ret;
612 }
613
614 static int mousevsc_hid_open(struct hid_device *hid)
615 {
616         return 0;
617 }
618
619 static void mousevsc_hid_close(struct hid_device *hid)
620 {
621 }
622
623 static struct hid_ll_driver mousevsc_ll_driver = {
624         .open = mousevsc_hid_open,
625         .close = mousevsc_hid_close,
626 };
627
628 static struct hid_driver mousevsc_hid_driver;
629
630 static void reportdesc_callback(struct hv_device *dev, void *packet, u32 len)
631 {
632         struct hid_device *hid_dev;
633         struct mousevsc_dev *input_device = hv_get_drvdata(dev);
634
635         hid_dev = hid_allocate_device();
636         if (IS_ERR(hid_dev))
637                 return;
638
639         hid_dev->ll_driver = &mousevsc_ll_driver;
640         hid_dev->driver = &mousevsc_hid_driver;
641
642         if (hid_parse_report(hid_dev, packet, len))
643                 return;
644
645         hid_dev->bus = BUS_VIRTUAL;
646         hid_dev->vendor = input_device->hid_dev_info.vendor;
647         hid_dev->product = input_device->hid_dev_info.product;
648         hid_dev->version = input_device->hid_dev_info.version;
649
650         sprintf(hid_dev->name, "%s", "Microsoft Vmbus HID-compliant Mouse");
651
652         if (!hidinput_connect(hid_dev, 0)) {
653                 hid_dev->claimed |= HID_CLAIMED_INPUT;
654
655                 input_device->connected = 1;
656
657         }
658
659         input_device->hid_device = hid_dev;
660 }
661
662 static int mousevsc_on_device_add(struct hv_device *device,
663                                         void *additional_info)
664 {
665         int ret = 0;
666         struct mousevsc_dev *input_dev;
667         struct hv_driver *input_drv;
668
669         input_dev = alloc_input_device(device);
670
671         if (!input_dev)
672                 return -ENOMEM;
673
674         input_dev->init_complete = false;
675
676         /* Open the channel */
677         ret = vmbus_open(device->channel,
678                 INPUTVSC_SEND_RING_BUFFER_SIZE,
679                 INPUTVSC_RECV_RING_BUFFER_SIZE,
680                 NULL,
681                 0,
682                 mousevsc_on_channel_callback,
683                 device
684                 );
685
686         if (ret != 0) {
687                 free_input_device(input_dev);
688                 return ret;
689         }
690
691
692         ret = mousevsc_connect_to_vsp(device);
693
694         if (ret != 0) {
695                 vmbus_close(device->channel);
696                 free_input_device(input_dev);
697                 return ret;
698         }
699
700         input_drv = drv_to_hv_drv(input_dev->device->device.driver);
701
702
703
704         /* Send the report desc back up */
705         /* workaround SA-167 */
706         if (input_dev->report_desc[14] == 0x25)
707                 input_dev->report_desc[14] = 0x29;
708
709         reportdesc_callback(device, input_dev->report_desc,
710                             input_dev->report_desc_size);
711
712         input_dev->init_complete = true;
713
714         return ret;
715 }
716
717 static int mousevsc_on_device_remove(struct hv_device *device)
718 {
719         struct mousevsc_dev *input_dev;
720         int ret = 0;
721
722
723         input_dev = release_input_device(device);
724
725
726         /*
727          * At this point, all outbound traffic should be disable. We only
728          * allow inbound traffic (responses) to proceed
729          *
730          * so that outstanding requests can be completed.
731          */
732         while (input_dev->num_outstanding_req)
733                 udelay(100);
734
735         input_dev = final_release_input_device(device);
736
737         /* Close the channel */
738         vmbus_close(device->channel);
739
740         free_input_device(input_dev);
741
742         return ret;
743 }
744
745
746 static int mousevsc_probe(struct hv_device *dev,
747                         const struct hv_vmbus_device_id *dev_id)
748 {
749
750         /* Call to the vsc driver to add the device */
751         return mousevsc_on_device_add(dev, NULL);
752
753 }
754
755 static int mousevsc_remove(struct hv_device *dev)
756 {
757         struct mousevsc_dev *input_dev = hv_get_drvdata(dev);
758
759         if (input_dev->connected) {
760                 hidinput_disconnect(input_dev->hid_device);
761                 input_dev->connected = 0;
762                 hid_destroy_device(input_dev->hid_device);
763         }
764
765         /*
766          * Call to the vsc driver to let it know that the device
767          * is being removed
768          */
769         return mousevsc_on_device_remove(dev);
770 }
771
772 static const struct hv_vmbus_device_id id_table[] = {
773         /* Mouse guid */
774         { VMBUS_DEVICE(0x9E, 0xB6, 0xA8, 0xCF, 0x4A, 0x5B, 0xc0, 0x4c,
775                        0xB9, 0x8B, 0x8B, 0xA1, 0xA1, 0xF3, 0xF9, 0x5A) },
776         { },
777 };
778
779 /*
780  * The mouse driver is not functional; do not auto-load it.
781  */
782 /* MODULE_DEVICE_TABLE(vmbus, id_table); */
783
784 static struct  hv_driver mousevsc_drv = {
785         .name = "mousevsc",
786         .id_table = id_table,
787         .probe = mousevsc_probe,
788         .remove = mousevsc_remove,
789 };
790
791 static int __init mousevsc_init(void)
792 {
793         return vmbus_driver_register(&mousevsc_drv);
794 }
795
796 static void __exit mousevsc_exit(void)
797 {
798         vmbus_driver_unregister(&mousevsc_drv);
799 }
800
801 MODULE_LICENSE("GPL");
802 MODULE_VERSION(HV_DRV_VERSION);
803 module_init(mousevsc_init);
804 module_exit(mousevsc_exit);
805