aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Fitzhardinge <jeremy@goop.org>2005-05-29 03:26:31 -0400
committerDmitry Torokhov <dtor_core@ameritech.net>2005-05-29 03:26:31 -0400
commit024ac44c701d43f5e2d34bd6a35b2813a36e6010 (patch)
tree2f0cefd615ce72353e75536ac1067f549e7b5715
parentf23488b2ab1b447ea4ea3d00cdb0d322a73e7f7f (diff)
Input: 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. Signed-off-by: Jeremy Fitzhardinge <jeremy@goop.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Vojtech Pavlik <vojtech@suse.cz> Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
-rw-r--r--drivers/input/joydev.c116
-rw-r--r--include/linux/joystick.h33
2 files changed, 116 insertions, 33 deletions
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c
index 627d343dfba1..816a585a0e6b 100644
--- a/drivers/input/joydev.c
+++ b/drivers/input/joydev.c
@@ -285,48 +285,33 @@ static unsigned int joydev_poll(struct file *file, poll_table *wait)
285 (POLLIN | POLLRDNORM) : 0) | (list->joydev->exist ? 0 : (POLLHUP | POLLERR)); 285 (POLLIN | POLLRDNORM) : 0) | (list->joydev->exist ? 0 : (POLLHUP | POLLERR));
286} 286}
287 287
288static int joydev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) 288static int joydev_ioctl_common(struct joydev *joydev, unsigned int cmd, void __user *argp)
289{ 289{
290 struct joydev_list *list = file->private_data;
291 struct joydev *joydev = list->joydev;
292 struct input_dev *dev = joydev->handle.dev; 290 struct input_dev *dev = joydev->handle.dev;
293 void __user *argp = (void __user *)arg;
294 int i, j; 291 int i, j;
295 292
296 if (!joydev->exist) return -ENODEV;
297
298 switch (cmd) { 293 switch (cmd) {
299 294
300 case JS_SET_CAL: 295 case JS_SET_CAL:
301 return copy_from_user(&joydev->glue.JS_CORR, argp, 296 return copy_from_user(&joydev->glue.JS_CORR, argp,
302 sizeof(struct JS_DATA_TYPE)) ? -EFAULT : 0; 297 sizeof(joydev->glue.JS_CORR)) ? -EFAULT : 0;
303 case JS_GET_CAL: 298 case JS_GET_CAL:
304 return copy_to_user(argp, &joydev->glue.JS_CORR, 299 return copy_to_user(argp, &joydev->glue.JS_CORR,
305 sizeof(struct JS_DATA_TYPE)) ? -EFAULT : 0; 300 sizeof(joydev->glue.JS_CORR)) ? -EFAULT : 0;
306 case JS_SET_TIMEOUT: 301 case JS_SET_TIMEOUT:
307 return get_user(joydev->glue.JS_TIMEOUT, (int __user *) arg); 302 return get_user(joydev->glue.JS_TIMEOUT, (s32 __user *) argp);
308 case JS_GET_TIMEOUT: 303 case JS_GET_TIMEOUT:
309 return put_user(joydev->glue.JS_TIMEOUT, (int __user *) arg); 304 return put_user(joydev->glue.JS_TIMEOUT, (s32 __user *) argp);
310 case JS_SET_TIMELIMIT:
311 return get_user(joydev->glue.JS_TIMELIMIT, (long __user *) arg);
312 case JS_GET_TIMELIMIT:
313 return put_user(joydev->glue.JS_TIMELIMIT, (long __user *) arg);
314 case JS_SET_ALL:
315 return copy_from_user(&joydev->glue, argp,
316 sizeof(struct JS_DATA_SAVE_TYPE)) ? -EFAULT : 0;
317 case JS_GET_ALL:
318 return copy_to_user(argp, &joydev->glue,
319 sizeof(struct JS_DATA_SAVE_TYPE)) ? -EFAULT : 0;
320 305
321 case JSIOCGVERSION: 306 case JSIOCGVERSION:
322 return put_user(JS_VERSION, (__u32 __user *) arg); 307 return put_user(JS_VERSION, (__u32 __user *) argp);
323 case JSIOCGAXES: 308 case JSIOCGAXES:
324 return put_user(joydev->nabs, (__u8 __user *) arg); 309 return put_user(joydev->nabs, (__u8 __user *) argp);
325 case JSIOCGBUTTONS: 310 case JSIOCGBUTTONS:
326 return put_user(joydev->nkey, (__u8 __user *) arg); 311 return put_user(joydev->nkey, (__u8 __user *) argp);
327 case JSIOCSCORR: 312 case JSIOCSCORR:
328 if (copy_from_user(joydev->corr, argp, 313 if (copy_from_user(joydev->corr, argp,
329 sizeof(struct js_corr) * joydev->nabs)) 314 sizeof(joydev->corr[0]) * joydev->nabs))
330 return -EFAULT; 315 return -EFAULT;
331 for (i = 0; i < joydev->nabs; i++) { 316 for (i = 0; i < joydev->nabs; i++) {
332 j = joydev->abspam[i]; 317 j = joydev->abspam[i];
@@ -335,7 +320,7 @@ static int joydev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
335 return 0; 320 return 0;
336 case JSIOCGCORR: 321 case JSIOCGCORR:
337 return copy_to_user(argp, joydev->corr, 322 return copy_to_user(argp, joydev->corr,
338 sizeof(struct js_corr) * joydev->nabs) ? -EFAULT : 0; 323 sizeof(joydev->corr[0]) * joydev->nabs) ? -EFAULT : 0;
339 case JSIOCSAXMAP: 324 case JSIOCSAXMAP:
340 if (copy_from_user(joydev->abspam, argp, sizeof(__u8) * (ABS_MAX + 1))) 325 if (copy_from_user(joydev->abspam, argp, sizeof(__u8) * (ABS_MAX + 1)))
341 return -EFAULT; 326 return -EFAULT;
@@ -371,6 +356,84 @@ static int joydev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
371 return -EINVAL; 356 return -EINVAL;
372} 357}
373 358
359#ifdef CONFIG_COMPAT
360static long joydev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
361{
362 struct joydev_list *list = file->private_data;
363 struct joydev *joydev = list->joydev;
364 void __user *argp = (void __user *)arg;
365 s32 tmp32;
366 struct JS_DATA_SAVE_TYPE_32 ds32;
367 int err;
368
369 if (!joydev->exist) return -ENODEV;
370 switch(cmd) {
371 case JS_SET_TIMELIMIT:
372 err = get_user(tmp32, (s32 __user *) arg);
373 if (err == 0)
374 joydev->glue.JS_TIMELIMIT = tmp32;
375 break;
376 case JS_GET_TIMELIMIT:
377 tmp32 = joydev->glue.JS_TIMELIMIT;
378 err = put_user(tmp32, (s32 __user *) arg);
379 break;
380
381 case JS_SET_ALL:
382 err = copy_from_user(&ds32, argp,
383 sizeof(ds32)) ? -EFAULT : 0;
384 if (err == 0) {
385 joydev->glue.JS_TIMEOUT = ds32.JS_TIMEOUT;
386 joydev->glue.BUSY = ds32.BUSY;
387 joydev->glue.JS_EXPIRETIME = ds32.JS_EXPIRETIME;
388 joydev->glue.JS_TIMELIMIT = ds32.JS_TIMELIMIT;
389 joydev->glue.JS_SAVE = ds32.JS_SAVE;
390 joydev->glue.JS_CORR = ds32.JS_CORR;
391 }
392 break;
393
394 case JS_GET_ALL:
395 ds32.JS_TIMEOUT = joydev->glue.JS_TIMEOUT;
396 ds32.BUSY = joydev->glue.BUSY;
397 ds32.JS_EXPIRETIME = joydev->glue.JS_EXPIRETIME;
398 ds32.JS_TIMELIMIT = joydev->glue.JS_TIMELIMIT;
399 ds32.JS_SAVE = joydev->glue.JS_SAVE;
400 ds32.JS_CORR = joydev->glue.JS_CORR;
401
402 err = copy_to_user(argp, &ds32,
403 sizeof(ds32)) ? -EFAULT : 0;
404 break;
405
406 default:
407 err = joydev_ioctl_common(joydev, cmd, argp);
408 }
409 return err;
410}
411#endif /* CONFIG_COMPAT */
412
413static int joydev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
414{
415 struct joydev_list *list = file->private_data;
416 struct joydev *joydev = list->joydev;
417 void __user *argp = (void __user *)arg;
418
419 if (!joydev->exist) return -ENODEV;
420
421 switch(cmd) {
422 case JS_SET_TIMELIMIT:
423 return get_user(joydev->glue.JS_TIMELIMIT, (long __user *) arg);
424 case JS_GET_TIMELIMIT:
425 return put_user(joydev->glue.JS_TIMELIMIT, (long __user *) arg);
426 case JS_SET_ALL:
427 return copy_from_user(&joydev->glue, argp,
428 sizeof(joydev->glue)) ? -EFAULT : 0;
429 case JS_GET_ALL:
430 return copy_to_user(argp, &joydev->glue,
431 sizeof(joydev->glue)) ? -EFAULT : 0;
432 default:
433 return joydev_ioctl_common(joydev, cmd, argp);
434 }
435}
436
374static struct file_operations joydev_fops = { 437static struct file_operations joydev_fops = {
375 .owner = THIS_MODULE, 438 .owner = THIS_MODULE,
376 .read = joydev_read, 439 .read = joydev_read,
@@ -379,6 +442,9 @@ static struct file_operations joydev_fops = {
379 .open = joydev_open, 442 .open = joydev_open,
380 .release = joydev_release, 443 .release = joydev_release,
381 .ioctl = joydev_ioctl, 444 .ioctl = joydev_ioctl,
445#ifdef CONFIG_COMPAT
446 .compat_ioctl = joydev_compat_ioctl,
447#endif
382 .fasync = joydev_fasync, 448 .fasync = joydev_fasync,
383}; 449};
384 450
diff --git a/include/linux/joystick.h b/include/linux/joystick.h
index b7e0ab622cd7..06b9af77eb7f 100644
--- a/include/linux/joystick.h
+++ b/include/linux/joystick.h
@@ -111,18 +111,35 @@ struct js_corr {
111#define JS_SET_ALL 8 111#define JS_SET_ALL 8
112 112
113struct JS_DATA_TYPE { 113struct JS_DATA_TYPE {
114 int buttons; 114 __s32 buttons;
115 int x; 115 __s32 x;
116 int y; 116 __s32 y;
117}; 117};
118 118
119struct JS_DATA_SAVE_TYPE { 119struct JS_DATA_SAVE_TYPE_32 {
120 int JS_TIMEOUT; 120 __s32 JS_TIMEOUT;
121 int BUSY; 121 __s32 BUSY;
122 long JS_EXPIRETIME; 122 __s32 JS_EXPIRETIME;
123 long JS_TIMELIMIT; 123 __s32 JS_TIMELIMIT;
124 struct JS_DATA_TYPE JS_SAVE; 124 struct JS_DATA_TYPE JS_SAVE;
125 struct JS_DATA_TYPE JS_CORR; 125 struct JS_DATA_TYPE JS_CORR;
126}; 126};
127 127
128struct JS_DATA_SAVE_TYPE_64 {
129 __s32 JS_TIMEOUT;
130 __s32 BUSY;
131 __s64 JS_EXPIRETIME;
132 __s64 JS_TIMELIMIT;
133 struct JS_DATA_TYPE JS_SAVE;
134 struct JS_DATA_TYPE JS_CORR;
135};
136
137#if BITS_PER_LONG == 64
138#define JS_DATA_SAVE_TYPE JS_DATA_SAVE_TYPE_64
139#elif BITS_PER_LONG == 32
140#define JS_DATA_SAVE_TYPE JS_DATA_SAVE_TYPE_32
141#else
142#error Unexpected BITS_PER_LONG
143#endif
144
128#endif /* _LINUX_JOYSTICK_H */ 145#endif /* _LINUX_JOYSTICK_H */