lkml.org 
[lkml]   [2005]   [Mar]   [6]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectImplement compat_ioctl for joydev
    This patch implements compat_ioctl for joydev.  I've tested it with a
    Logitech WingMan Rumblepad on an x86-64 machine, and on an ia32
    machine to make sure I didn't break anything.

    Patch against stock 2.6.11, but also tested with 2.6.11-mm1.

    Signed-off-by: Jeremy Fitzhardinge <jeremy@goop.org>

    Index: local-2.6/include/linux/joystick.h
    ===================================================================
    --- local-2.6.orig/include/linux/joystick.h 2005-03-05 13:40:49.000000000 -0800
    +++ local-2.6/include/linux/joystick.h 2005-03-06 11:25:42.000000000 -0800
    @@ -111,18 +111,35 @@
    #define JS_SET_ALL 8

    struct JS_DATA_TYPE {
    - int buttons;
    - int x;
    - int y;
    + __s32 buttons;
    + __s32 x;
    + __s32 y;
    };

    -struct JS_DATA_SAVE_TYPE {
    - int JS_TIMEOUT;
    - int BUSY;
    - long JS_EXPIRETIME;
    - long JS_TIMELIMIT;
    +struct JS_DATA_SAVE_TYPE_32 {
    + __s32 JS_TIMEOUT;
    + __s32 BUSY;
    + __s32 JS_EXPIRETIME;
    + __s32 JS_TIMELIMIT;
    struct JS_DATA_TYPE JS_SAVE;
    struct JS_DATA_TYPE JS_CORR;
    };

    +struct JS_DATA_SAVE_TYPE_64 {
    + __s32 JS_TIMEOUT;
    + __s32 BUSY;
    + __s64 JS_EXPIRETIME;
    + __s64 JS_TIMELIMIT;
    + struct JS_DATA_TYPE JS_SAVE;
    + struct JS_DATA_TYPE JS_CORR;
    +};
    +
    +#if BITS_PER_LONG == 64
    +#define JS_DATA_SAVE_TYPE JS_DATA_SAVE_TYPE_64
    +#elif BITS_PER_LONG == 32
    +#define JS_DATA_SAVE_TYPE JS_DATA_SAVE_TYPE_32
    +#else
    +#error Unexpected BITS_PER_LONG
    +#endif
    +
    #endif /* _LINUX_JOYSTICK_H */
    Index: local-2.6/drivers/input/joydev.c
    ===================================================================
    --- local-2.6.orig/drivers/input/joydev.c 2005-03-05 13:40:49.000000000 -0800
    +++ local-2.6/drivers/input/joydev.c 2005-03-06 11:39:00.000000000 -0800
    @@ -286,48 +286,33 @@
    return 0;
    }

    -static int joydev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
    +static int joydev_ioctl_common(struct joydev *joydev, unsigned int cmd, void __user *argp)
    {
    - struct joydev_list *list = file->private_data;
    - struct joydev *joydev = list->joydev;
    struct input_dev *dev = joydev->handle.dev;
    - void __user *argp = (void __user *)arg;
    int i, j;

    - if (!joydev->exist) return -ENODEV;
    -
    switch (cmd) {

    case JS_SET_CAL:
    return copy_from_user(&joydev->glue.JS_CORR, argp,
    - sizeof(struct JS_DATA_TYPE)) ? -EFAULT : 0;
    + sizeof(joydev->glue.JS_CORR)) ? -EFAULT : 0;
    case JS_GET_CAL:
    return copy_to_user(argp, &joydev->glue.JS_CORR,
    - sizeof(struct JS_DATA_TYPE)) ? -EFAULT : 0;
    + sizeof(joydev->glue.JS_CORR)) ? -EFAULT : 0;
    case JS_SET_TIMEOUT:
    - return get_user(joydev->glue.JS_TIMEOUT, (int __user *) arg);
    + return get_user(joydev->glue.JS_TIMEOUT, (s32 __user *) argp);
    case JS_GET_TIMEOUT:
    - return put_user(joydev->glue.JS_TIMEOUT, (int __user *) arg);
    - case JS_SET_TIMELIMIT:
    - return get_user(joydev->glue.JS_TIMELIMIT, (long __user *) arg);
    - case JS_GET_TIMELIMIT:
    - return put_user(joydev->glue.JS_TIMELIMIT, (long __user *) arg);
    - case JS_SET_ALL:
    - return copy_from_user(&joydev->glue, argp,
    - sizeof(struct JS_DATA_SAVE_TYPE)) ? -EFAULT : 0;
    - case JS_GET_ALL:
    - return copy_to_user(argp, &joydev->glue,
    - sizeof(struct JS_DATA_SAVE_TYPE)) ? -EFAULT : 0;
    + return put_user(joydev->glue.JS_TIMEOUT, (s32 __user *) argp);

    case JSIOCGVERSION:
    - return put_user(JS_VERSION, (__u32 __user *) arg);
    + return put_user(JS_VERSION, (__u32 __user *) argp);
    case JSIOCGAXES:
    - return put_user(joydev->nabs, (__u8 __user *) arg);
    + return put_user(joydev->nabs, (__u8 __user *) argp);
    case JSIOCGBUTTONS:
    - return put_user(joydev->nkey, (__u8 __user *) arg);
    + return put_user(joydev->nkey, (__u8 __user *) argp);
    case JSIOCSCORR:
    if (copy_from_user(joydev->corr, argp,
    - sizeof(struct js_corr) * joydev->nabs))
    + sizeof(joydev->corr[0]) * joydev->nabs))
    return -EFAULT;
    for (i = 0; i < joydev->nabs; i++) {
    j = joydev->abspam[i];
    @@ -336,7 +321,7 @@
    return 0;
    case JSIOCGCORR:
    return copy_to_user(argp, joydev->corr,
    - sizeof(struct js_corr) * joydev->nabs) ? -EFAULT : 0;
    + sizeof(joydev->corr[0]) * joydev->nabs) ? -EFAULT : 0;
    case JSIOCSAXMAP:
    if (copy_from_user(joydev->abspam, argp, sizeof(__u8) * ABS_MAX))
    return -EFAULT;
    @@ -372,6 +357,84 @@
    return -EINVAL;
    }

    +#ifdef CONFIG_COMPAT
    +static long joydev_compat_ioctl(struct file *file, unsigned cmd, unsigned long arg)
    +{
    + struct joydev_list *list = file->private_data;
    + struct joydev *joydev = list->joydev;
    + void __user *argp = (void __user *)arg;
    + s32 tmp32;
    + struct JS_DATA_SAVE_TYPE_32 ds32;
    + int err;
    +
    + if (!joydev->exist) return -ENODEV;
    + switch(cmd) {
    + case JS_SET_TIMELIMIT:
    + err = get_user(tmp32, (s32 __user *) arg);
    + if (err == 0)
    + joydev->glue.JS_TIMELIMIT = tmp32;
    + break;
    + case JS_GET_TIMELIMIT:
    + tmp32 = joydev->glue.JS_TIMELIMIT;
    + err = put_user(tmp32, (s32 __user *) arg);
    + break;
    +
    + case JS_SET_ALL:
    + err = copy_from_user(&ds32, argp,
    + sizeof(ds32)) ? -EFAULT : 0;
    + if (err == 0) {
    + joydev->glue.JS_TIMEOUT = ds32.JS_TIMEOUT;
    + joydev->glue.BUSY = ds32.BUSY;
    + joydev->glue.JS_EXPIRETIME = ds32.JS_EXPIRETIME;
    + joydev->glue.JS_TIMELIMIT = ds32.JS_TIMELIMIT;
    + joydev->glue.JS_SAVE = ds32.JS_SAVE;
    + joydev->glue.JS_CORR = ds32.JS_CORR;
    + }
    + break;
    +
    + case JS_GET_ALL:
    + ds32.JS_TIMEOUT = joydev->glue.JS_TIMEOUT;
    + ds32.BUSY = joydev->glue.BUSY;
    + ds32.JS_EXPIRETIME = joydev->glue.JS_EXPIRETIME;
    + ds32.JS_TIMELIMIT = joydev->glue.JS_TIMELIMIT;
    + ds32.JS_SAVE = joydev->glue.JS_SAVE;
    + ds32.JS_CORR = joydev->glue.JS_CORR;
    +
    + err = copy_to_user(argp, &ds32,
    + sizeof(ds32)) ? -EFAULT : 0;
    + break;
    +
    + default:
    + err = joydev_ioctl_common(joydev, cmd, argp);
    + }
    + return err;
    +}
    +#endif /* CONFIG_COMPAT */
    +
    +static int joydev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
    +{
    + struct joydev_list *list = file->private_data;
    + struct joydev *joydev = list->joydev;
    + void __user *argp = (void __user *)arg;
    +
    + if (!joydev->exist) return -ENODEV;
    +
    + switch(cmd) {
    + case JS_SET_TIMELIMIT:
    + return get_user(joydev->glue.JS_TIMELIMIT, (long __user *) arg);
    + case JS_GET_TIMELIMIT:
    + return put_user(joydev->glue.JS_TIMELIMIT, (long __user *) arg);
    + case JS_SET_ALL:
    + return copy_from_user(&joydev->glue, argp,
    + sizeof(joydev->glue)) ? -EFAULT : 0;
    + case JS_GET_ALL:
    + return copy_to_user(argp, &joydev->glue,
    + sizeof(joydev->glue)) ? -EFAULT : 0;
    + default:
    + return joydev_ioctl_common(joydev, cmd, argp);
    + }
    +}
    +
    static struct file_operations joydev_fops = {
    .owner = THIS_MODULE,
    .read = joydev_read,
    @@ -380,6 +443,9 @@
    .open = joydev_open,
    .release = joydev_release,
    .ioctl = joydev_ioctl,
    +#ifdef CONFIG_COMPAT
    + .compat_ioctl = joydev_compat_ioctl,
    +#endif
    .fasync = joydev_fasync,
    };

    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2005-03-22 14:10    [W:0.041 / U:0.224 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site