diff options
Diffstat (limited to 'drivers/input/input.c')
-rw-r--r-- | drivers/input/input.c | 46 |
1 files changed, 27 insertions, 19 deletions
diff --git a/drivers/input/input.c b/drivers/input/input.c index 41168d5f8c17..9c79bd56b51a 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/types.h> | 14 | #include <linux/types.h> |
15 | #include <linux/input.h> | 15 | #include <linux/input.h> |
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/slab.h> | ||
17 | #include <linux/random.h> | 18 | #include <linux/random.h> |
18 | #include <linux/major.h> | 19 | #include <linux/major.h> |
19 | #include <linux/proc_fs.h> | 20 | #include <linux/proc_fs.h> |
@@ -582,7 +583,8 @@ static int input_fetch_keycode(struct input_dev *dev, int scancode) | |||
582 | } | 583 | } |
583 | 584 | ||
584 | static int input_default_getkeycode(struct input_dev *dev, | 585 | static int input_default_getkeycode(struct input_dev *dev, |
585 | int scancode, int *keycode) | 586 | unsigned int scancode, |
587 | unsigned int *keycode) | ||
586 | { | 588 | { |
587 | if (!dev->keycodesize) | 589 | if (!dev->keycodesize) |
588 | return -EINVAL; | 590 | return -EINVAL; |
@@ -596,7 +598,8 @@ static int input_default_getkeycode(struct input_dev *dev, | |||
596 | } | 598 | } |
597 | 599 | ||
598 | static int input_default_setkeycode(struct input_dev *dev, | 600 | static int input_default_setkeycode(struct input_dev *dev, |
599 | int scancode, int keycode) | 601 | unsigned int scancode, |
602 | unsigned int keycode) | ||
600 | { | 603 | { |
601 | int old_keycode; | 604 | int old_keycode; |
602 | int i; | 605 | int i; |
@@ -654,12 +657,17 @@ static int input_default_setkeycode(struct input_dev *dev, | |||
654 | * This function should be called by anyone interested in retrieving current | 657 | * This function should be called by anyone interested in retrieving current |
655 | * keymap. Presently keyboard and evdev handlers use it. | 658 | * keymap. Presently keyboard and evdev handlers use it. |
656 | */ | 659 | */ |
657 | int input_get_keycode(struct input_dev *dev, int scancode, int *keycode) | 660 | int input_get_keycode(struct input_dev *dev, |
661 | unsigned int scancode, unsigned int *keycode) | ||
658 | { | 662 | { |
659 | if (scancode < 0) | 663 | unsigned long flags; |
660 | return -EINVAL; | 664 | int retval; |
665 | |||
666 | spin_lock_irqsave(&dev->event_lock, flags); | ||
667 | retval = dev->getkeycode(dev, scancode, keycode); | ||
668 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
661 | 669 | ||
662 | return dev->getkeycode(dev, scancode, keycode); | 670 | return retval; |
663 | } | 671 | } |
664 | EXPORT_SYMBOL(input_get_keycode); | 672 | EXPORT_SYMBOL(input_get_keycode); |
665 | 673 | ||
@@ -672,16 +680,14 @@ EXPORT_SYMBOL(input_get_keycode); | |||
672 | * This function should be called by anyone needing to update current | 680 | * This function should be called by anyone needing to update current |
673 | * keymap. Presently keyboard and evdev handlers use it. | 681 | * keymap. Presently keyboard and evdev handlers use it. |
674 | */ | 682 | */ |
675 | int input_set_keycode(struct input_dev *dev, int scancode, int keycode) | 683 | int input_set_keycode(struct input_dev *dev, |
684 | unsigned int scancode, unsigned int keycode) | ||
676 | { | 685 | { |
677 | unsigned long flags; | 686 | unsigned long flags; |
678 | int old_keycode; | 687 | int old_keycode; |
679 | int retval; | 688 | int retval; |
680 | 689 | ||
681 | if (scancode < 0) | 690 | if (keycode > KEY_MAX) |
682 | return -EINVAL; | ||
683 | |||
684 | if (keycode < 0 || keycode > KEY_MAX) | ||
685 | return -EINVAL; | 691 | return -EINVAL; |
686 | 692 | ||
687 | spin_lock_irqsave(&dev->event_lock, flags); | 693 | spin_lock_irqsave(&dev->event_lock, flags); |
@@ -1881,35 +1887,37 @@ static int input_open_file(struct inode *inode, struct file *file) | |||
1881 | const struct file_operations *old_fops, *new_fops = NULL; | 1887 | const struct file_operations *old_fops, *new_fops = NULL; |
1882 | int err; | 1888 | int err; |
1883 | 1889 | ||
1884 | lock_kernel(); | 1890 | err = mutex_lock_interruptible(&input_mutex); |
1891 | if (err) | ||
1892 | return err; | ||
1893 | |||
1885 | /* No load-on-demand here? */ | 1894 | /* No load-on-demand here? */ |
1886 | handler = input_table[iminor(inode) >> 5]; | 1895 | handler = input_table[iminor(inode) >> 5]; |
1887 | if (!handler || !(new_fops = fops_get(handler->fops))) { | 1896 | if (handler) |
1888 | err = -ENODEV; | 1897 | new_fops = fops_get(handler->fops); |
1889 | goto out; | 1898 | |
1890 | } | 1899 | mutex_unlock(&input_mutex); |
1891 | 1900 | ||
1892 | /* | 1901 | /* |
1893 | * That's _really_ odd. Usually NULL ->open means "nothing special", | 1902 | * That's _really_ odd. Usually NULL ->open means "nothing special", |
1894 | * not "no device". Oh, well... | 1903 | * not "no device". Oh, well... |
1895 | */ | 1904 | */ |
1896 | if (!new_fops->open) { | 1905 | if (!new_fops || !new_fops->open) { |
1897 | fops_put(new_fops); | 1906 | fops_put(new_fops); |
1898 | err = -ENODEV; | 1907 | err = -ENODEV; |
1899 | goto out; | 1908 | goto out; |
1900 | } | 1909 | } |
1910 | |||
1901 | old_fops = file->f_op; | 1911 | old_fops = file->f_op; |
1902 | file->f_op = new_fops; | 1912 | file->f_op = new_fops; |
1903 | 1913 | ||
1904 | err = new_fops->open(inode, file); | 1914 | err = new_fops->open(inode, file); |
1905 | |||
1906 | if (err) { | 1915 | if (err) { |
1907 | fops_put(file->f_op); | 1916 | fops_put(file->f_op); |
1908 | file->f_op = fops_get(old_fops); | 1917 | file->f_op = fops_get(old_fops); |
1909 | } | 1918 | } |
1910 | fops_put(old_fops); | 1919 | fops_put(old_fops); |
1911 | out: | 1920 | out: |
1912 | unlock_kernel(); | ||
1913 | return err; | 1921 | return err; |
1914 | } | 1922 | } |
1915 | 1923 | ||