Line data Source code
1 : /*
2 : * 32bit compatibility wrappers for the input subsystem.
3 : *
4 : * Very heavily based on evdev.c - Copyright (c) 1999-2002 Vojtech Pavlik
5 : *
6 : * This program is free software; you can redistribute it and/or modify it
7 : * under the terms of the GNU General Public License version 2 as published by
8 : * the Free Software Foundation.
9 : */
10 :
11 : #include <asm/uaccess.h>
12 : #include "input-compat.h"
13 :
14 : #ifdef CONFIG_COMPAT
15 :
16 : int input_event_from_user(const char __user *buffer,
17 : struct input_event *event)
18 0 : {
19 0 : if (INPUT_COMPAT_TEST) {
20 0 : struct input_event_compat compat_event;
21 0 :
22 0 : if (copy_from_user(&compat_event, buffer,
23 : sizeof(struct input_event_compat)))
24 0 : return -EFAULT;
25 :
26 0 : event->time.tv_sec = compat_event.time.tv_sec;
27 0 : event->time.tv_usec = compat_event.time.tv_usec;
28 0 : event->type = compat_event.type;
29 0 : event->code = compat_event.code;
30 0 : event->value = compat_event.value;
31 :
32 : } else {
33 0 : if (copy_from_user(event, buffer, sizeof(struct input_event)))
34 0 : return -EFAULT;
35 : }
36 :
37 0 : return 0;
38 : }
39 :
40 : int input_event_to_user(char __user *buffer,
41 : const struct input_event *event)
42 0 : {
43 0 : if (INPUT_COMPAT_TEST) {
44 0 : struct input_event_compat compat_event;
45 0 :
46 0 : compat_event.time.tv_sec = event->time.tv_sec;
47 0 : compat_event.time.tv_usec = event->time.tv_usec;
48 0 : compat_event.type = event->type;
49 0 : compat_event.code = event->code;
50 0 : compat_event.value = event->value;
51 :
52 0 : if (copy_to_user(buffer, &compat_event,
53 : sizeof(struct input_event_compat)))
54 0 : return -EFAULT;
55 :
56 : } else {
57 0 : if (copy_to_user(buffer, event, sizeof(struct input_event)))
58 0 : return -EFAULT;
59 : }
60 :
61 0 : return 0;
62 : }
63 :
64 : int input_ff_effect_from_user(const char __user *buffer, size_t size,
65 : struct ff_effect *effect)
66 0 : {
67 0 : if (INPUT_COMPAT_TEST) {
68 0 : struct ff_effect_compat *compat_effect;
69 0 :
70 0 : if (size != sizeof(struct ff_effect_compat))
71 0 : return -EINVAL;
72 :
73 : /*
74 : * It so happens that the pointer which needs to be changed
75 : * is the last field in the structure, so we can retrieve the
76 : * whole thing and replace just the pointer.
77 : */
78 0 : compat_effect = (struct ff_effect_compat *)effect;
79 :
80 0 : if (copy_from_user(compat_effect, buffer,
81 : sizeof(struct ff_effect_compat)))
82 0 : return -EFAULT;
83 :
84 0 : if (compat_effect->type == FF_PERIODIC &&
85 : compat_effect->u.periodic.waveform == FF_CUSTOM)
86 0 : effect->u.periodic.custom_data =
87 : compat_ptr(compat_effect->u.periodic.custom_data);
88 : } else {
89 0 : if (size != sizeof(struct ff_effect))
90 0 : return -EINVAL;
91 :
92 0 : if (copy_from_user(effect, buffer, sizeof(struct ff_effect)))
93 0 : return -EFAULT;
94 : }
95 :
96 0 : return 0;
97 : }
98 :
99 : #else
100 :
101 : int input_event_from_user(const char __user *buffer,
102 : struct input_event *event)
103 : {
104 : if (copy_from_user(event, buffer, sizeof(struct input_event)))
105 : return -EFAULT;
106 :
107 : return 0;
108 : }
109 :
110 : int input_event_to_user(char __user *buffer,
111 : const struct input_event *event)
112 : {
113 : if (copy_to_user(buffer, event, sizeof(struct input_event)))
114 : return -EFAULT;
115 :
116 : return 0;
117 : }
118 :
119 : int input_ff_effect_from_user(const char __user *buffer, size_t size,
120 : struct ff_effect *effect)
121 : {
122 : if (size != sizeof(struct ff_effect))
123 : return -EINVAL;
124 :
125 : if (copy_from_user(effect, buffer, sizeof(struct ff_effect)))
126 : return -EFAULT;
127 :
128 : return 0;
129 : }
130 :
131 : #endif /* CONFIG_COMPAT */
132 :
133 : EXPORT_SYMBOL_GPL(input_event_from_user);
134 : EXPORT_SYMBOL_GPL(input_event_to_user);
135 : EXPORT_SYMBOL_GPL(input_ff_effect_from_user);
|