Branch data 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 <linux/export.h>
12 : : #include <asm/uaccess.h>
13 : : #include "input-compat.h"
14 : :
15 : : #ifdef CONFIG_COMPAT
16 : :
17 : : int input_event_from_user(const char __user *buffer,
18 : : struct input_event *event)
19 : : {
20 : : if (INPUT_COMPAT_TEST && !COMPAT_USE_64BIT_TIME) {
21 : : struct input_event_compat compat_event;
22 : :
23 : : if (copy_from_user(&compat_event, buffer,
24 : : sizeof(struct input_event_compat)))
25 : : return -EFAULT;
26 : :
27 : : event->time.tv_sec = compat_event.time.tv_sec;
28 : : event->time.tv_usec = compat_event.time.tv_usec;
29 : : event->type = compat_event.type;
30 : : event->code = compat_event.code;
31 : : event->value = compat_event.value;
32 : :
33 : : } else {
34 : : if (copy_from_user(event, buffer, sizeof(struct input_event)))
35 : : return -EFAULT;
36 : : }
37 : :
38 : : return 0;
39 : : }
40 : :
41 : : int input_event_to_user(char __user *buffer,
42 : : const struct input_event *event)
43 : : {
44 : : if (INPUT_COMPAT_TEST && !COMPAT_USE_64BIT_TIME) {
45 : : struct input_event_compat compat_event;
46 : :
47 : : compat_event.time.tv_sec = event->time.tv_sec;
48 : : compat_event.time.tv_usec = event->time.tv_usec;
49 : : compat_event.type = event->type;
50 : : compat_event.code = event->code;
51 : : compat_event.value = event->value;
52 : :
53 : : if (copy_to_user(buffer, &compat_event,
54 : : sizeof(struct input_event_compat)))
55 : : return -EFAULT;
56 : :
57 : : } else {
58 : : if (copy_to_user(buffer, event, sizeof(struct input_event)))
59 : : return -EFAULT;
60 : : }
61 : :
62 : : return 0;
63 : : }
64 : :
65 : : int input_ff_effect_from_user(const char __user *buffer, size_t size,
66 : : struct ff_effect *effect)
67 : : {
68 : : if (INPUT_COMPAT_TEST) {
69 : : struct ff_effect_compat *compat_effect;
70 : :
71 : : if (size != sizeof(struct ff_effect_compat))
72 : : return -EINVAL;
73 : :
74 : : /*
75 : : * It so happens that the pointer which needs to be changed
76 : : * is the last field in the structure, so we can retrieve the
77 : : * whole thing and replace just the pointer.
78 : : */
79 : : compat_effect = (struct ff_effect_compat *)effect;
80 : :
81 : : if (copy_from_user(compat_effect, buffer,
82 : : sizeof(struct ff_effect_compat)))
83 : : return -EFAULT;
84 : :
85 : : if (compat_effect->type == FF_PERIODIC &&
86 : : compat_effect->u.periodic.waveform == FF_CUSTOM)
87 : : effect->u.periodic.custom_data =
88 : : compat_ptr(compat_effect->u.periodic.custom_data);
89 : : } else {
90 : : if (size != sizeof(struct ff_effect))
91 : : return -EINVAL;
92 : :
93 : : if (copy_from_user(effect, buffer, sizeof(struct ff_effect)))
94 : : return -EFAULT;
95 : : }
96 : :
97 : : return 0;
98 : : }
99 : :
100 : : #else
101 : :
102 : 0 : int input_event_from_user(const char __user *buffer,
103 : : struct input_event *event)
104 : : {
105 [ # # ]: 0 : if (copy_from_user(event, buffer, sizeof(struct input_event)))
106 : : return -EFAULT;
107 : :
108 : 0 : return 0;
109 : : }
110 : :
111 : 0 : int input_event_to_user(char __user *buffer,
112 : : const struct input_event *event)
113 : : {
114 [ # # ]: 0 : if (copy_to_user(buffer, event, sizeof(struct input_event)))
115 : : return -EFAULT;
116 : :
117 : 0 : return 0;
118 : : }
119 : :
120 : 0 : int input_ff_effect_from_user(const char __user *buffer, size_t size,
121 : : struct ff_effect *effect)
122 : : {
123 [ # # ]: 0 : if (size != sizeof(struct ff_effect))
124 : : return -EINVAL;
125 : :
126 [ # # ]: 0 : if (copy_from_user(effect, buffer, sizeof(struct ff_effect)))
127 : : return -EFAULT;
128 : :
129 : 0 : return 0;
130 : : }
131 : :
132 : : #endif /* CONFIG_COMPAT */
133 : :
134 : : EXPORT_SYMBOL_GPL(input_event_from_user);
135 : : EXPORT_SYMBOL_GPL(input_event_to_user);
136 : : EXPORT_SYMBOL_GPL(input_ff_effect_from_user);
|