diff options
| author | Jeremy Fitzhardinge <jeremy@goop.org> | 2005-05-29 03:26:31 -0400 |
|---|---|---|
| committer | Dmitry Torokhov <dtor_core@ameritech.net> | 2005-05-29 03:26:31 -0400 |
| commit | 024ac44c701d43f5e2d34bd6a35b2813a36e6010 (patch) | |
| tree | 2f0cefd615ce72353e75536ac1067f549e7b5715 /drivers/input/joydev.c | |
| parent | f23488b2ab1b447ea4ea3d00cdb0d322a73e7f7f (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>
Diffstat (limited to 'drivers/input/joydev.c')
| -rw-r--r-- | drivers/input/joydev.c | 116 |
1 files changed, 91 insertions, 25 deletions
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index 627d343dfb..816a585a0e 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 | ||
| 288 | static int joydev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | 288 | static 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 | ||
| 360 | static 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 | |||
| 413 | static 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 | |||
| 374 | static struct file_operations joydev_fops = { | 437 | static 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 | ||
