aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input')
-rw-r--r--drivers/input/evdev.c379
1 files changed, 180 insertions, 199 deletions
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index c1c220fcb763..d62c73f5ba93 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -236,7 +236,7 @@ static ssize_t evdev_read_compat(struct file * file, char __user * buffer, size_
236 event_compat.value = event->value; 236 event_compat.value = event->value;
237 237
238 if (copy_to_user(buffer + retval, &event_compat, 238 if (copy_to_user(buffer + retval, &event_compat,
239 sizeof(struct input_event_compat))) return -EFAULT; 239 sizeof(struct input_event_compat))) return -EFAULT;
240 list->tail = (list->tail + 1) & (EVDEV_BUFFER_SIZE - 1); 240 list->tail = (list->tail + 1) & (EVDEV_BUFFER_SIZE - 1);
241 retval += sizeof(struct input_event_compat); 241 retval += sizeof(struct input_event_compat);
242 } 242 }
@@ -272,7 +272,7 @@ static ssize_t evdev_read(struct file * file, char __user * buffer, size_t count
272 272
273 while (list->head != list->tail && retval + sizeof(struct input_event) <= count) { 273 while (list->head != list->tail && retval + sizeof(struct input_event) <= count) {
274 if (copy_to_user(buffer + retval, list->buffer + list->tail, 274 if (copy_to_user(buffer + retval, list->buffer + list->tail,
275 sizeof(struct input_event))) return -EFAULT; 275 sizeof(struct input_event))) return -EFAULT;
276 list->tail = (list->tail + 1) & (EVDEV_BUFFER_SIZE - 1); 276 list->tail = (list->tail + 1) & (EVDEV_BUFFER_SIZE - 1);
277 retval += sizeof(struct input_event); 277 retval += sizeof(struct input_event);
278 } 278 }
@@ -371,105 +371,112 @@ static long evdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
371 371
372 default: 372 default:
373 373
374 if (_IOC_TYPE(cmd) != 'E' || _IOC_DIR(cmd) != _IOC_READ) 374 if (_IOC_TYPE(cmd) != 'E')
375 return -EINVAL; 375 return -EINVAL;
376 376
377 if ((_IOC_NR(cmd) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0,0))) { 377 if (_IOC_DIR(cmd) == _IOC_READ) {
378 378
379 long *bits; 379 if ((_IOC_NR(cmd) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0,0))) {
380 int len; 380
381 381 long *bits;
382 switch (_IOC_NR(cmd) & EV_MAX) { 382 int len;
383 case 0: bits = dev->evbit; len = EV_MAX; break; 383
384 case EV_KEY: bits = dev->keybit; len = KEY_MAX; break; 384 switch (_IOC_NR(cmd) & EV_MAX) {
385 case EV_REL: bits = dev->relbit; len = REL_MAX; break; 385 case 0: bits = dev->evbit; len = EV_MAX; break;
386 case EV_ABS: bits = dev->absbit; len = ABS_MAX; break; 386 case EV_KEY: bits = dev->keybit; len = KEY_MAX; break;
387 case EV_MSC: bits = dev->mscbit; len = MSC_MAX; break; 387 case EV_REL: bits = dev->relbit; len = REL_MAX; break;
388 case EV_LED: bits = dev->ledbit; len = LED_MAX; break; 388 case EV_ABS: bits = dev->absbit; len = ABS_MAX; break;
389 case EV_SND: bits = dev->sndbit; len = SND_MAX; break; 389 case EV_MSC: bits = dev->mscbit; len = MSC_MAX; break;
390 case EV_FF: bits = dev->ffbit; len = FF_MAX; break; 390 case EV_LED: bits = dev->ledbit; len = LED_MAX; break;
391 default: return -EINVAL; 391 case EV_SND: bits = dev->sndbit; len = SND_MAX; break;
392 case EV_FF: bits = dev->ffbit; len = FF_MAX; break;
393 default: return -EINVAL;
394 }
395 len = NBITS(len) * sizeof(long);
396 if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
397 return copy_to_user(p, bits, len) ? -EFAULT : len;
392 } 398 }
393 len = NBITS(len) * sizeof(long);
394 if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
395 return copy_to_user(p, bits, len) ? -EFAULT : len;
396 }
397 399
398 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGKEY(0))) { 400 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGKEY(0))) {
399 int len; 401 int len;
400 len = NBITS(KEY_MAX) * sizeof(long); 402 len = NBITS(KEY_MAX) * sizeof(long);
401 if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); 403 if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
402 return copy_to_user(p, dev->key, len) ? -EFAULT : len; 404 return copy_to_user(p, dev->key, len) ? -EFAULT : len;
403 } 405 }
404 406
405 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGLED(0))) { 407 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGLED(0))) {
406 int len; 408 int len;
407 len = NBITS(LED_MAX) * sizeof(long); 409 len = NBITS(LED_MAX) * sizeof(long);
408 if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); 410 if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
409 return copy_to_user(p, dev->led, len) ? -EFAULT : len; 411 return copy_to_user(p, dev->led, len) ? -EFAULT : len;
410 } 412 }
411 413
412 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSND(0))) { 414 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSND(0))) {
413 int len; 415 int len;
414 len = NBITS(SND_MAX) * sizeof(long); 416 len = NBITS(SND_MAX) * sizeof(long);
415 if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); 417 if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
416 return copy_to_user(p, dev->snd, len) ? -EFAULT : len; 418 return copy_to_user(p, dev->snd, len) ? -EFAULT : len;
417 } 419 }
418 420
419 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0))) { 421 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0))) {
420 int len; 422 int len;
421 if (!dev->name) return -ENOENT; 423 if (!dev->name) return -ENOENT;
422 len = strlen(dev->name) + 1; 424 len = strlen(dev->name) + 1;
423 if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); 425 if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
424 return copy_to_user(p, dev->name, len) ? -EFAULT : len; 426 return copy_to_user(p, dev->name, len) ? -EFAULT : len;
425 } 427 }
426 428
427 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGPHYS(0))) { 429 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGPHYS(0))) {
428 int len; 430 int len;
429 if (!dev->phys) return -ENOENT; 431 if (!dev->phys) return -ENOENT;
430 len = strlen(dev->phys) + 1; 432 len = strlen(dev->phys) + 1;
431 if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); 433 if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
432 return copy_to_user(p, dev->phys, len) ? -EFAULT : len; 434 return copy_to_user(p, dev->phys, len) ? -EFAULT : len;
433 } 435 }
434 436
435 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGUNIQ(0))) { 437 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGUNIQ(0))) {
436 int len; 438 int len;
437 if (!dev->uniq) return -ENOENT; 439 if (!dev->uniq) return -ENOENT;
438 len = strlen(dev->uniq) + 1; 440 len = strlen(dev->uniq) + 1;
439 if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); 441 if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
440 return copy_to_user(p, dev->uniq, len) ? -EFAULT : len; 442 return copy_to_user(p, dev->uniq, len) ? -EFAULT : len;
441 } 443 }
442 444
443 if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) { 445 if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) {
444 446
445 int t = _IOC_NR(cmd) & ABS_MAX; 447 int t = _IOC_NR(cmd) & ABS_MAX;
446 448
447 abs.value = dev->abs[t]; 449 abs.value = dev->abs[t];
448 abs.minimum = dev->absmin[t]; 450 abs.minimum = dev->absmin[t];
449 abs.maximum = dev->absmax[t]; 451 abs.maximum = dev->absmax[t];
450 abs.fuzz = dev->absfuzz[t]; 452 abs.fuzz = dev->absfuzz[t];
451 abs.flat = dev->absflat[t]; 453 abs.flat = dev->absflat[t];
452 454
453 if (copy_to_user(p, &abs, sizeof(struct input_absinfo))) 455 if (copy_to_user(p, &abs, sizeof(struct input_absinfo)))
454 return -EFAULT; 456 return -EFAULT;
457
458 return 0;
459 }
455 460
456 return 0;
457 } 461 }
458 462
459 if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0))) { 463 if (_IOC_DIR(cmd) == _IOC_WRITE) {
460 464
461 int t = _IOC_NR(cmd) & ABS_MAX; 465 if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0))) {
462 466
463 if (copy_from_user(&abs, p, sizeof(struct input_absinfo))) 467 int t = _IOC_NR(cmd) & ABS_MAX;
464 return -EFAULT; 468
469 if (copy_from_user(&abs, p, sizeof(struct input_absinfo)))
470 return -EFAULT;
465 471
466 dev->abs[t] = abs.value; 472 dev->abs[t] = abs.value;
467 dev->absmin[t] = abs.minimum; 473 dev->absmin[t] = abs.minimum;
468 dev->absmax[t] = abs.maximum; 474 dev->absmax[t] = abs.maximum;
469 dev->absfuzz[t] = abs.fuzz; 475 dev->absfuzz[t] = abs.fuzz;
470 dev->absflat[t] = abs.flat; 476 dev->absflat[t] = abs.flat;
471 477
472 return 0; 478 return 0;
479 }
473 } 480 }
474 } 481 }
475 return -EINVAL; 482 return -EINVAL;
@@ -484,6 +491,28 @@ static long evdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
484#define LONG_COMPAT(x) ((x)/BITS_PER_LONG_COMPAT) 491#define LONG_COMPAT(x) ((x)/BITS_PER_LONG_COMPAT)
485#define test_bit_compat(bit, array) ((array[LONG_COMPAT(bit)] >> OFF_COMPAT(bit)) & 1) 492#define test_bit_compat(bit, array) ((array[LONG_COMPAT(bit)] >> OFF_COMPAT(bit)) & 1)
486 493
494#ifdef __BIG_ENDIAN
495#define bit_to_user(bit, max) \
496do { \
497 int i; \
498 int len = NBITS_COMPAT((max)) * sizeof(compat_long_t); \
499 if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); \
500 for (i = 0; i < len / sizeof(compat_long_t); i++) \
501 if (copy_to_user((compat_long_t*) p + i, \
502 (compat_long_t*) (bit) + i + 1 - ((i % 2) << 1), \
503 sizeof(compat_long_t))) \
504 return -EFAULT; \
505 return len; \
506} while (0)
507#else
508#define bit_to_user(bit, max) \
509do { \
510 int len = NBITS_COMPAT((max)) * sizeof(compat_long_t); \
511 if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); \
512 return copy_to_user(p, (bit), len) ? -EFAULT : len; \
513} while (0)
514#endif
515
487static long evdev_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg) 516static long evdev_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
488{ 517{
489 struct evdev_list *list = file->private_data; 518 struct evdev_list *list = file->private_data;
@@ -491,9 +520,6 @@ static long evdev_ioctl_compat(struct file *file, unsigned int cmd, unsigned lon
491 struct input_dev *dev = evdev->handle.dev; 520 struct input_dev *dev = evdev->handle.dev;
492 struct input_absinfo abs; 521 struct input_absinfo abs;
493 void __user *p = compat_ptr(arg); 522 void __user *p = compat_ptr(arg);
494#ifdef __BIG_ENDIAN
495 int i;
496#endif
497 523
498 if (!evdev->exist) return -ENODEV; 524 if (!evdev->exist) return -ENODEV;
499 525
@@ -511,141 +537,96 @@ static long evdev_ioctl_compat(struct file *file, unsigned int cmd, unsigned lon
511 537
512 default: 538 default:
513 539
514 if (_IOC_TYPE(cmd) != 'E' || _IOC_DIR(cmd) != _IOC_READ) 540 if (_IOC_TYPE(cmd) != 'E')
515 return -EINVAL; 541 return -EINVAL;
516 542
517 if ((_IOC_NR(cmd) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0,0))) { 543 if (_IOC_DIR(cmd) == _IOC_READ) {
518 544
519 long *bits; 545 if ((_IOC_NR(cmd) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0,0))) {
520 int len; 546 long *bits;
521 547 int max;
522 switch (_IOC_NR(cmd) & EV_MAX) { 548
523 case 0: bits = dev->evbit; len = EV_MAX; break; 549 switch (_IOC_NR(cmd) & EV_MAX) {
524 case EV_KEY: bits = dev->keybit; len = KEY_MAX; break; 550 case 0: bits = dev->evbit; max = EV_MAX; break;
525 case EV_REL: bits = dev->relbit; len = REL_MAX; break; 551 case EV_KEY: bits = dev->keybit; max = KEY_MAX; break;
526 case EV_ABS: bits = dev->absbit; len = ABS_MAX; break; 552 case EV_REL: bits = dev->relbit; max = REL_MAX; break;
527 case EV_MSC: bits = dev->mscbit; len = MSC_MAX; break; 553 case EV_ABS: bits = dev->absbit; max = ABS_MAX; break;
528 case EV_LED: bits = dev->ledbit; len = LED_MAX; break; 554 case EV_MSC: bits = dev->mscbit; max = MSC_MAX; break;
529 case EV_SND: bits = dev->sndbit; len = SND_MAX; break; 555 case EV_LED: bits = dev->ledbit; max = LED_MAX; break;
530 case EV_FF: bits = dev->ffbit; len = FF_MAX; break; 556 case EV_SND: bits = dev->sndbit; max = SND_MAX; break;
531 default: return -EINVAL; 557 case EV_FF: bits = dev->ffbit; max = FF_MAX; break;
558 default: return -EINVAL;
559 }
560 bit_to_user(bits, max);
532 } 561 }
533 len = NBITS_COMPAT(len) * sizeof(compat_long_t);
534 if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
535#ifdef __BIG_ENDIAN
536 for (i = 0; i < len / sizeof(compat_long_t); i++)
537 if (copy_to_user((compat_long_t*) p + i,
538 (compat_long_t*) bits + i + 1 - ((i % 2) << 1),
539 sizeof(compat_long_t)))
540 return -EFAULT;
541 return len;
542#else
543 return copy_to_user(p, bits, len) ? -EFAULT : len;
544#endif
545 }
546 562
547 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGKEY(0))) { 563 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGKEY(0)))
548 int len; 564 bit_to_user(dev->key, KEY_MAX);
549 len = NBITS_COMPAT(KEY_MAX) * sizeof(compat_long_t);
550 if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
551#ifdef __BIG_ENDIAN
552 for (i = 0; i < len / sizeof(compat_long_t); i++)
553 if (copy_to_user((compat_long_t*) p + i,
554 (compat_long_t*) dev->key + i + 1 - ((i % 2) << 1),
555 sizeof(compat_long_t)))
556 return -EFAULT;
557 return len;
558#else
559 return copy_to_user(p, dev->key, len) ? -EFAULT : len;
560#endif
561 }
562 565
563 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGLED(0))) { 566 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGLED(0)))
564 int len; 567 bit_to_user(dev->led, LED_MAX);
565 len = NBITS_COMPAT(LED_MAX) * sizeof(compat_long_t);
566 if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
567#ifdef __BIG_ENDIAN
568 for (i = 0; i < len / sizeof(compat_long_t); i++)
569 if (copy_to_user((compat_long_t*) p + i,
570 (compat_long_t*) dev->led + i + 1 - ((i % 2) << 1),
571 sizeof(compat_long_t)))
572 return -EFAULT;
573 return len;
574#else
575 return copy_to_user(p, dev->led, len) ? -EFAULT : len;
576#endif
577 }
578 568
579 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSND(0))) { 569 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSND(0)))
580 int len; 570 bit_to_user(dev->snd, SND_MAX);
581 len = NBITS_COMPAT(SND_MAX) * sizeof(compat_long_t);
582 if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
583#ifdef __BIG_ENDIAN
584 for (i = 0; i < len / sizeof(compat_long_t); i++)
585 if (copy_to_user((compat_long_t*) p + i,
586 (compat_long_t*) dev->snd + i + 1 - ((i % 2) << 1),
587 sizeof(compat_long_t)))
588 return -EFAULT;
589 return len;
590#else
591 return copy_to_user(p, dev->snd, len) ? -EFAULT : len;
592#endif
593 }
594 571
595 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0))) { 572 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0))) {
596 int len; 573 int len;
597 if (!dev->name) return -ENOENT; 574 if (!dev->name) return -ENOENT;
598 len = strlen(dev->name) + 1; 575 len = strlen(dev->name) + 1;
599 if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); 576 if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
600 return copy_to_user(p, dev->name, len) ? -EFAULT : len; 577 return copy_to_user(p, dev->name, len) ? -EFAULT : len;
601 } 578 }
602 579
603 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGPHYS(0))) { 580 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGPHYS(0))) {
604 int len; 581 int len;
605 if (!dev->phys) return -ENOENT; 582 if (!dev->phys) return -ENOENT;
606 len = strlen(dev->phys) + 1; 583 len = strlen(dev->phys) + 1;
607 if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); 584 if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
608 return copy_to_user(p, dev->phys, len) ? -EFAULT : len; 585 return copy_to_user(p, dev->phys, len) ? -EFAULT : len;
609 } 586 }
610 587
611 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGUNIQ(0))) { 588 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGUNIQ(0))) {
612 int len; 589 int len;
613 if (!dev->uniq) return -ENOENT; 590 if (!dev->uniq) return -ENOENT;
614 len = strlen(dev->uniq) + 1; 591 len = strlen(dev->uniq) + 1;
615 if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); 592 if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
616 return copy_to_user(p, dev->uniq, len) ? -EFAULT : len; 593 return copy_to_user(p, dev->uniq, len) ? -EFAULT : len;
617 } 594 }
618 595
619 if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) { 596 if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) {
620 597
621 int t = _IOC_NR(cmd) & ABS_MAX; 598 int t = _IOC_NR(cmd) & ABS_MAX;
622 599
623 abs.value = dev->abs[t]; 600 abs.value = dev->abs[t];
624 abs.minimum = dev->absmin[t]; 601 abs.minimum = dev->absmin[t];
625 abs.maximum = dev->absmax[t]; 602 abs.maximum = dev->absmax[t];
626 abs.fuzz = dev->absfuzz[t]; 603 abs.fuzz = dev->absfuzz[t];
627 abs.flat = dev->absflat[t]; 604 abs.flat = dev->absflat[t];
628 605
629 if (copy_to_user(p, &abs, sizeof(struct input_absinfo))) 606 if (copy_to_user(p, &abs, sizeof(struct input_absinfo)))
630 return -EFAULT; 607 return -EFAULT;
631 608
632 return 0; 609 return 0;
610 }
633 } 611 }
634 612
635 if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0))) { 613 if (_IOC_DIR(cmd) == _IOC_WRITE) {
636 614
637 int t = _IOC_NR(cmd) & ABS_MAX; 615 if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0))) {
638 616
639 if (copy_from_user(&abs, p, sizeof(struct input_absinfo))) 617 int t = _IOC_NR(cmd) & ABS_MAX;
640 return -EFAULT;
641 618
642 dev->abs[t] = abs.value; 619 if (copy_from_user(&abs, p, sizeof(struct input_absinfo)))
643 dev->absmin[t] = abs.minimum; 620 return -EFAULT;
644 dev->absmax[t] = abs.maximum;
645 dev->absfuzz[t] = abs.fuzz;
646 dev->absflat[t] = abs.flat;
647 621
648 return 0; 622 dev->abs[t] = abs.value;
623 dev->absmin[t] = abs.minimum;
624 dev->absmax[t] = abs.maximum;
625 dev->absfuzz[t] = abs.fuzz;
626 dev->absflat[t] = abs.flat;
627
628 return 0;
629 }
649 } 630 }
650 } 631 }
651 return -EINVAL; 632 return -EINVAL;