]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/blobdiff - drivers/input/input.c
Merge commit 'v2.6.33-rc5' into next
[mirror_ubuntu-focal-kernel.git] / drivers / input / input.c
index 30b503b8d67bfb64dd8d84a75adad686b9db403a..6c161e220868d6b6593e443e3b98fc80df2d0ee0 100644 (file)
@@ -614,12 +614,12 @@ static int input_default_setkeycode(struct input_dev *dev,
                }
        }
 
-       clear_bit(old_keycode, dev->keybit);
-       set_bit(keycode, dev->keybit);
+       __clear_bit(old_keycode, dev->keybit);
+       __set_bit(keycode, dev->keybit);
 
        for (i = 0; i < dev->keycodemax; i++) {
                if (input_fetch_keycode(dev, i) == old_keycode) {
-                       set_bit(old_keycode, dev->keybit);
+                       __set_bit(old_keycode, dev->keybit);
                        break; /* Setting the bit twice is useless, so break */
                }
        }
@@ -677,6 +677,9 @@ int input_set_keycode(struct input_dev *dev, int scancode, int keycode)
        if (retval)
                goto out;
 
+       /* Make sure KEY_RESERVED did not get enabled. */
+       __clear_bit(KEY_RESERVED, dev->keybit);
+
        /*
         * Simulate keyup event if keycode is not present
         * in the keymap anymore
@@ -1550,6 +1553,25 @@ void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int
 }
 EXPORT_SYMBOL(input_set_capability);
 
+#define INPUT_CLEANSE_BITMASK(dev, type, bits)                         \
+       do {                                                            \
+               if (!test_bit(EV_##type, dev->evbit))                   \
+                       memset(dev->bits##bit, 0,                       \
+                               sizeof(dev->bits##bit));                \
+       } while (0)
+
+static void input_cleanse_bitmasks(struct input_dev *dev)
+{
+       INPUT_CLEANSE_BITMASK(dev, KEY, key);
+       INPUT_CLEANSE_BITMASK(dev, REL, rel);
+       INPUT_CLEANSE_BITMASK(dev, ABS, abs);
+       INPUT_CLEANSE_BITMASK(dev, MSC, msc);
+       INPUT_CLEANSE_BITMASK(dev, LED, led);
+       INPUT_CLEANSE_BITMASK(dev, SND, snd);
+       INPUT_CLEANSE_BITMASK(dev, FF, ff);
+       INPUT_CLEANSE_BITMASK(dev, SW, sw);
+}
+
 /**
  * input_register_device - register device with input core
  * @dev: device to be registered
@@ -1569,13 +1591,19 @@ int input_register_device(struct input_dev *dev)
        const char *path;
        int error;
 
+       /* Every input device generates EV_SYN/SYN_REPORT events. */
        __set_bit(EV_SYN, dev->evbit);
 
+       /* KEY_RESERVED is not supposed to be transmitted to userspace. */
+       __clear_bit(KEY_RESERVED, dev->keybit);
+
+       /* Make sure that bitmasks not mentioned in dev->evbit are clean. */
+       input_cleanse_bitmasks(dev);
+
        /*
         * If delay and period are pre-set by the driver, then autorepeating
         * is handled by the driver itself and we don't do it in input.c.
         */
-
        init_timer(&dev->timer);
        if (!dev->rep[REP_DELAY] && !dev->rep[REP_PERIOD]) {
                dev->timer.data = (long) dev;