* [PATCH] Fix force feedback uploading for 32-bit apps on 64-bit kernel
@ 2008-03-27 21:20 drAke
0 siblings, 0 replies; only message in thread
From: drAke @ 2008-03-27 21:20 UTC (permalink / raw)
To: linux-input; +Cc: Adam Dawidowski
[-- Attachment #1: Type: text/plain, Size: 646 bytes --]
Hello,
Force feedback upload of effects through the event device (ioctl
EVIOCSFF) is not working in 32 bit apps like wine on a 64-bit kernel. 64
bit apps like fftest work.
This is due to the fact that struct ff_effect contains a pointer,
resulting in the structure having different sizes in 64 and 32 bit
programs. This means that the ioctl issued from 32 bit code isn't
handled, because it has a different number.
Attached patch (against 2.6.24.3) fixes this. Tested on x86_64.
Is this ok or are there some alignment issues, which forbid this simple
zero-copy solution?
PS. Please keep me in the CC list, as I'm not subscribing this list.
[-- Attachment #2: ioctl_EVIOCSFF_32bit_fix.patch --]
[-- Type: text/plain, Size: 3492 bytes --]
diff -ruNp 2.6.24.3/drivers/input/evdev.c 2.6.24.3-ioctl-fix/drivers/input/evdev.c
--- 2.6.24.3/drivers/input/evdev.c 2008-01-24 23:58:37.000000000 +0100
+++ 2.6.24.3-ioctl-fix/drivers/input/evdev.c 2008-03-26 22:12:02.000000000 +0100
@@ -577,6 +577,9 @@ static long evdev_do_ioctl(struct file *
struct input_dev *dev = evdev->handle.dev;
struct input_absinfo abs;
struct ff_effect effect;
+#ifdef CONFIG_COMPAT
+ struct ff_effect32 *effect32;
+#endif
int __user *ip = (int __user *)p;
int i, t, u, v;
int error;
@@ -632,10 +635,28 @@ static long evdev_do_ioctl(struct file *
return dev->setkeycode(dev, t, v);
+#ifdef CONFIG_COMPAT
+ case EVIOCSFF32:
+#endif
case EVIOCSFF:
- if (copy_from_user(&effect, p, sizeof(effect)))
+ if (copy_from_user(&effect, p, _IOC_SIZE(cmd)))
return -EFAULT;
+#ifdef CONFIG_COMPAT
+ /*
+ * It so happens that the pointer which needs to be changed
+ * is the last field in the structure, so we can copy the
+ * whole thing and replace just the pointer.
+ */
+ if (cmd == EVIOCSFF32) {
+ effect32 = (struct ff_effect32 *)&effect;
+ if (effect32->type == FF_PERIODIC &&
+ effect32->u.periodic.waveform == FF_CUSTOM)
+ effect.u.periodic.custom_data = compat_ptr(
+ effect32->u.periodic.custom_data);
+ }
+#endif
+
error = input_ff_upload(dev, &effect, file);
if (put_user(effect.id, &(((struct ff_effect __user *)p)->id)))
diff -ruNp 2.6.24.3/include/linux/input.h 2.6.24.3-ioctl-fix/include/linux/input.h
--- 2.6.24.3/include/linux/input.h 2008-01-24 23:58:37.000000000 +0100
+++ 2.6.24.3-ioctl-fix/include/linux/input.h 2008-03-25 22:17:59.000000000 +0100
@@ -12,6 +12,7 @@
#ifdef __KERNEL__
#include <linux/time.h>
#include <linux/list.h>
+#include <linux/compat.h>
#else
#include <sys/time.h>
#include <sys/ioctl.h>
@@ -75,7 +76,10 @@ struct input_absinfo {
#define EVIOCGABS(abs) _IOR('E', 0x40 + abs, struct input_absinfo) /* get abs value/limits */
#define EVIOCSABS(abs) _IOW('E', 0xc0 + abs, struct input_absinfo) /* set abs value/limits */
-#define EVIOCSFF _IOC(_IOC_WRITE, 'E', 0x80, sizeof(struct ff_effect)) /* send a force effect to a force feedback device */
+#define EVIOCSFF _IOW('E', 0x80, struct ff_effect) /* send a force effect to a force feedback device */
+#ifdef CONFIG_COMPAT
+#define EVIOCSFF32 _IOW('E', 0x80, struct ff_effect32)
+#endif
#define EVIOCRMFF _IOW('E', 0x81, int) /* Erase a force effect */
#define EVIOCGEFFECTS _IOR('E', 0x84, int) /* Report number of effects playable at the same time */
@@ -846,6 +850,21 @@ struct ff_periodic_effect {
__s16 *custom_data;
};
+#ifdef CONFIG_COMPAT
+struct ff_periodic_effect32 {
+ __u16 waveform;
+ __u16 period;
+ __s16 magnitude;
+ __s16 offset;
+ __u16 phase;
+
+ struct ff_envelope envelope;
+
+ __u32 custom_len;
+ compat_uptr_t custom_data;
+};
+#endif
+
/**
* struct ff_rumble_effect - defines parameters of a periodic force-feedback effect
* @strong_magnitude: magnitude of the heavy motor
@@ -898,6 +917,24 @@ struct ff_effect {
} u;
};
+#ifdef CONFIG_COMPAT
+struct ff_effect32 {
+ __u16 type;
+ __s16 id;
+ __u16 direction;
+ struct ff_trigger trigger;
+ struct ff_replay replay;
+
+ union {
+ struct ff_constant_effect constant;
+ struct ff_ramp_effect ramp;
+ struct ff_periodic_effect32 periodic;
+ struct ff_condition_effect condition[2]; /* One for each axis */
+ struct ff_rumble_effect rumble;
+ } u;
+};
+#endif
+
/*
* Force feedback effect types
*/
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2008-03-27 21:29 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-03-27 21:20 [PATCH] Fix force feedback uploading for 32-bit apps on 64-bit kernel drAke
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).