1 |
Author: dsd |
2 |
Date: 2008-06-29 16:49:31 +0000 (Sun, 29 Jun 2008) |
3 |
New Revision: 1325 |
4 |
|
5 |
Added: |
6 |
genpatches-2.6/trunk/2.6.25/2600_evdev-compat-ioctl-force-feedback.patch |
7 |
Modified: |
8 |
genpatches-2.6/trunk/2.6.25/0000_README |
9 |
Log: |
10 |
Fix evdev force feedback in 32-bit compat mode |
11 |
|
12 |
Modified: genpatches-2.6/trunk/2.6.25/0000_README |
13 |
=================================================================== |
14 |
--- genpatches-2.6/trunk/2.6.25/0000_README 2008-06-25 01:32:40 UTC (rev 1324) |
15 |
+++ genpatches-2.6/trunk/2.6.25/0000_README 2008-06-29 16:49:31 UTC (rev 1325) |
16 |
@@ -75,6 +75,10 @@ |
17 |
From: http://www.kernel.org |
18 |
Desc: Linux 2.6.25.9 |
19 |
|
20 |
+Patch: 2600_evdev-compat-ioctl-force-feedback.patch |
21 |
+From: http://bugs.gentoo.org/214700 |
22 |
+Desc: Fix evdev force feedback in 32-bit compat mode |
23 |
+ |
24 |
Patch: 2705_alsa-hda-fujitsu.patch |
25 |
From: Tony Vroon <chainsaw@g.o> |
26 |
Desc: Fix docking station headphone port and PC speaker for Fujitsu ALC262 |
27 |
|
28 |
Added: genpatches-2.6/trunk/2.6.25/2600_evdev-compat-ioctl-force-feedback.patch |
29 |
=================================================================== |
30 |
--- genpatches-2.6/trunk/2.6.25/2600_evdev-compat-ioctl-force-feedback.patch (rev 0) |
31 |
+++ genpatches-2.6/trunk/2.6.25/2600_evdev-compat-ioctl-force-feedback.patch 2008-06-29 16:49:31 UTC (rev 1325) |
32 |
@@ -0,0 +1,159 @@ |
33 |
+From: Adam Dawidowski <drake_ster@××.pl> |
34 |
+Date: Mon, 2 Jun 2008 05:08:10 +0000 (-0400) |
35 |
+Subject: Input: fix force feedback upload issue in compat mode |
36 |
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fdtor%2Finput.git;a=commitdiff_plain;h=bb00421d9b684253468bf751e7ce0a4667b721e8 |
37 |
+ |
38 |
+Input: fix force feedback upload issue in compat mode |
39 |
+ |
40 |
+Force feedback upload of effects through the event device (ioctl |
41 |
+EVIOCSFF) is not working in 32 bit applications running on 64-bit |
42 |
+kernel due to the fact that struct ff_effect contains a pointer, |
43 |
+resulting in the structure having different sizes in 64 and 32 bit |
44 |
+programs and causing difference in ioctl numbers. |
45 |
+ |
46 |
+[dtor@××××.ru: refactor to keep all ugliness in evdev] |
47 |
+ |
48 |
+Signed-off-by: Adam Dawidowski <drake_ster@××.pl> |
49 |
+Signed-off-by: Dmitry Torokhov <dtor@××××.ru> |
50 |
+--- |
51 |
+ |
52 |
+diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c |
53 |
+index b32984b..2d65411 100644 |
54 |
+--- a/drivers/input/evdev.c |
55 |
++++ b/drivers/input/evdev.c |
56 |
+@@ -300,6 +300,35 @@ struct input_event_compat { |
57 |
+ __s32 value; |
58 |
+ }; |
59 |
+ |
60 |
++struct ff_periodic_effect_compat { |
61 |
++ __u16 waveform; |
62 |
++ __u16 period; |
63 |
++ __s16 magnitude; |
64 |
++ __s16 offset; |
65 |
++ __u16 phase; |
66 |
++ |
67 |
++ struct ff_envelope envelope; |
68 |
++ |
69 |
++ __u32 custom_len; |
70 |
++ compat_uptr_t custom_data; |
71 |
++}; |
72 |
++ |
73 |
++struct ff_effect_compat { |
74 |
++ __u16 type; |
75 |
++ __s16 id; |
76 |
++ __u16 direction; |
77 |
++ struct ff_trigger trigger; |
78 |
++ struct ff_replay replay; |
79 |
++ |
80 |
++ union { |
81 |
++ struct ff_constant_effect constant; |
82 |
++ struct ff_ramp_effect ramp; |
83 |
++ struct ff_periodic_effect_compat periodic; |
84 |
++ struct ff_condition_effect condition[2]; /* One for each axis */ |
85 |
++ struct ff_rumble_effect rumble; |
86 |
++ } u; |
87 |
++}; |
88 |
++ |
89 |
+ /* Note to the author of this code: did it ever occur to |
90 |
+ you why the ifdefs are needed? Think about it again. -AK */ |
91 |
+ #ifdef CONFIG_X86_64 |
92 |
+@@ -368,6 +397,42 @@ static int evdev_event_to_user(char __user *buffer, |
93 |
+ return 0; |
94 |
+ } |
95 |
+ |
96 |
++static int evdev_ff_effect_from_user(const char __user *buffer, size_t size, |
97 |
++ struct ff_effect *effect) |
98 |
++{ |
99 |
++ if (COMPAT_TEST) { |
100 |
++ struct ff_effect_compat *compat_effect; |
101 |
++ |
102 |
++ if (size != sizeof(struct ff_effect_compat)) |
103 |
++ return -EINVAL; |
104 |
++ |
105 |
++ /* |
106 |
++ * It so happens that the pointer which needs to be changed |
107 |
++ * is the last field in the structure, so we can copy the |
108 |
++ * whole thing and replace just the pointer. |
109 |
++ */ |
110 |
++ |
111 |
++ compat_effect = (struct ff_effect_compat *)effect; |
112 |
++ |
113 |
++ if (copy_from_user(compat_effect, buffer, |
114 |
++ sizeof(struct ff_effect_compat))) |
115 |
++ return -EFAULT; |
116 |
++ |
117 |
++ if (compat_effect->type == FF_PERIODIC && |
118 |
++ compat_effect->u.periodic.waveform == FF_CUSTOM) |
119 |
++ effect->u.periodic.custom_data = |
120 |
++ compat_ptr(compat_effect->u.periodic.custom_data); |
121 |
++ } else { |
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 |
++ |
129 |
++ return 0; |
130 |
++} |
131 |
++ |
132 |
+ #else |
133 |
+ |
134 |
+ static inline size_t evdev_event_size(void) |
135 |
+@@ -393,6 +458,18 @@ static int evdev_event_to_user(char __user *buffer, |
136 |
+ return 0; |
137 |
+ } |
138 |
+ |
139 |
++static int evdev_ff_effect_from_user(const char __user *buffer, size_t size, |
140 |
++ struct ff_effect *effect) |
141 |
++{ |
142 |
++ if (size != sizeof(struct ff_effect)) |
143 |
++ return -EINVAL; |
144 |
++ |
145 |
++ if (copy_from_user(effect, buffer, sizeof(struct ff_effect))) |
146 |
++ return -EFAULT; |
147 |
++ |
148 |
++ return 0; |
149 |
++} |
150 |
++ |
151 |
+ #endif /* CONFIG_COMPAT */ |
152 |
+ |
153 |
+ static ssize_t evdev_write(struct file *file, const char __user *buffer, |
154 |
+@@ -633,17 +710,6 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, |
155 |
+ |
156 |
+ return input_set_keycode(dev, t, v); |
157 |
+ |
158 |
+- case EVIOCSFF: |
159 |
+- if (copy_from_user(&effect, p, sizeof(effect))) |
160 |
+- return -EFAULT; |
161 |
+- |
162 |
+- error = input_ff_upload(dev, &effect, file); |
163 |
+- |
164 |
+- if (put_user(effect.id, &(((struct ff_effect __user *)p)->id))) |
165 |
+- return -EFAULT; |
166 |
+- |
167 |
+- return error; |
168 |
+- |
169 |
+ case EVIOCRMFF: |
170 |
+ return input_ff_erase(dev, (int)(unsigned long) p, file); |
171 |
+ |
172 |
+@@ -733,6 +799,19 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, |
173 |
+ |
174 |
+ if (_IOC_DIR(cmd) == _IOC_WRITE) { |
175 |
+ |
176 |
++ if (_IOC_NR(cmd) == _IOC_NR(EVIOCSFF)) { |
177 |
++ |
178 |
++ if (evdev_ff_effect_from_user(p, _IOC_SIZE(cmd), &effect)) |
179 |
++ return -EFAULT; |
180 |
++ |
181 |
++ error = input_ff_upload(dev, &effect, file); |
182 |
++ |
183 |
++ if (put_user(effect.id, &(((struct ff_effect __user *)p)->id))) |
184 |
++ return -EFAULT; |
185 |
++ |
186 |
++ return error; |
187 |
++ } |
188 |
++ |
189 |
+ if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0))) { |
190 |
+ |
191 |
+ t = _IOC_NR(cmd) & ABS_MAX; |
192 |
|
193 |
-- |
194 |
gentoo-commits@l.g.o mailing list |