]> git.hungrycats.org Git - linux/commitdiff
[PATCH] setkeycode ioctl fix
authorKnut Petersen <knut_petersen@t-online.de>
Fri, 24 Oct 2003 01:30:34 +0000 (18:30 -0700)
committerLinus Torvalds <torvalds@home.osdl.org>
Fri, 24 Oct 2003 01:30:34 +0000 (18:30 -0700)
This is a bugfix for setkeycode() in /drivers/char/keyboard.c.

If we change a keycode the corresponding bit should be cleared if and
only if this keycode is not defined any longer.  I believe that this
also was intended with the original code, but the implementation is
faulty.

First off all the first three changed lines are obviously erroneus:
oldkey == truekey is false or true, you do not need to inclose this in a
for().  I believe the author intended INPUT_KEYCODE(dev,i) == oldkey.
But fixing this alone is not enough.

If somebody wants to interchange the definition of two keys A and B, the
normal way is to use two setkeycode calls:

    setkeycode (scancode A, keycode B);
    setkeycode (scancode B, keycode A);

The old code does a clearbit(oldkey ..) call even in situations where
two keys have the same definition, and this situation arises commonly in
the situation mentioned above.

Both errors are fixed with this patch.

drivers/char/keyboard.c

index 5ae189b27825697ea1c78929b0533ff290d06547..65594dad55fd7e07830e7a59ba231ec7486b50bb 100644 (file)
@@ -204,13 +204,13 @@ int setkeycode(unsigned int scancode, unsigned int keycode)
        oldkey = INPUT_KEYCODE(dev, scancode);
        INPUT_KEYCODE(dev, scancode) = keycode;
 
-       for (i = 0; i < dev->keycodemax; i++)
-               if(keycode == oldkey)
-                       break;
-       if (i == dev->keycodemax)
-               clear_bit(oldkey, dev->keybit);
+       clear_bit(oldkey, dev->keybit);
        set_bit(keycode, dev->keybit);
-       
+
+       for (i = 0; i < dev->keycodemax; i++)
+               if (INPUT_KEYCODE(dev,i) == oldkey)
+                       set_bit(oldkey, dev->keybit);
+
        return 0;
 }